diff --git a/math/stats/Statistics.h b/math/stats/Statistics.h index a8bbb2f..e689f68 100644 --- a/math/stats/Statistics.h +++ b/math/stats/Statistics.h @@ -59,6 +59,10 @@ namespace Stats { return sum / (double) cnt; } + T getSquaredSumAvg() const { + return sumSquared / (double)cnt; + } + /** get the given quantile (e.g. 0.5 for median) */ T getQuantile(const double q) const { if (q < 0) {return *values.begin();} diff --git a/sensors/offline/FileReader.h b/sensors/offline/FileReader.h index ce496c4..7d8a912 100644 --- a/sensors/offline/FileReader.h +++ b/sensors/offline/FileReader.h @@ -64,6 +64,7 @@ namespace Offline { std::vector> gps; std::vector> compass; std::vector> magnetometer; + std::vector> wifiFtm; /** all entries in linear order as they appeared while recording */ std::vector entries; @@ -102,6 +103,7 @@ namespace Offline { lin_acc.clear(); gravity.clear(); magnetometer.clear(); + wifiFtm.clear(); } const std::vector& getEntries() const {return entries;} @@ -130,6 +132,8 @@ namespace Offline { const std::vector>& getMagnetometer() const {return magnetometer;} + const std::vector>& getWifiFtm() const { return wifiFtm; } + /** get an interpolateable ground-truth based on the time-clicks during recording */ GroundTruth getGroundTruth(const Floorplan::IndoorMap* map, const std::vector groundTruthPoints) const { @@ -199,6 +203,7 @@ namespace Offline { else if (idx == (int)Sensor::COMPASS) {parseCompass(ts,data);} else if (idx == (int)Sensor::GPS) {parseGPS(ts,data);} else if (idx == (int)Sensor::MAGNETOMETER) {parseMagnetometer(ts,data);} + else if (idx == (int)Sensor::WIFI_FTM) {parseWifiFtm(ts, data);} else if (idx == (int)Sensor::ACTIVITY) {parseActivity(ts, data);} // TODO: this is a hack... @@ -313,6 +318,33 @@ namespace Offline { } + void parseWifiFtm(const uint64_t ts, const std::string& data) { + + Splitter s(data, sep); + + const int successMeas = s.getInteger(0); + const std::string mac = s.get(1); + const float dist = s.getFloat(2) / 1000; // mm -> m + const float distStdDev = s.getFloat(3) / 1000; + const float rssi = s.getFloat(4); + + const int numAttempts = !s.isEmpty(5) ? s.getInteger(5) : 0; + const int numSuccess = !s.isEmpty(6) ? s.getInteger(6) : 0; + + // append AP to current scan-entry + if (successMeas) + { + WiFiMeasurement meas(AccessPoint(mac), rssi, Timestamp::fromMS(ts), dist, distStdDev, numAttempts, numSuccess); + + wifiFtm.push_back(TS(ts, meas)); + entries.push_back(Entry(Sensor::WIFI_FTM, ts, this->wifiFtm.size() - 1)); + } + + // inform listener + //if (listener) {listener->onWiFi(Timestamp::fromMS(ts), wifi);} + + } + void parseBeacons(const uint64_t ts, const std::string& data) { const auto pos1 = data.find(';'); diff --git a/sensors/offline/Sensors.h b/sensors/offline/Sensors.h index 6c59dcb..1b5dd06 100644 --- a/sensors/offline/Sensors.h +++ b/sensors/offline/Sensors.h @@ -1,11 +1,11 @@ /* - * © Copyright 2014 – Urheberrechtshinweis + * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. - * (vgl. § 106 ff UrhG / § 97 UrhG) + * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef OFFLINE_SENSORS_H @@ -24,6 +24,7 @@ namespace Offline { WIFI = 8, BEACON = 9, GPS = 16, + WIFI_FTM = 17, ACTIVITY = 50, GROUND_TRUTH = 99, POS = 1001, // IPIN2016 diff --git a/sensors/offline/Splitter.h b/sensors/offline/Splitter.h index c8db760..c553355 100644 --- a/sensors/offline/Splitter.h +++ b/sensors/offline/Splitter.h @@ -34,12 +34,15 @@ public: const std::string& get(const int idx) const {return split.at(idx);} - const float getFloat(const int idx) const {return std::stof(get(idx));} + const float getFloat (const int idx) const {return std::stof(get(idx));} + const int getInteger(const int idx) const {return std::stoi(get(idx));} size_t size() const {return split.size();} bool empty() const {return split.empty();} + bool isEmpty(int idx) const { return has(idx) ? get(idx) == "" : true; } + private: void build() { diff --git a/sensors/radio/WiFiMeasurement.h b/sensors/radio/WiFiMeasurement.h index 71b7c6d..715e332 100644 --- a/sensors/radio/WiFiMeasurement.h +++ b/sensors/radio/WiFiMeasurement.h @@ -29,6 +29,18 @@ private: /** the measured signal strength */ float rssi; + /** FTM: estimated distance in m **/ + float distance = NAN; + + /** FTM: standard deviation of estimated distance in m. Only valid if numSuccessfulMeasurements >= 2 **/ + float distanceStdDev = NAN; + + /** FTM: The number of attempted measurements used in the RTT exchange **/ + int numAttemptedMeasurements = 0; + + /** FTM: The number of successful measurements used to calculate the distance and standard deviation **/ + int numSuccessfulMeasurements = 0; + /** OPTIONAL. frequence the signal was received */ float freq = NAN; @@ -52,6 +64,12 @@ public: ; } + /** ctor with timestamp and ftm */ + WiFiMeasurement(const AccessPoint& ap, const float rssi, const Timestamp ts, const float distance, const float distanceStdDev, const int numAttemptedMeasurements, const int numSuccessfulMeasurements) + : ap(ap), rssi(rssi), freq(NAN), ts(ts), distance(distance), distanceStdDev(distanceStdDev), numAttemptedMeasurements(numAttemptedMeasurements), numSuccessfulMeasurements(numSuccessfulMeasurements) { + ; + } + /** ctor with timestamp and freq*/ WiFiMeasurement(const AccessPoint& ap, const float rssi, const float freq, const Timestamp ts) : ap(ap), rssi(rssi), freq(freq), ts(ts) { ; @@ -68,6 +86,12 @@ public: /** OPTIONAL: get the measurement's timestamp (if known!) */ const Timestamp& getTimestamp() const {return ts;} + float getFtmDist() const { return distance; } + float getFtmDistStd() const { return distanceStdDev; } + + int getNumAttemptedMeasurements() const { return numAttemptedMeasurements; } + int getNumSuccessfulMeasurements() const { return numSuccessfulMeasurements; } + /** timestamp known? */ bool hasTimestamp() const {return ts == ts;} @@ -83,6 +107,8 @@ public: /** set the timestamp */ void setTimestamp(const Timestamp& val){ts = val;} + void setFtmDist(float val) { distance = val; } + /** as string for debug printing */ std::string asString() const { std::string res = ap.asString();