From 8236069094d5b8d3ded06655ffeea579aafcfc5d Mon Sep 17 00:00:00 2001 From: Markus Bullmann Date: Tue, 8 Oct 2019 16:46:22 +0200 Subject: [PATCH] Refactored code to walk multiple runs --- code/Eval.cpp | 6 +-- code/Plotty.h | 7 ++- code/Settings.h | 19 +++++-- code/main.cpp | 122 ++++++++++++++++++++++++++++---------------- code/mainProb.cpp | 20 ++++---- code/mainTrilat.cpp | 12 ++--- code/misc.h | 22 +++++--- 7 files changed, 130 insertions(+), 78 deletions(-) diff --git a/code/Eval.cpp b/code/Eval.cpp index f8edbad..7e12d5e 100644 --- a/code/Eval.cpp +++ b/code/Eval.cpp @@ -18,15 +18,15 @@ double ftmEval(SensorMode UseSensor, const Timestamp& currentTime, const Point3& const MACAddress& mac = wifi.getAP().getMAC(); int nucIndex = Settings::nucIndex(mac); - const Point3 apPos = Settings::data.CurrentPath.nucInfo(nucIndex).position; + const Point3 apPos = Settings::CurrentPath.nucInfo(nucIndex).position; // particlePos.z = 1.3; // smartphone höhe const float apDist = particlePos.getDistance(apPos); // compute ftm distance - float ftm_offset = Settings::data.CurrentPath.NUCs.at(mac).ftm_offset; + float ftm_offset = Settings::CurrentPath.NUCs.at(mac).ftm_offset; float ftmDist = wifi.getFtmDist() + ftm_offset; // in m; plus static offset - float rssi_pathloss = Settings::data.CurrentPath.NUCs.at(mac).rssi_pathloss; + float rssi_pathloss = Settings::CurrentPath.NUCs.at(mac).rssi_pathloss; float rssiDist = LogDistanceModel::rssiToDistance(-40, rssi_pathloss, wifi.getRSSI()); if (UseSensor == SensorMode::FTM) diff --git a/code/Plotty.h b/code/Plotty.h index b76fef5..d8f7344 100644 --- a/code/Plotty.h +++ b/code/Plotty.h @@ -580,9 +580,14 @@ public: void saveToFile(std::ofstream& stream){ gp.draw(splot); + +#if defined(_WINDOWS) + stream << "set terminal windows size 2000,1500\n"; +#elif stream << "set terminal x11 size 2000,1500\n"; +#endif stream << gp.getBuffer(); - stream << "pause -1\n"; +// stream << "pause -1\n"; gp.flush(); } diff --git a/code/Settings.h b/code/Settings.h index 245602e..10f3efc 100644 --- a/code/Settings.h +++ b/code/Settings.h @@ -10,8 +10,9 @@ namespace Settings { const std::string dataDir = "../measurements/data/"; const std::string errorDir = "../measurements/error/"; const std::string plotDataDir = "../plots/data/"; + const std::string outputDir = "../output/"; - const bool UseKalman = false; + const bool UseKalman = true; /** describes one dataset (map, training, parameter-estimation, ...) */ @@ -56,6 +57,7 @@ namespace Settings { }; struct DataSetup { + std::string name; std::string map; std::vector training; std::unordered_map NUCs; @@ -77,6 +79,7 @@ namespace Settings { const struct Data { const DataSetup Path0 = { + "path0", mapDir + "map0_ap_path0.xml", { dataDir + "Pixel2/Path0_0605.csv", @@ -94,6 +97,7 @@ namespace Settings { // 1 Path: U von TR nach TD und zurück; const DataSetup Path1 = { + "path1", mapDir + "map2_ap_path1.xml", { dataDir + "Pixel2/path1/1560153927208_2_1.csv", @@ -115,6 +119,7 @@ namespace Settings { // 2 Path: Wie 2 nur von TD zu TR const DataSetup Path2 = { + "path2", mapDir + "map2_ap_path1.xml", { dataDir + "Pixel2/path2/1560154622883_3_1.csv", @@ -137,6 +142,7 @@ namespace Settings { // 3 Path: U von TR nach TD; 4 mal das U const DataSetup Path3 = { + "path3", mapDir + "map2_ap_path2.xml", { dataDir + "Pixel2/path3/1560155227376_4_1.csv", @@ -158,6 +164,7 @@ namespace Settings { // 4 Path: In Räumen const DataSetup Path4 = { + "path4", mapDir + "map2_ap_path2.xml", { dataDir + "Pixel2/path4/1560156876457_5_1.csv", @@ -180,6 +187,7 @@ namespace Settings { // 5 Path: In Räumen extendend const DataSetup Path5 = { + "path5", mapDir + "map2_ap_path2.xml", { dataDir + "Pixel2/path5/1560158444772_6_1.csv", @@ -202,6 +210,7 @@ namespace Settings { // 6 Path: SHL Path 1 const DataSetup Path6 = { + "path6", mapDir + "shl.xml", { dataDir + "Pixel2/path6/14681054221905_6_1.csv" @@ -219,6 +228,7 @@ namespace Settings { // 7 Path: SHL Path 2; Versuche mit NUCs in den Räumen war nicht vielversprechend ... const DataSetup Path7 = { + "path7", mapDir + "shl.xml", { dataDir + "Pixel2/path7/23388354821394.csv", @@ -239,6 +249,7 @@ namespace Settings { // 8 Path: Wie SHL Path 2 nur, dass die NUCs im Gang stehen const DataSetup Path8 = { + "path8", mapDir + "shl.xml", { dataDir + "Pixel2/path8/25967118530318.csv", // gang @@ -257,6 +268,7 @@ namespace Settings { // 9 Path: SHL Path 3, NUCs stehen im Gang const DataSetup Path9 = { + "path9", mapDir + "shl_nuc_gang.xml", { dataDir + "Pixel2/path9/27911186920065.csv", @@ -273,11 +285,8 @@ namespace Settings { { 200, 201, 203, 104, 204, 205, 206, 207, 206, 208, 209, 210, 211, 212 }, true }; - - - const DataSetup CurrentPath = Path7; - } data; + static DataSetup CurrentPath = data.Path7; } diff --git a/code/main.cpp b/code/main.cpp index 5d29db9..c8d8b4a 100644 --- a/code/main.cpp +++ b/code/main.cpp @@ -50,7 +50,7 @@ std::vector> getFtmValues(Offline::FileReader& f if (wifi.getAP().getMAC() == nuc) { - Point3 apPos = Settings::data.CurrentPath.NUCs.find(wifi.getAP().getMAC())->second.position; + Point3 apPos = Settings::CurrentPath.NUCs.find(wifi.getAP().getMAC())->second.position; float apDist = gtPos.getDistance(apPos); float ftmDist = wifi.getFtmDist(); float rssi = wifi.getRSSI(); @@ -155,9 +155,9 @@ void exportFtmValues(Offline::FileReader& fr, Interpolator& gt auto wifi = fr.getWifiFtm()[e.idx].data; - int nucid = Settings::data.CurrentPath.NUCs.at(wifi.getAP().getMAC()).ID; - float ftm_offset = Settings::data.CurrentPath.NUCs.at(wifi.getAP().getMAC()).ftm_offset; - float rssi_pathloss = Settings::data.CurrentPath.NUCs.at(wifi.getAP().getMAC()).rssi_pathloss; + int nucid = Settings::CurrentPath.NUCs.at(wifi.getAP().getMAC()).ID; + float ftm_offset = Settings::CurrentPath.NUCs.at(wifi.getAP().getMAC()).ftm_offset; + float rssi_pathloss = Settings::CurrentPath.NUCs.at(wifi.getAP().getMAC()).rssi_pathloss; float rssiDist = LogDistanceModel::rssiToDistance(-40, rssi_pathloss, wifi.getRSSI()); float ftmDist = wifi.getFtmDist() + ftm_offset; //in m; plus static offset @@ -165,7 +165,7 @@ void exportFtmValues(Offline::FileReader& fr, Interpolator& gt int numMeas = wifi.getNumAttemptedMeasurements(); int numSuccessMeas = wifi.getNumSuccessfulMeasurements(); - Point3 apPos = Settings::data.CurrentPath.NUCs.find(wifi.getAP().getMAC())->second.position; + Point3 apPos = Settings::CurrentPath.NUCs.find(wifi.getAP().getMAC())->second.position; float apDist = gtPos.getDistance(apPos); fs << ts.ms() << ";" << nucid << ";" << apDist << ";" << rssiDist << ";" << ftmDist << ";" << ftmStdDev << ";" << numMeas << ";" << numSuccessMeas << "\n"; @@ -214,6 +214,13 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str std::ofstream errorFile; errorFile.open (evalDir.string() + "/" + std::to_string(walkIdx) + "_" + std::to_string(t) + ".csv"); + // Output dir + auto outputDir = std::filesystem::path(Settings::outputDir); + outputDir.append(Settings::CurrentPath.name + "_" + std::to_string(walkIdx)); + + if (!std::filesystem::exists(outputDir)) { + std::filesystem::create_directories(outputDir); + } // wifi auto kalmanMap = std::make_shared>(); @@ -245,10 +252,10 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str plot.setGroundTruth(gtPath); plot.setView(30, 0); // APs Positions - plot.addCircle(100000 + 0, Settings::data.CurrentPath.nucInfo(0).position.xy(), 0.05); - plot.addCircle(100000 + 1, Settings::data.CurrentPath.nucInfo(1).position.xy(), 0.05); - plot.addCircle(100000 + 2, Settings::data.CurrentPath.nucInfo(2).position.xy(), 0.05); - plot.addCircle(100000 + 3, Settings::data.CurrentPath.nucInfo(3).position.xy(), 0.05); + plot.addCircle(100000 + 0, Settings::CurrentPath.nucInfo(0).position.xy(), 0.1); + plot.addCircle(100000 + 1, Settings::CurrentPath.nucInfo(1).position.xy(), 0.1); + plot.addCircle(100000 + 2, Settings::CurrentPath.nucInfo(2).position.xy(), 0.1); + plot.addCircle(100000 + 3, Settings::CurrentPath.nucInfo(3).position.xy(), 0.1); plot.plot(); // particle-filter @@ -283,8 +290,8 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str std::vector timestamps; std::vector> gtDistances, ftmDistances, rssiDistances; // distance per AP - Plotta::Plotta errorPlot("errorPlot", Settings::plotDataDir + "errorData.py"); - Plotta::Plotta distsPlot("distsPlot", Settings::plotDataDir + "distances.py"); + Plotta::Plotta errorPlot("errorPlot", outputDir.string() + "/errorData.py"); + Plotta::Plotta distsPlot("distsPlot", outputDir.string() + "/distances.py"); for (const Offline::Entry& e : fr.getEntries()) { @@ -305,10 +312,10 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str Point2 gtPos = gtInterpolator.get(static_cast(ts.ms())).xy(); plot.setGroundTruth(Point3(gtPos.x, gtPos.y, 0.1)); - gtDistances.push_back({ gtPos.getDistance(Settings::data.CurrentPath.nucInfo(0).position.xy()), - gtPos.getDistance(Settings::data.CurrentPath.nucInfo(1).position.xy()), - gtPos.getDistance(Settings::data.CurrentPath.nucInfo(2).position.xy()), - gtPos.getDistance(Settings::data.CurrentPath.nucInfo(3).position.xy()) }); + gtDistances.push_back({ gtPos.getDistance(Settings::CurrentPath.nucInfo(0).position.xy()), + gtPos.getDistance(Settings::CurrentPath.nucInfo(1).position.xy()), + gtPos.getDistance(Settings::CurrentPath.nucInfo(2).position.xy()), + gtPos.getDistance(Settings::CurrentPath.nucInfo(3).position.xy()) }); Point3 estPos; float distErrorFtm = 0; @@ -339,10 +346,10 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str { WiFiMeasurement wifi2 = obs.ftm[i]; - Point3 apPos = Settings::data.CurrentPath.nuc(wifi2.getAP().getMAC()).position; + Point3 apPos = Settings::CurrentPath.nuc(wifi2.getAP().getMAC()).position; K::GnuplotColor color; - switch (Settings::data.CurrentPath.nuc(wifi2.getAP().getMAC()).ID) + switch (Settings::CurrentPath.nuc(wifi2.getAP().getMAC()).ID) { case 1: color = K::GnuplotColor::fromRGB(0, 255, 0); break; case 2: color = K::GnuplotColor::fromRGB(0, 0, 255); break; @@ -390,6 +397,18 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str printErrorStats(errorStats); + std::ofstream plot_out; + plot_out.open(outputDir.string() + "/plot.gp"); + + plot.clearDistanceCircles(); + plot.saveToFile(plot_out); + + std::ofstream errorStats_out; + errorStats_out.open(outputDir.string() + "/error_stats.txt"); + printErrorStats(errorStats_out, errorStats); + + errorPlot.frame(); + //system("pause"); return errorStats; @@ -417,45 +436,58 @@ int main(int argc, char** argv) CombinedStats tmp; std::string evaluationName = "prologic/tmp"; + + std::vector setupsToRun = { Settings::data.Path7, + Settings::data.Path8, + Settings::data.Path9 }; - for (size_t walkIdx = 0; walkIdx < 1 /*Settings::data.CurrentPath.training.size()*/; walkIdx++) + for (Settings::DataSetup setupToRun : setupsToRun) { - std::cout << "Executing walk " << walkIdx << "\n"; - for (int i = 0; i < 5; ++i) + Settings::CurrentPath = setupToRun; + + + for (size_t walkIdx = 0; walkIdx < 1 /*Settings::CurrentPath.training.size()*/; walkIdx++) { - std::cout << "Start of iteration " << i << "\n"; + std::cout << "Executing walk " << walkIdx << "\n"; + for (int i = 0; i < 1; ++i) + { + std::cout << "Start of iteration " << i << "\n"; - tmp = run(Settings::data.CurrentPath, walkIdx, evaluationName); + tmp = run(Settings::CurrentPath, walkIdx, evaluationName); - statsAVG.ftm.add(tmp.ftm.getAvg()); - statsMedian.ftm.add(tmp.ftm.getMedian()); - statsSTD.ftm.add(tmp.ftm.getStdDev()); - statsQuantil.ftm.add(tmp.ftm.getQuantile(0.75)); + statsAVG.ftm.add(tmp.ftm.getAvg()); + statsMedian.ftm.add(tmp.ftm.getMedian()); + statsSTD.ftm.add(tmp.ftm.getStdDev()); + statsQuantil.ftm.add(tmp.ftm.getQuantile(0.75)); - statsAVG.rssi.add(tmp.rssi.getAvg()); - statsMedian.rssi.add(tmp.rssi.getMedian()); - statsSTD.rssi.add(tmp.rssi.getStdDev()); - statsQuantil.rssi.add(tmp.rssi.getQuantile(0.75)); + statsAVG.rssi.add(tmp.rssi.getAvg()); + statsMedian.rssi.add(tmp.rssi.getMedian()); + statsSTD.rssi.add(tmp.rssi.getStdDev()); + statsQuantil.rssi.add(tmp.rssi.getQuantile(0.75)); - std::cout << "Iteration " << i << " completed" << std::endl; + std::cout << "Iteration " << i << " completed" << std::endl; + } } + + std::cout << "Results for path " << Settings::CurrentPath.name << std::endl; + std::cout << "==========================================================" << std::endl; + std::cout << "Average of all statistical data FTM: " << std::endl; + std::cout << "Median: " << statsMedian.ftm.getAvg() << std::endl; + std::cout << "Average: " << statsAVG.ftm.getAvg() << std::endl; + std::cout << "Standard Deviation: " << statsSTD.ftm.getAvg() << std::endl; + std::cout << "75 Quantil: " << statsQuantil.ftm.getAvg() << std::endl; + std::cout << "==========================================================" << std::endl; + + std::cout << "==========================================================" << std::endl; + std::cout << "Average of all statistical data RSSI: " << std::endl; + std::cout << "Median: " << statsMedian.rssi.getAvg() << std::endl; + std::cout << "Average: " << statsAVG.rssi.getAvg() << std::endl; + std::cout << "Standard Deviation: " << statsSTD.rssi.getAvg() << std::endl; + std::cout << "75 Quantil: " << statsQuantil.rssi.getAvg() << std::endl; + std::cout << "==========================================================" << std::endl; } - std::cout << "==========================================================" << std::endl; - std::cout << "Average of all statistical data FTM: " << std::endl; - std::cout << "Median: " << statsMedian.ftm.getAvg() << std::endl; - std::cout << "Average: " << statsAVG.ftm.getAvg() << std::endl; - std::cout << "Standard Deviation: " << statsSTD.ftm.getAvg() << std::endl; - std::cout << "75 Quantil: " << statsQuantil.ftm.getAvg() << std::endl; - std::cout << "==========================================================" << std::endl; - std::cout << "==========================================================" << std::endl; - std::cout << "Average of all statistical data RSSI: " << std::endl; - std::cout << "Median: " << statsMedian.rssi.getAvg() << std::endl; - std::cout << "Average: " << statsAVG.rssi.getAvg() << std::endl; - std::cout << "Standard Deviation: " << statsSTD.rssi.getAvg() << std::endl; - std::cout << "75 Quantil: " << statsQuantil.rssi.getAvg() << std::endl; - std::cout << "==========================================================" << std::endl; diff --git a/code/mainProb.cpp b/code/mainProb.cpp index 4702451..e410f1c 100644 --- a/code/mainProb.cpp +++ b/code/mainProb.cpp @@ -75,7 +75,7 @@ static void computeDensity(const BBox3& bbox, std::vector run(Settings::DataSetup setup, int walkIdx, std::str }; std::array apPositions{ - Settings::data.CurrentPath.NUCs.at(Settings::NUC1).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC2).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC3).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC4).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC1).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC2).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC3).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC4).position.xy(), }; std::vector obs; @@ -241,7 +241,7 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str plot.setCurEst(Point3(estPos.x, estPos.y, 0.1)); // Plot density - //plotDensity(plot, density); + plotDensity(plot, density); // Error distErrorFtm = gtPos.getDistance(estPos); @@ -304,14 +304,14 @@ int mainProp(int argc, char** argv) std::string evaluationName = "prologic/tmp"; - for (size_t walkIdx = 0; walkIdx < Settings::data.CurrentPath.training.size(); walkIdx++) + for (size_t walkIdx = 0; walkIdx < Settings::CurrentPath.training.size(); walkIdx++) { std::cout << "Executing walk " << walkIdx << "\n"; for (int i = 0; i < 1; ++i) { std::cout << "Start of iteration " << i << "\n"; - tmp = run(Settings::data.CurrentPath, walkIdx, evaluationName); + tmp = run(Settings::CurrentPath, walkIdx, evaluationName); statsAVG.ftm.add(tmp.ftm.getAvg()); statsMedian.ftm.add(tmp.ftm.getMedian()); diff --git a/code/mainTrilat.cpp b/code/mainTrilat.cpp index 008836a..8a5ac6b 100644 --- a/code/mainTrilat.cpp +++ b/code/mainTrilat.cpp @@ -67,10 +67,10 @@ static CombinedStats run(Settings::DataSetup setup, int walkIdx, std::str Plotta::Plotta plotta("test", "C:\\Temp\\Plotta\\dataTrilat.py"); std::vector apPositions{ - Settings::data.CurrentPath.NUCs.at(Settings::NUC1).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC2).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC3).position.xy(), - Settings::data.CurrentPath.NUCs.at(Settings::NUC4).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC1).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC2).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC3).position.xy(), + Settings::CurrentPath.NUCs.at(Settings::NUC4).position.xy(), }; plotta.add("apPos", apPositions); @@ -213,14 +213,14 @@ int mainTrilat(int argc, char** argv) std::string evaluationName = "prologic/tmp"; - for (size_t walkIdx = 0; walkIdx < Settings::data.CurrentPath.training.size(); walkIdx++) + for (size_t walkIdx = 0; walkIdx < Settings::CurrentPath.training.size(); walkIdx++) { std::cout << "Executing walk " << walkIdx << "\n"; for (int i = 0; i < 1; ++i) { std::cout << "Start of iteration " << i << "\n"; - tmp = run(Settings::data.CurrentPath, walkIdx, evaluationName); + tmp = run(Settings::CurrentPath, walkIdx, evaluationName); statsAVG.ftm.add(tmp.ftm.getAvg()); statsMedian.ftm.add(tmp.ftm.getMedian()); diff --git a/code/misc.h b/code/misc.h index e565f34..535d0c0 100644 --- a/code/misc.h +++ b/code/misc.h @@ -48,15 +48,21 @@ struct CombinedStats { Stats::Statistics rssi; }; +template +void printErrorStats(std::ostream& stream, const CombinedStats& errorStats) +{ + stream << "Walk error:" << "\n"; + stream << "[m] " << std::setw(10) << "mean" << std::setw(10) << "stdDev" << std::setw(10) << "median" << "\n"; + + stream << "FTM " << std::setw(10) << errorStats.ftm.getAvg() << std::setw(10) << errorStats.ftm.getStdDev() << std::setw(10) << errorStats.ftm.getMedian() << "\n"; + stream << "RSSI " << std::setw(10) << errorStats.rssi.getAvg() << std::setw(10) << errorStats.rssi.getStdDev() << std::setw(10) << errorStats.rssi.getMedian() << "\n"; + stream << std::endl; +} + template void printErrorStats(const CombinedStats& errorStats) { - std::cout << "Walk error:" << "\n"; - std::cout << "[m] " << std::setw(10) << "mean" << std::setw(10) << "stdDev" << std::setw(10) << "median" << "\n"; - - std::cout << "FTM " << std::setw(10) << errorStats.ftm.getAvg() << std::setw(10) << errorStats.ftm.getStdDev() << std::setw(10) << errorStats.ftm.getMedian() << "\n"; - std::cout << "RSSI " << std::setw(10) << errorStats.rssi.getAvg() << std::setw(10) << errorStats.rssi.getStdDev() << std::setw(10) << errorStats.rssi.getMedian() << "\n"; - std::cout << std::endl; + return printErrorStats(std::cout, errorStats); } @@ -94,10 +100,10 @@ static std::vector filterOfflineData(const Offline::FileReader& fr) auto ftm = fr.getWifiFtm()[e.idx].data; const MACAddress& mac = ftm.getAP().getMAC(); - float ftm_offset = Settings::data.CurrentPath.NUCs.at(mac).ftm_offset; + float ftm_offset = Settings::CurrentPath.NUCs.at(mac).ftm_offset; float ftmDist = ftm.getFtmDist() + ftm_offset; // in m; plus static offset - float rssi_pathloss = Settings::data.CurrentPath.NUCs.at(mac).rssi_pathloss; + float rssi_pathloss = Settings::CurrentPath.NUCs.at(mac).rssi_pathloss; float rssiDist = LogDistanceModel::rssiToDistance(-40, rssi_pathloss, ftm.getRSSI()); int nucIndex = Settings::nucIndex(mac);