#include "Controller.h" #include "ui/map/3D/MapView3D.h" #include "ui/map/2D/MapView2D.h" #include "ui/menu/MainMenu.h" #include "ui/MainWindow.h" #include "ui/dialog/LoadSetupDialog.h" #include "ui/debug/SensorDataWidget.h" #include #include #include #include #include #include #include #include "ui/LoggerUI.h" #include #include #include #include "sensors/dummy/SensorFactoryDummy.h" #include "sensors/android/SensorFactoryAndroid.h" #include "sensors/offline/SensorFactoryOffline.h" #include "tools/calibration/WiFiCalibrationDataModel.h" #include "nav/NavController.h" Controller::Controller() : sl(scaler) { // OpenGL setup // MUST happen before anything gets visible (= gets initialized) QSurfaceFormat format; format.setDepthBufferSize(16); QSurfaceFormat::setDefaultFormat(format); // configure the to-be-used sensor factory //SensorFactory::set(new SensorFactoryDummy()); //SensorFactory::set(new SensorFactoryOffline("/apps/android/workspace/YASMIN_DATA/offline/gyroacctestingfrank/nexus6/kleinerKreis_216steps_6runden_telefongerade.csv")); //SensorFactory::set(new SensorFactoryOffline("/apps/android/workspace/YASMIN_DATA/offline/gyroacctestingfrank/s3mini/kleinerKreis_225steps_6runden_telefongerade.csv")); //SensorFactory::set(new SensorFactoryOffline("/apps/android/workspace/YASMIN_DATA/offline/gyroacctestingfrank/s4/kleinerKreis_220steps_6runden_telefongeneigt.csv")); //SensorFactory::set(new SensorFactoryOffline(Settings::Data::getOfflineDir() + "bergwerk/path3/nexus/vor/1454782562231.csv")); //SensorFactory::set(new SensorFactoryOffline(Settings::Data::getOfflineDir() + "/bergwerk/path4/nexus/rueck/1454776724285_rueck.csv")); SensorFactory::set(new SensorFactoryOffline(Settings::Data::getOfflineDir() + "/bergwerk/path4/nexus/vor/1454776525797.csv")); // SensorFactory::set(new SensorFactoryAndroid()); // SensorFactory::get().getAccelerometer().start(); // SensorFactory::get().getGyroscope().start(); // SensorFactory::get().getBarometer().start(); // SensorFactory::get().getWiFi().start(); // create the main window mainWindow = new MainWindow(); // attach logger LoggerComposite* log = new LoggerComposite(); log->addLogger(new LoggerCOUT()); log->addLogger(new LoggerAndroid()); log->addLogger(new LoggerUI(mainWindow->getInfoWidget())); Log::setLogger(log); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::onLoadButton, this, &Controller::onLoadButton), "connect() failed"); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::onDebugButton, this, &Controller::onDebugButton), "connect() failed"); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::onStartButton, this, &Controller::onStartButton), "connect() failed"); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::onTransparentButton, this, &Controller::onTransparentButton), "connect() failed"); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::onCameraButton, this, &Controller::onCameraButton), "connect() failed"); Assert::isTrue(connect(mainWindow->getMainMenu(), &MainMenu::on3DButton, this, &Controller::on3DButton), "connect() failed"); // order is important! otherwise OpenGL fails! mainWindow->show(); // // start all sensors // SensorFactory::get().getAccelerometer().start(); // SensorFactory::get().getGyroscope().start(); // SensorFactory::get().getBarometer().start(); // SensorFactory::get().getWiFi().start(); } MapView3D* Controller::getMapView3D() const { return mainWindow->getMapView3D(); } MapView2D* Controller::getMapView2D() const { return mainWindow->getMapView2D(); } MainMenu* Controller::getMainMenu() const { return mainWindow->getMainMenu(); } InfoWidget* Controller::getInfoWidget() const { return mainWindow->getInfoWidget(); } #include #include void buildGridOnce(Grid* grid, Floorplan::IndoorMap* map, const std::string& fpFile, const std::string& saveFile) { //FloorplanHelper::align(map, grid->getGridSize_cm()); // ask questions const QMessageBox::StandardButton replyWiFiFP = QMessageBox::question(nullptr, "WiFi", "Use Fingerprints for WiFiCalibration?\n\nYes: Use fingerprints and num-optimize AP-Params\nNo: Use APs from the map.xml (pos+params)", QMessageBox::Yes|QMessageBox::No); // WiFi setup WiFiModelLogDistCeiling wifiModel(map); if (replyWiFiFP == QMessageBox::Yes) { VAPGrouper vg(VAPGrouper::Mode::LAST_MAC_DIGIT_TO_ZERO, VAPGrouper::Aggregation::AVERAGE); WiFiCalibrationDataModel mdl(fpFile); Assert::isFalse(mdl.getFingerprints().empty(), "no fingerprints available!"); WiFiOptimizer opt(map, vg); for (const WiFiFingerprint& fp : mdl.getFingerprints()) { opt.addFingerprint(fp); } const std::vector res = opt.optimizeAll(); WiFiGridEstimator::estimate(*grid, wifiModel, Settings::smartphoneAboveGround); for (const WiFiOptimizer::APParamsMAC& ap : res) { const WiFiModelLogDistCeiling::APEntry entry(ap.params.getPos(), ap.params.txp, ap.params.exp, ap.params.waf); wifiModel.addAP(ap.mac, entry); } } else { // load all APs from the floorplan and use same TXP/EXP/WAF for all of them wifiModel.loadAPs(map, Settings::WiFiModel::TXP, Settings::WiFiModel::EXP, Settings::WiFiModel::WAF); } // build the grid GridFactory gf(*grid); gf.build(map); // add node-importance Importance::addImportance(*grid); // stamp WiFi signal-strengths onto the grid WiFiGridEstimator::estimate(*grid, wifiModel, Settings::smartphoneAboveGround); // serialize the grid std::ofstream out(saveFile, std::ofstream::binary); grid->write(out); out.close(); } void Controller::on3DButton() { static bool use3D = false; use3D = !use3D; getMapView2D()->setVisible(!use3D); getMapView3D()->setVisible( use3D); } void Controller::onLoadButton() { // pick a map to load QDir dir = LoadSetupDialog::pickSetupFolder(); // cancelled? if (dir.path() == ".") { return; } QFile fMap(dir.path() + "/map.xml"); QFile fGrid(dir.path() + "/grid.dat"); QFile fWiFiFP(dir.path() + "/wifi_fp.dat"); Assert::isTrue(fMap.exists(), "map.xml missing"); //Assert::isTrue(fGrid.exists(), "grid.dat missing"); fMap.open(QIODevice::ReadOnly); QString str = QString(fMap.readAll()); im = Floorplan::Reader::readFromString(str.toStdString()); const std::string sGrid = fGrid.fileName().toStdString(); std::ifstream inp(sGrid, std::ifstream::binary); //Assert::isTrue(inp.good(), "failed to open grid.dat"); const std::string sWiFiFP = fWiFiFP.fileName().toStdString(); // create a new, empty grid if (grid) {delete grid; grid = nullptr;} grid = new Grid(Settings::Grid::gridSize_cm); // grid.dat empty? -> build one and save it if (!inp.good() || (inp.peek()&&0) || inp.eof()) { buildGridOnce(grid, im, sWiFiFP, sGrid); } else { grid->read(inp); } // create a new navigator if (nav) {delete nav; nav = nullptr;} nav = new NavController(this, grid, im); WiFiCalibrationDataModel* wifiCalib = new WiFiCalibrationDataModel(sWiFiFP); getMapView3D()->setMap(im); getMapView2D()->setMap(wifiCalib, im); getMapView3D()->showGridImportance(grid); getMapView2D()->showGridImportance(grid); getMapView3D()->setVisible(false); // attach ipin step logger nav->addListener(&sl); } void Controller::onDebugButton() { mainWindow->getSensorDataWidget()->setVisible( !mainWindow->getSensorDataWidget()->isVisible() ); } void Controller::onStartButton() { nav->start(); } void Controller::onTransparentButton() { mainWindow->getMapView3D()->toggleRenderMode(); } void Controller::onCameraButton() { nav->toggleCamera(); }