From ed83d90603aa1c27607cd6858ab785b8946f2b1d Mon Sep 17 00:00:00 2001 From: matlabbe Date: Wed, 16 Nov 2016 17:39:17 -0500 Subject: [PATCH] RTAB-Map.exe can be started with parameters as arguments (in similar way than rtabmap-console) --- app/src/main.cpp | 8 +- corelib/include/rtabmap/core/Parameters.h | 2 +- corelib/src/Parameters.cpp | 262 +++++++++++----------- guilib/include/rtabmap/gui/MainWindow.h | 1 + guilib/src/MainWindow.cpp | 65 ++++-- 5 files changed, 197 insertions(+), 141 deletions(-) diff --git a/app/src/main.cpp b/app/src/main.cpp index a8be3c06..eb91c326 100644 --- a/app/src/main.cpp +++ b/app/src/main.cpp @@ -47,6 +47,8 @@ int main(int argc, char* argv[]) /* Create tasks */ QApplication * app = new QApplication(argc, argv); + + ParametersMap parameters = Parameters::parseArguments(argc, argv, true); MainWindow * mainWindow = new MainWindow(); app->installEventFilter(mainWindow); // to catch FileOpen events. @@ -82,7 +84,11 @@ int main(int argc, char* argv[]) if(!database.empty()) { - QMetaObject::invokeMethod(mainWindow, "openDatabase", Qt::QueuedConnection, Q_ARG(QString, QString(database.c_str()))); + mainWindow->openDatabase(database.c_str()); + } + if(parameters.size()) + { + mainWindow->updateParameters(parameters); } // Now wait for application to finish diff --git a/corelib/include/rtabmap/core/Parameters.h b/corelib/include/rtabmap/core/Parameters.h index f1e6a90d..31ea069b 100644 --- a/corelib/include/rtabmap/core/Parameters.h +++ b/corelib/include/rtabmap/core/Parameters.h @@ -531,7 +531,7 @@ public: static void parse(const ParametersMap & parameters, ParametersMap & parametersOut); static const char * showUsage(); - static ParametersMap parseArguments(int argc, char * argv[]); + static ParametersMap parseArguments(int argc, char * argv[], bool onlyParameters = false); static std::string getVersion(); static std::string getDefaultDatabaseName(); diff --git a/corelib/src/Parameters.cpp b/corelib/src/Parameters.cpp index 937ff762..a74581d4 100644 --- a/corelib/src/Parameters.cpp +++ b/corelib/src/Parameters.cpp @@ -507,160 +507,172 @@ const char * Parameters::showUsage() ; } -ParametersMap Parameters::parseArguments(int argc, char * argv[]) +ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParameters) { ParametersMap out; const ParametersMap & parameters = getDefaultParameters(); const std::map > & removedParams = getRemovedParameters(); for(int i=0;ifirst + " = \"" + iter->second + "\""; - std::cout << - str << - std::setw(60 - str.size()) << - " [" << - rtabmap::Parameters::getDescription(iter->first).c_str() << - "]" << - std::endl; - } - UWARN("App will now exit after showing default RTAB-Map parameters because " - "argument \"--params\" is detected!"); - exit(0); - } - else // check for parameters - { - std::string key = uReplaceChar(argv[i], '-', ""); - ParametersMap::const_iterator iter = parameters.find(key); - if(iter != parameters.end()) + else if(strcmp(argv[i], "--logfile") == 0) { ++i; if(i < argc) { - uInsert(out, ParametersPair(iter->first, argv[i])); + ULogger::setType(ULogger::kTypeFile, argv[i], false); + } + else + { + UERROR("\"--logfile\" argument requires following file path"); + } + } + else if(strcmp(argv[i], "--logfilea") == 0) + { + ++i; + if(i < argc) + { + ULogger::setType(ULogger::kTypeFile, argv[i], true); + } + else + { + UERROR("\"--logfilea\" argument requires following file path"); + } + } + else if(strcmp(argv[i], "--udebug") == 0) + { + ULogger::setLevel(ULogger::kDebug); + } + else if(strcmp(argv[i], "--uinfo") == 0) + { + ULogger::setLevel(ULogger::kInfo); + } + else if(strcmp(argv[i], "--uwarn") == 0) + { + ULogger::setLevel(ULogger::kWarning); + } + else if(strcmp(argv[i], "--uerror") == 0) + { + ULogger::setLevel(ULogger::kError); + } + else if(strcmp(argv[i], "--ulogtime") == 0) + { + ++i; + if(i < argc) + { + ULogger::setPrintTime(uStr2Bool(argv[i])); + } + else + { + UERROR("\"--ulogtime\" argument requires a following boolean value"); + } + } + else if(strcmp(argv[i], "--ulogwhere") == 0) + { + ++i; + if(i < argc) + { + ULogger::setPrintWhere(uStr2Bool(argv[i])); + } + else + { + UERROR("\"--ulogwhere\" argument requires a following boolean value"); + } + } + else if(strcmp(argv[i], "--ulogthread") == 0) + { + ++i; + if(i < argc) + { + ULogger::setPrintThreadId(uStr2Bool(argv[i])); + } + else + { + UERROR("\"--ulogthread\" argument requires a following boolean value"); } } else { - // backward compatibility - std::map >::const_iterator jter = removedParams.find(key); - if(jter!=removedParams.end()) + checkParameters = true; + } + } + + if(checkParameters) // check for parameters + { + if(strcmp(argv[i], "--params") == 0) + { + for(rtabmap::ParametersMap::const_iterator iter=parameters.begin(); iter!=parameters.end(); ++iter) { - if(jter->second.first) + std::string str = "Param: " + iter->first + " = \"" + iter->second + "\""; + std::cout << + str << + std::setw(60 - str.size()) << + " [" << + rtabmap::Parameters::getDescription(iter->first).c_str() << + "]" << + std::endl; + } + UWARN("App will now exit after showing default RTAB-Map parameters because " + "argument \"--params\" is detected!"); + exit(0); + } + else + { + std::string key = uReplaceChar(argv[i], '-', ""); + ParametersMap::const_iterator iter = parameters.find(key); + if(iter != parameters.end()) + { + ++i; + if(i < argc) { - ++i; - if(i < argc) + uInsert(out, ParametersPair(iter->first, argv[i])); + } + } + else + { + // backward compatibility + std::map >::const_iterator jter = removedParams.find(key); + if(jter!=removedParams.end()) + { + if(jter->second.first) { - std::string value = argv[i]; - if(!value.empty()) + ++i; + if(i < argc) { - value = uReplaceChar(value, ',', ' '); // for table - key = jter->second.second; - UWARN("Parameter migration from \"%s\" to \"%s\" (value=%s).", - jter->first.c_str(), jter->second.second.c_str(), value.c_str()); - uInsert(out, ParametersPair(key, value)); + std::string value = argv[i]; + if(!value.empty()) + { + value = uReplaceChar(value, ',', ' '); // for table + key = jter->second.second; + UWARN("Parameter migration from \"%s\" to \"%s\" (value=%s).", + jter->first.c_str(), jter->second.second.c_str(), value.c_str()); + uInsert(out, ParametersPair(key, value)); + } } + else + { + UERROR("Value missing for argument \"%s\"", argv[i-1]); + } + } + else if(jter->second.second.empty()) + { + UERROR("Parameter \"%s\" doesn't exist anymore.", jter->first.c_str()); } else { - UERROR("Value missing for argument \"%s\"", argv[i-1]); + UERROR("Parameter \"%s\" doesn't exist anymore, check this similar parameter \"%s\".", jter->first.c_str(), jter->second.second.c_str()); } } - else if(jter->second.second.empty()) - { - UERROR("Parameter \"%s\" doesn't exist anymore.", jter->first.c_str()); - } - else - { - UERROR("Parameter \"%s\" doesn't exist anymore, check this similar parameter \"%s\".", jter->first.c_str(), jter->second.second.c_str()); - } } } } diff --git a/guilib/include/rtabmap/gui/MainWindow.h b/guilib/include/rtabmap/gui/MainWindow.h index 63f6b8a8..0391cddb 100644 --- a/guilib/include/rtabmap/gui/MainWindow.h +++ b/guilib/include/rtabmap/gui/MainWindow.h @@ -110,6 +110,7 @@ public slots: void processStats(const rtabmap::Statistics & stat); void updateCacheFromDatabase(const QString & path); void openDatabase(const QString & path); + void updateParameters(const rtabmap::ParametersMap & parameters); protected: virtual void closeEvent(QCloseEvent* event); diff --git a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp index ed789d33..e3b021b3 100644 --- a/guilib/src/MainWindow.cpp +++ b/guilib/src/MainWindow.cpp @@ -3821,6 +3821,22 @@ void MainWindow::configGUIModified() this->setWindowModified(true); } +void MainWindow::updateParameters(const ParametersMap & parameters) +{ + if(parameters.size()) + { + for(ParametersMap::const_iterator iter= parameters.begin(); iter!=parameters.end(); ++iter) + { + QString msg = tr("Parameter update \"%1\"=\"%2\"") + .arg(iter->first.c_str()) + .arg(iter->second.c_str()); + _ui->widget_console->appendMsg(msg); + UWARN(msg.toStdString().c_str()); + } + _preferencesDialog->updateParameters(parameters); + } +} + //ACTIONS void MainWindow::saveConfigGUI() { @@ -4089,22 +4105,43 @@ void MainWindow::startDetection() return; } } - if(bufferingSize != 0 && - (_preferencesDialog->getSourceDriver() != PreferencesDialog::kSrcDatabase || !_preferencesDialog->isSourceDatabaseStampsUsed())) + if(_preferencesDialog->getSourceDriver() != PreferencesDialog::kSrcDatabase || !_preferencesDialog->isSourceDatabaseStampsUsed()) { - int button = QMessageBox::question(this, - tr("Some images may be skipped!"), - tr("\"RTAB-Map/Images buffer size\" is not infinite (size=%1). As the " - "source input is a directory of images/video/database, some images may be " - "skipped by the detector if the \"Source/Input rate\" (which is %2 Hz) is higher than the " - "rate at which RTAB-Map can process the images. You may want to set the " - "\"RTAB-Map/Images buffer size\" to 0 (infinite) to guaranty that all " - "images are processed. Would you want to start the detection " - "anyway?").arg(bufferingSize).arg(inputRate), - QMessageBox::Yes | QMessageBox::No); - if(button == QMessageBox::No) + if(bufferingSize != 0) { - return; + int button = QMessageBox::question(this, + tr("Some images may be skipped!"), + tr("\"RTAB-Map/Images buffer size\" is not infinite (size=%1). As the " + "source input is a directory of images/video/database, some images may be " + "skipped by the detector if the \"Source/Input rate\" (which is %2 Hz) is higher than the " + "rate at which RTAB-Map can process the images. You may want to set the " + "\"RTAB-Map/Images buffer size\" to 0 (infinite) to guaranty that all " + "images are processed. Would you want to start the detection " + "anyway?").arg(bufferingSize).arg(inputRate), + QMessageBox::Yes | QMessageBox::No); + if(button == QMessageBox::No) + { + return; + } + } + else if(inputRate == 0) + { + int button = QMessageBox::question(this, + tr("Large number of images may be buffered!"), + tr("\"RTAB-Map/Images buffer size\" is infinite. As the " + "source input is a directory of images/video/database and " + "that \"Source/Input rate\" is infinite too, a lot of images " + "could be buffered at the same time (e.g., reading all images " + "of a directory at once). This could make the GUI not responsive. " + "You may want to set \"Source/Input rate\" at the rate at " + "which the images have been recorded. " + "Would you want to start the detection " + "anyway?").arg(bufferingSize).arg(inputRate), + QMessageBox::Yes | QMessageBox::No); + if(button == QMessageBox::No) + { + return; + } } } }