current state
This commit is contained in:
715
main.cpp
715
main.cpp
@@ -39,6 +39,472 @@
|
||||
|
||||
#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);
|
||||
|
||||
}
|
||||
|
||||
// build plots for the paper
|
||||
void paperOutputs() {
|
||||
|
||||
@@ -117,137 +583,51 @@ void paperOutputs() {
|
||||
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
// // 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);
|
||||
|
||||
// all combined
|
||||
auto removeNone = [] (const WiFiFingerprint& fp) -> bool {return false;};
|
||||
|
||||
// per floor
|
||||
auto only0th = [] (const WiFiFingerprint& fp) -> bool {return std::abs(fp.pos_m.z - (1.3)) > 0.1;};
|
||||
auto only1st = [] (const WiFiFingerprint& fp) -> bool {return std::abs(fp.pos_m.z - (4+1.3)) > 0.1;};
|
||||
auto only2nd = [] (const WiFiFingerprint& fp) -> bool {return std::abs(fp.pos_m.z - (4+3.4+1.3)) > 0.1;};
|
||||
auto only3rd = [] (const WiFiFingerprint& fp) -> bool {return 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 !bboxes0H.contains(fp.pos_m);};
|
||||
auto only0O = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes0O.contains(fp.pos_m);};
|
||||
auto only0I = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes0I.contains(fp.pos_m);};
|
||||
|
||||
auto only1H = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes1H.contains(fp.pos_m);};
|
||||
auto only1O = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes1O.contains(fp.pos_m);};
|
||||
auto only1I = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes1I.contains(fp.pos_m);};
|
||||
|
||||
auto only2H = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes2H.contains(fp.pos_m);};
|
||||
|
||||
auto only3H = [&] (const WiFiFingerprint& fp) -> bool {return !bboxes3H.contains(fp.pos_m);};
|
||||
rebuildAllModels(map, 0);
|
||||
/** detailled error analysis for above optimization routine */
|
||||
errorPlotAllModels(map);
|
||||
}
|
||||
|
||||
|
||||
// use fingerprints?
|
||||
EvalCompareOpt2 opt1(Settings::fMap, Settings::fCalib, removeNone);
|
||||
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);
|
||||
|
||||
// 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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
// optimize per floor
|
||||
EvalCompareOpt2 opt_f0(Settings::fMap, Settings::fCalib, only0th);
|
||||
EvalCompareOpt2::Result sf0 = opt_f0.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_f1(Settings::fMap, Settings::fCalib, only1st);
|
||||
EvalCompareOpt2::Result sf1 = opt_f1.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_f2(Settings::fMap, Settings::fCalib, only2nd);
|
||||
EvalCompareOpt2::Result sf2 = opt_f2.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_f3(Settings::fMap, Settings::fCalib, only3rd);
|
||||
EvalCompareOpt2::Result sf3 = opt_f3.optPosOptParamsForEach();
|
||||
|
||||
|
||||
// optimize per bbox
|
||||
EvalCompareOpt2 opt_0H(Settings::fMap, Settings::fCalib, only0H);
|
||||
EvalCompareOpt2::Result sf0H = opt_0H.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_0O(Settings::fMap, Settings::fCalib, only0O);
|
||||
EvalCompareOpt2::Result sf0O = opt_0O.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_0I(Settings::fMap, Settings::fCalib, only0I);
|
||||
EvalCompareOpt2::Result sf0I = opt_0I.optPosOptParamsForEach();
|
||||
|
||||
EvalCompareOpt2 opt_1H(Settings::fMap, Settings::fCalib, only1H);
|
||||
EvalCompareOpt2::Result sf1H = opt_1H.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_1O(Settings::fMap, Settings::fCalib, only1O);
|
||||
EvalCompareOpt2::Result sf1O = opt_1O.optPosOptParamsForEach();
|
||||
EvalCompareOpt2 opt_1I(Settings::fMap, Settings::fCalib, only1I);
|
||||
EvalCompareOpt2::Result sf1I = opt_1I.optPosOptParamsForEach();
|
||||
|
||||
EvalCompareOpt2 opt_2H(Settings::fMap, Settings::fCalib, only2H);
|
||||
EvalCompareOpt2::Result sf2H = opt_2H.optPosOptParamsForEach();
|
||||
|
||||
EvalCompareOpt2 opt_3H(Settings::fMap, Settings::fCalib, only3H);
|
||||
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.writeCodeTo(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);
|
||||
sleep(1);
|
||||
|
||||
}
|
||||
|
||||
@@ -302,7 +682,7 @@ void paperOutputs() {
|
||||
|
||||
pef.getGP().setTerminal("epslatex", K::GnuplotSize(8.5, 5));
|
||||
pef.getGP().setOutput(Settings::fPathGFX + "wifi-opt-error-hist-stair-outdoor.tex");
|
||||
pef.writeCodeTo(Settings::fPathGFX + "wifi-opt-error-hist-stair-outdoor.gp");
|
||||
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";
|
||||
@@ -546,8 +926,47 @@ int main(void) {
|
||||
|
||||
}
|
||||
|
||||
// show wifi multimodalities
|
||||
if (1 == 1) {
|
||||
|
||||
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,
|
||||
@@ -560,33 +979,51 @@ int main(void) {
|
||||
std::vector<std::vector<int>> gtIndices = {
|
||||
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::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,
|
||||
};
|
||||
|
||||
// EvalWiFiPaths ewp(Settings::fMap);
|
||||
// ewp.loadModel(Settings::wifiAllFixed, "empirc");
|
||||
// ewp.walks(files, gtIndices);
|
||||
int numScans = 0;
|
||||
for (const std::string& file : files) {
|
||||
Offline::FileReader reader(file);
|
||||
numScans += reader.getWiFiGroupedByTime().size();
|
||||
}
|
||||
|
||||
// ewp.loadModel(Settings::wifiEachOptParPos, "normal model");
|
||||
// ewp.walks(files, gtIndices);
|
||||
std::cout << "num scans: " << numScans << std::endl;
|
||||
|
||||
// ewp.loadModel(Settings::wifiEachOptParPos_multimodel, "model per floor");
|
||||
// ewp.walks(files, gtIndices);
|
||||
|
||||
// ewp.loadModel(Settings::wifiEachOptParPos_perBBox, "model per region");
|
||||
// ewp.walks(files, gtIndices);
|
||||
EvalWiFiPaths ewp(Settings::fMap);
|
||||
ewp.loadModel(Settings::wifiAllFixed, "\\noOptEmpiric{}");
|
||||
ewp.walks(files, gtIndices);
|
||||
|
||||
EvalWiFiPathMethods ewpm(Settings::fMap);
|
||||
ewpm.loadModel(Settings::wifiEachOptParPos_perBBox, "model per region", "original", "alternative");
|
||||
ewpm.walks(files, gtIndices);
|
||||
ewp.loadModel(Settings::wifiEachOptParPos, "\\optParamsPosEachAP{}");
|
||||
ewp.walks(files, gtIndices);
|
||||
|
||||
// export for paper
|
||||
// using errFuncOtherExponential and only path1a, path1b
|
||||
//ewpm.writeGP(Settings::fPathGFX, "normalVsExp");
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user