#include #include "filter/Structs.h" #include "Plotti.h" #include #include "filter/Logic.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "Settings.h" #include #include #include #include #include #include #include #include #include #include //frank //const std::string mapDir = "/mnt/data/workspaces/IPIN2016/IPIN2016/competition/maps/"; //const std::string dataDir = "/mnt/data/workspaces/IPIN2016/IPIN2016/competition/src/data/"; //toni const std::string mapDir = "/home/toni/Documents/programme/localization/russenJournal/russen/map/"; const std::string dataDir = "/home/toni/Documents/programme/localization/russenJournal/russen/data/"; const std::string errorDir = dataDir + "results/"; /** describes one dataset (map, training, parameter-estimation, ...) */ struct DataSetup { std::string map; std::vector training; std::string wifiParams; int minWifiOccurences; VAPGrouper::Mode vapMode; std::string grid; }; /** all configured datasets */ struct Data { DataSetup BERKWERK = { mapDir + "SHL/SHL25.xml", { dataDir + "bergwerk/path1/nexus/vor/1454775984079.csv", dataDir + "bergwerk/path1/galaxy/vor/1454776168794.csv", dataDir + "bergwerk/path2/nexus/vor/1454779863041.csv", dataDir + "bergwerk/path2/galaxy/vor/1454780113404.csv", dataDir + "bergwerk/path3/nexus/vor/1454782562231.csv", dataDir + "bergwerk/path3/galaxy/vor/1454782896548.csv", dataDir + "bergwerk/path4/nexus/vor/1454776525797.csv", dataDir + "bergwerk/path4/galaxy/vor/1454779020844.csv" }, dataDir + "bergwerk/wifiParams.txt", 40, VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, mapDir + "SHL/grid25.dat" }; DataSetup IPIN2015 = { mapDir + "SHL/SHL_IPIN2015_gt.xml", { dataDir + "ipin2015/galaxy/Path0/1433581471902.csv", dataDir + "ipin2015/nexus/Path0/1433606195078.csv", dataDir + "ipin2015/galaxy/Path1/1433587749492.csv", dataDir + "ipin2015/nexus/Path1/1433606670723.csv", dataDir + "ipin2015/galaxy/Path2/1433581471902.csv", dataDir + "ipin2015/nexus/Path2/1433607251262.csv", dataDir + "eiszeit/path2/1479986737368.csv" }, dataDir + "bergwerk/wifiParams.txt", 40, VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, mapDir + "SHL/grid_IPIN2015_gt.dat" }; } data; Floorplan::IndoorMap* MyState::map; void run(DataSetup setup, int numFile, std::string folder) { // load the floorplan Floorplan::IndoorMap* map = Floorplan::Reader::readFromFile(setup.map); MyState::map = map; WiFiModelLogDistCeiling WiFiModel(map); WiFiModel.loadAPs(map, Settings::WiFiModel::TXP, Settings::WiFiModel::EXP, Settings::WiFiModel::WAF); Assert::isFalse(WiFiModel.getAllAPs().empty(), "no AccessPoints stored within the map.xml"); BeaconModelLogDistCeiling beaconModel(map); beaconModel.loadBeaconsFromMap(map, Settings::BeaconModel::TXP, Settings::BeaconModel::EXP, Settings::BeaconModel::WAF); Assert::isFalse(beaconModel.getAllBeacons().empty(), "no Beacons stored within the map.xml"); // build the grid std::ifstream inp(setup.grid, std::ifstream::binary); Grid grid(20); // grid.dat empty? -> build one and save it if (!inp.good() || (inp.peek()&&0) || inp.eof()) { std::ofstream onp; onp.open(setup.grid); GridFactory factory(grid); factory.build(map); grid.write(onp); } else { grid.read(inp); } // add node-importance Importance::addImportance(grid); // stamp WiFi signal-strengths onto the grid WiFiGridEstimator::estimate(grid, WiFiModel, Settings::smartphoneAboveGround); // reading file FileReader fr(setup.training[numFile]); // doing ground truth stuff std::vector path_0 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2, 1, 0}; std::vector path_1 = {29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 13, 14, 15, 16, 17, 18, 19, 2, 1, 0}; std::vector path_2 = {29, 28, 27, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 19, 18, 17, 16, 15, 14, 13, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}; Interpolator gtInterpolator = fr.getGroundTruthPath(map, path_1); Plotti plot; plot.addFloors(map); plot.addOutline(map); plot.addStairs(map); plot.gp << "set autoscale xy\n"; //plot.addGrid(grid); // init ctrl and observation MyControl ctrl; ctrl.resetAfterTransition(); MyObs obs; int numParticles = 10000; PFEval* eval = new PFEval(WiFiModel, beaconModel, grid); //filter init //std::unique_ptr init = //K::ParticleFilterHistory pf(numParticles, std::unique_ptr(new PFInit(grid))); K::ParticleFilterHistory pf(numParticles, std::unique_ptr(new PFInitFixed(grid, GridPoint(1120.0f, 750.0f, 1080.0f), 90.0f))); pf.setTransition(std::unique_ptr(new PFTrans(grid, &ctrl))); pf.setEvaluation(std::unique_ptr(eval)); //resampling pf.setResampling(std::unique_ptr>(new K::ParticleFilterResamplingSimple())); //pf.setResampling(std::unique_ptr>(new K::ParticleFilterResamplingPercent(0.4))); pf.setNEffThreshold(0.95); //estimation //pf.setEstimation(std::unique_ptr>(new K::ParticleFilterEstimationWeightedAverage())); //pf.setEstimation(std::unique_ptr>(new K::ParticleFilterEstimationRegionalWeightedAverage())); pf.setEstimation(std::unique_ptr>(new K::ParticleFilterEstimationOrderedWeightedAverage(0.95))); //pf.setEstimation(std::unique_ptr>(new K::ParticleFilterEstimationKernelDensity())); Timestamp lastTimestamp = Timestamp::fromMS(0); StepDetection sd; TurnDetection td; MotionDetection md; RelativePressure relBaro; relBaro.setCalibrationTimeframe( Timestamp::fromMS(5000) ); K::Statistics errorStats; //file writing for error data long int t = static_cast(time(NULL)); std::ofstream errorFile; errorFile.open (errorDir + folder + "/error_" + std::to_string(numFile) + "_" + std::to_string(t) + ".csv"); // parse each sensor-value within the offline data for (const FileReader::Entry& e : fr.getEntries()) { const Timestamp ts = Timestamp::fromMS(e.ts); if (e.type == FileReader::Sensor::WIFI) { obs.wifi = fr.getWiFiGroupedByTime()[e.idx].data; } else if (e.type == FileReader::Sensor::BEACON){ obs.beacons.entries.push_back(fr.getBeacons()[e.idx].data); // remove to old beacon measurements obs.beacons.removeOld(ts); } else if (e.type == FileReader::Sensor::ACC) { if (sd.add(ts, fr.getAccelerometer()[e.idx].data)) { ++ctrl.numStepsSinceLastTransition; } const FileReader::TS& _acc = fr.getAccelerometer()[e.idx]; td.addAccelerometer(ts, _acc.data); } else if (e.type == FileReader::Sensor::GYRO) { const FileReader::TS& _gyr = fr.getGyroscope()[e.idx]; const float delta_gyro = td.addGyroscope(ts, _gyr.data); ctrl.turnSinceLastTransition_rad += delta_gyro; } else if (e.type == FileReader::Sensor::BARO) { relBaro.add(ts, fr.getBarometer()[e.idx].data); obs.relativePressure = relBaro.getPressureRealtiveToStart(); obs.sigmaPressure = relBaro.getSigma(); } else if (e.type == FileReader::Sensor::LIN_ACC) { md.addLinearAcceleration(ts, fr.getLinearAcceleration()[e.idx].data); } else if (e.type == FileReader::Sensor::GRAVITY) { md.addGravity(ts, fr.getGravity()[e.idx].data); Eigen::Vector2f curVec = md.getCurrentMotionAxis(); ctrl.motionDeltaAngle_rad = md.getMotionChangeInRad(); } if (ts.ms() - lastTimestamp.ms() > 500) { obs.currentTime = ts; MyState est = pf.update(&ctrl, obs); Point3 estPos = est.position.inMeter(); //current ground truth position Point3 gtPos = gtInterpolator.get(static_cast(ts.ms())); plot.pInterest.clear(); // plotting stuff static float angleSum = 0; angleSum += ctrl.turnSinceLastTransition_rad; //plot.showAngle(1, ctrl.turnAngle); plot.showAngle(2, angleSum + M_PI); //plot.debugWiFi(eval->model, obs.wifis, obs.curTS); //plot.debugProb(grid, std::bind(&PFEval::getGPS, eval, std::placeholders::_1, std::placeholders::_2), obs); //plot.debugProb(grid, std::bind(&PFEval::getWIFI, eval, std::placeholders::_1, std::placeholders::_2), obs); //plot.debugProb(grid, std::bind(&PFEval::getALL, eval, std::placeholders::_1, std::placeholders::_2), obs); plot.setEst(estPos); plot.setGT(gtPos); plot.addEstimationNode(estPos); plot.addParticles(pf.getParticles()); //plot.gp << "set arrow 919 from " << tt.pos.x << "," << tt.pos.y << "," << tt.pos.z << " to "<< tt.pos.x << "," << tt.pos.y << "," << tt.pos.z+1 << "lw 3\n"; //plot.gp << "set label 1001 at screen 0.02, 0.98 'base:" << relBaro.getBaseAvg() << " sigma:" << relBaro.getSigma() << " cur:" << relBaro.getPressureRealtiveToStart() << " hPa " << -relBaro.getPressureRealtiveToStart()/0.10/4.0f << " floor'\n"; int minutes = static_cast(ts.sec()) / 60; plot.gp << "set label 1002 at screen 0.02, 0.94 'Time: " << minutes << ":" << static_cast(static_cast(ts.sec())%60) << "'\n"; //plot.gp << "set label 1002 at screen 0.98, 0.98 'act:" << ctrl.barometer.act << "'\n"; // error between GT and estimation float err_m = gtPos.getDistance(estPos); errorStats.add(err_m); errorFile << err_m << "\n"; plot.show(); usleep(33*10); lastTimestamp = ts; // reset control ctrl.resetAfterTransition(); } } errorFile.close(); std::cout << "Statistical Analysis: " << std::endl; std::cout << "Median: " << errorStats.getMedian() << " Average: " << errorStats.getAvg() << std::endl; //Write the current plotti buffer into file std::ofstream plotFile; plotFile.open(errorDir + std::to_string(numFile) + "_" + std::to_string(t) + ".gp"); plot.saveToFile(plotFile); plotFile.close(); // for(int i = 0; i < map->floors.size(); ++i){ // plot.printSingleFloor("/home/toni/Documents/programme/localization/IPIN2016/competition/eval/"+ folder + "/image" + std::to_string(numFile) + "_" + std::to_string(t), i); // plot.show(); // usleep(1000*10); // } // plot.printSideView("/home/toni/Documents/programme/localization/IPIN2016/competition/eval/"+ folder + "/image" + std::to_string(numFile) + "_" + std::to_string(t), 90); // plot.show(); // plot.printSideView("/home/toni/Documents/programme/localization/IPIN2016/competition/eval/"+ folder + "/image" + std::to_string(numFile) + "_" + std::to_string(t), 0); // plot.show(); // plot.printOverview("/home/toni/Documents/programme/localization/IPIN2016/competition/eval/"+ folder + "/image" + std::to_string(numFile) + "_" + std::to_string(t)); // plot.show(); sleep(1); } int main(int argc, char** argv) { //Testing files //run(data.BERKWERK, 6, "EVALBERGWERK"); // Nexus vor run(data.IPIN2015, 3, "EVALIPIN2015"); // Nexus Path2 }