mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
UI: Added option to change map resolution on UI side, save/restore thresholds in figures, fixed basic panel's slam/rgbd mode checkboxes not changing the state of corresponding parameters.
This commit is contained in:
@@ -264,6 +264,11 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent, bool sh
|
||||
setupMainLayout(_preferencesDialog->isVerticalLayoutUsed());
|
||||
|
||||
ParametersMap parameters = _preferencesDialog->getAllParameters();
|
||||
// Override map resolution for UI
|
||||
if(_preferencesDialog->getGridUIResolution()>0)
|
||||
{
|
||||
uInsert(parameters, ParametersPair(Parameters::kGridCellSize(), uNumber2Str(_preferencesDialog->getGridUIResolution())));
|
||||
}
|
||||
_occupancyGrid = new OccupancyGrid(&_cachedLocalMaps, parameters);
|
||||
#ifdef RTABMAP_OCTOMAP
|
||||
_octomap = new OctoMap(&_cachedLocalMaps, parameters);
|
||||
@@ -3002,7 +3007,28 @@ void MainWindow::updateMapCloud(
|
||||
|
||||
jter->sensorData().uncompressDataConst(0, 0, 0, 0, &ground, &obstacles, &empty);
|
||||
|
||||
_cachedLocalMaps.add(iter->first, ground, obstacles, empty, jter->sensorData().gridCellSize(), jter->sensorData().gridViewPoint());
|
||||
double resolution = jter->sensorData().gridCellSize();
|
||||
if(_preferencesDialog->getGridUIResolution() > jter->sensorData().gridCellSize())
|
||||
{
|
||||
resolution = _preferencesDialog->getGridUIResolution();
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr groundCloud = util3d::voxelize(util3d::laserScanToPointCloud(LaserScan::backwardCompatibility(ground)), resolution);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr obstaclesCloud = util3d::voxelize(util3d::laserScanToPointCloud(LaserScan::backwardCompatibility(obstacles)), resolution);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr emptyCloud = util3d::voxelize(util3d::laserScanToPointCloud(LaserScan::backwardCompatibility(empty)), resolution);
|
||||
if(ground.channels() == 2)
|
||||
ground = util3d::laserScan2dFromPointCloud(*groundCloud).data();
|
||||
else
|
||||
ground = util3d::laserScanFromPointCloud(*groundCloud).data();
|
||||
if(obstacles.channels() == 2)
|
||||
obstacles = util3d::laserScan2dFromPointCloud(*obstaclesCloud).data();
|
||||
else
|
||||
obstacles = util3d::laserScanFromPointCloud(*obstaclesCloud).data();
|
||||
if(empty.channels() == 2)
|
||||
empty = util3d::laserScan2dFromPointCloud(*emptyCloud).data();
|
||||
else
|
||||
empty = util3d::laserScanFromPointCloud(*emptyCloud).data();
|
||||
}
|
||||
|
||||
_cachedLocalMaps.add(iter->first, ground, obstacles, empty, resolution, jter->sensorData().gridViewPoint());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5976,6 +6002,12 @@ void MainWindow::startDetection()
|
||||
"progress will not be shown in the GUI."));
|
||||
}
|
||||
|
||||
// Override map resolution for UI
|
||||
if(_preferencesDialog->getGridUIResolution()>0)
|
||||
{
|
||||
uInsert(parameters, ParametersPair(Parameters::kGridCellSize(), uNumber2Str(_preferencesDialog->getGridUIResolution())));
|
||||
}
|
||||
|
||||
_cachedLocalMaps.clear();
|
||||
|
||||
delete _occupancyGrid;
|
||||
@@ -7513,7 +7545,8 @@ void MainWindow::saveFigures()
|
||||
{
|
||||
QList<int> curvesPerFigure;
|
||||
QStringList curveNames;
|
||||
_ui->statsToolBox->getFiguresSetup(curvesPerFigure, curveNames);
|
||||
QStringList curveThresholds;
|
||||
_ui->statsToolBox->getFiguresSetup(curvesPerFigure, curveNames, curveThresholds);
|
||||
|
||||
QStringList curvesPerFigureStr;
|
||||
for(int i=0; i<curvesPerFigure.size(); ++i)
|
||||
@@ -7526,17 +7559,24 @@ void MainWindow::saveFigures()
|
||||
}
|
||||
_preferencesDialog->saveCustomConfig("Figures", "counts", curvesPerFigureStr.join(" "));
|
||||
_preferencesDialog->saveCustomConfig("Figures", "curves", curveNames.join(" "));
|
||||
_preferencesDialog->saveCustomConfig("Figures", "thresholds", curveThresholds.join(" "));
|
||||
}
|
||||
|
||||
void MainWindow::loadFigures()
|
||||
{
|
||||
QString curvesPerFigure = _preferencesDialog->loadCustomConfig("Figures", "counts");
|
||||
QString curveNames = _preferencesDialog->loadCustomConfig("Figures", "curves");
|
||||
QString curveThresholds = _preferencesDialog->loadCustomConfig("Figures", "thresholds");
|
||||
|
||||
if(!curvesPerFigure.isEmpty())
|
||||
{
|
||||
QStringList curvesPerFigureList = curvesPerFigure.split(" ");
|
||||
QStringList curvesNamesList = curveNames.split(" ");
|
||||
QStringList curveThresholdsList = curveThresholds.split(" ");
|
||||
if(curveThresholdsList[0].isEmpty()) {
|
||||
curveThresholdsList.clear();
|
||||
}
|
||||
UASSERT(curveThresholdsList.isEmpty() || curveThresholdsList.size() == curvesNamesList.size());
|
||||
|
||||
int j=0;
|
||||
for(int i=0; i<curvesPerFigureList.size(); ++i)
|
||||
@@ -7553,7 +7593,23 @@ void MainWindow::loadFigures()
|
||||
_ui->statsToolBox->addCurve(curvesNamesList[j++].replace('_', ' '));
|
||||
for(int k=1; k<count && j<curveNames.size(); ++k)
|
||||
{
|
||||
_ui->statsToolBox->addCurve(curvesNamesList[j++].replace('_', ' '), false);
|
||||
if(curveThresholdsList.size())
|
||||
{
|
||||
bool ok = false;
|
||||
double thresholdValue = curveThresholdsList[j].toDouble(&ok);
|
||||
if(ok)
|
||||
{
|
||||
_ui->statsToolBox->addThreshold(curvesNamesList[j++].replace('_', ' '), thresholdValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ui->statsToolBox->addCurve(curvesNamesList[j++].replace('_', ' '), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ui->statsToolBox->addCurve(curvesNamesList[j++].replace('_', ' '), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -626,6 +626,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->doubleSpinBox_subtractFilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_subtractFilteringAngle, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
|
||||
connect(_ui->doubleSpinBox_map_resolution, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->checkBox_map_shown, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_map_opacity, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->checkBox_elevation_shown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
@@ -2005,6 +2006,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
}
|
||||
else if(groupBox->objectName() == _ui->groupBox_gridMap2->objectName())
|
||||
{
|
||||
_ui->doubleSpinBox_map_resolution->setValue(0);
|
||||
_ui->checkBox_map_shown->setChecked(false);
|
||||
_ui->doubleSpinBox_map_opacity->setValue(0.75);
|
||||
_ui->checkBox_elevation_shown->setCheckState(Qt::Unchecked);
|
||||
@@ -2490,6 +2492,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
||||
_ui->doubleSpinBox_subtractFilteringRadius->setValue(settings.value("subtractFilteringRadius", _ui->doubleSpinBox_subtractFilteringRadius->value()).toDouble());
|
||||
_ui->doubleSpinBox_subtractFilteringAngle->setValue(settings.value("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value()).toDouble());
|
||||
|
||||
_ui->doubleSpinBox_map_resolution->setValue(settings.value("gridUIResolution", _ui->doubleSpinBox_map_resolution->value()).toDouble());
|
||||
_ui->checkBox_map_shown->setChecked(settings.value("gridMapShown", _ui->checkBox_map_shown->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_map_opacity->setValue(settings.value("gridMapOpacity", _ui->doubleSpinBox_map_opacity->value()).toDouble());
|
||||
_ui->checkBox_elevation_shown->setCheckState((Qt::CheckState)settings.value("elevationMapShown", _ui->checkBox_elevation_shown->checkState()).toInt());
|
||||
@@ -3033,6 +3036,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
||||
settings.setValue("subtractFilteringRadius", _ui->doubleSpinBox_subtractFilteringRadius->value());
|
||||
settings.setValue("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value());
|
||||
|
||||
settings.setValue("gridUIResolution", _ui->doubleSpinBox_map_resolution->value());
|
||||
settings.setValue("gridMapShown", _ui->checkBox_map_shown->isChecked());
|
||||
settings.setValue("gridMapOpacity", _ui->doubleSpinBox_map_opacity->value());
|
||||
settings.setValue("elevationMapShown", _ui->checkBox_elevation_shown->checkState());
|
||||
@@ -4964,6 +4968,7 @@ void PreferencesDialog::updateBasicParameter()
|
||||
{
|
||||
_ui->general_checkBox_activateRGBD->blockSignals(true);
|
||||
_ui->general_checkBox_activateRGBD->setChecked(_ui->general_checkBox_activateRGBD_2->isChecked());
|
||||
addParameter(_ui->general_checkBox_activateRGBD, _ui->general_checkBox_activateRGBD->isChecked());
|
||||
_ui->general_checkBox_activateRGBD->blockSignals(false);
|
||||
}
|
||||
else if(sender() == _ui->general_checkBox_SLAM_mode)
|
||||
@@ -4976,6 +4981,7 @@ void PreferencesDialog::updateBasicParameter()
|
||||
{
|
||||
_ui->general_checkBox_SLAM_mode->blockSignals(true);
|
||||
_ui->general_checkBox_SLAM_mode->setChecked(_ui->general_checkBox_SLAM_mode_2->isChecked());
|
||||
addParameter(_ui->general_checkBox_SLAM_mode, _ui->general_checkBox_SLAM_mode->isChecked());
|
||||
_ui->general_checkBox_SLAM_mode->blockSignals(false);
|
||||
}
|
||||
else
|
||||
@@ -5899,6 +5905,10 @@ double PreferencesDialog::getSubtractFilteringAngle() const
|
||||
{
|
||||
return _ui->doubleSpinBox_subtractFilteringAngle->value()*M_PI/180.0;
|
||||
}
|
||||
double PreferencesDialog::getGridUIResolution() const
|
||||
{
|
||||
return _ui->doubleSpinBox_map_resolution->value();
|
||||
}
|
||||
bool PreferencesDialog::getGridMapShown() const
|
||||
{
|
||||
return _ui->checkBox_map_shown->isChecked();
|
||||
|
||||
@@ -584,10 +584,11 @@ void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
}
|
||||
|
||||
void StatsToolBox::getFiguresSetup(QList<int> & curvesPerFigure, QStringList & curveNames)
|
||||
void StatsToolBox::getFiguresSetup(QList<int> & curvesPerFigure, QStringList & curveNames, QStringList & curveThresholds)
|
||||
{
|
||||
curvesPerFigure.clear();
|
||||
curveNames.clear();
|
||||
curveThresholds.clear();
|
||||
for(QMap<QString, QWidget*>::iterator i=_figures.begin(); i!=_figures.end(); ++i)
|
||||
{
|
||||
QList<UPlot *> plots = i.value()->findChildren<UPlot *>();
|
||||
@@ -596,6 +597,10 @@ void StatsToolBox::getFiguresSetup(QList<int> & curvesPerFigure, QStringList & c
|
||||
QStringList names = plots[0]->curveNames();
|
||||
curvesPerFigure.append(names.size());
|
||||
curveNames.append(names);
|
||||
for(int j=0; j<names.size(); ++j)
|
||||
{
|
||||
curveThresholds.append(plots[0]->isThreshold(names[j])?QString::number(plots[0]->getThresholdValue(names[j])):"NA");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -628,6 +633,22 @@ void StatsToolBox::addCurve(const QString & name, bool newFigure, bool cacheOn)
|
||||
ULOGGER_ERROR("Not supposed to be here...");
|
||||
}
|
||||
}
|
||||
void StatsToolBox::addThreshold(const QString & name, qreal value)
|
||||
{
|
||||
QString plotName = _plotMenu->actions().last()->text();
|
||||
QWidget * fig = _figures.value(plotName, (QWidget*)0);
|
||||
if(fig)
|
||||
{
|
||||
UPlot * plot = fig->findChild<UPlot *>(plotName);
|
||||
if(plot)
|
||||
plot->addThreshold(name, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("There are no figures, cannot add threshold \"%s\"", name.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StatsToolBox::setWorkingDirectory(const QString & workingDirectory)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>11</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,0">
|
||||
@@ -2414,7 +2414,33 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_20" columnstretch="0,1">
|
||||
<item row="1" column="0">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_map_shown">
|
||||
<property name="text">
|
||||
<string>Show in 3D map view.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_map_shown_2">
|
||||
<property name="text">
|
||||
<string>Resolution. Set 0 to use same value from Local Occupancy Grid panel.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_map_opacity">
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
@@ -2433,27 +2459,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_map_shown">
|
||||
<property name="text">
|
||||
<string>Show in 3D map view.</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_170">
|
||||
<property name="text">
|
||||
<string>Opacity.</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_map_shown">
|
||||
<property name="text">
|
||||
<string/>
|
||||
@@ -2463,17 +2469,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_show_elevation">
|
||||
<property name="text">
|
||||
<string>Show Elevation Map in 3D map view.</string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_elevation_shown">
|
||||
<property name="toolTip">
|
||||
<string>Partially checked: Height color map. Checked: RGB color map.</string>
|
||||
@@ -2489,6 +2485,54 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_show_elevation">
|
||||
<property name="text">
|
||||
<string>Show Elevation Map in 3D map view.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_170">
|
||||
<property name="text">
|
||||
<string>Opacity.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_map_resolution">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -1055,6 +1055,7 @@ UPlotCurveThreshold::UPlotCurveThreshold(const QString & name, qreal thesholdVal
|
||||
UPlotCurve(name, parent),
|
||||
_orientation(orientation)
|
||||
{
|
||||
_threshold = thesholdValue;
|
||||
if(_orientation == Qt::Horizontal)
|
||||
{
|
||||
this->addValue(0, thesholdValue);
|
||||
@@ -1080,6 +1081,7 @@ void UPlotCurveThreshold::setThreshold(qreal threshold)
|
||||
if(_items.size() == 3)
|
||||
{
|
||||
UPlotItem * item = 0;
|
||||
_threshold = threshold;
|
||||
if(_orientation == Qt::Horizontal)
|
||||
{
|
||||
item = (UPlotItem*)_items.at(0);
|
||||
@@ -2193,10 +2195,10 @@ bool UPlot::addCurve(UPlotCurve * curve, bool ownershipTransferred)
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList UPlot::curveNames()
|
||||
QStringList UPlot::curveNames() const
|
||||
{
|
||||
QStringList names;
|
||||
for(QList<UPlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
for(QList<UPlotCurve*>::const_iterator iter = _curves.constBegin(); iter!=_curves.constEnd(); ++iter)
|
||||
{
|
||||
if(*iter)
|
||||
{
|
||||
@@ -2206,9 +2208,38 @@ QStringList UPlot::curveNames()
|
||||
return names;
|
||||
}
|
||||
|
||||
bool UPlot::contains(const QString & curveName)
|
||||
bool UPlot::isThreshold(const QString & curveName) const
|
||||
{
|
||||
for(QList<UPlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
for(QList<UPlotCurve*>::const_iterator iter = _curves.constBegin(); iter!=_curves.constEnd(); ++iter)
|
||||
{
|
||||
if(*iter && (*iter)->name().compare(curveName) == 0)
|
||||
{
|
||||
return qobject_cast<UPlotCurveThreshold*>(*iter) != 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
double UPlot::getThresholdValue(const QString & curveName) const
|
||||
{
|
||||
for(QList<UPlotCurve*>::const_iterator iter = _curves.constBegin(); iter!=_curves.constEnd(); ++iter)
|
||||
{
|
||||
if(*iter && (*iter)->name().compare(curveName) == 0)
|
||||
{
|
||||
UPlotCurveThreshold* curve = qobject_cast<UPlotCurveThreshold*>(*iter);
|
||||
if(curve)
|
||||
{
|
||||
return curve->getThreshold();
|
||||
}
|
||||
}
|
||||
}
|
||||
UERROR("Curve \"%s\" not found as theshold!", curveName.toStdString().c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UPlot::contains(const QString & curveName) const
|
||||
{
|
||||
for(QList<UPlotCurve*>::const_iterator iter = _curves.constBegin(); iter!=_curves.constEnd(); ++iter)
|
||||
{
|
||||
if(*iter && (*iter)->name().compare(curveName) == 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user