#ifndef SENSORREADER_H #define SENSORREADER_H #include #include #include #include #include #include "Recording.h" #include "Sensors.h" /** * parse all sensor values from HandyGames data-files */ class SensorReader { private: static constexpr int bufSize = 4096; public: /** parse all values within the given file */ static Recording read(const std::string& file) { Recording rec; Sensors curSensor = Sensors::UNKNOWN; char buf[bufSize]; // check std::ifstream f(file.c_str()); if (!f.good()) {throw "error!";} // parse each line while(!f.bad() && !f.eof()) { // read the next line f.getline(buf, bufSize); std::string line(buf); // new sensor section? -> switch the current sensor if (startsWith(line, "// [SENSOR] ")) { std::string tmp = line.substr(19); int idx = indexOf(tmp, ";"); curSensor = getSensor(tmp.substr(0, idx)); } // skip empty lines else if (line.empty()) {;} // parse sensor values else { switch (curSensor) { case Sensors::TYPE_ACCELEROMETER: parseAccel(rec, line); break; case Sensors::TYPE_GYROSCOPE: parseGyro(rec, line); break; case Sensors::TYPE_MAGNETIC_FIELD: parseMagField(rec, line); break; default: break; } } } // done return rec; } static void parseAccel(Recording& rec, const std::string& line) { const std::vector values = split(line); rec.accel.add(getTS(values[0]), SensorAccelerometer(getFloat(values[1]), getFloat(values[2]), getFloat(values[3]))); } static void parseGyro(Recording& rec, const std::string& line) { const std::vector values = split(line); rec.gyro.add(getTS(values[0]), SensorGyro(getFloat(values[1]), getFloat(values[2]), getFloat(values[3]))); } static void parseMagField(Recording& rec, const std::string& line) { const std::vector values = split(line); rec.magField.add(getTS(values[0]), SensorMagneticField(getFloat(values[1]), getFloat(values[2]), getFloat(values[3]))); } /** get the timestamp for the given string-value */ static uint64_t getTS(const std::string& s) { return std::stoul(s) / 1000 / 1000; } /** convert the given string to a float value */ static float getFloat(const std::string& s) { return std::stof(s); } /** does the given haystack start with the given needle? */ static bool startsWith(const std::string& haystack, const std::string& needle) { if (needle.length() > haystack.length()) {return false;} return memcmp(haystack.data(), needle.data(), needle.length()) == 0; } /** position of the first occurence of needle within haystack */ static int indexOf(const std::string& haystack, const std::string& needle, const int start = 0) { std::string::size_type index = haystack.find(needle, start); return (index == std::string::npos ) ? (-1) : (index); } static std::vector split(const std::string& str) { std::vector list; int last = 0; while(true) { const int next = indexOf(str, ",", last); if (next == -1) { std::string sub = str.substr(last, str.length()-last-2); list.push_back(sub); break; } else { std::string sub = str.substr(last, next-last); list.push_back(sub); last = next+2; } } return list; } }; #endif // SENSORREADER_H