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/WiFiFingerprints.h
frank a22290415e fixed some issues with stats::variance
fixed umbrella header for stats
added error-feedback to wifi optimizers
improved logging for wifi optimizers
adjusted calling-API for wifi-optimizers
2018-05-20 18:56:49 +02:00

145 lines
3.2 KiB
C++

#ifndef WIFIFINGERPRINTS_H
#define WIFIFINGERPRINTS_H
#include <fstream>
#include "WiFiFingerprint.h"
#include <iostream>
/**
* helper class to load and save fingerprints.
* fingerprints are wifi-measurements given at some known location
* those can be used to e.g. optimize access-point models etc.
*/
class WiFiFingerprints {
static constexpr const char* name = "Fingerprints";
private:
// /** the file to save the calibration model to */
// std::string file;
/** all fingerprints (position -> measurements) within the model */
std::vector<WiFiFingerprint> fingerprints;
public:
/** empty ctor */
WiFiFingerprints() {
}
/** ctor from file */
WiFiFingerprints(const std::string& file) {
load(file);
}
const std::vector<WiFiFingerprint>& getFingerprints() const {
return fingerprints;
}
std::vector<WiFiFingerprint>& getFingerprints() {
return fingerprints;
}
/** attach the given fingerprint */
void add(const WiFiFingerprint& fp) {
fingerprints.push_back(fp);
}
/** get all fingerprints that measured exactly the given mac [no VAP grouping] */
const std::vector<WiFiFingerprint> getFingerprintsFor(const MACAddress& mac) const {
std::vector<WiFiFingerprint> res;
// process each fingerprint location
for (const WiFiFingerprint& _fp : fingerprints) {
// start with an empty copy
WiFiFingerprint fp = _fp; fp.measurements.entries.clear();
// only add the measurements that belong to the requested mac
for (const WiFiMeasurement& _m : _fp.measurements.entries) {
if (_m.getAP().getMAC() == mac) {
fp.measurements.entries.push_back(_m);
}
}
if (fp.measurements.entries.size() > 0) { // got some measurements for this AP?
res.push_back(fp);
}
}
return res;
}
/** deserialize the model */
void load(const std::string& file) {
// open and check
std::ifstream inp(file.c_str());
if (inp.bad() || inp.eof() || ! inp.is_open()) { return; }
// read all entries
while (!inp.eof()) {
// each section starts with [fingerprint]
std::string section;
inp >> section;
if (inp.eof()) {break;}
if (section != "[fingerprint]") {throw Exception("error!");}
// deserialize it
WiFiFingerprint wfp;
wfp.read(inp);
if (wfp.measurements.entries.empty()) {continue;}
fingerprints.push_back(wfp);
}
Log::add(name, "loaded " + std::to_string(fingerprints.size()) + " fingerprints");
inp.close();
}
/** serialize the model */
void save(const std::string& file) {
// open and check
std::ofstream out(file.c_str());
if (out.bad()) {throw Exception("error while opening " + file + " for write");}
// write all entries
for (const WiFiFingerprint& wfp : fingerprints) {
out << "[fingerprint]\n";
wfp.write(out);
}
// done
out.close();
}
/** get the fingerprint for the given location. if no fingerprint exists, an empty one is created! */
WiFiFingerprint& getFingerprint(const Point3 pos_m) {
// try to find an existing one
for (WiFiFingerprint& wfp : fingerprints) {
// get within range of floating-point rounding issues
if (wfp.pos_m.getDistance(pos_m) < 0.01) {return wfp;}
}
// create a new one and return its reference
WiFiFingerprint wfp(pos_m);
fingerprints.push_back(wfp);
return fingerprints.back();
}
};
#endif // WIFIFINGERPRINTS_H