mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Added optimizeFromGraphEnd (default true) parameter. It can be used to keep the map referential from the oldest node in the current graph
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1441 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -225,7 +225,8 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.0, "Min linear displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.0, "Min linear displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
||||||
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.0, "Min angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.0, "Min angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
||||||
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 1, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 1, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
||||||
RTABMAP_PARAM(RGBD, ToroIterations, int, 100, "TORO graph optimization iterations")
|
RTABMAP_PARAM(RGBD, ToroIterations, int, 100, "TORO graph optimization iterations");
|
||||||
|
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, true, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node).");
|
||||||
|
|
||||||
// Local loop closure detection
|
// Local loop closure detection
|
||||||
RTABMAP_PARAM(RGBD, LocalLoopDetectionTime, bool, true, "Detection over all locations in STM.");
|
RTABMAP_PARAM(RGBD, LocalLoopDetectionTime, bool, true, "Detection over all locations in STM.");
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ private:
|
|||||||
int _localDetectMaxDiffID;
|
int _localDetectMaxDiffID;
|
||||||
int _toroIterations;
|
int _toroIterations;
|
||||||
std::string _databasePath;
|
std::string _databasePath;
|
||||||
|
bool _optimizeFromGraphEnd;
|
||||||
|
|
||||||
int _lcHypothesisId;
|
int _lcHypothesisId;
|
||||||
float _lcHypothesisValue;
|
float _lcHypothesisValue;
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ Rtabmap::Rtabmap() :
|
|||||||
_localDetectMaxDiffID(Parameters::defaultRGBDLocalLoopDetectionMaxDiffID()),
|
_localDetectMaxDiffID(Parameters::defaultRGBDLocalLoopDetectionMaxDiffID()),
|
||||||
_toroIterations(Parameters::defaultRGBDToroIterations()),
|
_toroIterations(Parameters::defaultRGBDToroIterations()),
|
||||||
_databasePath(""),
|
_databasePath(""),
|
||||||
|
_optimizeFromGraphEnd(Parameters::defaultRGBDOptimizeFromGraphEnd()),
|
||||||
_lcHypothesisId(0),
|
_lcHypothesisId(0),
|
||||||
_lcHypothesisValue(0),
|
_lcHypothesisValue(0),
|
||||||
_retrievedId(0),
|
_retrievedId(0),
|
||||||
@@ -339,6 +340,7 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionNeighbors(), _localDetectMaxNeighbors);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionNeighbors(), _localDetectMaxNeighbors);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxDiffID(), _localDetectMaxDiffID);
|
Parameters::parse(parameters, Parameters::kRGBDLocalLoopDetectionMaxDiffID(), _localDetectMaxDiffID);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDToroIterations(), _toroIterations);
|
Parameters::parse(parameters, Parameters::kRGBDToroIterations(), _toroIterations);
|
||||||
|
Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), _optimizeFromGraphEnd);
|
||||||
|
|
||||||
// RGB-D SLAM stuff
|
// RGB-D SLAM stuff
|
||||||
if((iter=parameters.find(Parameters::kLccIcpType())) != parameters.end())
|
if((iter=parameters.find(Parameters::kLccIcpType())) != parameters.end())
|
||||||
@@ -826,13 +828,6 @@ bool Rtabmap::process(const Image & image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset map correction if we are mapping!
|
|
||||||
if(_memory->isIncremental() && !_mapCorrection.isIdentity())
|
|
||||||
{
|
|
||||||
UWARN("Reset map correction because we are now mapping!");
|
|
||||||
_mapCorrection.setIdentity();
|
|
||||||
}
|
|
||||||
|
|
||||||
Transform newPose = _mapCorrection * signature->getPose();
|
Transform newPose = _mapCorrection * signature->getPose();
|
||||||
_optimizedPoses.insert(std::make_pair(signature->id(), newPose));
|
_optimizedPoses.insert(std::make_pair(signature->id(), newPose));
|
||||||
|
|
||||||
@@ -1358,6 +1353,13 @@ bool Rtabmap::process(const Image & image)
|
|||||||
UINFO("Update map correction: SLAM mode");
|
UINFO("Update map correction: SLAM mode");
|
||||||
// SLAM mode!
|
// SLAM mode!
|
||||||
optimizeCurrentMap(signature->id(), false, _optimizedPoses, &_constraints);
|
optimizeCurrentMap(signature->id(), false, _optimizedPoses, &_constraints);
|
||||||
|
|
||||||
|
// Update map correction, it should be identify when optimizing from the last node
|
||||||
|
_mapCorrection = _optimizedPoses.at(signature->id()) * signature->getPose().inverse();
|
||||||
|
if(_mapCorrection.getNormSquared() > 0.001f && _optimizeFromGraphEnd)
|
||||||
|
{
|
||||||
|
UERROR("Map correction should be identity when optimizing from the last node. T=%s", _mapCorrection.prettyPrint().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(_lcHypothesisId > 0 || localSpaceClosureId > 0 || signaturesRetrieved.size())
|
else if(_lcHypothesisId > 0 || localSpaceClosureId > 0 || signaturesRetrieved.size())
|
||||||
{
|
{
|
||||||
@@ -1957,6 +1959,21 @@ void Rtabmap::optimizeCurrentMap(
|
|||||||
|
|
||||||
std::map<int, int> ids = _memory->getNeighborsId(id, 0, lookInDatabase?-1:0, true);
|
std::map<int, int> ids = _memory->getNeighborsId(id, 0, lookInDatabase?-1:0, true);
|
||||||
UDEBUG("ids=%d", (int)ids.size());
|
UDEBUG("ids=%d", (int)ids.size());
|
||||||
|
if(!_optimizeFromGraphEnd && ids.size() > 1)
|
||||||
|
{
|
||||||
|
UTimer timer;
|
||||||
|
UDEBUG("Optimize from the first location (%d) instead of the last (%d) "
|
||||||
|
"in the local graph. Recomputing neighbors depth...");
|
||||||
|
|
||||||
|
int first = ids.begin()->first;
|
||||||
|
ids = _memory->getNeighborsId(first, 0, lookInDatabase?-1:0, true);
|
||||||
|
|
||||||
|
UDEBUG("Optimize from the first location (%d) instead of the last (%d) "
|
||||||
|
"in the local graph. Recomputing neighbors depth... time=%fs",
|
||||||
|
first,
|
||||||
|
id,
|
||||||
|
timer.ticks());
|
||||||
|
}
|
||||||
|
|
||||||
std::map<int, Transform> poses;
|
std::map<int, Transform> poses;
|
||||||
std::multimap<int, Link> edgeConstraints;
|
std::multimap<int, Link> edgeConstraints;
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ public:
|
|||||||
void setCameraTargetFollow(bool enabled = true);
|
void setCameraTargetFollow(bool enabled = true);
|
||||||
void setCameraFree();
|
void setCameraFree();
|
||||||
void setCameraLockZ(bool enabled = true);
|
void setCameraLockZ(bool enabled = true);
|
||||||
|
void setGridShown(bool shown);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void render();
|
void render();
|
||||||
@@ -128,6 +129,8 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void createMenu();
|
void createMenu();
|
||||||
void mouseEventOccurred (const pcl::visualization::MouseEvent &event, void* viewer_void);
|
void mouseEventOccurred (const pcl::visualization::MouseEvent &event, void* viewer_void);
|
||||||
|
void addGrid();
|
||||||
|
void removeGrid();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pcl::visualization::PCLVisualizer * _visualizer;
|
pcl::visualization::PCLVisualizer * _visualizer;
|
||||||
|
|||||||
@@ -557,6 +557,55 @@ void CloudViewer::setCameraLockZ(bool enabled)
|
|||||||
_aLockViewZ->setChecked(enabled);
|
_aLockViewZ->setChecked(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CloudViewer::setGridShown(bool shown)
|
||||||
|
{
|
||||||
|
_aShowGrid->setChecked(shown);
|
||||||
|
if(shown)
|
||||||
|
{
|
||||||
|
this->addGrid();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->removeGrid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloudViewer::addGrid()
|
||||||
|
{
|
||||||
|
if(_gridLines.empty())
|
||||||
|
{
|
||||||
|
float cellSize = 1.0f;
|
||||||
|
int cellCount = 50;
|
||||||
|
double r=0.5;
|
||||||
|
double g=0.5;
|
||||||
|
double b=0.5;
|
||||||
|
int id = 0;
|
||||||
|
float min = -float(cellCount/2) * cellSize;
|
||||||
|
float max = float(cellCount/2) * cellSize;
|
||||||
|
std::string name;
|
||||||
|
for(float i=min; i<=max; i += cellSize)
|
||||||
|
{
|
||||||
|
//over x
|
||||||
|
name = uFormat("line%d", ++id);
|
||||||
|
_visualizer->addLine(pcl::PointXYZ(i, min, 0.0f), pcl::PointXYZ(i, max, 0.0f), r, g, b, name);
|
||||||
|
_gridLines.push_back(name);
|
||||||
|
//over y
|
||||||
|
name = uFormat("line%d", ++id);
|
||||||
|
_visualizer->addLine(pcl::PointXYZ(min, i, 0.0f), pcl::PointXYZ(max, i, 0.0f), r, g, b, name);
|
||||||
|
_gridLines.push_back(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CloudViewer::removeGrid()
|
||||||
|
{
|
||||||
|
for(std::list<std::string>::iterator iter = _gridLines.begin(); iter!=_gridLines.end(); ++iter)
|
||||||
|
{
|
||||||
|
_visualizer->removeShape(*iter);
|
||||||
|
}
|
||||||
|
_gridLines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Eigen::Vector3f rotatePointAroundAxe(
|
Eigen::Vector3f rotatePointAroundAxe(
|
||||||
const Eigen::Vector3f & point,
|
const Eigen::Vector3f & point,
|
||||||
const Eigen::Vector3f & axis,
|
const Eigen::Vector3f & axis,
|
||||||
@@ -742,34 +791,11 @@ void CloudViewer::handleAction(QAction * a)
|
|||||||
{
|
{
|
||||||
if(_aShowGrid->isChecked())
|
if(_aShowGrid->isChecked())
|
||||||
{
|
{
|
||||||
float cellSize = 1.0f;
|
this->addGrid();
|
||||||
int cellCount = 50;
|
|
||||||
double r=0.5;
|
|
||||||
double g=0.5;
|
|
||||||
double b=0.5;
|
|
||||||
int id = 0;
|
|
||||||
float min = -float(cellCount/2) * cellSize;
|
|
||||||
float max = float(cellCount/2) * cellSize;
|
|
||||||
std::string name;
|
|
||||||
for(float i=min; i<=max; i += cellSize)
|
|
||||||
{
|
|
||||||
//over x
|
|
||||||
name = uFormat("line%d", ++id);
|
|
||||||
_visualizer->addLine(pcl::PointXYZ(i, min, 0.0f), pcl::PointXYZ(i, max, 0.0f), r, g, b, name);
|
|
||||||
_gridLines.push_back(name);
|
|
||||||
//over y
|
|
||||||
name = uFormat("line%d", ++id);
|
|
||||||
_visualizer->addLine(pcl::PointXYZ(min, i, 0.0f), pcl::PointXYZ(max, i, 0.0f), r, g, b, name);
|
|
||||||
_gridLines.push_back(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(std::list<std::string>::iterator iter = _gridLines.begin(); iter!=_gridLines.end(); ++iter)
|
this->removeGrid();
|
||||||
{
|
|
||||||
_visualizer->removeShape(*iter);
|
|
||||||
}
|
|
||||||
_gridLines.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->render();
|
this->render();
|
||||||
|
|||||||
@@ -513,7 +513,6 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
|||||||
{
|
{
|
||||||
OdometryEvent * odomEvent = (OdometryEvent*)anEvent;
|
OdometryEvent * odomEvent = (OdometryEvent*)anEvent;
|
||||||
if(_ui->dockWidget_cloudViewer->isVisible() &&
|
if(_ui->dockWidget_cloudViewer->isVisible() &&
|
||||||
_preferencesDialog->isCloudsShown(1) &&
|
|
||||||
_lastOdometryProcessed &&
|
_lastOdometryProcessed &&
|
||||||
!_processingStatistics)
|
!_processingStatistics)
|
||||||
{
|
{
|
||||||
@@ -1279,6 +1278,11 @@ void MainWindow::updateNodeVisibility(int nodeId, bool visible)
|
|||||||
}
|
}
|
||||||
else if(viewerClouds.contains(cloudName))
|
else if(viewerClouds.contains(cloudName))
|
||||||
{
|
{
|
||||||
|
if(visible)
|
||||||
|
{
|
||||||
|
//make sure the transformation was done
|
||||||
|
_ui->widget_cloudViewer->updateCloudPose(cloudName, _currentPosesMap.find(nodeId)->second);
|
||||||
|
}
|
||||||
_ui->widget_cloudViewer->setCloudVisibility(cloudName, visible);
|
_ui->widget_cloudViewer->setCloudVisibility(cloudName, visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1292,6 +1296,11 @@ void MainWindow::updateNodeVisibility(int nodeId, bool visible)
|
|||||||
}
|
}
|
||||||
else if(viewerClouds.contains(scanName))
|
else if(viewerClouds.contains(scanName))
|
||||||
{
|
{
|
||||||
|
if(visible)
|
||||||
|
{
|
||||||
|
//make sure the transformation was done
|
||||||
|
_ui->widget_cloudViewer->updateCloudPose(scanName, _currentPosesMap.find(nodeId)->second);
|
||||||
|
}
|
||||||
_ui->widget_cloudViewer->setCloudVisibility(scanName, visible);
|
_ui->widget_cloudViewer->setCloudVisibility(scanName, visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1481,8 +1490,6 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
|
|||||||
_initProgressDialog->appendText(tr("Inserted %1 local transforms.").arg(_localTransformsMap.size()));
|
_initProgressDialog->appendText(tr("Inserted %1 local transforms.").arg(_localTransformsMap.size()));
|
||||||
_initProgressDialog->incrementStep();
|
_initProgressDialog->incrementStep();
|
||||||
|
|
||||||
_odometryCorrection.setIdentity();
|
|
||||||
|
|
||||||
_initProgressDialog->appendText("Inserting data in the cache... done.");
|
_initProgressDialog->appendText("Inserting data in the cache... done.");
|
||||||
|
|
||||||
if(event.getPoses().size())
|
if(event.getPoses().size())
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->rgdb_newMapOdomChange->setObjectName(Parameters::kRGBDNewMapOdomChangeDistance().c_str());
|
_ui->rgdb_newMapOdomChange->setObjectName(Parameters::kRGBDNewMapOdomChangeDistance().c_str());
|
||||||
_ui->odomScanHistory->setObjectName(Parameters::kRGBDScanMatchingSize().c_str());
|
_ui->odomScanHistory->setObjectName(Parameters::kRGBDScanMatchingSize().c_str());
|
||||||
_ui->globalDetection_toroIterations->setObjectName(Parameters::kRGBDToroIterations().c_str());
|
_ui->globalDetection_toroIterations->setObjectName(Parameters::kRGBDToroIterations().c_str());
|
||||||
|
_ui->globalDetection_optimizeFromGraphEnd->setObjectName(Parameters::kRGBDOptimizeFromGraphEnd().c_str());
|
||||||
|
|
||||||
_ui->groupBox_localDetection_time->setObjectName(Parameters::kRGBDLocalLoopDetectionTime().c_str());
|
_ui->groupBox_localDetection_time->setObjectName(Parameters::kRGBDLocalLoopDetectionTime().c_str());
|
||||||
_ui->groupBox_localDetection_space->setObjectName(Parameters::kRGBDLocalLoopDetectionSpace().c_str());
|
_ui->groupBox_localDetection_space->setObjectName(Parameters::kRGBDLocalLoopDetectionSpace().c_str());
|
||||||
@@ -1934,7 +1935,7 @@ void PreferencesDialog::addParameter(const QObject * object, bool value)
|
|||||||
{
|
{
|
||||||
// add all RGBD parameters!
|
// add all RGBD parameters!
|
||||||
this->addParameters(_ui->groupBox_slam_update);
|
this->addParameters(_ui->groupBox_slam_update);
|
||||||
this->addParameters(_ui->groupBox_odom_correction);
|
this->addParameters(_ui->groupBox_graphOptimization);
|
||||||
this->addParameters(_ui->groupBox_localDetection_time);
|
this->addParameters(_ui->groupBox_localDetection_time);
|
||||||
this->addParameters(_ui->groupBox_localDetection_space);
|
this->addParameters(_ui->groupBox_localDetection_space);
|
||||||
this->addParameters(_ui->groupBox_globalConstraints);
|
this->addParameters(_ui->groupBox_globalConstraints);
|
||||||
@@ -2822,6 +2823,9 @@ void PreferencesDialog::testOdometry(int type)
|
|||||||
|
|
||||||
OdometryViewer * odomViewer = new OdometryViewer(10, 2, 0.0, this->getOdomQualityWarnThr(), window);
|
OdometryViewer * odomViewer = new OdometryViewer(10, 2, 0.0, this->getOdomQualityWarnThr(), window);
|
||||||
|
|
||||||
|
odomViewer->setCameraFree();
|
||||||
|
odomViewer->setGridShown(true);
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout();
|
QVBoxLayout *layout = new QVBoxLayout();
|
||||||
layout->addWidget(odomViewer);
|
layout->addWidget(odomViewer);
|
||||||
window->setLayout(layout);
|
window->setLayout(layout);
|
||||||
@@ -2835,6 +2839,8 @@ void PreferencesDialog::testOdometry(int type)
|
|||||||
|
|
||||||
window->showNormal();
|
window->showNormal();
|
||||||
|
|
||||||
|
_ui->pushButton_testOdometry->setEnabled(false);
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
uSleep(500);
|
uSleep(500);
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
@@ -2859,6 +2865,7 @@ void PreferencesDialog::cleanOdometryTest()
|
|||||||
delete _odomThread;
|
delete _odomThread;
|
||||||
_odomThread = 0;
|
_odomThread = 0;
|
||||||
}
|
}
|
||||||
|
_ui->pushButton_testOdometry->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>876</width>
|
<width>1007</width>
|
||||||
<height>526</height>
|
<height>628</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -63,9 +63,9 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-210</y>
|
||||||
<width>577</width>
|
<width>709</width>
|
||||||
<height>632</height>
|
<height>1089</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>17</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29">
|
<layout class="QVBoxLayout" name="verticalLayout_29">
|
||||||
@@ -4311,7 +4311,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_83">
|
<widget class="QLabel" name="label_83">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Rigid transformations between nodes are saved on the neighbor links of the RTAB-Map's graph. On loop closures, a new constraint is added to the graph and TORO optimizes the graph. RGB-D images must be sent to work (see Source->Openni).</string>
|
<string>Rigid transformations between nodes are saved on the neighbor links of the RTAB-Map's graph. On loop closures, a new constraint is added to the graph and TORO optimizes the graph. RGB-D images must be sent to work (see Source->RGB-D Camera).</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -4321,7 +4321,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_slam_update">
|
<widget class="QGroupBox" name="groupBox_slam_update">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Update</string>
|
<string>Map update</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout_20">
|
<layout class="QFormLayout" name="formLayout_20">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
@@ -4402,6 +4402,19 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_scanMatching">
|
||||||
|
<property name="text">
|
||||||
|
<string>Laser scan matching history size for odometry correction. Set to 0 to disable odometry correction. ICP 2D only is used here.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QSpinBox" name="odomScanHistory"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -4461,6 +4474,9 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout_5">
|
<layout class="QFormLayout" name="formLayout_5">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QComboBox" name="globalDetection_icpType">
|
<widget class="QComboBox" name="globalDetection_icpType">
|
||||||
<property name="sizeAdjustPolicy">
|
<property name="sizeAdjustPolicy">
|
||||||
@@ -4490,36 +4506,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_31">
|
|
||||||
<property name="text">
|
|
||||||
<string>TORO graph optimization iterations</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QSpinBox" name="globalDetection_toroIterations">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>10000</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="label_51">
|
|
||||||
<property name="text">
|
|
||||||
<string>Maximum ICP correction distance accepted. A large translation difference between the visual transformation and ICP transformation results in wrong transformations in most cases.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="globalDetection_icpMaxDistance">
|
<widget class="QDoubleSpinBox" name="globalDetection_icpMaxDistance">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
@@ -4539,33 +4525,64 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_51">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum ICP correction distance accepted. A large translation difference between the visual transformation and ICP transformation results in wrong transformations in most cases.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_odom_correction">
|
<widget class="QGroupBox" name="groupBox_graphOptimization">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Odometry correction (laser scans are required)</string>
|
<string>Graph optimization</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout_21">
|
<layout class="QFormLayout" name="formLayout_19">
|
||||||
<property name="fieldGrowthPolicy">
|
|
||||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QSpinBox" name="odomScanHistory"/>
|
<widget class="QSpinBox" name="globalDetection_toroIterations">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_scanMatching">
|
<widget class="QLabel" name="label_31">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Laser scan matching history size for odometry correction. Set to 0 to disable odometry correction. ICP 2D only is used here.</string>
|
<string>TORO graph optimization iterations</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_151">
|
||||||
|
<property name="text">
|
||||||
|
<string>Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node).</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="globalDetection_optimizeFromGraphEnd">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -5218,7 +5235,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_111">
|
<widget class="QLabel" name="label_111">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Local history size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words.</string>
|
<string>Local history size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words. This will decrease odometry drifting when the camera is not moving.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -5333,7 +5350,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="7" column="1">
|
<item row="7" column="1">
|
||||||
<widget class="QLabel" name="label_149">
|
<widget class="QLabel" name="label_149">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Maximum distance for visual word correspondences. </string>
|
<string>Maximum distance for visual word correspondences. Lower the value, higher the precision but higher the chance of RED screens (odometry lost).</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -5443,7 +5460,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="11" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QLabel" name="label_104">
|
<widget class="QLabel" name="label_104">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Max feature depth. For ICP, it is the max cloud depth.</string>
|
<string>Max feature depth.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ void showUsage()
|
|||||||
" -au # Angular update (default 0.0 radian)\n"
|
" -au # Angular update (default 0.0 radian)\n"
|
||||||
" -reset # Reset countdown (default 0 = disabled)\n"
|
" -reset # Reset countdown (default 0 = disabled)\n"
|
||||||
" -gpu Use GPU\n"
|
" -gpu Use GPU\n"
|
||||||
" -lh # Local history (default 1)\n"
|
" -lh # Local history (default 0)\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -brief_bytes # BRIEF bytes (default 32)\n"
|
" -brief_bytes # BRIEF bytes (default 32)\n"
|
||||||
" -fast_thr # FAST threshold (default 30)\n"
|
" -fast_thr # FAST threshold (default 30)\n"
|
||||||
@@ -52,6 +52,7 @@ void showUsage()
|
|||||||
" odometryViewer -odom 0 -lh 5000 SURF example\n"
|
" odometryViewer -odom 0 -lh 5000 SURF example\n"
|
||||||
" odometryViewer -odom 1 -lh 10000 SIFT example\n"
|
" odometryViewer -odom 1 -lh 10000 SIFT example\n"
|
||||||
" odometryViewer -odom 4 -nn 2 -lh 1000 FAST/BRIEF example\n"
|
" odometryViewer -odom 4 -nn 2 -lh 1000 FAST/BRIEF example\n"
|
||||||
|
" odometryViewer -odom 3 -nn 2 -lh 1000 FAST/FREAK example\n"
|
||||||
" odometryViewer -icp -in 0.05 -i 30 ICP example\n");
|
" odometryViewer -icp -in 0.05 -i 30 ICP example\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -649,6 +650,9 @@ int main (int argc, char * argv[])
|
|||||||
UEventsManager::addHandler(&odomThread);
|
UEventsManager::addHandler(&odomThread);
|
||||||
UEventsManager::addHandler(&odomViewer);
|
UEventsManager::addHandler(&odomViewer);
|
||||||
|
|
||||||
|
odomViewer.setCameraFree();
|
||||||
|
odomViewer.setGridShown(true);
|
||||||
|
|
||||||
odomViewer.setWindowTitle("Odometry viewer");
|
odomViewer.setWindowTitle("Odometry viewer");
|
||||||
odomViewer.setMinimumWidth(800);
|
odomViewer.setMinimumWidth(800);
|
||||||
odomViewer.setMinimumHeight(500);
|
odomViewer.setMinimumHeight(500);
|
||||||
|
|||||||
Reference in New Issue
Block a user