218 lines
5.1 KiB
C++
Executable File
218 lines
5.1 KiB
C++
Executable File
#ifndef EVALWIFIGROUNDPROB_H
|
|
#define EVALWIFIGROUNDPROB_H
|
|
|
|
#include <KLib/math/statistics/Statistics.h>
|
|
|
|
#include "Indoor/sensors/radio/setup/WiFiOptimizer.h"
|
|
#include "Indoor/sensors/radio/setup/WiFiFingerprint.h"
|
|
#include "Indoor/sensors/radio/setup/WiFiFingerprints.h"
|
|
|
|
#include "Indoor/sensors/radio/setup/WiFiOptimizer.h"
|
|
#include "Indoor/sensors/radio/setup/WiFiOptimizerLogDistCeiling.h"
|
|
|
|
#include "Indoor/sensors/radio/VAPGrouper.h"
|
|
|
|
#include "Indoor/floorplan/v2/Floorplan.h"
|
|
#include "Indoor/floorplan/v2/FloorplanReader.h"
|
|
#include "Indoor/floorplan/v2/FloorplanHelper.h"
|
|
#include "Indoor/floorplan/v2/FloorplanCeilings.h"
|
|
|
|
#include "Indoor/sensors/radio/model/WiFiModelLogDistCeiling.h"
|
|
#include "Indoor/sensors/offline/FileReader.h"
|
|
|
|
#include "Indoor/sensors/radio/WiFiProbabilityFree.h"
|
|
|
|
#include "../Helper.h"
|
|
|
|
#include <vector>
|
|
#include "../plots/Plotty.h"
|
|
|
|
class PlotWiFiGroundProb {
|
|
|
|
private:
|
|
|
|
const Floorplan::IndoorMap* map;
|
|
|
|
const float stepSize_m = 3.0;
|
|
//std::vector<Point3> pos;
|
|
|
|
struct Entry {
|
|
Point3 pos;
|
|
K::GnuplotObjectPolygon* poly;
|
|
float max = -1;
|
|
float sum = 0;
|
|
int cnt = 0;
|
|
};
|
|
|
|
std::vector<Entry> pos;
|
|
|
|
Plotty plot;
|
|
|
|
public:
|
|
|
|
/** ctor */
|
|
PlotWiFiGroundProb(const Floorplan::IndoorMap* map, Plotty::Settings settings = Plotty::Settings()) : map(map), plot(map) {
|
|
|
|
plot.settings = settings;
|
|
|
|
buildEvalPoints();
|
|
plot.buildFloorplan();
|
|
|
|
|
|
|
|
}
|
|
|
|
Plotty& getPlot() {
|
|
return plot;
|
|
}
|
|
|
|
/** plot the ground-probability for the given measurement */
|
|
void show(const WiFiObserverFree& prob, const WiFiMeasurements& mes, const Timestamp ts) {
|
|
|
|
// determine min/max probability
|
|
double min = +99999;
|
|
double max = -99999;
|
|
for (Entry& e : pos) {
|
|
const double p = prob.getProbability(e.pos, ts, mes);
|
|
if (p < min) {min = p;}
|
|
if (p > max) {max = p;}
|
|
}
|
|
const double diff = max-min;
|
|
|
|
// render
|
|
for (Entry& e : pos) {
|
|
const double p = prob.getProbability(e.pos, ts, mes);
|
|
double f = (p-min) / diff * 255;
|
|
if (f < 0) {f = 0;}
|
|
if (f > 255) {f = 255;}
|
|
|
|
e.sum += p;
|
|
e.cnt++;
|
|
|
|
//if (f > e.max) {
|
|
const K::GnuplotColor c = K::GnuplotColor::fromHSV(0, f, 255);
|
|
e.poly->getFill().setColor(c);
|
|
e.max = f;
|
|
|
|
e.poly->setEnabled(f > 32);
|
|
//}
|
|
// if (f < 32) {
|
|
// e.poly->setEnabled(false);
|
|
// } else {
|
|
// e.poly->setEnabled(true);
|
|
// }
|
|
|
|
//plot.cpoints.add(K::GnuplotPoint3(pt.x, pt.y, pt.z), p);
|
|
}
|
|
|
|
}
|
|
|
|
void showStrongest(const WiFiObserverFree& prob, const WiFiMeasurements& mes, const float hue) {
|
|
|
|
// determine min/max probability
|
|
double min = +99999;
|
|
double max = -99999;
|
|
for (Entry& e : pos) {
|
|
const double p = prob.getProbability(e.pos, mes.entries.front().getTimestamp(), mes);
|
|
if (p < min) {min = p;}
|
|
if (p > max) {max = p;}
|
|
}
|
|
const double diff = max-min;
|
|
|
|
// render
|
|
for (Entry& e : pos) {
|
|
|
|
// get probability within [0:255]
|
|
const double p = prob.getProbability(e.pos, mes.entries.front().getTimestamp(), mes);
|
|
const double f = (p-min) / diff * 255;
|
|
|
|
if (p != p) {
|
|
throw Exception("nan");
|
|
}
|
|
|
|
// overwrite weak entries
|
|
if (f > e.max) {
|
|
|
|
const K::GnuplotColor c = K::GnuplotColor::fromHSV(hue, f, 245);
|
|
e.poly->getFill().setColor(c);
|
|
e.max = f;
|
|
|
|
// disable unlikely onces to save performance and disk-space
|
|
e.poly->setEnabled(f > 32);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void update() {
|
|
|
|
double min = +99999;
|
|
double max = -99999;
|
|
for (Entry& e : pos) {
|
|
const double p = e.sum / e.cnt;
|
|
if (p < min) {min = p;}
|
|
if (p > max) {max = p;}
|
|
}
|
|
double diff = max-min;
|
|
|
|
for (Entry& e : pos) {
|
|
const double p = e.sum / e.cnt;
|
|
const double f = (p-min) / diff * 255;
|
|
const K::GnuplotColor c = K::GnuplotColor::fromHSV(0, f, 255);
|
|
e.poly->getFill().setColor(c);
|
|
}
|
|
|
|
}
|
|
|
|
void plotMe() {
|
|
plot.plot();
|
|
}
|
|
|
|
private:
|
|
|
|
/** get a list of all points among the outline */
|
|
void buildEvalPoints() {
|
|
|
|
BBox3 bbox = FloorplanHelper::getBBox(map);
|
|
|
|
for (Floorplan::Floor* f : map->floors) {
|
|
for (float y = bbox.getMin().y; y < bbox.getMax().y; y += stepSize_m) {
|
|
for (float x = bbox.getMin().x; x < bbox.getMax().x; x += stepSize_m) {
|
|
|
|
GridFactory<int>::PartOfOutline part = GridFactory<int>::isPartOfFloorOutline(x*100, y*100, f->outline);
|
|
if (part != GridFactory<int>::PartOfOutline::NO) {
|
|
|
|
const float s = stepSize_m/2.0f;
|
|
|
|
Entry e;
|
|
|
|
e.poly = new K::GnuplotObjectPolygon();
|
|
e.poly->add(K::GnuplotCoordinate3(x-s, y-s, f->atHeight, K::GnuplotCoordinateSystem::FIRST));
|
|
e.poly->add(K::GnuplotCoordinate3(x+s, y-s, f->atHeight, K::GnuplotCoordinateSystem::FIRST));
|
|
e.poly->add(K::GnuplotCoordinate3(x+s, y+s, f->atHeight, K::GnuplotCoordinateSystem::FIRST));
|
|
e.poly->add(K::GnuplotCoordinate3(x-s, y+s, f->atHeight, K::GnuplotCoordinateSystem::FIRST));
|
|
e.poly->close();
|
|
e.poly->getFill().setStyle(K::GnuplotFillStyle::SOLID);
|
|
e.poly->setStroke(K::GnuplotStroke::NONE());
|
|
e.poly->setZIndex(f->atHeight - 0.001); // between outline and obstacles
|
|
|
|
e.pos = Point3(x, y, f->atHeight);
|
|
|
|
pos.push_back(e);
|
|
plot.splot.getObjects().add(e.poly);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
#endif // EVALWIFIGROUNDPROB_H
|