Refactored code to walk multiple runs

This commit is contained in:
2019-10-08 16:46:22 +02:00
parent 08be3e9af5
commit 8236069094
7 changed files with 130 additions and 78 deletions

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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<std::string> training;
std::unordered_map<MACAddress, NUCSettings> 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;
}

View File

@@ -50,7 +50,7 @@ std::vector<std::tuple<float, float, float>> 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<uint64_t, Point3>& 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<uint64_t, Point3>& 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<float> 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<std::unordered_map<MACAddress, Kalman>>();
@@ -245,10 +252,10 @@ static CombinedStats<float> 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<float> run(Settings::DataSetup setup, int walkIdx, std::str
std::vector<int> timestamps;
std::vector<std::array<float, 4>> 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<float> run(Settings::DataSetup setup, int walkIdx, std::str
Point2 gtPos = gtInterpolator.get(static_cast<uint64_t>(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<float> 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<float> 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<float> tmp;
std::string evaluationName = "prologic/tmp";
std::vector<Settings::DataSetup> 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;

View File

@@ -75,7 +75,7 @@ static void computeDensity(const BBox3& bbox, std::vector<std::pair<Point2, doub
int nucIndex = Settings::nucIndex(mac);
// compute AP distance
const Point3 apPos = Settings::data.CurrentPath.nucInfo(nucIndex).position;
const Point3 apPos = Settings::CurrentPath.nucInfo(nucIndex).position;
Point3 pos = Point3(pt.x, pt.y, 1.3); // smartphone h<>he
const float apDist = pos.getDistance(apPos);
@@ -83,7 +83,7 @@ static void computeDensity(const BBox3& bbox, std::vector<std::pair<Point2, doub
if (useFtm)
{
// 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
dist = ftmDist;
@@ -91,7 +91,7 @@ static void computeDensity(const BBox3& bbox, std::vector<std::pair<Point2, doub
else
{
// compute rssi distance
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, 2.25 /*rssi_pathloss*/, wifi.getRSSI());
dist = rssiDist;
@@ -187,10 +187,10 @@ static CombinedStats<float> run(Settings::DataSetup setup, int walkIdx, std::str
};
std::array<Point2, 4> 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<WiFiMeasurement> obs;
@@ -241,7 +241,7 @@ static CombinedStats<float> 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());

View File

@@ -67,10 +67,10 @@ static CombinedStats<float> run(Settings::DataSetup setup, int walkIdx, std::str
Plotta::Plotta plotta("test", "C:\\Temp\\Plotta\\dataTrilat.py");
std::vector<Point2> 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());

View File

@@ -48,15 +48,21 @@ struct CombinedStats {
Stats::Statistics<T> rssi;
};
template<typename T>
void printErrorStats(std::ostream& stream, const CombinedStats<T>& 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<typename T>
void printErrorStats(const CombinedStats<T>& 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<WifiMeas> 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);