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
2018-10-25 11:50:12 +02:00

155 lines
3.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © 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)
*/
#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