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
OTHER2017/main.cpp
2017-04-25 16:39:58 +02:00

1162 lines
37 KiB
C++

#define BREAK raise(SIGTRAP);
#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/model/WiFiModels.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 <KLib/misc/gnuplot/Gnuplot.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementLines.h>
#include <KLib/misc/gnuplot/GnuplotSplot.h>
#include <KLib/misc/gnuplot/GnuplotSplotElementPoints.h>
#include <KLib/misc/gnuplot/GnuplotSplotElementLines.h>
#include <Indoor/geo/EarthMapping.h>
#include "Settings.h"
#include "EvalCompareOpt.h"
#include "EvalCompareOpt2.h"
#include "EvalApOpt.h"
#include "EvalData.h"
#include "EvalWiFiSigStrength.h"
#include "pf/EvalWalk.h"
#include "EvalWifiOptResult.h"
#include "wifi/EvalWiFiConvex.h"
#include "wifi/EvalWiFiGround.h"
#include "wifi/EvalWiFi.h"
#include "wifi/EvalWiFiPaths.h"
#include "wifi/EvalWiFiPathMethods.h"
#include "plots/PlotErrFunc.h"
void rebuildAllModels(Floorplan::IndoorMap* map, const int skip = 0, bool ignoreStaircases = false) {
// // use walks?
// std::vector<std::pair<std::string, std::vector<int>>> calibWalks = {
// std::make_pair(Settings::path1a, Settings::GroundTruth::path1),
// std::make_pair(Settings::path1b, Settings::GroundTruth::path1),
// std::make_pair(Settings::path2a, Settings::GroundTruth::path2),
// std::make_pair(Settings::path2b, Settings::GroundTruth::path2),
// };
// EvalCompareOpt2 opt1(Settings::fMap, calibWalks);
int skipCnt = 0;
auto skipper = [&] (const WiFiFingerprint& fp) -> bool {
if (skip == 0) {return false;}
++skipCnt;
return ((skipCnt % skip) != 0);
};
// all combined
auto removeNone = [] (const WiFiFingerprint& fp) -> bool {return false;};
// per floor
auto only0th = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || std::abs(fp.pos_m.z - (1.3)) > 0.1;};
auto only1st = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || std::abs(fp.pos_m.z - (4+1.3)) > 0.1;};
auto only2nd = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || std::abs(fp.pos_m.z - (4+3.4+1.3)) > 0.1;};
auto only3rd = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || std::abs(fp.pos_m.z - (4+3.4+3.4+1.3)) > 0.1;};
// per bbox
#include "bboxes.h"
auto only0H = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes0H.contains(fp.pos_m);};
auto only0O = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes0O.contains(fp.pos_m);};
auto only0I = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes0I.contains(fp.pos_m);};
auto only1H = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes1H.contains(fp.pos_m);};
auto only1O = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes1O.contains(fp.pos_m);};
auto only1I = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes1I.contains(fp.pos_m);};
auto only2H = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes2H.contains(fp.pos_m);};
auto only3H = [&] (const WiFiFingerprint& fp) -> bool {return skipper(fp) || !bboxes3H.contains(fp.pos_m);};
// use fingerprints?
EvalCompareOpt2 opt1(Settings::fMap, Settings::fCalib, skipper, ignoreStaircases);
// optimize using all floors
EvalCompareOpt2::Result s1 = opt1.fixedPosFixedParamsForAll(); //BREAK;
EvalCompareOpt2::Result s2 = opt1.fixedPosOptParamsForAll(); //BREAK;
EvalCompareOpt2::Result s3 = opt1.fixedPosOptParamsForEach(); //BREAK;
EvalCompareOpt2::Result s4 = opt1.optPosOptParamsForEach(); //BREAK;
// optimize per floor
EvalCompareOpt2 opt_f0(Settings::fMap, Settings::fCalib, only0th, ignoreStaircases);
EvalCompareOpt2::Result sf0 = opt_f0.optPosOptParamsForEach();
EvalCompareOpt2 opt_f1(Settings::fMap, Settings::fCalib, only1st, ignoreStaircases);
EvalCompareOpt2::Result sf1 = opt_f1.optPosOptParamsForEach();
EvalCompareOpt2 opt_f2(Settings::fMap, Settings::fCalib, only2nd, ignoreStaircases);
EvalCompareOpt2::Result sf2 = opt_f2.optPosOptParamsForEach();
EvalCompareOpt2 opt_f3(Settings::fMap, Settings::fCalib, only3rd, ignoreStaircases);
EvalCompareOpt2::Result sf3 = opt_f3.optPosOptParamsForEach();
// optimize per bbox
EvalCompareOpt2 opt_0H(Settings::fMap, Settings::fCalib, only0H, ignoreStaircases);
EvalCompareOpt2::Result sf0H = opt_0H.optPosOptParamsForEach();
EvalCompareOpt2 opt_0O(Settings::fMap, Settings::fCalib, only0O, ignoreStaircases);
EvalCompareOpt2::Result sf0O = opt_0O.optPosOptParamsForEach();
EvalCompareOpt2 opt_0I(Settings::fMap, Settings::fCalib, only0I, ignoreStaircases);
EvalCompareOpt2::Result sf0I = opt_0I.optPosOptParamsForEach();
EvalCompareOpt2 opt_1H(Settings::fMap, Settings::fCalib, only1H, ignoreStaircases);
EvalCompareOpt2::Result sf1H = opt_1H.optPosOptParamsForEach();
EvalCompareOpt2 opt_1O(Settings::fMap, Settings::fCalib, only1O, ignoreStaircases);
EvalCompareOpt2::Result sf1O = opt_1O.optPosOptParamsForEach();
EvalCompareOpt2 opt_1I(Settings::fMap, Settings::fCalib, only1I, ignoreStaircases);
EvalCompareOpt2::Result sf1I = opt_1I.optPosOptParamsForEach();
EvalCompareOpt2 opt_2H(Settings::fMap, Settings::fCalib, only2H, ignoreStaircases);
EvalCompareOpt2::Result sf2H = opt_2H.optPosOptParamsForEach();
EvalCompareOpt2 opt_3H(Settings::fMap, Settings::fCalib, only3H, ignoreStaircases);
EvalCompareOpt2::Result sf3H = opt_3H.optPosOptParamsForEach();
// save models to file
s1.model.saveXML(Settings::wifiAllFixed);
s2.model.saveXML(Settings::wifiAllOptPar);
s3.model.saveXML(Settings::wifiEachOptPar);
s4.model.saveXML(Settings::wifiEachOptParPos);
sf0.model.saveXML(Settings::wifiEachOptParPos_only0th);
sf1.model.saveXML(Settings::wifiEachOptParPos_only1st);
sf2.model.saveXML(Settings::wifiEachOptParPos_only2nd);
sf3.model.saveXML(Settings::wifiEachOptParPos_only3rd);
// fancy combined model
WiFiModelPerFloor wmpf(map);
wmpf.add(&sf0.model, map->floors[0]);
wmpf.add(&sf1.model, map->floors[1]);
wmpf.add(&sf2.model, map->floors[2]);
wmpf.add(&sf3.model, map->floors[3]);
wmpf.saveXML(Settings::wifiEachOptParPos_multimodel);
// ultra fancy combined model
WiFiModelPerBBox wmbb(map);
wmbb.add(&sf0H.model, bboxes0H);
wmbb.add(&sf0O.model, bboxes0O);
wmbb.add(&sf0I.model, bboxes0I);
wmbb.add(&sf1H.model, bboxes1H);
wmbb.add(&sf1O.model, bboxes1O);
wmbb.add(&sf1I.model, bboxes1I);
wmbb.add(&sf2H.model, bboxes2H);
wmbb.add(&sf3H.model, bboxes3H);
wmbb.saveXML(Settings::wifiEachOptParPos_perBBox);
PlotErrFunc pef("\\small{error (dB)}", "\\small{fingerprints (\\%)}");
pef.add("\\small{empiric}", &s1.errSingle);
pef.add("\\small{real pos, opt params}", &s2.errSingle);
pef.add("\\small{real pos, opt params [per AP]}", &s3.errSingle);
pef.add("\\small{opt pos, opt params [per AP]}", &s4.errSingle);
pef.getGP().setTerminal("epslatex", K::GnuplotSize(8.5, 5));
pef.getGP().setOutput(Settings::fPathGFX + "wifi-opt-error-hist-methods.tex");
pef.writePlotToFile(Settings::fPathGFX + "wifi-opt-error-hist-methods.gp");
pef.getGP() << "set key right bottom width -4 samplen 0.5\n";
pef.getGP() << "set rmargin 0.4\n";
pef.getGP() << "set tmargin 0.4\n";
pef.plot();
int i = 0; (void) i;
//return;
//sleep(1000);
}
std::vector<K::Statistics<float>> errorStatAllModels(Floorplan::IndoorMap* map) {
WiFiModelFactory fac(map);
WiFiFingerprints calib(Settings::fCalib);
VAPGrouper vap(VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, VAPGrouper::Aggregation::AVERAGE);
for (WiFiFingerprint& fp : calib.getFingerprints()) {
fp.measurements = vap.group(fp.measurements);
}
// calculate the error (model vs scan) for each fingerprint using the given model
auto calc = [&] (const WiFiModel* model, K::Statistics<float>* stats) {
for (const WiFiFingerprint& fp : calib.getFingerprints()) {
for (const WiFiMeasurement& m : fp.measurements.entries) {
const float scanRSSI = m.getRSSI();
const float modelRSSI = model->getRSSI(m.getAP().getMAC(), fp.pos_m);
if (modelRSSI != modelRSSI) {
std::cout << "unknown AP: " << m.getAP().getMAC().asString() << std::endl;
continue;
}
const float errAbs = std::abs(modelRSSI-scanRSSI);
stats->add(errAbs);
}
}
};
// models
WiFiModel* mdlAllFixed = fac.loadXML(Settings::wifiAllFixed);
K::Statistics<float> statsAllFixed;
calc(mdlAllFixed, &statsAllFixed);
WiFiModel* mdlAllOptPar = fac.loadXML(Settings::wifiAllOptPar);
K::Statistics<float> statsAllOptPar;
calc(mdlAllOptPar, &statsAllOptPar);
WiFiModel* mdlEachOptPar = fac.loadXML(Settings::wifiEachOptPar);
K::Statistics<float> statsEachOptPar;
calc(mdlEachOptPar, &statsEachOptPar);
WiFiModel* mdlEachOptParPos = fac.loadXML(Settings::wifiEachOptParPos);
K::Statistics<float> statsEachOptParPos;
calc(mdlEachOptParPos, &statsEachOptParPos);
WiFiModel* mdlFloor = fac.loadXML(Settings::wifiEachOptParPos_multimodel);
K::Statistics<float> statsFloor;
calc(mdlFloor, &statsFloor);
WiFiModel* mdlBbox = fac.loadXML(Settings::wifiEachOptParPos_perBBox);
K::Statistics<float> statsBbox;
calc(mdlBbox, &statsBbox);
return {
statsAllFixed,
statsAllOptPar,
statsEachOptPar,
statsEachOptParPos,
statsFloor,
statsBbox,
};
}
/** error plot for all used optimization models */
void errorPlotAllModels(Floorplan::IndoorMap* map) {
std::vector<K::Statistics<float>> errors = errorStatAllModels(map);
PlotErrFunc plot("", "fingerprints (%)");
plot.getPlot().getAxisX().setTicsLabelFormat("%h dB");
plot.add("\\noOptEmpiric{}", &errors[0]);
plot.add("\\optParamsAllAP{}", &errors[1]);
plot.add("\\optParamsEachAP{}", &errors[2]);
plot.add("\\optParamsPosEachAP{}", &errors[3]);
plot.add("\\optPerFloor{}", &errors[4]);
plot.add("\\optPerRegion{}", &errors[5]);
plot.getPlot().getKey().setVisible(true);
plot.getPlot().getKey().setPosition(K::GnuplotKey::Hor::RIGHT, K::GnuplotKey::Ver::BOTTOM);
// debug view
plot.setYRange(0, 95, 5);
plot.plot();
sleep(2);
plot.setYRange(95, 100, 1);
plot.plot();
sleep(2);
// LATEX
// plot.getGP() << "set lmargin 4.2\n";
// plot.getGP() << "set tmargin 0.1\n";
// plot.getGP() << "set rmargin 0.2\n";
// plot.getGP() << "set bmargin 1.9\n";
plot.getPlot().getMargin().set(4.2, 0.2, 0.1, 1.9);
plot.getPlot().getAxisY().setLabelOffset(3.0,0);
plot.getPlot().setStringMod(new K::GnuplotStringModLaTeX());
plot.getPlot().getKey().setSampleLength(0.5);
plot.getPlot().getKey().setWidthIncrement(+7.0);
plot.setYRange(0, 95, 5);
plot.getPlot().getAxisY().setRange(K::GnuplotAxis::Range(0, 100));
plot.getPlot().getAxisY().setTicsStep(0, 25, 100);
plot.getGP().setTerminal("epslatex", K::GnuplotSize(8.6, 4.0));
plot.getPlot().getAxisX().setTicsStep(4); // 4dB
plot.getPlot().getAxisX().setRange(K::GnuplotAxis::Range(0, 16));
plot.getGP().setOutput(Settings::fPathGFX + "/wifi_model_error_0_95.tex");
plot.writePlotToFile(Settings::fPathGFX + "/wifi_model_error_0_95.gp");
plot.plot();
plot.getPlot().getKey().setVisible(false);
plot.setYRange(97, 100, 1);
plot.getPlot().getAxisY().setTicsStep(1);
plot.getGP().setTerminal("epslatex", K::GnuplotSize(8.6, 2.6));
plot.getPlot().getAxisX().setRange(K::GnuplotAxis::Range(5, 35));
plot.getPlot().getAxisX().setTicsStep(5); // 5dB
plot.getGP().setOutput(Settings::fPathGFX + "/wifi_model_error_95_100.tex");
plot.writePlotToFile(Settings::fPathGFX + "/wifi_model_error_95_100.gp");
plot.plot();
int i = 0; (void) i;
//sleep(1000);
}
/** error plot for the given stats. used for fingerprint errors */
void errorPlotNumFingerprints(const std::vector<K::Statistics<float>>& stats, const std::vector<std::string>& titles, const std::string& name) {
PlotErrFunc plot("", "fingerprints (%)");
plot.getPlot().getAxisX().setTicsLabelFormat("%h dB");
plot.getPlot().getKey().setVisible(true);
plot.getPlot().getKey().setPosition(K::GnuplotKey::Hor::RIGHT, K::GnuplotKey::Ver::BOTTOM);
plot.clear();
for (int j = 0; j < titles.size(); ++j) {
plot.add(titles[j], &stats[j]);
}
// // debug view
// plot.setYRange(0, 90, 5);
// plot.plot();
// sleep(5);
// plot.setYRange(90, 100, 5);
// plot.plot();
// sleep(5);
// LATEX
// plot.getGP() << "set lmargin 4.2\n";
// plot.getGP() << "set tmargin 0.1\n";
// plot.getGP() << "set rmargin 0.2\n";
// plot.getGP() << "set bmargin 1.9\n";
plot.getPlot().getMargin().set(4.2, 0.2, 0.1, 1.9);
plot.getPlot().getAxisY().setLabelOffset(3.0,0);
plot.getPlot().setStringMod(new K::GnuplotStringModLaTeX());
plot.getPlot().getKey().setSampleLength(0.5);
plot.getPlot().getKey().setWidthIncrement(-5.0);
plot.setYRange(0, 90, 5);
plot.getPlot().getAxisY().setRange(K::GnuplotAxis::Range(0, 100));
plot.getPlot().getAxisY().setTicsStep(0, 25, 100);
plot.getGP().setTerminal("epslatex", K::GnuplotSize(8.6, 3.3));
plot.getPlot().getAxisX().setTicsStep(4); // 4dB
plot.getPlot().getAxisX().setRange(K::GnuplotAxis::Range(0, 16));
plot.getGP().setOutput(Settings::fPathGFX + "/" + name + "_0_90.tex");
plot.writePlotToFile(Settings::fPathGFX + "/" + name + "_0_90.gp");
plot.plot();
plot.getPlot().getKey().setVisible(false);
plot.setYRange(90, 100, 1);
plot.getPlot().getAxisY().setTicsStep(2);
plot.getGP().setTerminal("epslatex", K::GnuplotSize(8.6, 2.6));
plot.getPlot().getAxisX().setRange(K::GnuplotAxis::Range(5, 35));
plot.getPlot().getAxisX().setTicsStep(5); // 5dB
plot.getGP().setOutput(Settings::fPathGFX + "/" + name + "_90_100.tex");
plot.writePlotToFile(Settings::fPathGFX + "/" + name + "_90_100.gp");
plot.plot();
}
/** show all fingerprints within the building */
void plotAllFingerprints(Floorplan::IndoorMap* map) {
WiFiFingerprints calib(Settings::fCalib);
LeHelper::removeNonFHWS(calib);
VAPGrouper vap(VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, VAPGrouper::Aggregation::AVERAGE);
for (WiFiFingerprint& fp : calib.getFingerprints()) {
fp.measurements = vap.group(fp.measurements);
}
// estimate stats
K::Statistics<float> fpVisible;
for (const WiFiFingerprint& fp : calib.getFingerprints()) {
fpVisible.add(fp.measurements.entries.size());
}
Plotty* p = new Plotty(map);
p->buildFloorplan();
p->cpoints.clear();
for (const WiFiFingerprint& fp : calib.getFingerprints()) {
const K::GnuplotPoint3 gp(fp.pos_m.x, fp.pos_m.y, fp.pos_m.z);
const float size = fp.measurements.entries.size() / 10.0 * 1.0;
const Point3 pos = fp.pos_m - Point3(0,0,1.2);
Color c;
if (pos.z < 4) {c = Color::fromRGB(128,128,128);}
else if (pos.z < 6) {c = Color::fromRGB(255,96,96);}
else if (pos.z < 9) {c = Color::fromRGB(128,255,128);}
else {c = Color::fromRGB(128,128,255);}
K::GnuplotObjectPolygon* poly = p->addFloorRect(pos, size, c);
poly->setZIndex(pos.z + 0.1); // above the floor
const int visibleAPs = fp.measurements.entries.size();
if (visibleAPs == fpVisible.getMin() || visibleAPs == fpVisible.getMax()) {
p->addLabel("\\footnotesize{" + std::to_string(fp.measurements.entries.size()) + "}", pos+Point3(0,1,1)*0.25);
}
}
std::cout << fpVisible.asString() << std::endl;
p->splot.getCustom() << "set view equal xy\n";
p->splot.getCustom() << "unset border\n";
p->splot.getMargin().set(1, 0,0,0);
p->splot.getAxisX().setTicsVisible(false);
p->splot.getAxisY().setTicsVisible(false);
p->splot.getAxisZ().setTicsVisible(false);
p->splot.getAxisZ().setRange(K::GnuplotAxis::Range(-8, 19.5));
p->splot.getView().setCamera(74,30);
p->splot.getView().setScaleAll(3.8);
p->splot.getObjects().reOrderByZIndex();
p->plot();
p->gp.setTerminal("epslatex", K::GnuplotSize(8.6, 5.0));
p->gp.setOutput(Settings::fPathGFX + "/all_fingerprints.tex");
p->gp.writePlotToFile(Settings::fPathGFX + "/all_fingerprints.gp");
p->plot();
sleep(100);
}
/** show all walked paths */
void plotAllWalks(Floorplan::IndoorMap* map) {
using Walk = std::vector<Point3>;
Walk path1 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path1);
Walk path2 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path2);
//Walk path_toni_all_1 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path_toni_all_1);
//Walk path_toni_all_2 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path_toni_all_2);
Walk path_toni_inst_1 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path_toni_inst_1);
Walk path_toni_inst_2 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path_toni_inst_2);
Walk path_toni_inst_3 = FloorplanHelper::getGroundTruth(map, Settings::GroundTruth::path_toni_inst_3);
const std::vector<Walk> walks = {
path1,
path2,
//path_toni_all_1, same as path1
//path_toni_all_2, same as path2
path_toni_inst_1,
path_toni_inst_2,
path_toni_inst_3
};
const std::vector<std::string> titles = {
"path 1", "path 2", "path 3", "path 4", "path 5"
};
Plotty* p = new Plotty(map);
p->buildFloorplan();
std::vector<std::string> colors = {"#000000", "#ff0000", "#00cc00", "#0000ff", "#009999", "#aa00aa"};
int i = 0;
for (const Walk& walk : walks) {
K::GnuplotSplotElementLines* line = new K::GnuplotSplotElementLines();
line->getStroke().setWidth(2);
line->getStroke().getColor().setHexStr(colors[i]);
line->setTitle(titles[i]);
//line->getStroke().setType( (i > 3) ? K::GnuplotDashtype::DASHED : K::GnuplotDashtype::SOLID );
float oy = 0;
if (i == 2) {oy -= 0.5;}
if (i == 3) {oy += 0.5;}
for (const Point3& pt : walk) {
line->add(K::GnuplotPoint3(pt.x, pt.y+oy, pt.z));
}
p->splot.add(line);
++i;
}
p->splot.getKey().setVisible(true);
//p->splot.getKey().setPosition(K::GnuplotKey::Hor::RIGHT, K::GnuplotKey::Ver::TOP);
p->splot.getKey().setPosition(K::GnuplotCoordinate2(0.99, 0.99, K::GnuplotCoordinateSystem::SCREEN));
p->splot.getKey().setSampleLength(0.5);
//p->splot.getKey().setWidthIncrement(-4);
p->splot.setStringMod(new K::GnuplotStringModLaTeX());
p->splot.getCustom() << "set view equal xy\n";
p->splot.getCustom() << "unset border\n";
p->splot.getMargin().set(1, 0,0,0);
p->splot.getAxisX().setTicsVisible(false);
p->splot.getAxisY().setTicsVisible(false);
p->splot.getAxisZ().setTicsVisible(false);
p->splot.getAxisZ().setRange(K::GnuplotAxis::Range(-8, 19.5));
p->splot.getView().setCamera(74,30);
p->splot.getView().setScaleAll(3.8);
p->splot.getObjects().reOrderByZIndex();
p->plot();
p->gp.setTerminal("epslatex", K::GnuplotSize(8.6, 5.0));
p->gp.setOutput(Settings::fPathGFX + "/all_walks.tex");
p->gp.writePlotToFile(Settings::fPathGFX + "/all_walks.gp");
p->plot();
sleep(100);
}
void plotEstAndRealApPosDistance(Floorplan::IndoorMap* map) {
WiFiModelLogDistCeiling mdl(map);
mdl.loadXML(Settings::wifiEachOptParPos);
K::Statistics<float> statsTxp;
K::Statistics<float> statsExp;
K::Statistics<float> statsWaf;
K::Statistics<float> statsPosErr;
int numAPs = 0;
int numWrongZ = 0;
for (const AccessPoint& ap : mdl.getAllAPs()) {
// param range
const WiFiModelLogDistCeiling::APEntry params = mdl.getAP(ap.getMAC());
statsTxp.add(params.txp);
statsExp.add(params.exp);
statsWaf.add(params.waf);
// position error
const Point3 mdlPos = params.position_m;
const auto& it = FloorplanHelper::getAP(map, ap.getMAC());
const Floorplan::AccessPoint* fap = it.first;
const Floorplan::Floor* floor = it.second;
const Point3 realPos = fap->getPos(floor);
const float posErr = mdlPos.getDistance(realPos);
statsPosErr.add(posErr);
// wrong z?
if (mdlPos.z < floor->atHeight || mdlPos.z > (floor->atHeight+floor->height)) {
++numWrongZ;
}
++numAPs;
}
PlotErrFunc pef("", "\\docAP{}s (%)");
pef.getPlot().getAxisX().setTicsLabelFormat("%h m");
pef.add("oo", &statsPosErr);
pef.plot();
const std::string file = Settings::fPathGFX + "/" + "wifiOptApPosDifference";
pef.getGP().setOutput(file + ".tex");
pef.getGP().setTerminal("epslatex", K::GnuplotSize(8.6, 2.8));
pef.getPlot().getMargin().set(3.5, 0.2, 0.1, 2.0);
pef.writePlotToFile(file + ".gp");
pef.getPlot().setStringMod(new K::GnuplotStringModLaTeX());
pef.plot();
std::cout << "TXP:\t" << statsTxp.asString() << std::endl;
std::cout << "EXP:\t" << statsExp.asString() << std::endl;
std::cout << "WAF:\t" << statsWaf.asString() << std::endl;
std::cout << "Pos:\t" << statsPosErr.asString() << std::endl;
std::cout << "WrongZ:\t" << numWrongZ << " (" << (numWrongZ*100.0f/numAPs) << "%) "<< std::endl;
int i = 0; (void) i;
}
// build plots for the paper
void paperOutputs() {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);
// show optimization behaviour
if (1 == 0) {
EvalWiFiConvex eval(map, Settings::fCalib);
eval.showParams();
//eval.showPos();
eval.showPosZ();
return;
}
// show fingerprints as plot
if (1 == 0){
EvalWiFiSigStrength sig(Settings::fMap, Settings::fCalib);
Plotty* p = new Plotty(map);
p->writeCodeTo(Settings::fPathGFX + "compare-wifi-in-out.gp");
p->writeEpsTex(Settings::fPathGFX + "compare-wifi-in-out.tex", K::GnuplotSize(8.6, 4.7));
p->settings.floors = {0};
p->settings.maxZ = 1;
p->settings.outlineColor = K::GnuplotColor::fromRGB(170,170,170);
p->buildFloorplan();
sig.forPaperNN(p, MACAddress("d8:84:66:4a:23:d0"));
p->equalXY();
p->setView(0,0);
p->setScale(3.45, 3.45, -0.005, -0.04);
p->addRectangleW(Point3(62.5, 24, 0), Point3(72, 35, 0), K::GnuplotColor::fromRGB(0,0,0), 3, true); // small
p->addRectangleW(Point3(8.0, 39.75, 0), Point3(72, 43.75, 0), K::GnuplotColor::fromRGB(0,0,0), 3, true); // big
p->noFrame();
p->plot();
delete p;
}
// perform varios AP-param optimizations
// generate error plot showing the performance of each
// save the resulting wifi-models to XML for later re-use during the walk-eval <<<<<< !!!!
if (1 == 0) {
#include "bboxes.h"
Plotty pt(map);
pt.settings.outline = false;
pt.buildFloorplan();
// coloring
K::GnuplotColor cH = K::GnuplotColor::fromRGB(220,220,220);
K::GnuplotColor cO = K::GnuplotColor::fromRGB(0,128,0);
K::GnuplotColor cI = K::GnuplotColor::fromRGB(190,190,190);
// floor 0
pt.addBBoxes(bboxes0H, cH);
pt.addBBoxes(bboxes0O, cO);
pt.addBBoxes(bboxes0I, cI);
// floor 1
pt.addBBoxes(bboxes1H, cH);
pt.addBBoxes(bboxes1O, cO);
pt.addBBoxes(bboxes1I, cI);
// floor 2
pt.addBBoxes(bboxes2H, cH);
// floor 3
pt.addBBoxes(bboxes3H, cH);
pt.plot();
int i = 0; (void) i;
}
// show all fingerprints
if (1 == 0) {
plotAllFingerprints(map);
}
// show all walks
if (1 == 0) {
plotAllWalks(map);
}
// perform varios AP-param optimizations
// generate error plot showing the performance of each
// save the resulting wifi-models to XML for later re-use during the walk-eval <<<<<< !!!!
if (1 == 0) {
rebuildAllModels(map, 0);
/** detailled error analysis for above optimization routine */
errorPlotAllModels(map);
}
if (1 == 0) {
rebuildAllModels(map,4);
std::vector<K::Statistics<float>> stats4 = errorStatAllModels(map);
rebuildAllModels(map,2);
std::vector<K::Statistics<float>> stats2 = errorStatAllModels(map);
rebuildAllModels(map,0,true);
std::vector<K::Statistics<float>> statsNoStairs = errorStatAllModels(map);
rebuildAllModels(map,0); // ensure all output files are overwritten with the "all fingerprints" opt!!!
std::vector<K::Statistics<float>> stats0 = errorStatAllModels(map);
// analyze all 5 opt strategies. skip the empiric one: stats0[0]
for (int i = 1; i < 6; ++i) {
std::string name = "wifi_model_error_num_fingerprints_method_" + std::to_string(i);
errorPlotNumFingerprints(
{stats0[0], stats4[i], stats2[i], stats0[i], statsNoStairs[i]},
{"empiric", "25%", "50%", "100%", "no stairs"},
name
);
sleep(1);
}
sleep(1);
}
/** plot wifi eval results */
if (1 == 0) {
WiFiFingerprints fps;
fps.load(Settings::fCalib);
EvalWiFiOptResult eval1(Settings::fMap);
eval1.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos, fps);
EvalWiFiOptResult eval2(Settings::fMap);
eval2.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiAllFixed, fps);
// advanced model [1 model per floor]
EvalWiFiOptResult evalfloor(Settings::fMap);
evalfloor.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos_only0th, fps);
evalfloor.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos_only1st, fps);
evalfloor.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos_only2nd, fps);
evalfloor.showErrorPerFingerprint<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos_only3rd, fps);
evalfloor.showErrorPerFingerprint<WiFiModelPerFloor>(Settings::wifiEachOptParPos_multimodel, fps);
// more advanved model [1 model per bbox-region]
EvalWiFiOptResult evalBBox(Settings::fMap);
evalBBox.showErrorPerFingerprint<WiFiModelPerBBox>(Settings::wifiEachOptParPos_perBBox, fps);
int i = 0; (void) i;
}
// error histogram all pos, all params, between in/out/stair, in/out, in/stair, in
if(1==0){
EvalCompareOpt e1(Settings::fMap, Settings::fCalib, false, false, false);
EvalCompareOpt e2(Settings::fMap, Settings::fCalib, true, false, false);
EvalCompareOpt e3(Settings::fMap, Settings::fCalib, false, true, false);
EvalCompareOpt e4(Settings::fMap, Settings::fCalib, true, true, false);
K::Statistics<float> s1 = e1.optPosOptParamsForEach().errAbs;
K::Statistics<float> s2 = e2.optPosOptParamsForEach().errAbs;
K::Statistics<float> s3 = e3.optPosOptParamsForEach().errAbs;
K::Statistics<float> s4 = e4.optPosOptParamsForEach().errAbs;
PlotErrFunc pef("\\small{error (dB)}", "\\small{fingerprints (\\%)}");
pef.add("\\small{floor + stairs + out}", &s1);
pef.add("\\small{floor + out}", &s2);
pef.add("\\small{floor + stairs}", &s3);
pef.add("\\small{floor}", &s4);
pef.getGP().setTerminal("epslatex", K::GnuplotSize(8.5, 5));
pef.getGP().setOutput(Settings::fPathGFX + "wifi-opt-error-hist-stair-outdoor.tex");
pef.writePlotToFile(Settings::fPathGFX + "wifi-opt-error-hist-stair-outdoor.gp");
pef.getGP() << "set key right bottom width -3\n";
pef.getGP() << "set rmargin 0.4\n";
pef.getGP() << "set tmargin 0.4\n";
pef.plot();
}
// wifi issue for path1
if (1 == 0) {
Offline::FileReader reader(Settings::path1a);
PlotWifiMeasurements plot;
for (int i = 0; i < 60; ++i) {
const WiFiMeasurements mes = reader.getWiFiGroupedByTime().at(i).data;
const WiFiMeasurements mes2 = Settings::WiFiModel::vg_eval.group(mes);
plot.add(mes2);
}
K::GnuplotObjectRectangle rect(
K::GnuplotCoordinate2(0, K::GnuplotCoordinateSystem::FIRST, 0, K::GnuplotCoordinateSystem::GRAPH),
K::GnuplotCoordinate2(10, K::GnuplotCoordinateSystem::FIRST, 1, K::GnuplotCoordinateSystem::GRAPH),
K::GnuplotFill(K::GnuplotFillStyle::SOLID, K::GnuplotColor::fromRGB(128,128,128), 0.5),
K::GnuplotStroke()
);
plot.getPlot().setGrid(true);
plot.getPlot().getKey().setVisible(false);
plot.getPlot().getObjects().add(&rect);
plot.plot();
sleep(100);
}
}
void testWAF() {
Floorplan::Ceilings ceilings;
ceilings.addCeiling(3);
ceilings.addCeiling(6);
ceilings.addCeiling(9);
ceilings.addCeiling(12);
K::Gnuplot gp;
K::GnuplotPlot gplot;
K::GnuplotPlotElementLines lines; gplot.add(&lines);
const Point3 posAP(0, 0, 8);
for (float z = 0; z < 15; z += 0.1) {
const Point3 posMe(0, 0, z);
float factor = ceilings.numCeilingsBetweenFloat(posAP, posMe);
lines.add({z, factor});
}
gp.draw(gplot);
gp.flush();
sleep(1000);
}
void showFingerprintsFor(const std::string& mapFile, const std::string& fpFile, const std::string& smac) {
WiFiFingerprints calib(fpFile);
VAPGrouper vap(VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, VAPGrouper::Aggregation::AVERAGE);
for (WiFiFingerprint& fp : calib.getFingerprints()) {
fp.measurements = vap.group(fp.measurements);
}
const MACAddress mac(smac);
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(mapFile);
Plotty p(map);
p.buildFloorplan();
std::vector<WiFiFingerprint> fps = calib.getFingerprintsFor(mac);
for (const WiFiFingerprint& fp : fps) {
if (fp.measurements.entries.size() != 1) {throw "123";}
const float rssi = fp.measurements.entries[0].getRSSI();
const float s = (rssi-100) / (-40 - -100);
const Color c = Color::fromHSV(s*100, 255, 255);
p.addFloorRect(fp.pos_m, 3, c);
}
p.plot();
sleep(1);
}
void showModelFor(const std::string& mapFile, const std::string& modelXml, const std::string& smac) {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(mapFile);
WiFiModelFactory fac(map);
WiFiModel* model = fac.loadXML(modelXml);
const MACAddress mac(smac);
Plotty p(map);
p.buildFloorplan();
const float ss = 2.0;
for (Floorplan::Floor* floor : map->floors) {
for (float y = -20; y < 70; y+=ss) {
for (float x = -10; x < 130; x+=ss) {
const Point3 pos(x,y,floor->atHeight+1.3);
// limit estimations to the floorplan's outline
bool contained = false;
for (Floorplan::FloorOutlinePolygon* poly : floor->outline) {
HelperPoly hp(*poly);
if (hp.contains(pos.xy()*100)) {
if (poly->method == Floorplan::OutlineMethod::ADD) {
contained = true;
}
}
}
if (!contained) {continue;}
const float rssi = model->getRSSI(mac, pos);
const float s = (rssi-100) / (-40 - -100);
const Color c = Color::fromHSV(s*100, 255, 255);
p.addFloorRect(pos, 3, c);
}
}
}
p.plot();
sleep(1);
}
int main(void) {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);
//testWAF();
//paperOutputs(); return 0;
//showFingerprintsFor(Settings::fMap, Settings::fCalib, "D8:84:66:4A:4A:D0");
//showModelFor(Settings::fMap, Settings::wifiEachOptParPos_multimodel, "D8:84:66:4A:4A:D0");
//showFingerprintsFor(Settings::fMap, Settings::fCalib, "D8:84:66:4A:4A:E0");
//showModelFor(Settings::fMap, Settings::wifiEachOptParPos_multimodel, "D8:84:66:4A:4A:E0");
if (1 == 1) {
plotEstAndRealApPosDistance(map);
int i = 0; (void) i;
}
// calib error in/out
if (1 == 0) {
// outdoor only
bool ignoreStaircases = true;
bool ignoreOutdoor = false;
bool ignoreIndoor = true;
EvalCompareOpt opt1(Settings::fMap, Settings::fCalib, ignoreStaircases, ignoreOutdoor, ignoreIndoor);
EvalCompareOpt::Result s1 = opt1.optPosOptParamsForEach();
std::cout << s1.errAbs.asString() << std::endl;
// stairs only
ignoreStaircases = false;
ignoreOutdoor = true;
ignoreIndoor = true;
EvalCompareOpt opt3(Settings::fMap, Settings::fCalib, ignoreStaircases, ignoreOutdoor, ignoreIndoor);
EvalCompareOpt::Result s3 = opt3.optPosOptParamsForEach();
std::cout << s3.errAbs.asString() << std::endl;
// indoor only
ignoreStaircases = true;
ignoreOutdoor = true;
ignoreIndoor = false;
EvalCompareOpt opt2(Settings::fMap, Settings::fCalib, ignoreStaircases, ignoreOutdoor, ignoreIndoor);
EvalCompareOpt::Result s2 = opt2.optPosOptParamsForEach();
std::cout << s2.errAbs.asString() << std::endl;
}
// prob on ground
if (1 == 0) {
EvalWiFiGround eval(map, Settings::wifiEachOptParPos_multimodel);
//eval.show(Settings::path1a);
eval.show(Settings::path2a);
int i = 0; (void) i;
}
// walks
if (1 == 0) {
Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(Settings::fMap);;
EvalWalk walk(map);
walk.walk1();
return 0;
}
// test gps within data files
if (1 == 0) {
EvalData::dumpGPSforPath(Settings::path1a); BREAK;
EvalData::dumpGPSforPath(Settings::path1b); BREAK;
EvalData::dumpGPSforPath(Settings::path2a); BREAK;
EvalData::dumpGPSforPath(Settings::path2b); BREAK;
}
// eval average signal-strength per AP
if (1 == 0) {
EvalWiFiSigStrength ewss(Settings::fMap, Settings::fCalib);
ewss.perAP_avg();
}
// test wifi within data files
if (1 == 0) {
//EvalWiFi ew1(Settings::fMap, Settings::path1a, Settings::GroundTruth::path1);
EvalWiFi ew1(Settings::fMap, Settings::path1a, Settings::GroundTruth::path1);
//ew1.fixedParams(-40, 2.5, -8); BREAK;
//ew1.fixedParams(-64.5905, 1.25988, -2.47863); BREAK;
//ew1.fixedParams(-59.4903,1.52411,-3.25077); BREAK;
//ew1.load(Settings::wifiEachOptParPos);
ew1.load(Settings::wifiAllFixed, "empirc");
//ew1.load(Settings::wifiAllOptPar, "opt params all APs");
//ew1.load(Settings::wifiEachOptPar, "opt params each AP");
ew1.load(Settings::wifiEachOptParPos, "normal model");
ew1.load(Settings::wifiEachOptParPos_multimodel, "model per floor");
ew1.load(Settings::wifiEachOptParPos_perBBox, "model per region");
//ew1.load<WiFiModelLogDistCeiling>(Settings::wifiEachOptParPos_only1st, "everything opt");
//ew1.writeTeX("path1");
sleep(1000);
}
// show wifi multimodalities
if (1 == 0) {
Plotty::Settings settings;
settings.maxZ = 8;
EvalWiFiGround ewg(map, Settings::wifiEachOptParPos_perBBox, settings);
//ewg.show(Settings::path1a, 30);
//ewg.show(Settings::path1a, 70);
//ewg.show(Settings::path1a, 90);
int hueGreen = 120*255/360;
int hueYellow = 60*255/360;
int hueBlue = 210*255/360;
int hueRed = 0*255/360;
ewg.addGT(Settings::path1a, 100, hueGreen, Settings::GroundTruth::path1);
ewg.addGT(Settings::path1a, 170-8, hueBlue, Settings::GroundTruth::path1);
ewg.addGT(Settings::path1a, 200, hueRed, Settings::GroundTruth::path1);
// green
ewg.add(Settings::path1a, 100, hueGreen);
// yellow
ewg.add(Settings::path1a, 170, hueBlue);
// red
ewg.add(Settings::path1a, 200, hueRed);
ewg.groundProb->getPlot().splot.getObjects().reOrderByZIndex();
ewg.groundProb->plotMe();
ewg.writeGP(Settings::fPathGFX, "wifiMultimodality");
sleep(1000);
}
if (1 == 0) {
std::vector<std::string> files = {
Settings::path1a, Settings::path1b,
Settings::path2a, Settings::path2b,
Settings::path_toni_all_1a, Settings::path_toni_all_1b,
Settings::path_toni_all_2a, Settings::path_toni_all_2b,
Settings::path_toni_inst_1a, Settings::path_toni_inst_1b,
Settings::path_toni_inst_2a, Settings::path_toni_inst_2b,
Settings::path_toni_inst_3a, Settings::path_toni_inst_3b,
};
std::vector<std::vector<int>> gtIndices = {
Settings::GroundTruth::path1, Settings::GroundTruth::path1,
Settings::GroundTruth::path2, Settings::GroundTruth::path2,
Settings::GroundTruth::path1, Settings::GroundTruth::path1,
Settings::GroundTruth::path2, Settings::GroundTruth::path2,
// Settings::GroundTruth::path_toni_all_1, Settings::GroundTruth::path_toni_all_1,
// Settings::GroundTruth::path_toni_all_2, Settings::GroundTruth::path_toni_all_2,
Settings::GroundTruth::path_toni_inst_1, Settings::GroundTruth::path_toni_inst_1,
Settings::GroundTruth::path_toni_inst_2, Settings::GroundTruth::path_toni_inst_2,
Settings::GroundTruth::path_toni_inst_3, Settings::GroundTruth::path_toni_inst_3,
};
int numScans = 0;
for (const std::string& file : files) {
Offline::FileReader reader(file);
numScans += reader.getWiFiGroupedByTime().size();
}
std::cout << "num scans: " << numScans << std::endl;
EvalWiFiPaths ewp(Settings::fMap);
ewp.loadModel(Settings::wifiAllFixed, "\\noOptEmpiric{}");
ewp.walks(files, gtIndices);
ewp.loadModel(Settings::wifiEachOptParPos, "\\optParamsPosEachAP{}");
ewp.walks(files, gtIndices);
ewp.loadModel(Settings::wifiEachOptParPos_multimodel, "\\optPerFloor{}");
ewp.walks(files, gtIndices);
ewp.loadModel(Settings::wifiEachOptParPos_perBBox, "\\optPerRegion{}");
ewp.walks(files, gtIndices);
ewp.writeGP(Settings::fPathGFX, "modelPerformance");
// examine various modifications
if (1 == 0) {
EvalWiFiPathMethods ewpm(Settings::fMap);
ewpm.loadModel(Settings::wifiEachOptParPos_perBBox, "model per region", "original", "alternative");
ewpm.walks(files, gtIndices);
// export for paper
// using errFuncOtherExponential and only path1a, path1b
//ewpm.writeGP(Settings::fPathGFX, "normalVsExp");
}
sleep(10000);
}
// run earthmapping
//testMapEarthReg(fMap);
if (1 == 0) {
EvalApOpt eval(Settings::fMap, Settings::fCalib);
eval.optAll();
}
// compare wifi opt methods
if (1 == 0) {
const bool ignoreStaircases = false;
const bool ignoreOutdoor = false;
const bool ignoreIndoor = false;
EvalCompareOpt opt(Settings::fMap, Settings::fCalib, ignoreStaircases, ignoreOutdoor, ignoreIndoor);
EvalCompareOpt::Result s1 = opt.fixedPosFixedParamsForAll(); //BREAK;
EvalCompareOpt::Result s2 = opt.fixedPosOptParamsForAll(); //BREAK;
EvalCompareOpt::Result s3 = opt.fixedPosOptParamsForEach(); //BREAK;
EvalCompareOpt::Result s4 = opt.optPosOptParamsForEach(); //BREAK;
PlotErrFunc pef("error (dB)", "fingerprints (%)");
pef.add("empiric", &s1.errAbs);
pef.add("real pos, opt params [same for all]", &s2.errAbs);
pef.add("real pos, opt params [for each]", &s3.errAbs);
pef.add("opt pos, opt params [for each]", &s4.errAbs);
pef.plot();
}
// compare leaving out fingerprints
if (1 == 0) {
EvalCompareOpt e1(Settings::fMap, Settings::fCalib, false, false, false);
EvalCompareOpt e2(Settings::fMap, Settings::fCalib, true, false, false);
EvalCompareOpt e3(Settings::fMap, Settings::fCalib, false, true, false);
EvalCompareOpt e4(Settings::fMap, Settings::fCalib, true, true, false);
K::Statistics<float> s1 = e1.optPosOptParamsForEach().errAbs;
K::Statistics<float> s2 = e2.optPosOptParamsForEach().errAbs;
K::Statistics<float> s3 = e3.optPosOptParamsForEach().errAbs;
K::Statistics<float> s4 = e4.optPosOptParamsForEach().errAbs;
PlotErrFunc pef("error (dB)", "fingerprints (%)");
pef.add("floor + stairs + out", &s1);
pef.add("floor + out", &s2);
pef.add("floor + stairs", &s3);
pef.add("floor", &s4);
pef.plot();
}
}