/* * © 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 WIFIGRIDESTIMATOR_H #define WIFIGRIDESTIMATOR_H #include "../../grid/Grid.h" #include "model/WiFiModel.h" #include "WiFiGridNode.h" #include "../../Assertions.h" #include "../../floorplan/v2/Floorplan.h" #include /** * estimates the signal-strength for all APs at a given GridNode * and stores this precalculated value onto the node */ class WiFiGridEstimator { public: // /** // * convenience method // */ // template static void estimate(Grid& grid, WiFiModel& mdl, const Floorplan::IndoorMap* im) { // // list of all APs // std::vector aps; // for (const Floorplan::Floor* f : im->floors) { // for (const Floorplan::AccessPoint* ap : f->accesspoints) { // aps.push_back(LocatedAccessPoint(*ap)); // } // } // // perform estimation // estimate(grid, mdl, aps); // } /** * perform a signal-strength estimation for all of the given access points * using the provided signal-strength prediction model. * store the estimated strength onto each node. * as nodes only provide a limited number of rssi-entries, * store only the strongest ones. * * as the smartphone is held above the ground, we do NOT want to estimate * the signal strength for the nodes (on the ground) but for the nodes * + the height the smartphone is held at * */ template static void estimate(Grid& grid, WiFiModel& mdl, const float smartphoneAtHeight) { // sanity checks Assert::isTrue(Node::getMapAPs().empty(), "there are already APs stored on the grid nodes!"); // all APs known to the model std::vector aps = mdl.getAllAPs(); // attach each access-points to a vector shared for all grid-nodes for (const AccessPoint& ap : aps) { Node::getMapAPs().push_back(ap); } // smartphone offset (meter above ground) const Point3 smartphoneOffset(0,0,smartphoneAtHeight); // process each node for (Node& n : grid) { // keep the strongest APs to attach to this node std::vector nodeAPs; // process each AP known to the model for (int apIdx = 0; apIdx < (int) aps.size(); ++apIdx) { // estimate the signal-strength const float rssi = mdl.getRSSI(aps[apIdx].getMAC(), n.inMeter() + smartphoneOffset); // (temporarily) keep it nodeAPs.push_back(WiFiGridNodeAP(apIdx, rssi)); } // now sort all the visible APs by signal strength auto comp = [] (const WiFiGridNodeAP& ap1, const WiFiGridNodeAP& ap2) {return ap1.getRSSI() > ap2.getRSSI();}; std::sort(nodeAPs.begin(), nodeAPs.end(), comp); // and finally attach the strongest X to the node const int cnt = std::min( n.getMaxAPs(), (int) nodeAPs.size() ); for (int i = 0; i < cnt; ++i) { n.strongestAPs[i] = nodeAPs[i]; } } } /** gnuplot visualization dump for the given AP */ template static void dump(Grid& grid, const std::string& mac, const std::string& filename) { std::ofstream out(filename); out << "splot '-' with points palette \n"; for (Node& n : grid) { out << n.x_cm << " " << n.y_cm << " " << n.z_cm << " " << n.getRSSI(mac) << "\n"; } out << "e\n"; out.close(); } }; #endif // WIFIGRIDESTIMATOR_H