#ifndef ALLINONESENSOR_H #define ALLINONESENSOR_H #include "Settings.h" #include #include "../WiFiSensor.h" #include "../AccelerometerSensor.h" #include "../GyroscopeSensor.h" #include "../BarometerSensor.h" #include "../CompassSensor.h" #include "../GPSSensor.h" #include #include class AllInOneSensor : public WiFiSensor, public AccelerometerSensor, public GyroscopeSensor, public BarometerSensor, public CompassSensor, public GPSSensor, public Offline::Listener { private: std::string file; bool running = false; std::thread thread; public: AllInOneSensor(const std::string& file) : file(file) { ; } void start() { if (running) {return;} running = true; thread = std::thread(&AllInOneSensor::run, this); } void stop() { if (!running) {return;} running = false; thread.join(); } bool isRunning() const override { return running; } protected: virtual void onGyroscope(const Timestamp _ts, const GyroscopeData data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); GyroscopeSensor::informListeners(ts, data); } virtual void onAccelerometer(const Timestamp _ts, const AccelerometerData data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); AccelerometerSensor::informListeners(ts, data); } virtual void onGravity(const Timestamp ts, const AccelerometerData data) override { (void) ts; (void) data; } virtual void onWiFi(const Timestamp _ts, const WiFiMeasurements data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); WiFiMeasurements copy = data; for (WiFiMeasurement& m : copy.entries) {m.setTimestamp(ts);} // make each timestmap also relative WiFiSensor::informListeners(ts, copy); } virtual void onBarometer(const Timestamp _ts, const BarometerData data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); BarometerSensor::informListeners(ts, data); } virtual void onGPS(const Timestamp _ts, const GPSData data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); GPSSensor::informListeners(ts, data); } virtual void onCompass(const Timestamp _ts, const CompassData data) override { const Timestamp ts = relativeTS(_ts); handbrake(ts); CompassSensor::informListeners(ts, data); } private: Timestamp baseTS; Timestamp relativeTS(const Timestamp ts) { if (baseTS.isZero()) {baseTS = ts;} return ts - baseTS; } /** handbrake for the offline-parser to ensure realtime events */ Timestamp startSensorTS; Timestamp startSystemTS; void handbrake(const Timestamp ts) { if (startSensorTS.isZero()) {startSensorTS = ts;} if (startSystemTS.isZero()) {startSystemTS = Timestamp::fromUnixTime();} const Timestamp runtimeOfflineData = ts - startSensorTS;; const Timestamp runtimeSystemTime = (Timestamp::fromUnixTime() - startSystemTS) * Settings::offlineSensorSpeedup; const Timestamp diff = (runtimeOfflineData - runtimeSystemTime); if (diff > Timestamp::fromMS(0)) { std::this_thread::sleep_for(std::chrono::milliseconds(diff.ms())); } } private: /** * file-parsing runs in a background thread * the parsing is manually slowed down via handbrake() * which blocks during the event callbacks */ void run() { OfflineAndroid parser; parser.parse(file, this); } }; #endif // ALLINONESENSOR_H