ParametersToolBox.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 //
29 // Original version from Find-Object: https://github.com/introlab/find-object
30 //
31 
33 #include <rtabmap/core/Optimizer.h>
34 
36 #include <QComboBox>
37 #include <QDoubleSpinBox>
38 #include <QLineEdit>
39 #include <QStackedWidget>
40 #include <QScrollArea>
41 #include <QLabel>
42 #include <QGroupBox>
43 #include <QCheckBox>
44 #include <QVBoxLayout>
45 #include <QMessageBox>
46 #include <QPushButton>
47 #include <stdio.h>
50 #include <rtabmap/utilite/UStl.h>
51 #include <opencv2/opencv_modules.hpp>
52 
53 namespace rtabmap {
54 
56  QWidget(parent),
57  comboBox_(new QComboBox(this)),
58  stackedWidget_(new QStackedWidget(this))
59 {
60  QVBoxLayout * layout = new QVBoxLayout(this);
61  this->setLayout(layout);
62 
63  layout->addWidget(comboBox_);
64  layout->addWidget(stackedWidget_, 1);
65  QPushButton * resetButton = new QPushButton(this);
66  resetButton->setText(tr("Restore Defaults"));
67  layout->addWidget(resetButton);
68  connect(resetButton, SIGNAL(clicked()), this, SLOT(resetCurrentPage()));
69 }
70 
72 {
73 }
74 
75 QWidget * ParametersToolBox::getParameterWidget(const QString & key)
76 {
77  return this->findChild<QWidget*>(key);
78 }
79 
80 QStringList ParametersToolBox::resetPage(int index)
81 {
82  QStringList paramChanged;
83  const QObjectList & children = stackedWidget_->widget(index)->children().first()->children().first()->children();
84  for(int j=0; j<children.size();++j)
85  {
86  QString key = children.at(j)->objectName();
87  // ignore working memory
88  QString group = key.split("/").first();
89  if(parameters_.find(key.toStdString())!=parameters_.end())
90  {
91  UASSERT_MSG(parameters_.find(key.toStdString()) != parameters_.end(), uFormat("key=%s", key.toStdString().c_str()).c_str());
92  std::string value = Parameters::getDefaultParameters().at(key.toStdString());
93  parameters_.at(key.toStdString()) = value;
94 
95  if(qobject_cast<QComboBox*>(children.at(j)))
96  {
97  if(((QComboBox*)children.at(j))->currentIndex() != QString::fromStdString(value).split(':').first().toInt())
98  {
99  ((QComboBox*)children.at(j))->setCurrentIndex(QString::fromStdString(value).split(':').first().toInt());
100  paramChanged.append(key);
101  }
102  }
103  else if(qobject_cast<QSpinBox*>(children.at(j)))
104  {
105  if(((QSpinBox*)children.at(j))->value() != uStr2Int(value))
106  {
107  ((QSpinBox*)children.at(j))->setValue(uStr2Int(value));
108  paramChanged.append(key);
109  }
110  }
111  else if(qobject_cast<QDoubleSpinBox*>(children.at(j)))
112  {
113  if(((QDoubleSpinBox*)children.at(j))->value() != uStr2Double(value))
114  {
115  ((QDoubleSpinBox*)children.at(j))->setValue(uStr2Double(value));
116  paramChanged.append(key);
117  }
118  }
119  else if(qobject_cast<QCheckBox*>(children.at(j)))
120  {
121  if(((QCheckBox*)children.at(j))->isChecked() != uStr2Bool(value))
122  {
123  ((QCheckBox*)children.at(j))->setChecked(uStr2Bool(value));
124  paramChanged.append(key);
125  }
126  }
127  else if(qobject_cast<QLineEdit*>(children.at(j)))
128  {
129  if(((QLineEdit*)children.at(j))->text().compare(QString::fromStdString(value)) != 0)
130  {
131  ((QLineEdit*)children.at(j))->setText(QString::fromStdString(value));
132  paramChanged.append(key);
133  }
134  }
135  }
136  }
137  return paramChanged;
138 }
139 
141 {
142  this->blockSignals(true);
143  QStringList paramChanged = this->resetPage(stackedWidget_->currentIndex());
144  this->blockSignals(false);
145  Q_EMIT parametersChanged(paramChanged);
146 }
147 
149 {
150  QStringList paramChanged;
151  this->blockSignals(true);
152  for(int i=0; i< stackedWidget_->count(); ++i)
153  {
154  paramChanged.append(this->resetPage(i));
155  }
156  this->blockSignals(false);
157  Q_EMIT parametersChanged(paramChanged);
158 }
159 
161 {
162  //show/hide not used parameters
163  /*QComboBox * descriptorBox = this->findChild<QComboBox*>(Parameters::kFeature2D_2Descriptor());
164  QComboBox * detectorBox = this->findChild<QComboBox*>(Parameters::kFeature2D_1Detector());
165  if(descriptorBox && detectorBox)
166  {
167  QString group = Parameters::kFeature2D_2Descriptor().split('/').first();
168  QWidget * panel = 0;
169  for(int i=0; i<this->count(); ++i)
170  {
171  if(this->widget(i)->objectName().compare(group) == 0)
172  {
173  panel = this->widget(i);
174  break;
175  }
176  }
177  if(panel)
178  {
179  const QObjectList & objects = panel->children();
180  QString descriptorName = descriptorBox->currentText();
181  QString detectorName = detectorBox->currentText();
182 
183  for(int i=0; i<objects.size(); ++i)
184  {
185  if(!objects[i]->objectName().isEmpty())
186  {
187  if(objects[i]->objectName().contains(descriptorName) || objects[i]->objectName().contains(detectorName))
188  {
189  ((QWidget*)objects[i])->setVisible(true);
190  }
191  else if(objects[i]->objectName().contains("Fast") && detectorName == QString("ORB"))
192  {
193  ((QWidget*)objects[i])->setVisible(true); // ORB uses some FAST parameters
194  }
195  else if(!objects[i]->objectName().split('/').at(1).at(0).isDigit())
196  {
197  ((QWidget*)objects[i])->setVisible(false);
198  }
199  }
200  }
201  }
202  }*/
203 }
204 
206 {
207  parameters_ = parameters;
208  QWidget * currentItem = 0;
209  QStringList groups;
210  for(ParametersMap::const_iterator iter=parameters.begin();
211  iter!=parameters.end();
212  ++iter)
213  {
214  QStringList splitted = QString::fromStdString(iter->first).split('/');
215  QString group = splitted.first();
216 
217  QString name = splitted.last();
218  if(currentItem == 0 || currentItem->objectName().compare(group) != 0)
219  {
220  groups.push_back(group);
221  QScrollArea * area = new QScrollArea(this);
222  stackedWidget_->addWidget(area);
223  currentItem = new QWidget();
224  currentItem->setObjectName(group);
225  QVBoxLayout * layout = new QVBoxLayout(currentItem);
226  layout->setSizeConstraint(QLayout::SetMinimumSize);
227  layout->setContentsMargins(0,0,0,0);
228  layout->setSpacing(0);
229  area->setWidget(currentItem);
230 
231  addParameter(layout, iter->first, iter->second);
232  }
233  else
234  {
235  addParameter((QVBoxLayout*)currentItem->layout(), iter->first, iter->second);
236  }
237  }
238  comboBox_->addItems(groups);
239  connect(comboBox_, SIGNAL(currentIndexChanged(int)), stackedWidget_, SLOT(setCurrentIndex(int)));
240 
242 }
243 
244 void ParametersToolBox::updateParameter(const std::string & key, const std::string & value)
245 {
246  QString group = QString::fromStdString(key).split("/").first();
247  if(parameters_.find(key) != parameters_.end())
248  {
249  parameters_.at(key) = value;
250  QWidget * widget = this->findChild<QWidget*>(key.c_str());
251  QString type = QString::fromStdString(Parameters::getType(key));
252  if(type.compare("string") == 0)
253  {
254  QString valueQt = QString::fromStdString(value);
255  if(valueQt.contains(';'))
256  {
257  // It's a list, just change the index
258  QStringList splitted = valueQt.split(':');
259  ((QComboBox*)widget)->setCurrentIndex(splitted.first().toInt());
260  }
261  else
262  {
263  ((QLineEdit*)widget)->setText(valueQt);
264  }
265  }
266  else if(type.compare("int") == 0)
267  {
268  ((QSpinBox*)widget)->setValue(uStr2Int(value));
269  }
270  else if(type.compare("uint") == 0)
271  {
272  ((QSpinBox*)widget)->setValue(uStr2Int(value));
273  }
274  else if(type.compare("double") == 0)
275  {
276  ((QDoubleSpinBox*)widget)->setValue(uStr2Double(value));
277  }
278  else if(type.compare("float") == 0)
279  {
280  ((QDoubleSpinBox*)widget)->setValue(uStr2Float(value));
281  }
282  else if(type.compare("bool") == 0)
283  {
284  ((QCheckBox*)widget)->setChecked(uStr2Bool(value));
285  }
286  }
287 }
288 
290  QVBoxLayout * layout,
291  const std::string & key,
292  const std::string & value)
293 {
294  std::string type = Parameters::getType(key);
295  if(type.compare("string") == 0)
296  {
297  addParameter(layout, key.c_str(), QString::fromStdString(value));
298  }
299  else if(type.compare("int") == 0)
300  {
301  addParameter(layout, key.c_str(), uStr2Int(value));
302  }
303  else if(type.compare("uint") == 0)
304  {
305  addParameter(layout, key.c_str(), uStr2Int(value));
306  }
307  else if(type.compare("double") == 0)
308  {
309  addParameter(layout, key.c_str(), uStr2Double(value));
310  }
311  else if(type.compare("float") == 0)
312  {
313  addParameter(layout, key.c_str(), uStr2Double(value));
314  }
315  else if(type.compare("bool") == 0)
316  {
317  addParameter(layout, key.c_str(), uStr2Bool(value));
318  }
319 }
320 
321 void ParametersToolBox::addParameter(QVBoxLayout * layout,
322  const QString & key,
323  const QString & value)
324 {
325  if(value.contains(';'))
326  {
327  QComboBox * widget = new QComboBox(this);
328  widget->setObjectName(key);
329  QStringList splitted = value.split(':');
330  widget->addItems(splitted.last().split(';'));
331 
332  widget->setCurrentIndex(splitted.first().toInt());
333  connect(widget, SIGNAL(currentIndexChanged(int)), this, SLOT(changeParameter(int)));
334  addParameter(layout, key, widget);
335  }
336  else
337  {
338  QLineEdit * widget = new QLineEdit(value, this);
339  widget->setObjectName(key);
340  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
341  addParameter(layout, key, widget);
342  }
343 }
344 
345 void ParametersToolBox::addParameter(QVBoxLayout * layout,
346  const QString & key,
347  const double & value)
348 {
349  QDoubleSpinBox * widget = new QDoubleSpinBox(this);
350  int decimals = 0;
351  int decimalValue = 0;
352 
353  QString str = Parameters::getDefaultParameters().at(key.toStdString()).c_str();
354  if(!str.isEmpty())
355  {
356  str.replace(',', '.');
357  QStringList items = str.split('.');
358  if(items.size() == 2)
359  {
360  decimals = items.back().length();
361  decimalValue = items.back().toInt();
362  }
363  }
364 
365  double def = uStr2Double(Parameters::getDefaultParameters().at(key.toStdString()));
366  if(def<0.001 || (decimals >= 4 && decimalValue>0))
367  {
368  widget->setDecimals(5);
369  widget->setSingleStep(0.0001);
370  }
371  else if(def<0.01 || (decimals >= 3 && decimalValue>0))
372  {
373  widget->setDecimals(4);
374  widget->setSingleStep(0.001);
375  }
376  else if(def<0.1 || (decimals >= 2 && decimalValue>0))
377  {
378  widget->setDecimals(3);
379  widget->setSingleStep(0.01);
380  }
381  else if(def<1.0 || (decimals >= 1 && decimalValue>0))
382  {
383  widget->setDecimals(2);
384  widget->setSingleStep(0.1);
385  }
386  else
387  {
388  widget->setDecimals(1);
389  }
390 
391 
392  if(def>0.0)
393  {
394  widget->setMaximum(def*1000000.0);
395  }
396  else if(def==0.0)
397  {
398  widget->setMaximum(1000000.0);
399  }
400  else if(def<0.0)
401  {
402  widget->setMinimum(def*1000000.0);
403  widget->setMaximum(0.0);
404  }
405 
406  // set minimum for selected parameters
407  if(key.compare(Parameters::kGridMinGroundHeight().c_str()) == 0 ||
408  key.compare(Parameters::kGridMaxGroundHeight().c_str()) == 0 ||
409  key.compare(Parameters::kGridMaxObstacleHeight().c_str()) == 0)
410  {
411  widget->setMinimum(-1000000.0);
412  }
413 
414  widget->setValue(value);
415  widget->setObjectName(key);
416  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
417  addParameter(layout, key, widget);
418 }
419 
420 void ParametersToolBox::addParameter(QVBoxLayout * layout,
421  const QString & key,
422  const int & value)
423 {
424  QSpinBox * widget = new QSpinBox(this);
425  int def = uStr2Int(Parameters::getDefaultParameters().at(key.toStdString()));
426 
427  if(def>0)
428  {
429  widget->setMaximum(def*1000000);
430  }
431  else if(def == 0)
432  {
433  widget->setMaximum(1000000);
434  }
435  else if(def<0)
436  {
437  widget->setMinimum(def*1000000);
438  widget->setMaximum(0);
439  }
440  widget->setValue(value);
441  widget->setObjectName(key);
442 
443  if(key.compare(Parameters::kVisFeatureType().c_str()) == 0)
444  {
445 #ifndef RTABMAP_NONFREE
446  if(value <= 1)
447  {
448  UWARN("SURF/SIFT not available, setting feature default to FAST/BRIEF.");
449  widget->setValue(4);
450  }
451 #endif
452  }
453  if(key.compare(Parameters::kOptimizerStrategy().c_str()) == 0)
454  {
455  if(value == 0 && !Optimizer::isAvailable(Optimizer::kTypeTORO))
456  {
458  {
459  UWARN("TORO is not available, setting optimization default to GTSAM.");
460  widget->setValue(2);
461  }
463  {
464  UWARN("TORO is not available, setting optimization default to g2o.");
465  widget->setValue(1);
466  }
467  }
468  if(value == 1 && !Optimizer::isAvailable(Optimizer::kTypeG2O))
469  {
471  {
472  UWARN("g2o is not available, setting optimization default to GTSAM.");
473  widget->setValue(2);
474  }
476  {
477  UWARN("g2o is not available, setting optimization default to TORO.");
478  widget->setValue(0);
479  }
480  }
482  {
484  {
485  UWARN("GTSAM is not available, setting optimization default to g2o.");
486  widget->setValue(2);
487  }
489  {
490  UWARN("GTSAM is not available, setting optimization default to TORO.");
491  widget->setValue(1);
492  }
493  }
497  {
498  widget->setEnabled(false);
499  }
500  }
501 
502  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
503  addParameter(layout, key, widget);
504 }
505 
506 void ParametersToolBox::addParameter(QVBoxLayout * layout,
507  const QString & key,
508  const bool & value)
509 {
510  QCheckBox * widget = new QCheckBox(this);
511  widget->setChecked(value);
512  widget->setObjectName(key);
513  connect(widget, SIGNAL(stateChanged(int)), this, SLOT(changeParameter(int)));
514  addParameter(layout, key, widget);
515 }
516 
517 void ParametersToolBox::addParameter(QVBoxLayout * layout, const QString & key, QWidget * widget)
518 {
519  QHBoxLayout * hLayout = new QHBoxLayout();
520  layout->insertLayout(layout->count()-1, hLayout);
521  QString tmp = key.split('/').last();
522  QLabel * label = new QLabel(tmp, this);
523  label->setObjectName(key+"/label");
524  label->setToolTip(QString("<FONT>%1 [default=%2]</FONT>")
525  .arg(Parameters::getDescription(key.toStdString()).c_str())
526  .arg(uValue(Parameters::getDefaultParameters(), key.toStdString(), std::string("?")).c_str()));
527  label->setTextInteractionFlags(Qt::TextSelectableByMouse);
528  hLayout->addWidget(label);
529  hLayout->addWidget(widget);
530 }
531 
532 void ParametersToolBox::changeParameter(const QString & value)
533 {
534  if(sender())
535  {
536  parameters_.at(sender()->objectName().toStdString()) = value.toStdString();
537  QStringList paramChanged;
538  paramChanged.append(sender()->objectName());
539  Q_EMIT parametersChanged(paramChanged);
540  }
541 }
543 {
544  if(sender())
545  {
546  QDoubleSpinBox * doubleSpinBox = qobject_cast<QDoubleSpinBox*>(sender());
547  QSpinBox * spinBox = qobject_cast<QSpinBox*>(sender());
548  QLineEdit * lineEdit = qobject_cast<QLineEdit*>(sender());
549  if(doubleSpinBox)
550  {
551  parameters_.at(sender()->objectName().toStdString()) = uNumber2Str(doubleSpinBox->value());
552  }
553  else if(spinBox)
554  {
555  parameters_.at(sender()->objectName().toStdString()) = uNumber2Str(spinBox->value());
556  }
557  else if(lineEdit)
558  {
559  parameters_.at(sender()->objectName().toStdString()) = lineEdit->text().toStdString();
560  }
561  QStringList paramChanged;
562  paramChanged.append(sender()->objectName());
563  Q_EMIT parametersChanged(paramChanged);
564  }
565 }
566 
567 void ParametersToolBox::changeParameter(const int & value)
568 {
569  if(sender())
570  {
571  QStringList paramChanged;
572  QComboBox * comboBox = qobject_cast<QComboBox*>(sender());
573  QCheckBox * checkBox = qobject_cast<QCheckBox*>(sender());
574  if(comboBox)
575  {
576  QStringList items;
577  for(int i=0; i<comboBox->count(); ++i)
578  {
579  items.append(comboBox->itemText(i));
580  }
581  QString merged = QString::number(value) + QString(":") + items.join(";");
582  parameters_.at(sender()->objectName().toStdString()) = merged.toStdString();
583 
585  }
586  else if(checkBox)
587  {
588  parameters_.at(sender()->objectName().toStdString()) = uBool2Str(value==Qt::Checked?true:false);
589  }
590 
591  paramChanged.append(sender()->objectName());
592  Q_EMIT parametersChanged(paramChanged);
593  }
594 }
595 
596 } // namespace find_object
int UTILITE_EXP uStr2Int(const std::string &str)
void parametersChanged(const QStringList &name)
void addParameter(QVBoxLayout *layout, const std::string &key, const std::string &value)
static std::string getDescription(const std::string &paramKey)
Definition: Parameters.cpp:461
double UTILITE_EXP uStr2Double(const std::string &str)
bool UTILITE_EXP uStr2Bool(const char *str)
ParametersToolBox(QWidget *parent=0)
float UTILITE_EXP uStr2Float(const std::string &str)
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:43
std::string UTILITE_EXP uBool2Str(bool boolean)
Some conversion functions.
static bool isAvailable(Optimizer::Type type)
Definition: Optimizer.cpp:47
QWidget * getParameterWidget(const QString &key)
Wrappers of STL for convenient functions.
#define UASSERT_MSG(condition, msg_str)
Definition: ULogger.h:67
QStackedWidget * stackedWidget_
QStringList resetPage(int index)
static std::string getType(const std::string &paramKey)
Definition: Parameters.cpp:446
void setupUi(const ParametersMap &parameters)
static const ParametersMap & getDefaultParameters()
Definition: Parameters.h:778
void updateParameter(const std::string &key, const std::string &value)
ULogger class and convenient macros.
#define UWARN(...)
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
Definition: UConversion.cpp:90
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
Definition: UStl.h:240


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:34:59