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

181 lines
4.5 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 WIFIGRIDNODE_H
#define WIFIGRIDNODE_H
#include <cstdint>
#include "AccessPoint.h"
#include "../../misc/Debug.h"
/**
* rssi model-estimation for one AP, denoted by its index [among all APs present within the map]
* the signal strength is stored as uint8_t and allows a granularity of 0.25 dB between -40 and -103 dB
*/
struct WiFiGridNodeAP {
private:
static const uint8_t UNUSED_IDX = 255;
private:
/** access-point index -> max 255 APs/Map */
uint8_t idx;
/** access-point rssi */
uint8_t rssi;
public:
/** empty ctor */
WiFiGridNodeAP() : idx(UNUSED_IDX), rssi(0) {
int i = 0; (void) i;
}
/** ctor */
WiFiGridNodeAP(const int idx, const float rssi) : idx(idx), rssi(stretch(rssi)) {
int i = 0; (void) i;
}
/** is this entry valid/used? */
bool isValid() const {return idx != UNUSED_IDX;}
/** set AP and its signal strength */
void set(const int apIdx, const float rssi) {
this->idx = apIdx;
this->rssi = stretch(rssi);
}
/** get the predicted signal-strength */
float getRSSI() const {return unstretch(rssi);}
/** get the access-point's index */
int getAPIdx() const {return idx;}
private:
/** [-40:-103] -> [0:252] => this allows 0.25 steps */
static inline int8_t stretch(float rssi) {
if (rssi > -40) {rssi = -40;}
if (rssi < -103) {rssi = -103;}
return std::round((-rssi - 40) * 4);
}
/** [0:252] -> [-40:-103] */
static inline float unstretch(const float rssi) {
return -(rssi / 4.0f + 40.0f);
}
};// __attribute__((packed));
/**
* base-class for grid-nodes that contain wifi signal-strength estimations.
* such estimations are calculated offline and added to each node.
* this also allows for using very complex signal-strength estimation models
*/
template <int maxAccessPoints> struct WiFiGridNode {
/** contains the 10 strongest APs measureable at this position */
WiFiGridNodeAP strongestAPs[maxAccessPoints];
/** ctor */
explicit WiFiGridNode() : strongestAPs() {
;
}
/** get the maximum number of APs each node is able to store */
int getMaxAPs() const {return maxAccessPoints;}
/**
* get the RSSI for the given AP
* returns 0 if unknown
*/
float getRSSI(const std::string& mac) const {
return getRSSI(MACAddress(mac));
}
/**
* get the RSSI for the given AP
* returns 0 if unknown
*/
float getRSSI(const MACAddress mac) const {
for (const WiFiGridNodeAP& ap : strongestAPs) {
//std::cout << getMapAPs()[ap.getAPIdx()].getMAC().asString() << std::endl;
//std::cout << mac.asString() << std::endl;
if (!ap.isValid()) {break;} // reached the end of all APs visible on this node
if (getMapAPs()[ap.getAPIdx()].getMAC() == mac) {return ap.getRSSI();} // does this APs MAC match with the requested MAC? -> found!
}
return 0;
}
/** get the number of access-points visible at this node */
int getNumVisibleAPs() const {
for (int i = 0; i < getMaxAPs(); ++i) {
if (!strongestAPs[i].isValid()) {return i;}
}
return getMaxAPs();
}
/** shared vector of all accesspoints the are present within the map. the IDX referes to this vector */
static std::vector<AccessPoint>& getMapAPs() {
static std::vector<AccessPoint> list;
return list;
}
protected:
static constexpr const char* name = "WiFiGridNode";
/** serialize static members */
static void staticSerialize(std::ostream& out) {
// number of APs within map
const int numAPs = getMapAPs().size();
// serialize number and APs within map
out.write((const char*) &numAPs, sizeof(numAPs));
out.write((const char*) getMapAPs().data(), sizeof(getMapAPs()[0])*numAPs);
Log::add(name, "serialized " + std::to_string(numAPs) + " APs");
}
/** deserialize static members */
static void staticDeserialize(std::istream& inp) {
// get number of APs within map
int numAPs;
inp.read((char*) &numAPs, sizeof(numAPs));
// allocate
getMapAPs().resize(numAPs);
// deserialize APs within map
inp.read((char*) getMapAPs().data(), sizeof(getMapAPs()[0])*numAPs);
Log::add(name, "de-serialized " + std::to_string(numAPs) + " APs");
std::string aps; for (const AccessPoint& ap : getMapAPs()) {aps += ap.getMAC().asString() + " ";}
Log::add(name, aps);
}
};// __attribute__((packed));
#endif // WIFIGRIDNODE_H