DbViewer: added new graph optimization options: span to all maps and ignore some links

This commit is contained in:
matlabbe
2015-05-23 13:36:36 -04:00
parent 85af9c4f01
commit 56323eac2a
4 changed files with 347 additions and 120 deletions

View File

@@ -156,6 +156,7 @@ private:
rtabmap::Memory * memory_;
QString pathDatabase_;
std::list<std::map<int, rtabmap::Transform> > graphes_;
std::multimap<int, rtabmap::Link> graphLinks_;
std::map<int, rtabmap::Transform> poses_;
std::multimap<int, rtabmap::Link> links_;
std::multimap<int, rtabmap::Link> linksRefined_;

View File

@@ -195,8 +195,13 @@ DatabaseViewer::DatabaseViewer(QWidget * parent) :
connect(ui_->horizontalSlider_iterations, SIGNAL(sliderMoved(int)), this, SLOT(sliderIterationsValueChanged(int)));
connect(ui_->spinBox_iterations, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->spinBox_optimizationsFrom, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->checkBox_spanAllMaps, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreCovariance, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreGlobalLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreLocalLoopSpace, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreLocalLoopTime, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->comboBox_graphOptimizer, SIGNAL(currentIndexChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_2dslam, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->spinBox_optimizationDepth, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
@@ -217,7 +222,13 @@ DatabaseViewer::DatabaseViewer(QWidget * parent) :
//connect(ui_->graphicsView_B, SIGNAL(configChanged()), this, SLOT(configModified()));
// Graph view
connect(ui_->spinBox_iterations, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_spanAllMaps, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreCovariance, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreGlobalLoop, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreLocalLoopSpace, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreLocalLoopTime, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->comboBox_graphOptimizer, SIGNAL(currentIndexChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_2dslam, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_optimizationDepth, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
@@ -320,8 +331,13 @@ void DatabaseViewer::readSettings()
settings.beginGroup("optimization");
ui_->spinBox_iterations->setValue(settings.value("iterations", ui_->spinBox_iterations->value()).toInt());
ui_->checkBox_spanAllMaps->setChecked(settings.value("spanToAllMaps", ui_->checkBox_spanAllMaps->isChecked()).toBool());
ui_->checkBox_ignoreCovariance->setChecked(settings.value("ignoreCovariance", ui_->checkBox_ignoreCovariance->isChecked()).toBool());
ui_->checkBox_ignorePoseCorrection->setChecked(settings.value("ignorePoseCorrection", ui_->checkBox_ignorePoseCorrection->isChecked()).toBool());
ui_->checkBox_ignoreGlobalLoop->setChecked(settings.value("ignoreGlobalLoop", ui_->checkBox_ignoreGlobalLoop->isChecked()).toBool());
ui_->checkBox_ignoreLocalLoopSpace->setChecked(settings.value("ignoreLocalLoopSpace", ui_->checkBox_ignoreLocalLoopSpace->isChecked()).toBool());
ui_->checkBox_ignoreLocalLoopTime->setChecked(settings.value("ignoreLocalLoopTime", ui_->checkBox_ignoreLocalLoopTime->isChecked()).toBool());
ui_->checkBox_ignoreUserLoop->setChecked(settings.value("ignoreUserLoop", ui_->checkBox_ignoreUserLoop->isChecked()).toBool());
ui_->comboBox_graphOptimizer->setCurrentIndex(settings.value("strategy", ui_->comboBox_graphOptimizer->currentIndex()).toInt());
ui_->checkBox_2dslam->setChecked(settings.value("slam2d", ui_->checkBox_2dslam->isChecked()).toBool());
ui_->spinBox_optimizationDepth->setValue(settings.value("depth", ui_->spinBox_optimizationDepth->value()).toInt());
@@ -395,8 +411,13 @@ void DatabaseViewer::writeSettings()
// save optimization settings
settings.beginGroup("optimization");
settings.setValue("iterations", ui_->spinBox_iterations->value());
settings.setValue("spanToAllMaps", ui_->checkBox_spanAllMaps->isChecked());
settings.setValue("ignoreCovariance", ui_->checkBox_ignoreCovariance->isChecked());
settings.setValue("ignorePoseCorrection", ui_->checkBox_ignorePoseCorrection->isChecked());
settings.setValue("ignoreGlobalLoop", ui_->checkBox_ignoreGlobalLoop->isChecked());
settings.setValue("ignoreLocalLoopSpace", ui_->checkBox_ignoreLocalLoopSpace->isChecked());
settings.setValue("ignoreLocalLoopTime", ui_->checkBox_ignoreLocalLoopTime->isChecked());
settings.setValue("ignoreUserLoop", ui_->checkBox_ignoreUserLoop->isChecked());
settings.setValue("strategy", ui_->comboBox_graphOptimizer->currentIndex());
settings.setValue("slam2d", ui_->checkBox_2dslam->isChecked());
settings.setValue("depth", ui_->spinBox_optimizationDepth->value());
@@ -475,6 +496,7 @@ bool DatabaseViewer::openDatabase(const QString & path)
neighborLinks_.clear();
loopLinks_.clear();
graphes_.clear();
graphLinks_.clear();
poses_.clear();
mapIds_.clear();
links_.clear();
@@ -875,6 +897,7 @@ void DatabaseViewer::updateIds()
ui_->actionGenerate_TORO_graph_graph->setEnabled(false);
graphes_.clear();
graphLinks_.clear();
neighborLinks_.clear();
loopLinks_.clear();
for(std::multimap<int, rtabmap::Link>::iterator iter = links_.begin(); iter!=links_.end(); ++iter)
@@ -996,8 +1019,7 @@ void DatabaseViewer::generateLocalGraph()
void DatabaseViewer::generateTOROGraph()
{
std::multimap<int, Link> links = updateLinksWithModifications(links_);
if(!graphes_.size() || !links.size())
if(!graphes_.size() || !graphLinks_.size())
{
QMessageBox::warning(this, tr("Cannot generate a TORO graph"), tr("No poses or no links..."));
return;
@@ -1010,7 +1032,7 @@ void DatabaseViewer::generateTOROGraph()
QString path = QFileDialog::getSaveFileName(this, tr("Save File"), pathDatabase_+"/constraints" + QString::number(id) + ".graph", tr("TORO file (*.graph)"));
if(!path.isEmpty())
{
graph::TOROOptimizer::saveGraph(path.toStdString(), uValueAt(graphes_, id), links);
graph::TOROOptimizer::saveGraph(path.toStdString(), uValueAt(graphes_, id), graphLinks_);
}
}
}
@@ -2362,8 +2384,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
UINFO("Update local maps list... done");
}
std::map<int, rtabmap::Transform> & graph = uValueAt(graphes_, value);
std::multimap<int, Link> links = updateLinksWithModifications(links_);
ui_->graphViewer->updateGraph(graph, links, mapIds_);
ui_->graphViewer->updateGraph(graph, graphLinks_, mapIds_);
if(graph.size() && localMaps_.size() && ui_->graphViewer->isGridMapVisible())
{
float xMin, yMin;
@@ -2393,7 +2414,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
//compute total length (neighbor links)
float length = 0.0f;
for(std::multimap<int, rtabmap::Link>::const_iterator iter=links.begin(); iter!=links.end(); ++iter)
for(std::multimap<int, rtabmap::Link>::const_iterator iter=graphLinks_.begin(); iter!=graphLinks_.end(); ++iter)
{
std::map<int, rtabmap::Transform>::const_iterator jterA = graph.find(iter->first);
std::map<int, rtabmap::Transform>::const_iterator jterB = graph.find(iter->second.to());
@@ -2415,36 +2436,81 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
}
void DatabaseViewer::updateGraphView()
{
ui_->label_loopClosures->clear();
ui_->label_nodes->clear();
if(poses_.size())
{
if(!uContains(poses_, ui_->spinBox_optimizationsFrom->value()))
int fromId = ui_->spinBox_optimizationsFrom->value();
if(!uContains(poses_, fromId))
{
QMessageBox::warning(this, tr(""), tr("Graph optimization from id (%1) for which node is not linked to graph.\n Minimum=%2, Maximum=%3")
.arg(ui_->spinBox_optimizationsFrom->value())
.arg(fromId)
.arg(poses_.begin()->first)
.arg(poses_.rbegin()->first));
return;
}
graphes_.clear();
graphLinks_.clear();
std::map<int, rtabmap::Transform> poses = poses_;
// filter current map if not spanning to all maps
if(!ui_->checkBox_spanAllMaps->isChecked() && uContains(mapIds_, fromId) && mapIds_.at(fromId) >= 0)
{
int currentMapId = mapIds_.at(fromId);
for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end();)
{
if(!uContains(mapIds_, iter->first) ||
mapIds_.at(iter->first) != currentMapId)
{
iter = poses.erase(iter);
}
else
{
++iter;
}
}
}
graphes_.push_back(poses);
std::map<int, rtabmap::Transform> finalPoses;
graphes_.push_back(poses_);
ui_->actionGenerate_TORO_graph_graph->setEnabled(true);
std::multimap<int, rtabmap::Link> links;
std::multimap<int, rtabmap::Link> links = links_;
// filter current map if not spanning to all maps
if(!ui_->checkBox_spanAllMaps->isChecked() && uContains(mapIds_, fromId) && mapIds_.at(fromId) >= 0)
{
int currentMapId = mapIds_.at(fromId);
for(std::multimap<int, rtabmap::Link>::iterator iter=links.begin(); iter!=links.end();)
{
if(!uContains(mapIds_, iter->second.from()) ||
!uContains(mapIds_, iter->second.to()) ||
mapIds_.at(iter->second.from()) != currentMapId ||
mapIds_.at(iter->second.to()) != currentMapId)
{
iter = links.erase(iter);
}
else
{
++iter;
}
}
}
if(ui_->checkBox_ignorePoseCorrection->isChecked())
{
std::multimap<int, Link> tmp = links_;
std::multimap<int, Link> tmp = links;
for(std::multimap<int, Link>::iterator iter=tmp.begin(); iter!=tmp.end(); ++iter)
{
if(iter->second.type() == Link::kNeighbor)
{
Transform poseFrom = uValue(poses_, iter->second.from(), Transform());
Transform poseTo = uValue(poses_, iter->second.to(), Transform());
Transform poseFrom = uValue(poses, iter->second.from(), Transform());
Transform poseTo = uValue(poses, iter->second.to(), Transform());
if(!poseFrom.isNull() && !poseTo.isNull())
{
iter->second.setTransform(poseFrom.inverse() * poseTo); // recompute raw odom transformation
iter->second.setVariance(1.0f, 1.0f); // reset variance
}
}
}
@@ -2452,8 +2518,56 @@ void DatabaseViewer::updateGraphView()
}
else
{
links = updateLinksWithModifications(links_);
links = updateLinksWithModifications(links);
}
// filter links
int totalGlobal = 0;
int totalLocalTime = 0;
int totalLocalSpace = 0;
int totalUser = 0;
for(std::multimap<int, rtabmap::Link>::iterator iter=links.begin(); iter!=links.end();)
{
if(iter->second.type() == Link::kGlobalClosure)
{
if(ui_->checkBox_ignoreGlobalLoop->isChecked())
{
iter = links.erase(iter);
continue;
}
++totalGlobal;
}
else if(iter->second.type() == Link::kLocalSpaceClosure)
{
if(ui_->checkBox_ignoreLocalLoopSpace->isChecked())
{
iter = links.erase(iter);
continue;
}
++totalLocalSpace;
}
else if(iter->second.type() == Link::kLocalTimeClosure)
{
if(ui_->checkBox_ignoreLocalLoopTime->isChecked())
{
iter = links.erase(iter);
continue;
}
++totalLocalTime;
}
else if(iter->second.type() == Link::kUserClosure)
{
if(ui_->checkBox_ignoreUserLoop->isChecked())
{
iter = links.erase(iter);
continue;
}
++totalUser;
}
++iter;
}
ui_->label_loopClosures->setText(tr("(%1, %2, %3, %4)").arg(totalGlobal).arg(totalLocalSpace).arg(totalLocalTime).arg(totalUser));
graph::Optimizer * optimizer = 0;
if(ui_->comboBox_graphOptimizer->currentIndex() == graph::Optimizer::kTypeG2O)
{
@@ -2463,12 +2577,11 @@ void DatabaseViewer::updateGraphView()
{
optimizer = new graph::TOROOptimizer(ui_->spinBox_iterations->value(), ui_->checkBox_2dslam->isChecked(), ui_->checkBox_ignoreCovariance->isChecked());
}
int fromId = ui_->spinBox_optimizationsFrom->value();
std::map<int, rtabmap::Transform> posesOut;
std::multimap<int, rtabmap::Link> linksOut;
optimizer->getConnectedGraph(
fromId,
poses_,
poses,
links,
posesOut,
linksOut,
@@ -2476,9 +2589,11 @@ void DatabaseViewer::updateGraphView()
QTime time;
time.start();
finalPoses = optimizer->optimize(fromId, posesOut, linksOut, &graphes_);
std::map<int, rtabmap::Transform> finalPoses = optimizer->optimize(fromId, posesOut, linksOut, &graphes_);
ui_->label_timeOptimization->setNum(double(time.elapsed())/1000.0);
graphes_.push_back(finalPoses);
graphLinks_ = linksOut;
ui_->label_nodes->setNum((int)finalPoses.size());
delete optimizer;
}
if(graphes_.size())

View File

@@ -1928,10 +1928,8 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
{
UINFO("Received map!");
UINFO(" signatures = %d", event.getSignatures().size());
UINFO(" map ids = %d", event.getMapIds().size());
UINFO(" poses = %d", event.getPoses().size());
UINFO(" constraints = %d", event.getConstraints().size());
_initProgressDialog->appendText(tr(" poses = %1").arg(event.getPoses().size()));
_initProgressDialog->appendText(tr(" constraints = %1").arg(event.getConstraints().size()));
_initProgressDialog->setMaximumSteps(int(event.getSignatures().size()+event.getPoses().size()+1));
_initProgressDialog->appendText(QString("Inserting data in the cache (%1 signatures downloaded)...").arg(event.getSignatures().size()));

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>1183</width>
<width>1285</width>
<height>804</height>
</rect>
</property>
@@ -50,8 +50,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>162</width>
<height>173</height>
<width>172</width>
<height>184</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
@@ -233,8 +233,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>162</width>
<height>173</height>
<width>172</width>
<height>184</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
@@ -411,8 +411,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>1183</width>
<height>25</height>
<width>1285</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@@ -666,34 +666,17 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5" columnstretch="0,1">
<item row="2" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Total path length (m)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_optimizationsFrom"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_optimizeFrom">
<property name="text">
<string>Optimize from</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_pathLength">
<item row="6" column="0">
<widget class="QLabel" name="label_loopClosures">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_39">
<item row="4" column="0">
<widget class="QLabel" name="label_timeGrid">
<property name="text">
<string>Time optimization (s)</string>
<string/>
</property>
</widget>
</item>
@@ -704,6 +687,37 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_optimizationsFrom"/>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_52">
<property name="text">
<string>Nodes</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_39">
<property name="text">
<string>Time optimization (s)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_41">
<property name="text">
<string>Loop closures (G, LS, LT, U)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Total path length (m)</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_45">
<property name="text">
@@ -711,8 +725,36 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_timeGrid">
<item row="2" column="0">
<widget class="QLabel" name="label_pathLength">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="0,1">
<item>
<widget class="QLabel" name="label_optimizeFrom">
<property name="text">
<string>Graph root</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBox_spanAllMaps">
<property name="text">
<string>Span to all maps</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_nodes">
<property name="text">
<string/>
</property>
@@ -741,15 +783,15 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>4</number>
<number>2</number>
</property>
<widget class="QWidget" name="page">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>314</width>
<height>303</height>
<width>312</width>
<height>314</height>
</rect>
</property>
<attribute name="label">
@@ -968,8 +1010,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>314</height>
<width>351</width>
<height>331</height>
</rect>
</property>
<attribute name="label">
@@ -1236,37 +1278,50 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>246</width>
<height>198</height>
<y>-118</y>
<width>330</width>
<height>304</height>
</rect>
</property>
<attribute name="label">
<string>Graph optimization</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7" columnstretch="0,1">
<item row="0" column="0">
<widget class="QComboBox" name="comboBox_graphOptimizer">
<item>
<property name="text">
<string>TORO</string>
</property>
</item>
<item>
<property name="text">
<string>g2o</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_40">
<layout class="QGridLayout" name="gridLayout_7" columnstretch="0,0,0">
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_2dslam">
<property name="text">
<string>Strategy</string>
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="6" column="2">
<widget class="QLabel" name="label_48">
<property name="text">
<string>Ignore global loop closures</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="checkBox_ignoreUserLoop">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Iterations</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_iterations">
<property name="suffix">
<string/>
@@ -1282,14 +1337,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Iterations</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_optimizationDepth">
<property name="suffix">
<string/>
@@ -1305,15 +1353,15 @@
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_8">
<item row="5" column="2">
<widget class="QLabel" name="label_35">
<property name="text">
<string>Depth (0=inf)</string>
<string>Ignore pose correction</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_ignoreCovariance">
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_ignoreGlobalLoop">
<property name="text">
<string/>
</property>
@@ -1322,14 +1370,7 @@
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Ignore covariance</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_ignorePoseCorrection">
<property name="text">
<string/>
@@ -1339,15 +1380,8 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_35">
<property name="text">
<string>Ignore pose correction</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_2dslam">
<item row="8" column="0">
<widget class="QCheckBox" name="checkBox_ignoreLocalLoopTime">
<property name="text">
<string/>
</property>
@@ -1356,26 +1390,105 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_41">
<item row="0" column="0" colspan="2">
<widget class="QComboBox" name="comboBox_graphOptimizer">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>TORO</string>
</property>
</item>
<item>
<property name="text">
<string>g2o</string>
</property>
</item>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>2d SLAM</string>
<string>Depth (0=inf)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="9" column="2">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Ignore user loop closures</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Ignore local loop closures (space)</string>
</property>
</widget>
</item>
<item row="10" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<width>0</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="checkBox_ignoreLocalLoopSpace">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_49">
<property name="text">
<string>Ignore local loop closures (time)</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_40">
<property name="text">
<string>Strategy</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_ignoreCovariance">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_51">
<property name="text">
<string>2d SLAM</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Ignore covariance</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
@@ -1383,8 +1496,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>243</width>
<height>284</height>
<width>248</width>
<height>319</height>
</rect>
</property>
<attribute name="label">
@@ -1577,8 +1690,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>256</width>
<height>151</height>
<width>201</width>
<height>126</height>
</rect>
</property>
<attribute name="label">