ParametersToolBox.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 //
00029 // Original version from Find-Object: https://github.com/introlab/find-object
00030 //
00031 
00032 #include <rtabmap/core/Parameters.h>
00033 #include <rtabmap/core/Optimizer.h>
00034 
00035 #include "ParametersToolBox.h"
00036 #include <QComboBox>
00037 #include <QDoubleSpinBox>
00038 #include <QLineEdit>
00039 #include <QStackedWidget>
00040 #include <QScrollArea>
00041 #include <QLabel>
00042 #include <QGroupBox>
00043 #include <QCheckBox>
00044 #include <QVBoxLayout>
00045 #include <QMessageBox>
00046 #include <QPushButton>
00047 #include <stdio.h>
00048 #include <rtabmap/utilite/ULogger.h>
00049 #include <rtabmap/utilite/UConversion.h>
00050 #include <opencv2/opencv_modules.hpp>
00051 
00052 namespace rtabmap {
00053 
00054 ParametersToolBox::ParametersToolBox(QWidget *parent) :
00055         QWidget(parent),
00056         comboBox_(new QComboBox(this)),
00057         stackedWidget_(new QStackedWidget(this)),
00058         parameters_(Parameters::getDefaultParameters())
00059 {
00060         QVBoxLayout * layout = new QVBoxLayout(this);
00061         this->setLayout(layout);
00062 
00063         layout->addWidget(comboBox_);
00064         layout->addWidget(stackedWidget_, 1);
00065         QPushButton * resetButton = new QPushButton(this);
00066         resetButton->setText(tr("Restore Defaults"));
00067         layout->addWidget(resetButton);
00068         connect(resetButton, SIGNAL(clicked()), this, SLOT(resetCurrentPage()));
00069 }
00070 
00071 ParametersToolBox::~ParametersToolBox()
00072 {
00073 }
00074 
00075 QWidget * ParametersToolBox::getParameterWidget(const QString & key)
00076 {
00077         return this->findChild<QWidget*>(key);
00078 }
00079 
00080 QStringList ParametersToolBox::resetPage(int index)
00081 {
00082         QStringList paramChanged;
00083         const QObjectList & children = stackedWidget_->widget(index)->children().first()->children().first()->children();
00084         for(int j=0; j<children.size();++j)
00085         {
00086                 QString key = children.at(j)->objectName();
00087                 // ignore working memory
00088                 QString group = key.split("/").first();
00089                 if(!ignoredGroups_.contains(group) && parameters_.find(key.toStdString())!=parameters_.end())
00090                 {
00091                         UASSERT_MSG(parameters_.find(key.toStdString()) != parameters_.end(), uFormat("key=%s", key.toStdString().c_str()).c_str());
00092                         std::string value = Parameters::getDefaultParameters().at(key.toStdString());
00093                         parameters_.at(key.toStdString()) = value;
00094 
00095                         if(qobject_cast<QComboBox*>(children.at(j)))
00096                         {
00097                                 if(((QComboBox*)children.at(j))->currentIndex() != QString::fromStdString(value).split(':').first().toInt())
00098                                 {
00099                                         ((QComboBox*)children.at(j))->setCurrentIndex(QString::fromStdString(value).split(':').first().toInt());
00100                                         paramChanged.append(key);
00101                                 }
00102                         }
00103                         else if(qobject_cast<QSpinBox*>(children.at(j)))
00104                         {
00105                                 if(((QSpinBox*)children.at(j))->value() != uStr2Int(value))
00106                                 {
00107                                         ((QSpinBox*)children.at(j))->setValue(uStr2Int(value));
00108                                         paramChanged.append(key);
00109                                 }
00110                         }
00111                         else if(qobject_cast<QDoubleSpinBox*>(children.at(j)))
00112                         {
00113                                 if(((QDoubleSpinBox*)children.at(j))->value() != uStr2Double(value))
00114                                 {
00115                                         ((QDoubleSpinBox*)children.at(j))->setValue(uStr2Double(value));
00116                                         paramChanged.append(key);
00117                                 }
00118                         }
00119                         else if(qobject_cast<QCheckBox*>(children.at(j)))
00120                         {
00121                                 if(((QCheckBox*)children.at(j))->isChecked() != uStr2Bool(value))
00122                                 {
00123                                         ((QCheckBox*)children.at(j))->setChecked(uStr2Bool(value));
00124                                         paramChanged.append(key);
00125                                 }
00126                         }
00127                         else if(qobject_cast<QLineEdit*>(children.at(j)))
00128                         {
00129                                 if(((QLineEdit*)children.at(j))->text().compare(QString::fromStdString(value)) != 0)
00130                                 {
00131                                         ((QLineEdit*)children.at(j))->setText(QString::fromStdString(value));
00132                                         paramChanged.append(key);
00133                                 }
00134                         }
00135                 }
00136         }
00137         return paramChanged;
00138 }
00139 
00140 void ParametersToolBox::resetCurrentPage()
00141 {
00142         this->blockSignals(true);
00143         QStringList paramChanged = this->resetPage(stackedWidget_->currentIndex());
00144         this->blockSignals(false);
00145         Q_EMIT parametersChanged(paramChanged);
00146 }
00147 
00148 void ParametersToolBox::resetAllPages()
00149 {
00150         QStringList paramChanged;
00151         this->blockSignals(true);
00152         for(int i=0; i< stackedWidget_->count(); ++i)
00153         {
00154                 paramChanged.append(this->resetPage(i));
00155         }
00156         this->blockSignals(false);
00157         Q_EMIT parametersChanged(paramChanged);
00158 }
00159 
00160 void ParametersToolBox::updateParametersVisibility()
00161 {
00162         //show/hide not used parameters
00163         /*QComboBox * descriptorBox = this->findChild<QComboBox*>(Parameters::kFeature2D_2Descriptor());
00164         QComboBox * detectorBox = this->findChild<QComboBox*>(Parameters::kFeature2D_1Detector());
00165         if(descriptorBox && detectorBox)
00166         {
00167                 QString group = Parameters::kFeature2D_2Descriptor().split('/').first();
00168                 QWidget * panel = 0;
00169                 for(int i=0; i<this->count(); ++i)
00170                 {
00171                         if(this->widget(i)->objectName().compare(group) == 0)
00172                         {
00173                                 panel = this->widget(i);
00174                                 break;
00175                         }
00176                 }
00177                 if(panel)
00178                 {
00179                         const QObjectList & objects = panel->children();
00180                         QString descriptorName = descriptorBox->currentText();
00181                         QString detectorName = detectorBox->currentText();
00182 
00183                         for(int i=0; i<objects.size(); ++i)
00184                         {
00185                                 if(!objects[i]->objectName().isEmpty())
00186                                 {
00187                                         if(objects[i]->objectName().contains(descriptorName) || objects[i]->objectName().contains(detectorName))
00188                                         {
00189                                                 ((QWidget*)objects[i])->setVisible(true);
00190                                         }
00191                                         else if(objects[i]->objectName().contains("Fast") && detectorName == QString("ORB"))
00192                                         {
00193                                                 ((QWidget*)objects[i])->setVisible(true);       // ORB uses some FAST parameters
00194                                         }
00195                                         else if(!objects[i]->objectName().split('/').at(1).at(0).isDigit())
00196                                         {
00197                                                 ((QWidget*)objects[i])->setVisible(false);
00198                                         }
00199                                 }
00200                         }
00201                 }
00202         }*/
00203 }
00204 
00205 void ParametersToolBox::setupUi(const QSet<QString> & ignoredGroups)
00206 {
00207         ignoredGroups_ = ignoredGroups;
00208         QWidget * currentItem = 0;
00209         const ParametersMap & parameters = Parameters::getDefaultParameters();
00210         QStringList groups;
00211         for(ParametersMap::const_iterator iter=parameters.begin();
00212                         iter!=parameters.end();
00213                         ++iter)
00214         {
00215                 QStringList splitted = QString::fromStdString(iter->first).split('/');
00216                 QString group = splitted.first();
00217                 if(!ignoredGroups_.contains(group))
00218                 {
00219                         QString name = splitted.last();
00220                         if(currentItem == 0 || currentItem->objectName().compare(group) != 0)
00221                         {
00222                                 groups.push_back(group);
00223                                 QScrollArea * area = new QScrollArea(this);
00224                                 stackedWidget_->addWidget(area);
00225                                 currentItem = new QWidget();
00226                                 currentItem->setObjectName(group);
00227                                 QVBoxLayout * layout = new QVBoxLayout(currentItem);
00228                                 layout->setSizeConstraint(QLayout::SetMinimumSize);
00229                                 layout->setContentsMargins(0,0,0,0);
00230                                 layout->setSpacing(0);
00231                                 area->setWidget(currentItem);
00232 
00233                                 addParameter(layout, iter->first, iter->second);
00234                         }
00235                         else
00236                         {
00237                                 addParameter((QVBoxLayout*)currentItem->layout(), iter->first, iter->second);
00238                         }
00239                 }
00240         }
00241         comboBox_->addItems(groups);
00242         connect(comboBox_, SIGNAL(currentIndexChanged(int)), stackedWidget_, SLOT(setCurrentIndex(int)));
00243 
00244         updateParametersVisibility();
00245 }
00246 
00247 void ParametersToolBox::updateParameter(const std::string & key, const std::string & value)
00248 {
00249         QString group = QString::fromStdString(key).split("/").first();
00250         if(!ignoredGroups_.contains(group))
00251         {
00252                 if(parameters_.find(key) == parameters_.end())
00253                 {
00254                         UWARN("key=\"%s\" doesn't exist", key.c_str());
00255                 }
00256                 else
00257                 {
00258                         parameters_.at(key) = value;
00259                         QWidget * widget = this->findChild<QWidget*>(key.c_str());
00260                         QString type = QString::fromStdString(Parameters::getType(key));
00261                         if(type.compare("string") == 0)
00262                         {
00263                                 QString valueQt = QString::fromStdString(value);
00264                                 if(valueQt.contains(';'))
00265                                 {
00266                                         // It's a list, just change the index
00267                                         QStringList splitted = valueQt.split(':');
00268                                         ((QComboBox*)widget)->setCurrentIndex(splitted.first().toInt());
00269                                 }
00270                                 else
00271                                 {
00272                                         ((QLineEdit*)widget)->setText(valueQt);
00273                                 }
00274                         }
00275                         else if(type.compare("int") == 0)
00276                         {
00277                                 ((QSpinBox*)widget)->setValue(uStr2Int(value));
00278                         }
00279                         else if(type.compare("uint") == 0)
00280                         {
00281                                 ((QSpinBox*)widget)->setValue(uStr2Int(value));
00282                         }
00283                         else if(type.compare("double") == 0)
00284                         {
00285                                 ((QDoubleSpinBox*)widget)->setValue(uStr2Double(value));
00286                         }
00287                         else if(type.compare("float") == 0)
00288                         {
00289                                 ((QDoubleSpinBox*)widget)->setValue(uStr2Float(value));
00290                         }
00291                         else if(type.compare("bool") == 0)
00292                         {
00293                                 ((QCheckBox*)widget)->setChecked(uStr2Bool(value));
00294                         }
00295                 }
00296         }
00297 }
00298 
00299 void ParametersToolBox::addParameter(
00300                 QVBoxLayout * layout,
00301                 const std::string & key,
00302                 const std::string & value)
00303 {
00304         std::string type = Parameters::getType(key);
00305         if(type.compare("string") == 0)
00306         {
00307                 addParameter(layout, key.c_str(), QString::fromStdString(value));
00308         }
00309         else if(type.compare("int") == 0)
00310         {
00311                 addParameter(layout, key.c_str(), uStr2Int(value));
00312         }
00313         else if(type.compare("uint") == 0)
00314         {
00315                 addParameter(layout, key.c_str(), uStr2Int(value));
00316         }
00317         else if(type.compare("double") == 0)
00318         {
00319                 addParameter(layout, key.c_str(), uStr2Double(value));
00320         }
00321         else if(type.compare("float") == 0)
00322         {
00323                 addParameter(layout, key.c_str(), uStr2Double(value));
00324         }
00325         else if(type.compare("bool") == 0)
00326         {
00327                 addParameter(layout, key.c_str(), uStr2Bool(value));
00328         }
00329 }
00330 
00331 void ParametersToolBox::addParameter(QVBoxLayout * layout,
00332                 const QString & key,
00333                 const QString & value)
00334 {
00335         if(value.contains(';'))
00336         {
00337                 QComboBox * widget = new QComboBox(this);
00338                 widget->setObjectName(key);
00339                 QStringList splitted = value.split(':');
00340                 widget->addItems(splitted.last().split(';'));
00341 
00342                 widget->setCurrentIndex(splitted.first().toInt());
00343                 connect(widget, SIGNAL(currentIndexChanged(int)), this, SLOT(changeParameter(int)));
00344                 addParameter(layout, key, widget);
00345         }
00346         else
00347         {
00348                 QLineEdit * widget = new QLineEdit(value, this);
00349                 widget->setObjectName(key);
00350                 connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
00351                 addParameter(layout, key, widget);
00352         }
00353 }
00354 
00355 void ParametersToolBox::addParameter(QVBoxLayout * layout,
00356                 const QString & key,
00357                 const double & value)
00358 {
00359         QDoubleSpinBox * widget = new QDoubleSpinBox(this);
00360         double def = uStr2Double(Parameters::getDefaultParameters().at(key.toStdString()));
00361         if(def<0.01)
00362         {
00363                 widget->setDecimals(4);
00364         }
00365         else if(def<0.1)
00366         {
00367                 widget->setDecimals(3);
00368         }
00369 
00370         if(def>0.0)
00371         {
00372                 widget->setMaximum(def*1000000.0);
00373         }
00374         else if(def==0.0)
00375         {
00376                 widget->setMaximum(1000000.0);
00377         }
00378         else if(def<0.0)
00379         {
00380                 widget->setMinimum(def*1000000.0);
00381                 widget->setMaximum(0.0);
00382         }
00383         widget->setValue(value);
00384         widget->setObjectName(key);
00385         connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
00386         addParameter(layout, key, widget);
00387 }
00388 
00389 void ParametersToolBox::addParameter(QVBoxLayout * layout,
00390                 const QString & key,
00391                 const int & value)
00392 {
00393         QSpinBox * widget = new QSpinBox(this);
00394         int def = uStr2Int(Parameters::getDefaultParameters().at(key.toStdString()));
00395 
00396         if(def>0)
00397         {
00398                 widget->setMaximum(def*1000000);
00399         }
00400         else if(def == 0)
00401         {
00402                 widget->setMaximum(1000000);
00403         }
00404         else if(def<0)
00405         {
00406                 widget->setMinimum(def*1000000);
00407                 widget->setMaximum(0);
00408         }
00409         widget->setValue(value);
00410         widget->setObjectName(key);
00411 
00412         if(key.compare(Parameters::kVisFeatureType().c_str()) == 0)
00413         {
00414 #ifndef RTABMAP_NONFREE
00415                 if(value <= 1)
00416                 {
00417                         UWARN("SURF/SIFT not available, setting feature default to FAST/BRIEF.");
00418                         widget->setValue(4);
00419                 }
00420 #endif
00421         }
00422         if(key.compare(Parameters::kOptimizerStrategy().c_str()) == 0)
00423         {
00424                 if(value == 0 && !Optimizer::isAvailable(Optimizer::kTypeTORO))
00425                 {
00426                         if(Optimizer::isAvailable(Optimizer::kTypeGTSAM))
00427                         {
00428                                 UWARN("TORO is not available, setting optimization default to GTSAM.");
00429                                 widget->setValue(2);
00430                         }
00431                         else if(Optimizer::isAvailable(Optimizer::kTypeG2O))
00432                         {
00433                                 UWARN("TORO is not available, setting optimization default to g2o.");
00434                                 widget->setValue(1);
00435                         }
00436                 }
00437                 if(value == 1 && !Optimizer::isAvailable(Optimizer::kTypeG2O))
00438                 {
00439                         if(Optimizer::isAvailable(Optimizer::kTypeGTSAM))
00440                         {
00441                                 UWARN("g2o is not available, setting optimization default to GTSAM.");
00442                                 widget->setValue(2);
00443                         }
00444                         else if(Optimizer::isAvailable(Optimizer::kTypeTORO))
00445                         {
00446                                 UWARN("g2o is not available, setting optimization default to TORO.");
00447                                 widget->setValue(0);
00448                         }
00449                 }
00450                 if(value == 2 && !Optimizer::isAvailable(Optimizer::kTypeGTSAM))
00451                 {
00452                         if(Optimizer::isAvailable(Optimizer::kTypeG2O))
00453                         {
00454                                 UWARN("GTSAM is not available, setting optimization default to g2o.");
00455                                 widget->setValue(2);
00456                         }
00457                         else if(Optimizer::isAvailable(Optimizer::kTypeTORO))
00458                         {
00459                                 UWARN("GTSAM is not available, setting optimization default to TORO.");
00460                                 widget->setValue(1);
00461                         }
00462                 }
00463                 if(!Optimizer::isAvailable(Optimizer::kTypeG2O) &&
00464                         !Optimizer::isAvailable(Optimizer::kTypeGTSAM) &&
00465                         !Optimizer::isAvailable(Optimizer::kTypeTORO))
00466                 {
00467                         widget->setEnabled(false);
00468                 }
00469         }
00470 
00471         connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
00472         addParameter(layout, key, widget);
00473 }
00474 
00475 void ParametersToolBox::addParameter(QVBoxLayout * layout,
00476                 const QString & key,
00477                 const bool & value)
00478 {
00479         QCheckBox * widget = new QCheckBox(this);
00480         widget->setChecked(value);
00481         widget->setObjectName(key);
00482         connect(widget, SIGNAL(stateChanged(int)), this, SLOT(changeParameter(int)));
00483         addParameter(layout, key, widget);
00484 }
00485 
00486 void ParametersToolBox::addParameter(QVBoxLayout * layout, const QString & key, QWidget * widget)
00487 {
00488         QHBoxLayout * hLayout = new QHBoxLayout();
00489         layout->insertLayout(layout->count()-1, hLayout);
00490         QString tmp = key.split('/').last();
00491         if(tmp.at(0).isDigit())
00492         {
00493                 tmp.remove(0,1);
00494         }
00495         QLabel * label = new QLabel(tmp, this);
00496         label->setObjectName(key+"/label");
00497         label->setToolTip(QString("<FONT>%1</FONT>").arg(Parameters::getDescription(key.toStdString()).c_str()));
00498         label->setTextInteractionFlags(Qt::TextSelectableByMouse);
00499         hLayout->addWidget(label);
00500         hLayout->addWidget(widget);
00501 }
00502 
00503 void ParametersToolBox::changeParameter(const QString & value)
00504 {
00505         if(sender())
00506         {
00507                 parameters_.at(sender()->objectName().toStdString()) = value.toStdString();
00508                 QStringList paramChanged;
00509                 paramChanged.append(sender()->objectName());
00510                 Q_EMIT parametersChanged(paramChanged);
00511         }
00512 }
00513 void ParametersToolBox::changeParameter()
00514 {
00515         if(sender())
00516         {
00517                 QDoubleSpinBox * doubleSpinBox = qobject_cast<QDoubleSpinBox*>(sender());
00518                 QSpinBox * spinBox = qobject_cast<QSpinBox*>(sender());
00519                 QLineEdit * lineEdit = qobject_cast<QLineEdit*>(sender());
00520                 if(doubleSpinBox)
00521                 {
00522                         parameters_.at(sender()->objectName().toStdString()) = uNumber2Str(doubleSpinBox->value());
00523                 }
00524                 else if(spinBox)
00525                 {
00526                         parameters_.at(sender()->objectName().toStdString()) = uNumber2Str(spinBox->value());
00527                 }
00528                 else if(lineEdit)
00529                 {
00530                         parameters_.at(sender()->objectName().toStdString()) =  lineEdit->text().toStdString();
00531                 }
00532                 QStringList paramChanged;
00533                 paramChanged.append(sender()->objectName());
00534                 Q_EMIT parametersChanged(paramChanged);
00535         }
00536 }
00537 
00538 void ParametersToolBox::changeParameter(const int & value)
00539 {
00540         if(sender())
00541         {
00542                 QStringList paramChanged;
00543                 QComboBox * comboBox = qobject_cast<QComboBox*>(sender());
00544                 QCheckBox * checkBox = qobject_cast<QCheckBox*>(sender());
00545                 if(comboBox)
00546                 {
00547                         QStringList items;
00548                         for(int i=0; i<comboBox->count(); ++i)
00549                         {
00550                                 items.append(comboBox->itemText(i));
00551                         }
00552                         QString merged = QString::number(value) + QString(":") + items.join(";");
00553                         parameters_.at(sender()->objectName().toStdString()) = merged.toStdString();
00554 
00555                         this->updateParametersVisibility();
00556                 }
00557                 else if(checkBox)
00558                 {
00559                         parameters_.at(sender()->objectName().toStdString()) = uBool2Str(value==Qt::Checked?true:false);
00560                 }
00561 
00562                 paramChanged.append(sender()->objectName());
00563                 Q_EMIT parametersChanged(paramChanged);
00564         }
00565 }
00566 
00567 } // namespace find_object


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:17