#ifndef STEPLOGGER_H #define STEPLOGGER_H #include #include #include #include #include #include #include "Scaler.h" #include "Config.h" #include "IPINHelper.h" class StepLogger { private: EvalConfig cfg; std::string configFile; std::string competitorID = "navindoor"; std::ofstream outButtons; std::ofstream outPositions; /** all step-logger wayponts defined within the config file */ std::vector waypoints; int curWP = 0; public: /** ctor with the map<->world scaler */ StepLogger() { loadConfig(); start(); } public: /** log current timestamp + waypoint and proceed with the next one */ void onButtonPress() { // sanity check if (isDone()) {throw Exception("all waypoints were processed");} // construct output string std::stringstream ss; std::string wpEntry = waypoints[curWP]; ++curWP; wpEntry = replace(wpEntry, ":" , " : "); ss << Timestamp::fromUnixTime().ms() << " : " << wpEntry << "\r\n"; // log std::cout << ss.str() << std::flush; outButtons << ss.str(); outButtons.flush(); } /** all waypoints done? */ bool isDone() const { return curWP >= (int)waypoints.size(); } /** log our map-relative format */ void onNewEstimation(const double lat, const double lon, const double floorNr) { // construct output string std::stringstream ss; ss << Timestamp::fromUnixTime().ms() << " : " << lat << " : " << lon << " : " << floorNr << "\r\n"; // log std::cout << ss.str() << std::endl; outPositions << ss.str(); outPositions.flush(); } /** get the current waypoint's number, starting at 0 */ int getCurrentWaypointNumber() const { return curWP; } private: /** split the given string */ std::vector split(const std::string& str, const char delim) { std::vector res; int start = 0; while (true) { size_t pos = str.find(delim, start); if (pos == std::string::npos) {break;} const std::string sub = str.substr(start, pos-start); res.push_back(sub); start = pos + 1; } return res; } /** string replacement helper */ std::string replace(std::string str, const std::string& from, const std::string& to) { size_t start_pos = 0; while((start_pos = str.find(from, start_pos)) != std::string::npos) { str.replace(start_pos, from.length(), to); start_pos += to.length(); } return str; } /** get the current time as [YYYYMMDD]T[HHMMSS] */ std::string getDate() const { const char* format = "%Y%m%dT%H%m%S"; std::time_t t = std::time(nullptr); struct tm* tt = std::localtime(&t); char buf[128]; strftime(buf, 128, format, tt); return std::string(buf); // std::stringstream ss; // ss << std::put_time(tt, format); // return ss.str(); } private: /** load the config.ini and parse the waypoints */ void loadConfig() { cfg.load(IPINHelper::getDataFolder() + "it.cnr.isti.steplogger.config.ini"); const std::string tmp = cfg.get("counter"); waypoints = split(tmp, ','); } /** create the data-folder, open the two output files and perform sanity checks */ void start() { // get the output data folder and construct filenames const std::string folder = getOutputFolder(); const std::string fBtn = folder + "buttonsPressed.log"; const std::string fPos = folder + "positions.log"; // open two output files outButtons.open(fBtn); if (!outButtons.good()) {throw Exception("error while creating file");} outPositions.open(fPos); if (!outPositions.good()) {throw Exception("error while creating file");} // reset current WayPoint curWP = 0; } /** get a DateTime dependent data folder */ std::string getOutputFolder() { const std::string& folder = IPINHelper::getDataFolder(); const std::string date = getDate(); const std::string sub = folder + date + "_" + competitorID + "/"; mkdir(sub.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); return sub; } // // config file // Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + // File.separator + // "it.cnr.isti.steplogger.config.ini"; // buttonsPressed.log // milliseconds " : " number-starting-at-1" : "???" : "???" : "floor? // see configFile config.ini // java current time millis // positions.log // timestamp " " x " " y " " z // storage/sdcard0/Download/it.cnr.isti.steplogger/ // Within the folder it.cnr.isti.steplogger/ StepLogger creates a folder for every measurement session, the logs are placed in folder whose name follows this convention: // [YearMonthDay]T[HourMinutesSeconds][Competitor ID] // // Coordinates will need to be in the WGS84 coordinate system (longitude and latitude) for x, y, // //and the number of floor (an integer starting from 0) for z. }; #endif // STEPLOGGER_H