This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/sensors/radio/setup/WiFiFingerprint.h
kazu 06e0e0a5aa fixed some potential issues with MAC addresses
added corresponding test-cases
switched to newer version of tinyxml due to some issues
adjusted affected code-parts accordingly
for better re-use, moved ceiling-calculation to a new class
some minor fixes
new helper methods
worked on wifi-opt
2017-03-20 11:19:57 +01:00

95 lines
2.6 KiB
C++

#ifndef WIFIFINGERPRINT_H
#define WIFIFINGERPRINT_H
#include "../../../geo/Point3.h"
#include "../WiFiMeasurements.h"
#include <unordered_map>
/**
* denotes a wifi fingerprint:
* known position and 1-n measurements [wifi-scan on all channels] conducted at this position
*
* if more than one measurement is conducted, each AP is contained more than once!
*/
struct WiFiFingerprint {
/** real-world-position that was measured */
Point3 pos_m;
/** seen APs at the given location */
WiFiMeasurements measurements;
/** ctor */
WiFiFingerprint() {;}
/** ctor */
WiFiFingerprint(const Point3 pos_m) : pos_m(pos_m) {;}
/** as each AP might be contained more than once (scanned more than once), group them by MAC and use the average RSSI */
WiFiMeasurements average() {
// group scans by MAC (all measurements for one AP)
std::unordered_map<MACAddress, WiFiMeasurements> group;
for (WiFiMeasurement& m : measurements.entries) {
group[m.getAP().getMAC()].entries.push_back(m);
}
// create the output that contains the AP's average
WiFiMeasurements res;
for (auto& it : group) {
const WiFiMeasurements& apMeasurements = it.second;
WiFiMeasurement avg = apMeasurements.entries.front(); // average starts with a copy of the first entry (to get all data-fields beside the rssi)
for (int i = 1; i < (int)apMeasurements.entries.size(); ++i) { // sum up all other entries [1:end]
avg.setRssi(avg.getRSSI() + apMeasurements.entries[i].getRSSI());
}
avg.setRssi(avg.getRSSI() / apMeasurements.entries.size());
res.entries.push_back(avg); // add to output
}
// done
return res;
}
/** serialize */
void write(std::ostream& out) const {
out << "pos: " << pos_m.x << " " << pos_m.y << " " << pos_m.z << "\n";
out << "num: " << measurements.entries.size() << "\n";
for (const WiFiMeasurement& wm : measurements.entries) {
out << wm.getTimestamp().ms() << " " << wm.getAP().getMAC().asString() << " " << wm.getRSSI() << "\n";
}
}
/** deserialize */
void read(std::istream& inp) {
std::string tmp;
// read the position
inp >> tmp; if ("pos:" != tmp) {throw "error";}
inp >> pos_m.x >> pos_m.y >> pos_m.z;
// number of entries
inp >> tmp; if ("num:" != tmp) {throw "error";}
int numEntries; inp >> numEntries;
// read the entries
for (int i = 0; i < numEntries; ++i) {
uint64_t ms; inp >> ms;
std::string mac; inp >> mac;
float rssi; inp >> rssi;
WiFiMeasurement wm(AccessPoint(MACAddress(mac)), rssi, Timestamp::fromMS(ms));
measurements.entries.push_back(wm);
}
}
};
#endif // WIFIFINGERPRINT_H