30 #include "ui_mainWindow.h" 73 #include <QtGui/QCloseEvent> 74 #include <QtGui/QPixmap> 75 #include <QtCore/QDir> 76 #include <QtCore/QFile> 77 #include <QtCore/QTextStream> 78 #include <QtCore/QFileInfo> 79 #include <QMessageBox> 80 #include <QFileDialog> 81 #include <QGraphicsEllipseItem> 82 #include <QDockWidget> 83 #include <QtCore/QBuffer> 84 #include <QtCore/QTimer> 85 #include <QtCore/QTime> 86 #include <QActionGroup> 87 #include <QtGui/QDesktopServices> 88 #include <QtCore/QStringList> 89 #include <QtCore/QProcess> 90 #include <QSplashScreen> 91 #include <QInputDialog> 92 #include <QToolButton> 109 #include <pcl/visualization/cloud_viewer.h> 110 #include <pcl/common/transforms.h> 111 #include <pcl/common/common.h> 112 #include <pcl/io/pcd_io.h> 113 #include <pcl/io/ply_io.h> 114 #include <pcl/filters/filter.h> 115 #include <pcl/search/kdtree.h> 117 #ifdef RTABMAP_OCTOMAP 121 #ifdef HAVE_OPENCV_ARUCO 122 #include <opencv2/aruco.hpp> 125 #define LOG_FILE_NAME "LogRtabmap.txt" 126 #define SHARE_SHOW_LOG_FILE "share/rtabmap/showlogs.m" 127 #define SHARE_GET_PRECISION_RECALL_FILE "share/rtabmap/getPrecisionRecall.m" 128 #define SHARE_IMPORT_FILE "share/rtabmap/importfile.m" 144 _preferencesDialog(0),
146 _exportCloudsDialog(0),
147 _exportBundlerDialog(0),
151 _processingStatistics(
false),
152 _processingDownloadedMap(
false),
154 _odometryReceived(
false),
155 _newDatabasePath(
""),
156 _newDatabasePathOutput(
""),
157 _openedDatabasePath(
""),
158 _databaseUpdated(
false),
159 _odomImageShow(
true),
160 _odomImageDepthShow(
false),
161 _savedMaximized(
false),
163 _cachedMemoryUsage(0),
164 _createdCloudsMemoryUsage(0),
167 _odometryCorrection(
Transform::getIdentity()),
168 _processingOdometry(
false),
173 _rawLikelihoodCurve(0),
174 _exportPosesFrame(0),
175 _autoScreenCaptureOdomSync(
false),
176 _autoScreenCaptureRAM(
false),
177 _autoScreenCapturePNG(
false),
179 _progressCanceled(
false)
186 QSplashScreen * splash = 0;
187 if (showSplashScreen)
189 QPixmap pixmap(
":images/RTAB-Map.png");
190 splash =
new QSplashScreen(pixmap);
192 splash->showMessage(tr(
"Loading..."));
193 QApplication::processEvents();
208 _ui =
new Ui_mainWindow();
224 UDEBUG(
"Setup ui... end");
226 QString title(
"RTAB-Map[*]");
227 this->setWindowTitle(title);
228 this->setWindowIconText(tr(
"RTAB-Map"));
229 this->setObjectName(
"MainWindow");
234 _ui->widget_mainWindow->setVisible(
false);
250 bool statusBarShown =
false;
262 #ifdef RTABMAP_OCTOMAP 270 _ui->label_elapsedTime->setText(
"00:00:00");
276 _ui->imageView_source->setBackgroundColor(
_ui->imageView_source->getDefaultBackgroundColor());
277 _ui->imageView_loopClosure->setBackgroundColor(
_ui->imageView_loopClosure->getDefaultBackgroundColor());
278 _ui->imageView_odometry->setBackgroundColor(
_ui->imageView_odometry->getDefaultBackgroundColor());
279 _ui->imageView_odometry->setAlpha(200);
287 _ui->posteriorPlot->showLegend(
false);
288 _ui->posteriorPlot->setFixedYAxis(0,1);
295 _ui->likelihoodPlot->showLegend(
false);
299 _ui->rawLikelihoodPlot->showLegend(
false);
305 connect(
_ui->widget_mapVisibility, SIGNAL(visibilityChanged(
int,
bool)),
this, SLOT(
updateNodeVisibility(
int,
bool)));
308 connect(
_ui->actionExit, SIGNAL(triggered()),
this, SLOT(close()));
309 qRegisterMetaType<MainWindow::State>(
"MainWindow::State");
312 qRegisterMetaType<rtabmap::RtabmapEvent3DMap>(
"rtabmap::RtabmapEvent3DMap");
314 qRegisterMetaType<rtabmap::RtabmapGlobalPathEvent>(
"rtabmap::RtabmapGlobalPathEvent");
320 _ui->menuShow_view->addAction(
_ui->dockWidget_imageView->toggleViewAction());
321 _ui->menuShow_view->addAction(
_ui->dockWidget_posterior->toggleViewAction());
322 _ui->menuShow_view->addAction(
_ui->dockWidget_likelihood->toggleViewAction());
323 _ui->menuShow_view->addAction(
_ui->dockWidget_rawlikelihood->toggleViewAction());
324 _ui->menuShow_view->addAction(
_ui->dockWidget_statsV2->toggleViewAction());
325 _ui->menuShow_view->addAction(
_ui->dockWidget_console->toggleViewAction());
326 _ui->menuShow_view->addAction(
_ui->dockWidget_cloudViewer->toggleViewAction());
327 _ui->menuShow_view->addAction(
_ui->dockWidget_loopClosureViewer->toggleViewAction());
328 _ui->menuShow_view->addAction(
_ui->dockWidget_mapVisibility->toggleViewAction());
329 _ui->menuShow_view->addAction(
_ui->dockWidget_graphViewer->toggleViewAction());
330 _ui->menuShow_view->addAction(
_ui->dockWidget_odometry->toggleViewAction());
331 _ui->menuShow_view->addAction(
_ui->toolBar->toggleViewAction());
332 _ui->toolBar->setWindowTitle(tr(
"File toolbar"));
333 _ui->menuShow_view->addAction(
_ui->toolBar_2->toggleViewAction());
334 _ui->toolBar_2->setWindowTitle(tr(
"Control toolbar"));
335 QAction * a =
_ui->menuShow_view->addAction(
"Progress dialog");
336 a->setCheckable(
false);
338 QAction * statusBarAction =
_ui->menuShow_view->addAction(
"Status bar");
339 statusBarAction->setCheckable(
true);
340 statusBarAction->setChecked(statusBarShown);
341 connect(statusBarAction, SIGNAL(toggled(
bool)), this->statusBar(), SLOT(setVisible(
bool)));
344 connect(
_ui->actionSave_GUI_config, SIGNAL(triggered()),
this, SLOT(
saveConfigGUI()));
345 connect(
_ui->actionNew_database, SIGNAL(triggered()),
this, SLOT(
newDatabase()));
346 connect(
_ui->actionOpen_database, SIGNAL(triggered()),
this, SLOT(
openDatabase()));
347 connect(
_ui->actionClose_database, SIGNAL(triggered()),
this, SLOT(
closeDatabase()));
348 connect(
_ui->actionEdit_database, SIGNAL(triggered()),
this, SLOT(
editDatabase()));
352 connect(
_ui->actionDump_the_memory, SIGNAL(triggered()),
this, SLOT(
dumpTheMemory()));
353 connect(
_ui->actionDump_the_prediction_matrix, SIGNAL(triggered()),
this, SLOT(
dumpThePrediction()));
354 connect(
_ui->actionSend_goal, SIGNAL(triggered()),
this, SLOT(
sendGoal()));
355 connect(
_ui->actionSend_waypoints, SIGNAL(triggered()),
this, SLOT(
sendWaypoints()));
356 connect(
_ui->actionCancel_goal, SIGNAL(triggered()),
this, SLOT(
cancelGoal()));
357 connect(
_ui->actionLabel_current_location, SIGNAL(triggered()),
this, SLOT(
label()));
358 connect(
_ui->actionClear_cache, SIGNAL(triggered()),
this, SLOT(
clearTheCache()));
359 connect(
_ui->actionAbout, SIGNAL(triggered()),
_aboutDialog , SLOT(exec()));
360 connect(
_ui->actionHelp, SIGNAL(triggered()),
this , SLOT(
openHelp()));
361 connect(
_ui->actionPrint_loop_closure_IDs_to_console, SIGNAL(triggered()),
this, SLOT(
printLoopClosureIds()));
363 connect(
_ui->actionRaw_format_txt, SIGNAL(triggered()),
this , SLOT(
exportPosesRaw()));
366 connect(
_ui->actionKITTI_format_txt, SIGNAL(triggered()),
this , SLOT(
exportPosesKITTI()));
369 connect(
_ui->actionDelete_memory, SIGNAL(triggered()),
this , SLOT(
deleteMemory()));
375 connect(
_ui->actionDefault_views, SIGNAL(triggered(
bool)),
this, SLOT(
setDefaultViews()));
377 connect(
_ui->actionScreenshot, SIGNAL(triggered()),
this, SLOT(
takeScreenshot()));
387 connect(
_ui->actionSave_point_cloud, SIGNAL(triggered()),
this, SLOT(
exportClouds()));
388 connect(
_ui->actionExport_2D_Grid_map_bmp_png, SIGNAL(triggered()),
this, SLOT(
exportGridMap()));
389 connect(
_ui->actionExport_images_RGB_jpg_Depth_png, SIGNAL(triggered()),
this , SLOT(
exportImages()));
390 connect(
_ui->actionExport_cameras_in_Bundle_format_out, SIGNAL(triggered()), SLOT(
exportBundlerFormat()));
391 connect(
_ui->actionExport_octomap, SIGNAL(triggered()),
this, SLOT(
exportOctomap()));
392 connect(
_ui->actionView_high_res_point_cloud, SIGNAL(triggered()),
this, SLOT(
viewClouds()));
393 connect(
_ui->actionReset_Odometry, SIGNAL(triggered()),
this, SLOT(
resetOdometry()));
394 connect(
_ui->actionTrigger_a_new_map, SIGNAL(triggered()),
this, SLOT(
triggerNewMap()));
395 connect(
_ui->actionData_recorder, SIGNAL(triggered()),
this, SLOT(
dataRecorder()));
396 connect(
_ui->actionPost_processing, SIGNAL(triggered()),
this, SLOT(
postProcessing()));
397 connect(
_ui->actionDepth_Calibration, SIGNAL(triggered()),
this, SLOT(
depthCalibration()));
399 _ui->actionPause->setShortcut(Qt::Key_Space);
400 _ui->actionSave_GUI_config->setShortcut(QKeySequence::Save);
403 this->addAction(
_ui->actionSave_GUI_config);
404 _ui->actionReset_Odometry->setEnabled(
false);
405 _ui->actionPost_processing->setEnabled(
false);
406 _ui->actionAnchor_clouds_to_ground_truth->setEnabled(
false);
408 QToolButton* toolButton =
new QToolButton(
this);
409 toolButton->setMenu(
_ui->menuSelect_source);
410 toolButton->setPopupMode(QToolButton::InstantPopup);
411 toolButton->setIcon(QIcon(
":images/kinect_xbox_360.png"));
412 toolButton->setToolTip(
"Select sensor driver");
413 _ui->toolBar->addWidget(toolButton)->setObjectName(
"toolbar_source");
415 #if defined(Q_WS_MAC) || defined(Q_WS_WIN) 418 _ui->menuEdit->removeAction(
_ui->actionOpen_working_directory);
423 connect(
_ui->actionUsbCamera, SIGNAL(triggered()),
this, SLOT(
selectStream()));
424 connect(
_ui->actionOpenNI_PCL, SIGNAL(triggered()),
this, SLOT(
selectOpenni()));
425 connect(
_ui->actionOpenNI_PCL_ASUS, SIGNAL(triggered()),
this, SLOT(
selectOpenni()));
427 connect(
_ui->actionOpenNI_CV, SIGNAL(triggered()),
this, SLOT(
selectOpenniCv()));
429 connect(
_ui->actionOpenNI2, SIGNAL(triggered()),
this, SLOT(
selectOpenni2()));
430 connect(
_ui->actionOpenNI2_kinect, SIGNAL(triggered()),
this, SLOT(
selectOpenni2()));
431 connect(
_ui->actionOpenNI2_sense, SIGNAL(triggered()),
this, SLOT(
selectOpenni2()));
433 connect(
_ui->actionKinect_for_Windows_SDK_v2, SIGNAL(triggered()),
this, SLOT(
selectK4W2()));
434 connect(
_ui->actionKinect_for_Azure, SIGNAL(triggered()),
this, SLOT(
selectK4A()));
435 connect(
_ui->actionRealSense_R200, SIGNAL(triggered()),
this, SLOT(
selectRealSense()));
436 connect(
_ui->actionRealSense_ZR300, SIGNAL(triggered()),
this, SLOT(
selectRealSense()));
447 connect(
_ui->actionMYNT_EYE_S_SDK, SIGNAL(triggered()),
this, SLOT(
selectMyntEyeS()));
473 QActionGroup * modeGrp =
new QActionGroup(
this);
474 modeGrp->addAction(
_ui->actionSLAM_mode);
475 modeGrp->addAction(
_ui->actionLocalization_mode);
483 qRegisterMetaType<PreferencesDialog::PANEL_FLAGS>(
"PreferencesDialog::PANEL_FLAGS");
485 qRegisterMetaType<rtabmap::ParametersMap>(
"rtabmap::ParametersMap");
502 connect(
_ui->toolBar->toggleViewAction(), SIGNAL(toggled(
bool)),
this, SLOT(
configGUIModified()));
503 connect(
_ui->toolBar, SIGNAL(orientationChanged(Qt::Orientation)),
this, SLOT(
configGUIModified()));
504 connect(statusBarAction, SIGNAL(toggled(
bool)),
this, SLOT(
configGUIModified()));
505 QList<QDockWidget*> dockWidgets = this->findChildren<QDockWidget*>();
506 for(
int i=0; i<dockWidgets.size(); ++i)
508 connect(dockWidgets[i], SIGNAL(dockLocationChanged(Qt::DockWidgetArea)),
this, SLOT(
configGUIModified()));
509 connect(dockWidgets[i]->toggleViewAction(), SIGNAL(toggled(
bool)),
this, SLOT(
configGUIModified()));
511 connect(
_ui->dockWidget_graphViewer->toggleViewAction(), SIGNAL(triggered()),
this, SLOT(
updateGraphView()));
513 _ui->dockWidget_posterior->installEventFilter(
this);
514 _ui->dockWidget_likelihood->installEventFilter(
this);
515 _ui->dockWidget_rawlikelihood->installEventFilter(
this);
516 _ui->dockWidget_statsV2->installEventFilter(
this);
517 _ui->dockWidget_console->installEventFilter(
this);
518 _ui->dockWidget_loopClosureViewer->installEventFilter(
this);
519 _ui->dockWidget_mapVisibility->installEventFilter(
this);
520 _ui->dockWidget_graphViewer->installEventFilter(
this);
521 _ui->dockWidget_odometry->installEventFilter(
this);
522 _ui->dockWidget_cloudViewer->installEventFilter(
this);
523 _ui->dockWidget_imageView->installEventFilter(
this);
537 qRegisterMetaType<rtabmap::Statistics>(
"rtabmap::Statistics");
540 qRegisterMetaType<rtabmap::CameraInfo>(
"rtabmap::CameraInfo");
543 qRegisterMetaType<rtabmap::OdometryEvent>(
"rtabmap::OdometryEvent");
552 _ui->statsToolBox->setNewFigureMaxItems(50);
565 if(
_ui->statsToolBox->findChildren<
StatItem*>().size() == 0)
568 for(std::map<std::string, float>::const_iterator iter = statistics.begin(); iter != statistics.end(); ++iter)
571 if(!QString((*iter).first.c_str()).contains(
"Gt/"))
573 _ui->statsToolBox->updateStat(QString((*iter).first.c_str()).replace(
'_',
' '),
false);
578 _ui->statsToolBox->updateStat(
"Planning/From/",
false);
579 _ui->statsToolBox->updateStat(
"Planning/Time/ms",
false);
580 _ui->statsToolBox->updateStat(
"Planning/Goal/",
false);
581 _ui->statsToolBox->updateStat(
"Planning/Poses/",
false);
582 _ui->statsToolBox->updateStat(
"Planning/Length/m",
false);
584 _ui->statsToolBox->updateStat(
"Camera/Time capturing/ms",
false);
585 _ui->statsToolBox->updateStat(
"Camera/Time decimation/ms",
false);
586 _ui->statsToolBox->updateStat(
"Camera/Time disparity/ms",
false);
587 _ui->statsToolBox->updateStat(
"Camera/Time mirroring/ms",
false);
588 _ui->statsToolBox->updateStat(
"Camera/Time scan from depth/ms",
false);
590 _ui->statsToolBox->updateStat(
"Odometry/ID/",
false);
591 _ui->statsToolBox->updateStat(
"Odometry/Features/",
false);
592 _ui->statsToolBox->updateStat(
"Odometry/Matches/",
false);
593 _ui->statsToolBox->updateStat(
"Odometry/MatchesRatio/",
false);
594 _ui->statsToolBox->updateStat(
"Odometry/Inliers/",
false);
595 _ui->statsToolBox->updateStat(
"Odometry/InliersMeanDistance/m",
false);
596 _ui->statsToolBox->updateStat(
"Odometry/InliersDistribution/",
false);
597 _ui->statsToolBox->updateStat(
"Odometry/InliersRatio/",
false);
598 _ui->statsToolBox->updateStat(
"Odometry/ICPInliersRatio/",
false);
599 _ui->statsToolBox->updateStat(
"Odometry/ICPRotation/rad",
false);
600 _ui->statsToolBox->updateStat(
"Odometry/ICPTranslation/m",
false);
601 _ui->statsToolBox->updateStat(
"Odometry/ICPStructuralComplexity/",
false);
602 _ui->statsToolBox->updateStat(
"Odometry/ICPStructuralDistribution/",
false);
603 _ui->statsToolBox->updateStat(
"Odometry/ICPCorrespondences/",
false);
604 _ui->statsToolBox->updateStat(
"Odometry/StdDevLin/",
false);
605 _ui->statsToolBox->updateStat(
"Odometry/StdDevAng/",
false);
606 _ui->statsToolBox->updateStat(
"Odometry/VarianceLin/",
false);
607 _ui->statsToolBox->updateStat(
"Odometry/VarianceAng/",
false);
608 _ui->statsToolBox->updateStat(
"Odometry/TimeEstimation/ms",
false);
609 _ui->statsToolBox->updateStat(
"Odometry/TimeFiltering/ms",
false);
610 _ui->statsToolBox->updateStat(
"Odometry/GravityRollError/deg",
false);
611 _ui->statsToolBox->updateStat(
"Odometry/GravityPitchError/deg",
false);
612 _ui->statsToolBox->updateStat(
"Odometry/LocalMapSize/",
false);
613 _ui->statsToolBox->updateStat(
"Odometry/LocalScanMapSize/",
false);
614 _ui->statsToolBox->updateStat(
"Odometry/LocalKeyFrames/",
false);
615 _ui->statsToolBox->updateStat(
"Odometry/localBundleOutliers/",
false);
616 _ui->statsToolBox->updateStat(
"Odometry/localBundleConstraints/",
false);
617 _ui->statsToolBox->updateStat(
"Odometry/localBundleTime/ms",
false);
618 _ui->statsToolBox->updateStat(
"Odometry/KeyFrameAdded/",
false);
619 _ui->statsToolBox->updateStat(
"Odometry/Interval/ms",
false);
620 _ui->statsToolBox->updateStat(
"Odometry/Speed/kph",
false);
621 _ui->statsToolBox->updateStat(
"Odometry/Speed/mph",
false);
622 _ui->statsToolBox->updateStat(
"Odometry/Speed/mps",
false);
623 _ui->statsToolBox->updateStat(
"Odometry/SpeedGuess/kph",
false);
624 _ui->statsToolBox->updateStat(
"Odometry/SpeedGuess/mph",
false);
625 _ui->statsToolBox->updateStat(
"Odometry/SpeedGuess/mps",
false);
626 _ui->statsToolBox->updateStat(
"Odometry/Distance/m",
false);
627 _ui->statsToolBox->updateStat(
"Odometry/T/m",
false);
628 _ui->statsToolBox->updateStat(
"Odometry/Tx/m",
false);
629 _ui->statsToolBox->updateStat(
"Odometry/Ty/m",
false);
630 _ui->statsToolBox->updateStat(
"Odometry/Tz/m",
false);
631 _ui->statsToolBox->updateStat(
"Odometry/Troll/deg",
false);
632 _ui->statsToolBox->updateStat(
"Odometry/Tpitch/deg",
false);
633 _ui->statsToolBox->updateStat(
"Odometry/Tyaw/deg",
false);
634 _ui->statsToolBox->updateStat(
"Odometry/Px/m",
false);
635 _ui->statsToolBox->updateStat(
"Odometry/Py/m",
false);
636 _ui->statsToolBox->updateStat(
"Odometry/Pz/m",
false);
637 _ui->statsToolBox->updateStat(
"Odometry/Proll/deg",
false);
638 _ui->statsToolBox->updateStat(
"Odometry/Ppitch/deg",
false);
639 _ui->statsToolBox->updateStat(
"Odometry/Pyaw/deg",
false);
641 _ui->statsToolBox->updateStat(
"GUI/Refresh odom/ms",
false);
642 _ui->statsToolBox->updateStat(
"GUI/RGB-D cloud/ms",
false);
643 _ui->statsToolBox->updateStat(
"GUI/Graph Update/ms",
false);
644 #ifdef RTABMAP_OCTOMAP 645 _ui->statsToolBox->updateStat(
"GUI/Octomap Update/ms",
false);
646 _ui->statsToolBox->updateStat(
"GUI/Octomap Rendering/ms",
false);
648 _ui->statsToolBox->updateStat(
"GUI/Grid Update/ms",
false);
649 _ui->statsToolBox->updateStat(
"GUI/Grid Rendering/ms",
false);
650 _ui->statsToolBox->updateStat(
"GUI/Refresh stats/ms",
false);
651 _ui->statsToolBox->updateStat(
"GUI/Cache Data Size/MB",
false);
652 _ui->statsToolBox->updateStat(
"GUI/Cache Clouds Size/MB",
false);
653 #ifdef RTABMAP_OCTOMAP 654 _ui->statsToolBox->updateStat(
"GUI/Octomap Size/MB",
false);
681 #ifdef RTABMAP_OCTOMAP 692 qobject_cast<QHBoxLayout *>(
_ui->layout_imageview->layout())->setDirection(QBoxLayout::TopToBottom);
696 qobject_cast<QHBoxLayout *>(
_ui->layout_imageview->layout())->setDirection(QBoxLayout::LeftToRight);
735 bool processStopped =
true;
748 processStopped =
false;
756 if(this->isWindowModified())
758 QMessageBox::Button b=QMessageBox::question(
this,
760 tr(
"There are unsaved changed settings. Save them?"),
761 QMessageBox::Save | QMessageBox::Cancel | QMessageBox::Discard);
762 if(b == QMessageBox::Save)
766 else if(b != QMessageBox::Discard)
778 _ui->statsToolBox->closeFigures();
780 _ui->dockWidget_imageView->close();
781 _ui->dockWidget_likelihood->close();
782 _ui->dockWidget_rawlikelihood->close();
783 _ui->dockWidget_posterior->close();
784 _ui->dockWidget_statsV2->close();
785 _ui->dockWidget_console->close();
786 _ui->dockWidget_cloudViewer->close();
787 _ui->dockWidget_loopClosureViewer->close();
788 _ui->dockWidget_mapVisibility->close();
789 _ui->dockWidget_graphViewer->close();
790 _ui->dockWidget_odometry->close();
794 UERROR(
"Camera must be already deleted here!");
805 UERROR(
"OdomThread must be already deleted here!");
825 else if(anEvent->
getClassName().compare(
"RtabmapEvent") == 0)
829 int highestHypothesisId = int(
uValue(stats.
data(), Statistics::kLoopHighest_hypothesis_id(), 0.0f));
830 int proximityClosureId = int(
uValue(stats.
data(), Statistics::kProximitySpace_last_detection_id(), 0.0f));
831 bool rejectedHyp = bool(
uValue(stats.
data(), Statistics::kLoopRejectedHypothesis(), 0.0f));
832 float highestHypothesisValue =
uValue(stats.
data(), Statistics::kLoopHighest_hypothesis_value(), 0.0f);
834 _ui->actionPause_on_match->isChecked())
837 highestHypothesisId > 0 &&
839 _ui->actionPause_when_a_loop_hypothesis_is_rejected->isChecked() &&
842 (proximityClosureId > 0 &&
843 _ui->actionPause_on_local_loop_detection->isChecked()))
849 QMetaObject::invokeMethod(
this,
"beep");
861 else if(anEvent->
getClassName().compare(
"RtabmapEventInit") == 0)
869 else if(anEvent->
getClassName().compare(
"RtabmapEvent3DMap") == 0)
874 else if(anEvent->
getClassName().compare(
"RtabmapGlobalPathEvent") == 0)
879 else if(anEvent->
getClassName().compare(
"RtabmapLabelErrorEvent") == 0)
884 else if(anEvent->
getClassName().compare(
"RtabmapGoalStatusEvent") == 0)
888 else if(anEvent->
getClassName().compare(
"CameraEvent") == 0)
895 QMetaObject::invokeMethod(
this,
"beep");
919 else if(anEvent->
getClassName().compare(
"OdometryEvent") == 0)
938 else if(anEvent->
getClassName().compare(
"ULogEvent") == 0)
943 QMetaObject::invokeMethod(
_ui->dockWidget_console,
"show");
950 QMetaObject::invokeMethod(
this,
"beep");
991 if(
_ui->imageView_odometry->toolTip().isEmpty())
993 _ui->imageView_odometry->setToolTip(
994 "Background Color Code:\n" 995 " Dark Red = Odometry Lost\n" 996 " Dark Yellow = Low Inliers\n" 997 "Feature Color code:\n" 999 " Yellow = Not matched features from previous frame(s)\n" 1005 bool lostStateChanged =
false;
1012 _ui->imageView_odometry->setBackgroundColor(Qt::darkRed);
1024 _ui->imageView_odometry->setBackgroundColor(Qt::darkYellow);
1031 _ui->imageView_odometry->setBackgroundColor(
_ui->imageView_odometry->getDefaultBackgroundColor());
1034 if(!pose.
isNull() && (
_ui->dockWidget_cloudViewer->isVisible() ||
_ui->graphicsView_graphView->isVisible()))
1039 if(
_ui->dockWidget_cloudViewer->isVisible())
1041 bool cloudUpdated =
false;
1042 bool scanUpdated =
false;
1043 bool featuresUpdated =
false;
1044 bool filteredGravityUpdated =
false;
1045 bool accelerationUpdated =
false;
1055 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
1056 pcl::IndicesPtr indices(
new std::vector<int>);
1071 pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(
new pcl::PointCloud<pcl::PointXYZRGB>);
1075 Eigen::Vector3f viewpoint(0.0
f,0.0
f,0.0
f);
1093 Eigen::Vector3f(pose.
x(), pose.
y(), pose.
z()) + viewpoint);
1098 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
1099 pcl::toPCLPointCloud2(*cloud, textureMesh->cloud);
1100 textureMesh->tex_polygons.push_back(polygons);
1101 int w = cloud->width;
1102 int h = cloud->height;
1104 textureMesh->tex_coordinates.resize(1);
1105 int nPoints = (int)(textureMesh->cloud.data.size()/textureMesh->cloud.point_step);
1106 textureMesh->tex_coordinates[0].resize(nPoints);
1107 for(
int i=0; i<nPoints; ++i)
1110 textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
1111 float(i % w) /
float(w),
1112 float(h - i / w) /
float(h));
1115 pcl::TexMaterial mesh_material;
1116 mesh_material.tex_d = 1.0f;
1117 mesh_material.tex_Ns = 75.0f;
1118 mesh_material.tex_illum = 1;
1120 mesh_material.tex_name =
"material_odom";
1121 mesh_material.tex_file =
"";
1122 textureMesh->tex_materials.push_back(mesh_material);
1126 UERROR(
"Adding cloudOdom to viewer failed!");
1131 UERROR(
"Adding cloudOdom to viewer failed!");
1139 UERROR(
"Adding cloudOdom to viewer failed!");
1147 cloudUpdated =
true;
1159 bool scanAdded =
false;
1188 UERROR(
"Adding scanMapOdom to viewer failed!");
1215 bool scanAdded =
false;
1219 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloud;
1229 pcl::PointCloud<pcl::PointNormal>::Ptr cloud;
1239 pcl::PointCloud<pcl::PointXYZI>::Ptr cloud;
1249 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
1260 UERROR(
"Adding scanOdom to viewer failed!");
1278 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1281 for(std::map<int, cv::Point3f>::const_iterator iter=odom.
info().
localMap.begin(); iter!=odom.
info().
localMap.end(); ++iter)
1286 (*cloud)[i].x = iter->second.x;
1287 (*cloud)[i].y = iter->second.y;
1288 (*cloud)[i].z = iter->second.z;
1292 (*cloud)[i].r = inlier?0:255;
1293 (*cloud)[i].g = 255;
1307 featuresUpdated =
true;
1313 for(QMap<std::string, Transform>::iterator iter = addedFrustums.begin(); iter!=addedFrustums.end(); ++iter)
1315 std::list<std::string> splitted =
uSplitNumChar(iter.key());
1316 if(splitted.size() == 2)
1318 int id = std::atoi(splitted.back().c_str());
1319 if(splitted.front().compare(
"f_odom_") == 0 &&
1329 std::string frustumId =
uFormat(
"f_odom_%d", iter->first);
1340 QColor color = Qt::yellow;
1355 _cloudViewer->
addOrUpdateLine(
"odom_imu_orientation",
_odometryCorrection*pose, (
_odometryCorrection*pose).translation()*
Transform(gravity[0], gravity[1], gravity[2], 0, 0, 0)*pose.
rotation().
inverse(), Qt::yellow,
true,
true);
1356 filteredGravityUpdated =
true;
1363 Eigen::Vector3f gravity(
1369 _cloudViewer->
addOrUpdateLine(
"odom_imu_acc",
_odometryCorrection*pose,
_odometryCorrection*pose*
Transform(gravity[0], gravity[1], gravity[2], 0, 0, 0), Qt::red,
true,
true);
1370 accelerationUpdated =
true;
1415 #if PCL_VERSION_COMPARE(>=, 1, 7, 2) 1429 if(
_ui->graphicsView_graphView->isVisible())
1434 _ui->graphicsView_graphView->update();
1438 if(
_ui->dockWidget_odometry->isVisible() &&
1441 if(
_ui->imageView_odometry->isFeaturesShown())
1447 std::multimap<int, cv::KeyPoint> kpInliers;
1452 _ui->imageView_odometry->setFeatures(
1459 _ui->imageView_odometry->setFeatures(
1471 std::vector<cv::KeyPoint> kpts;
1473 _ui->imageView_odometry->setFeatures(
1481 bool monoInitialization =
false;
1484 monoInitialization =
true;
1487 _ui->imageView_odometry->clearLines();
1488 if(lost && !monoInitialization)
1490 if(lostStateChanged)
1497 _ui->imageView_odometry->setImageShown(
true);
1498 _ui->imageView_odometry->setImageDepthShown(
true);
1502 if(lostStateChanged)
1536 if(
_ui->imageView_odometry->isFeaturesShown() ||
_ui->imageView_odometry->isLinesShown())
1543 if(
_ui->imageView_odometry->isFeaturesShown() && inliers.find(i) != inliers.end())
1545 _ui->imageView_odometry->setFeatureColor(i, Qt::green);
1547 if(
_ui->imageView_odometry->isLinesShown())
1549 _ui->imageView_odometry->addLine(
1554 inliers.find(i) != inliers.end()?Qt::blue:Qt::yellow);
1565 _ui->imageView_odometry->update();
1722 QTime time, totalTime;
1732 int refMapId = -1, loopMapId = -1;
1737 int highestHypothesisId =
static_cast<float>(
uValue(stat.
data(), Statistics::kLoopHighest_hypothesis_id(), 0.0f));
1744 _ui->label_refId->setText(QString(
"New ID = %1 [%2]").arg(stat.
refImageId()).arg(refMapId));
1748 float totalTime =
static_cast<float>(
uValue(stat.
data(), Statistics::kTimingTotal(), 0.0f));
1755 bool highestHypothesisIsSaved = (bool)
uValue(stat.
data(), Statistics::kLoopHypothesis_reactivated(), 0.0f);
1757 bool smallMovement = (bool)
uValue(stat.
data(), Statistics::kMemorySmall_movement(), 0.0f);
1759 bool fastMovement = (bool)
uValue(stat.
data(), Statistics::kMemoryFast_movement(), 0.0f);
1770 _ui->imageView_source->isVisible() ||
1779 cv::Mat tmpRgb, tmpDepth, tmpG, tmpO, tmpE;
1782 uncompressImages?&tmpRgb:0,
1783 uncompressImages?&tmpDepth:0,
1784 uncompressScan?&tmpScan:0,
1785 0, &tmpG, &tmpO, &tmpE);
1790 if(smallMovement || fastMovement)
1798 unsigned int count = 0;
1801 for(std::multimap<int, int>::const_iterator jter=signature.
getWords().upper_bound(-1); jter!=signature.
getWords().end(); ++jter)
1818 _ui->imageView_source->clear();
1819 _ui->imageView_loopClosure->clear();
1821 _ui->imageView_source->setBackgroundColor(
_ui->imageView_source->getDefaultBackgroundColor());
1822 _ui->imageView_loopClosure->setBackgroundColor(
_ui->imageView_loopClosure->getDefaultBackgroundColor());
1824 _ui->label_matchId->clear();
1827 int rehearsalMerged = (int)
uValue(stat.
data(), Statistics::kMemoryRehearsal_merged(), 0.0f);
1828 bool rehearsedSimilarity = (float)
uValue(stat.
data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0
f;
1829 int proximityTimeDetections = (int)
uValue(stat.
data(), Statistics::kProximityTime_detections(), 0.0f);
1830 bool scanMatchingSuccess = (bool)
uValue(stat.
data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
1831 _ui->label_stats_imageNumber->setText(QString(
"%1 [%2]").arg(stat.
refImageId()).arg(refMapId));
1833 if(rehearsalMerged > 0)
1835 _ui->imageView_source->setBackgroundColor(Qt::blue);
1837 else if(proximityTimeDetections > 0)
1839 _ui->imageView_source->setBackgroundColor(Qt::darkYellow);
1841 else if(scanMatchingSuccess)
1843 _ui->imageView_source->setBackgroundColor(Qt::darkCyan);
1845 else if(rehearsedSimilarity)
1847 _ui->imageView_source->setBackgroundColor(Qt::darkBlue);
1849 else if(smallMovement)
1851 _ui->imageView_source->setBackgroundColor(Qt::gray);
1853 else if(fastMovement)
1855 _ui->imageView_source->setBackgroundColor(Qt::magenta);
1858 if(
_ui->label_refId->toolTip().isEmpty())
1860 _ui->label_refId->setToolTip(
1861 "Background Color Code:\n" 1862 " Blue = Weight Update Merged\n" 1863 " Dark Blue = Weight Update\n" 1864 " Dark Yellow = Proximity Detection in Time\n" 1865 " Dark Cyan = Neighbor Link Refined\n" 1866 " Gray = Small Movement\n" 1867 " Magenta = Fast Movement\n" 1868 "Feature Color code:\n" 1870 " Yellow = New but Not Unique\n" 1871 " Red = In Vocabulary\n" 1872 " Blue = In Vocabulary and in Previous Signature\n" 1873 " Pink = In Vocabulary and in Loop Closure Signature\n" 1874 " Gray = Not Quantized to Vocabulary");
1877 if(
_ui->label_matchId->toolTip().isEmpty())
1879 _ui->label_matchId->setToolTip(
1880 "Background Color Code:\n" 1881 " Green = Accepted Loop Closure Detection\n" 1882 " Red = Rejected Loop Closure Detection\n" 1883 " Yellow = Proximity Detection in Space\n" 1884 "Feature Color code:\n" 1885 " Red = In Vocabulary\n" 1886 " Pink = In Vocabulary and in Loop Closure Signature\n" 1887 " Gray = Not Quantized to Vocabulary");
1890 UDEBUG(
"time= %d ms", time.restart());
1892 int rejectedHyp = bool(
uValue(stat.
data(), Statistics::kLoopRejectedHypothesis(), 0.0f));
1893 float highestHypothesisValue =
uValue(stat.
data(), Statistics::kLoopHighest_hypothesis_value(), 0.0f);
1894 int landmarkId =
static_cast<int>(
uValue(stat.
data(), Statistics::kLoopLandmark_detected(), 0.0f));
1895 int landmarkNodeRef =
static_cast<int>(
uValue(stat.
data(), Statistics::kLoopLandmark_detected_node_ref(), 0.0f));
1898 int shownLoopId = 0;
1904 _ui->imageView_loopClosure->setBackgroundColor(Qt::green);
1905 _ui->label_stats_loopClosuresDetected->setText(QString::number(
_ui->label_stats_loopClosuresDetected->text().toInt() + 1));
1906 if(highestHypothesisIsSaved)
1908 _ui->label_stats_loopClosuresReactivatedDetected->setText(QString::number(
_ui->label_stats_loopClosuresReactivatedDetected->text().toInt() + 1));
1910 _ui->label_matchId->setText(QString(
"Match ID = %1 [%2]").arg(stat.
loopClosureId()).arg(loopMapId));
1915 _ui->imageView_loopClosure->setBackgroundColor(Qt::yellow);
1916 _ui->label_matchId->setText(QString(
"Local match = %1 [%2]").arg(stat.
proximityDetectionId()).arg(loopMapId));
1919 else if(landmarkId!=0)
1921 _ui->imageView_loopClosure->setBackgroundColor(QColor(
"orange"));
1922 _ui->label_matchId->setText(QString(
"Landmark match = %1 with %2").arg(landmarkId).arg(landmarkNodeRef));
1923 matchId = landmarkNodeRef;
1930 _ui->imageView_loopClosure->setBackgroundColor(Qt::red);
1931 _ui->label_stats_loopClosuresRejected->setText(QString::number(
_ui->label_stats_loopClosuresRejected->text().toInt() + 1));
1932 _ui->label_matchId->setText(QString(
"Loop hypothesis %1 rejected!").arg(highestHypothesisId));
1940 _ui->label_matchId->setText(QString(
"Highest hypothesis (%1)").arg(highestHypothesisId));
1946 shownLoopId = matchId>0?matchId:highestHypothesisId;
1951 loopSignature = iter.value();
1952 bool uncompressImages =
_ui->imageView_source->isVisible() ||
1955 if(uncompressImages || uncompressScan)
1957 cv::Mat tmpRGB, tmpDepth;
1960 uncompressImages?&tmpRGB:0,
1961 uncompressImages?&tmpDepth:0,
1962 uncompressScan?&tmpScan:0);
1985 refImage = refImage.clone();
1990 loopImage = loopImage.clone();
1997 qimageThread.
start();
1998 qimageLoopThread.
start();
1999 qimageThread.
join();
2000 qimageLoopThread.
join();
2002 QImage lcImg = qimageLoopThread.
getQImage();
2003 UDEBUG(
"time= %d ms", time.restart());
2007 _ui->imageView_source->setImage(img);
2028 if(sceneRect.isValid())
2030 _ui->imageView_source->setSceneRect(sceneRect);
2035 _ui->imageView_loopClosure->setImage(lcImg);
2041 if(
_ui->imageView_loopClosure->sceneRect().isNull())
2043 _ui->imageView_loopClosure->setSceneRect(
_ui->imageView_source->sceneRect());
2047 UDEBUG(
"time= %d ms", time.restart());
2050 std::multimap<int, cv::KeyPoint> wordsA;
2051 std::multimap<int, cv::KeyPoint> wordsB;
2052 for(std::map<int, int>::const_iterator iter=signature.
getWords().begin(); iter!=signature.
getWords().end(); ++iter)
2054 wordsA.insert(wordsA.end(), std::make_pair(iter->first, signature.
getWordsKpts()[iter->second]));
2056 for(std::map<int, int>::const_iterator iter=loopSignature.
getWords().begin(); iter!=loopSignature.
getWords().end(); ++iter)
2058 wordsB.insert(wordsB.end(), std::make_pair(iter->first, loopSignature.
getWordsKpts()[iter->second]));
2062 UDEBUG(
"time= %d ms", time.restart());
2071 signature.
setPose(loopClosureTransform);
2073 if(
_ui->dockWidget_loopClosureViewer->isVisible())
2077 UINFO(
"Updating loop closure cloud view time=%fs", loopTimer.
elapsed());
2081 UDEBUG(
"time= %d ms", time.restart());
2086 if(!stat.
posterior().empty() &&
_ui->dockWidget_posterior->isVisible())
2095 if(!stat.
likelihood().empty() &&
_ui->dockWidget_likelihood->isVisible())
2099 if(!stat.
rawLikelihood().empty() &&
_ui->dockWidget_rawlikelihood->isVisible())
2105 const std::map<std::string, float> & statistics = stat.
data();
2106 std::string odomStr =
"Odometry/";
2107 for(std::map<std::string, float>::const_iterator iter = statistics.begin(); iter != statistics.end(); ++iter)
2110 if((*iter).first.size()<odomStr.size() || (*iter).first.substr(0, odomStr.size()).compare(odomStr)!=0)
2116 UDEBUG(
"time= %d ms", time.restart());
2122 if(stat.
poses().size())
2135 for(std::map<int, std::string>::const_iterator iter=stat.
labels().begin(); iter!=stat.
labels().end(); ++iter)
2137 uInsert(labels, std::pair<int, std::string>(*iter));
2141 _ui->graphicsView_graphView->getWorldMapRotation()==0.0f &&
2147 _ui->graphicsView_graphView->setWorldMapRotation(gpsRotationOffset);
2150 _ui->graphicsView_graphView->getWorldMapRotation() != 0.0f)
2152 _ui->graphicsView_graphView->setWorldMapRotation(0.0
f);
2156 std::map<int, Transform> poses = stat.
poses();
2158 UDEBUG(
"time= %d ms", time.restart());
2160 #if PCL_VERSION_COMPARE(>=, 1, 7, 2) 2191 if(
_ui->graphicsView_graphView->isVisible())
2193 _ui->graphicsView_graphView->updateReferentialPosition(poses.rbegin()->second);
2199 if(poses.find(stat.
refImageId())!=poses.end())
2201 poses.insert(std::make_pair(0, poses.at(stat.
refImageId())));
2204 if(groundTruth.find(stat.
refImageId())!=groundTruth.end())
2206 groundTruth.insert(std::make_pair(0, groundTruth.at(stat.
refImageId())));
2211 std::map<std::string, float> updateCloudSats;
2223 UDEBUG(
"time= %d ms", time.restart());
2225 for(std::map<std::string, float>::iterator iter=updateCloudSats.begin(); iter!=updateCloudSats.end(); ++iter)
2232 if(
_ui->graphicsView_graphView->isVisible())
2238 _ui->graphicsView_graphView->updatePosterior(stat.
posterior());
2254 _ui->graphicsView_graphView->updateLocalPath(stat.
localPath());
2258 _ui->graphicsView_graphView->setGlobalPath(std::vector<std::pair<int, Transform> >());
2284 _ui->label_stats_loopClosuresDetected->setText(QString::number(
_ui->label_stats_loopClosuresDetected->text().toInt() + 1));
2285 _ui->label_matchId->setText(QString(
"Match ID = %1 [%2]").arg(stat.
loopClosureId()).arg(loopMapId));
2289 _ui->label_matchId->clear();
2291 float elapsedTime =
static_cast<float>(totalTime.elapsed());
2292 UINFO(
"Updating GUI time = %fs", elapsedTime/1000.0
f);
2307 #ifdef RTABMAP_OCTOMAP 2323 const std::map<int, Transform> & posesIn,
2324 const std::multimap<int, Link> & constraints,
2325 const std::map<int, int> & mapIdsIn,
2326 const std::map<int, std::string> & labels,
2327 const std::map<int, Transform> & groundTruths,
2328 bool verboseProgress,
2329 std::map<std::string, float> * stats)
2332 std::map<int, Transform> nodePoses(posesIn.lower_bound(0), posesIn.end());
2333 UDEBUG(
"nodes=%d landmarks=%d constraints=%d mapIdsIn=%d labelsIn=%d",
2334 (
int)nodePoses.size(), (int)(posesIn.size() - nodePoses.size()), (
int)constraints.size(), (int)mapIdsIn.size(), (int)labels.size());
2353 std::map<int, Transform> poses;
2354 std::map<int, int> mapIds;
2359 bool hasZero = nodePoses.find(0) != nodePoses.end();
2362 std::map<int, Transform> posesInTmp = nodePoses;
2363 posesInTmp.erase(0);
2370 for(std::map<int, Transform>::iterator iter= poses.begin(); iter!=poses.end(); ++iter)
2372 std::map<int, int>::const_iterator jter = mapIdsIn.find(iter->first);
2373 if(jter!=mapIdsIn.end())
2375 mapIds.insert(*jter);
2381 poses.insert(*nodePoses.find(0));
2386 _progressDialog->
appendText(tr(
"Map update: %1 nodes shown of %2 (cloud filtering is on)").arg(poses.size()).arg(nodePoses.size()));
2387 QApplication::processEvents();
2396 std::map<int, bool> posesMask;
2397 for(std::map<int, Transform>::const_iterator iter = nodePoses.begin(); iter!=nodePoses.end(); ++iter)
2399 posesMask.insert(posesMask.end(), std::make_pair(iter->first, poses.find(iter->first) != poses.end()));
2401 _ui->widget_mapVisibility->setMap(nodePoses, posesMask);
2403 if(groundTruths.size() &&
_ui->actionAnchor_clouds_to_ground_truth->isChecked())
2405 for(std::map<int, Transform>::iterator iter = poses.begin(); iter!=poses.end(); ++iter)
2407 std::map<int, Transform>::const_iterator gtIter = groundTruths.find(iter->first);
2408 if(gtIter!=groundTruths.end())
2410 iter->second = gtIter->second;
2414 UWARN(
"Not found ground truth pose for node %d", iter->first);
2420 _ui->actionAnchor_clouds_to_ground_truth->setChecked(
false);
2424 if(maxNodes > 0 && poses.size()>1)
2427 std::map<int, Transform> nearestPoses;
2428 nearestPoses.insert(*poses.rbegin());
2429 for(std::map<int, float>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
2431 std::map<int, Transform>::iterator pter = poses.find(iter->first);
2432 if(pter != poses.end())
2434 nearestPoses.insert(*pter);
2438 if(poses.find(0) != poses.end())
2440 nearestPoses.insert(*poses.find(0));
2446 UDEBUG(
"Update map with %d locations", poses.size());
2450 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
2452 if(!iter->second.isNull())
2454 std::string cloudName =
uFormat(
"cloud%d", iter->first);
2456 if(iter->first == 0)
2458 viewerClouds.remove(cloudName);
2467 if(viewerClouds.contains(cloudName))
2472 if(tCloud.
isNull() || iter->second != tCloud)
2476 UERROR(
"Updating pose cloud %d failed!", iter->first);
2488 std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> createdCloud = this->
createAndAddCloudToMap(iter->first, iter->second,
uValue(mapIds, iter->first, -1));
2495 else if(viewerClouds.contains(cloudName))
2501 std::string scanName =
uFormat(
"scan%d", iter->first);
2502 if(iter->first == 0)
2504 viewerClouds.remove(scanName);
2509 if(viewerClouds.contains(scanName))
2514 if(tScan.
isNull() || iter->second != tScan)
2518 UERROR(
"Updating pose scan %d failed!", iter->first);
2529 if(!jter->sensorData().laserScanCompressed().isEmpty() || !jter->sensorData().laserScanRaw().isEmpty())
2535 else if(viewerClouds.contains(scanName))
2541 bool updateGridMap =
2542 ((
_ui->graphicsView_graphView->isVisible() &&
_ui->graphicsView_graphView->isGridMapVisible()) ||
2545 bool updateOctomap =
false;
2546 #ifdef RTABMAP_OCTOMAP 2552 if(updateGridMap || updateOctomap)
2561 jter->sensorData().uncompressDataConst(0, 0, 0, 0, &ground, &obstacles, &empty);
2565 #ifdef RTABMAP_OCTOMAP 2568 if((ground.empty() || ground.channels() > 2) &&
2569 (obstacles.empty() || obstacles.channels() > 2))
2571 cv::Point3f viewpoint = jter->sensorData().gridViewPoint();
2574 else if(!ground.empty() || !obstacles.empty())
2576 UWARN(
"Node %d: Cannot update octomap with 2D occupancy grids.", iter->first);
2584 std::string featuresName =
uFormat(
"features%d", iter->first);
2585 if(iter->first == 0)
2587 viewerClouds.remove(featuresName);
2592 if(viewerClouds.contains(featuresName))
2597 if(tFeatures.
isNull() || iter->second != tFeatures)
2601 UERROR(
"Updating pose features %d failed!", iter->first);
2610 if(!jter->getWords3().empty())
2616 else if(viewerClouds.contains(featuresName))
2622 std::string gravityName =
uFormat(
"gravity%d", iter->first);
2623 if(iter->first == 0)
2625 viewerLines.erase(gravityName);
2631 if(linkIter != constraints.end())
2633 Transform gravityT = linkIter->second.transform();
2635 gravity = (gravityT.
rotation()*(iter->second).
rotation().inverse()).toEigen3f()*gravity;
2636 _cloudViewer->
addOrUpdateLine(gravityName, iter->second, (iter->second).translation()*
Transform(gravity[0], gravity[1], gravity[2], 0, 0, 0)*iter->second.
rotation().
inverse(), Qt::yellow,
false,
false);
2639 else if(viewerLines.find(gravityName)!=viewerLines.end())
2648 if(poses.size() < 200 || i % 100 == 0)
2650 QApplication::processEvents();
2663 for(QMap<std::string, Transform>::iterator iter = viewerClouds.begin(); iter!=viewerClouds.end(); ++iter)
2665 std::list<std::string> splitted =
uSplitNumChar(iter.key());
2667 if(splitted.size() == 2)
2669 id = std::atoi(splitted.back().c_str());
2670 if(poses.find(
id) == poses.end())
2674 UDEBUG(
"Hide %s", iter.key().c_str());
2681 for(std::set<std::string>::iterator iter = viewerLines.begin(); iter!=viewerLines.end(); ++iter)
2685 if(splitted.size() == 2)
2687 id = std::atoi(splitted.back().c_str());
2688 if(poses.find(
id) == poses.end())
2690 UDEBUG(
"Remove %s", iter->c_str());
2699 stats->insert(std::make_pair(
"GUI/RGB-D cloud/ms", (
float)timer.
restart()*1000.0f));
2708 for(QMap<std::string, Transform>::iterator iter = addedFrustums.begin(); iter!=addedFrustums.end(); ++iter)
2710 std::list<std::string> splitted =
uSplitNumChar(iter.key());
2711 if(splitted.size() == 2)
2713 if((splitted.front().compare(
"f_") == 0 || splitted.front().compare(
"f_gt_") == 0))
2731 std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > graphs;
2739 std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator kter = graphs.find(mapId);
2740 if(kter == graphs.end())
2742 kter = graphs.insert(std::make_pair(mapId, pcl::PointCloud<pcl::PointXYZ>::Ptr(
new pcl::PointCloud<pcl::PointXYZ>))).first;
2744 pcl::PointXYZ pt(iter->second.x(), iter->second.y(), iter->second.z());
2745 kter->second->push_back(pt);
2751 std::string frustumId =
uFormat(
"f_%d", iter->first);
2766 QColor color = (Qt::GlobalColor)((mapId+3) % 12 + 7 );
2771 std::string gtFrustumId =
uFormat(
"f_gt_%d", iter->first);
2789 std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator kter = graphs.find(mapId);
2790 if(kter == graphs.end())
2792 kter = graphs.insert(std::make_pair(mapId, pcl::PointCloud<pcl::PointXYZ>::Ptr(
new pcl::PointCloud<pcl::PointXYZ>))).first;
2795 pcl::PointXYZ pt(t.
x(), t.
y(), t.
z());
2796 kter->second->push_back(pt);
2801 for(std::map<
int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator iter=graphs.begin(); iter!=graphs.end(); ++iter)
2803 QColor color = Qt::gray;
2804 if(iter->first >= 0)
2806 color = (Qt::GlobalColor)((iter->first+3) % 12 + 7 );
2814 UDEBUG(
"remove not used frustums");
2815 for(QMap<std::string, Transform>::iterator iter = addedFrustums.begin(); iter!=addedFrustums.end(); ++iter)
2817 std::list<std::string> splitted =
uSplitNumChar(iter.key());
2818 if(splitted.size() == 2)
2820 int id = std::atoi(splitted.back().c_str());
2821 if((splitted.front().compare(
"f_") == 0 || splitted.front().compare(
"f_gt_") == 0) &&
2833 UDEBUG(
"labels.size()=%d", (
int)labels.size());
2839 for(std::map<int, std::string>::const_iterator iter=labels.begin(); iter!=labels.end(); ++iter)
2841 if(nodePoses.find(iter->first)!=nodePoses.end())
2843 int mapId =
uValue(mapIdsIn, iter->first, -1);
2844 QColor color = Qt::gray;
2847 color = (Qt::GlobalColor)((mapId+3) % 12 + 7 );
2862 stats->insert(std::make_pair(
"GUI/Graph Update/ms", (
float)timer.
restart()*1000.0f));
2865 #ifdef RTABMAP_OCTOMAP 2873 UINFO(
"Octomap update time = %fs", time.
ticks());
2877 stats->insert(std::make_pair(
"GUI/Octomap Update/ms", (
float)timer.
restart()*1000.0f));
2889 pcl::IndicesPtr obstacles(
new std::vector<int>);
2891 if(obstacles->size())
2897 UINFO(
"Octomap show 3d map time = %fs", time.
ticks());
2902 stats->insert(std::make_pair(
"GUI/Octomap Rendering/ms", (
float)timer.
restart()*1000.0f));
2907 #if PCL_VERSION_COMPARE(>=, 1, 7, 2) 2912 for(std::map<int, Transform>::const_iterator iter=posesIn.begin(); iter!=posesIn.end() && iter->first<0; ++iter)
2914 #if PCL_VERSION_COMPARE(>=, 1, 7, 2) 2921 std::string(
"landmark_str_") + num,
2931 if(
_ui->graphicsView_graphView->isVisible())
2933 _ui->graphicsView_graphView->updateGraph(posesIn, constraints, mapIdsIn);
2937 for(std::map<int, Transform>::iterator iter=gtPoses.begin(); iter!=gtPoses.end(); ++iter)
2939 iter->second = mapToGt * iter->second;
2941 _ui->graphicsView_graphView->updateGTGraph(gtPoses);
2954 #ifdef RTABMAP_OCTOMAP 2969 stats->insert(std::make_pair(
"GUI/Grid Update/ms", (
float)timer.
restart()*1000.0f));
2983 if(
_ui->graphicsView_graphView->isVisible())
2985 _ui->graphicsView_graphView->updateMap(map8U, resolution, xMin, yMin);
2989 _ui->graphicsView_graphView->update();
2994 stats->insert(std::make_pair(
"GUI/Grid Rendering/ms", (
float)timer.
restart()*1000.0f));
3003 if(viewerClouds.contains(
"cloudOdom"))
3019 if(viewerClouds.contains(
"scanOdom"))
3035 if(viewerClouds.contains(
"scanMapOdom"))
3051 if(viewerClouds.contains(
"featuresOdom"))
3072 #ifdef RTABMAP_OCTOMAP 3075 _ui->actionExport_octomap->setEnabled(
false);
3087 std::string cloudName =
uFormat(
"cloud%d", nodeId);
3088 std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> outputPair;
3091 UERROR(
"Cloud %d already added to map.", nodeId);
3098 UERROR(
"Node %d is not in the cache.", nodeId);
3104 if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) &&
3105 (!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty()))
3107 cv::Mat image, depth;
3111 bool rectifyOnlyFeatures = Parameters::defaultRtabmapRectifyOnlyFeatures();
3112 bool imagesAlreadyRectified = Parameters::defaultRtabmapImagesAlreadyRectified();
3113 Parameters::parse(allParameters, Parameters::kRtabmapRectifyOnlyFeatures(), rectifyOnlyFeatures);
3114 Parameters::parse(allParameters, Parameters::kRtabmapImagesAlreadyRectified(), imagesAlreadyRectified);
3115 if(rectifyOnlyFeatures && !imagesAlreadyRectified)
3123 cv::Mat rectifiedImages = data.
imageRaw().clone();
3129 for(
unsigned int i=0; i<data.
cameraModels().size(); ++i)
3138 UWARN(
"Initializing rectification maps for camera %d (only done for the first image received)...", i);
3140 UWARN(
"Initializing rectification maps for camera %d (only done for the first image received)... done!", i);
3146 rectifiedImage.copyTo(cv::Mat(rectifiedImages, cv::Rect(subImageWidth*i, 0, subImageWidth, data.
imageRaw().rows)));
3150 UWARN(
"Camera %d of data %d is not valid for rectification (%dx%d).",
3156 UINFO(
"Time rectification: %fs", time.
ticks());
3158 image = rectifiedImages;
3162 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
3163 pcl::IndicesPtr indices(
new std::vector<int>);
3164 UASSERT_MSG(nodeId == 0 || nodeId == data.
id(),
uFormat(
"nodeId=%d data.id()=%d", nodeId, data.
id()).c_str());
3176 Eigen::Vector3f viewPoint(0.0
f,0.0
f,0.0
f);
3179 viewPoint[0] = data.
cameraModels()[0].localTransform().x();
3180 viewPoint[1] = data.
cameraModels()[0].localTransform().y();
3181 viewPoint[2] = data.
cameraModels()[0].localTransform().z();
3195 indices->resize(cloud->size());
3196 for(
unsigned int i=0; i<cloud->size(); ++i)
3203 if(indices->size() &&
3218 if(indices->size() &&
3229 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3234 pcl::IndicesPtr beforeFiltering = indices;
3235 if( cloud->size() &&
3258 pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
3262 UWARN(
"Cloud subtraction with angle filtering is activated but " 3263 "cloud normal K search is 0. Subtraction is done with angle.");
3267 if(cloudWithNormals->size() &&
3294 UINFO(
"Time subtract filtering %d from %d -> %d (%fs)",
3296 (int)beforeFiltering->size(),
3297 (int)indices->size(),
3310 pcl::PointCloud<pcl::PointXYZRGB>::Ptr output;
3326 pcl::PointCloud<pcl::PointXYZRGB>::Ptr outputFiltered(
new pcl::PointCloud<pcl::PointXYZRGB>);
3327 std::vector<pcl::Vertices> outputPolygons;
3332 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
3333 pcl::toPCLPointCloud2(*outputFiltered, textureMesh->cloud);
3334 textureMesh->tex_polygons.push_back(outputPolygons);
3335 int w = cloud->width;
3336 int h = cloud->height;
3338 textureMesh->tex_coordinates.resize(1);
3339 int nPoints = (int)outputFiltered->size();
3340 textureMesh->tex_coordinates[0].resize(nPoints);
3341 for(
int i=0; i<nPoints; ++i)
3344 UASSERT(i < (
int)denseToOrganizedIndices.size());
3345 int originalVertex = denseToOrganizedIndices[i];
3346 textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
3347 float(originalVertex % w) /
float(w),
3348 float(h - originalVertex / w) /
float(h));
3351 pcl::TexMaterial mesh_material;
3352 mesh_material.tex_d = 1.0f;
3353 mesh_material.tex_Ns = 75.0f;
3354 mesh_material.tex_illum = 1;
3356 std::stringstream tex_name;
3357 tex_name <<
"material_" << nodeId;
3358 tex_name >> mesh_material.tex_name;
3360 mesh_material.tex_file =
"";
3362 textureMesh->tex_materials.push_back(mesh_material);
3366 UERROR(
"Adding texture mesh %d to viewer failed!", nodeId);
3375 UERROR(
"Adding mesh cloud %d to viewer failed!", nodeId);
3387 UWARN(
"Online meshing is activated but the generated cloud is " 3388 "dense (voxel filtering is used or multiple cameras are used). Disable " 3389 "online meshing in Preferences->3D Rendering to hide this warning.");
3395 pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
3398 QColor color = Qt::gray;
3401 color = (Qt::GlobalColor)(mapId+3 % 12 + 7 );
3406 if(cloudWithNormals->size())
3408 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr outputWithNormals;
3413 UERROR(
"Adding cloud %d to viewer failed!", nodeId);
3424 UERROR(
"Adding cloud %d to viewer failed!", nodeId);
3434 outputPair.first = output;
3435 outputPair.second = indices;
3461 std::string scanName =
uFormat(
"scan%d", nodeId);
3464 UERROR(
"Scan %d already added to map.", nodeId);
3471 UERROR(
"Node %d is not in the cache.", nodeId);
3475 if(!iter->sensorData().laserScanCompressed().isEmpty() || !iter->sensorData().laserScanRaw().isEmpty())
3478 iter->sensorData().uncompressData(0, 0, &scan);
3490 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
3491 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudRGB;
3492 pcl::PointCloud<pcl::PointXYZI>::Ptr cloudI;
3493 pcl::PointCloud<pcl::PointNormal>::Ptr cloudWithNormals;
3494 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudRGBWithNormals;
3495 pcl::PointCloud<pcl::PointXYZINormal>::Ptr cloudIWithNormals;
3538 if((!scan.
is2d()) &&
3542 if(cloudRGBWithNormals.get())
3555 if(cloudIWithNormals.get())
3568 if(cloudWithNormals.get())
3622 if( (cloud.get() || cloudRGB.get() || cloudI.get()) &&
3625 Eigen::Vector3f scanViewpoint(
3630 pcl::PointCloud<pcl::Normal>::Ptr normals;
3631 if(cloud.get() && cloud->size())
3641 cloudWithNormals.reset(
new pcl::PointCloud<pcl::PointNormal>);
3642 pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
3645 else if(cloudRGB.get() && cloudRGB->size())
3649 cloudRGBWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3650 pcl::concatenateFields(*cloudRGB, *normals, *cloudRGBWithNormals);
3653 else if(cloudI.get())
3663 cloudIWithNormals.reset(
new pcl::PointCloud<pcl::PointXYZINormal>);
3664 pcl::concatenateFields(*cloudI, *normals, *cloudIWithNormals);
3669 QColor color = Qt::gray;
3672 color = (Qt::GlobalColor)(mapId+3 % 12 + 7 );
3675 if(cloudRGBWithNormals.get())
3678 if(added && nodeId > 0)
3683 else if(cloudIWithNormals.get())
3686 if(added && nodeId > 0)
3698 else if(cloudWithNormals.get())
3701 if(added && nodeId > 0)
3713 else if(cloudRGB.get())
3716 if(added && nodeId > 0)
3721 else if(cloudI.get())
3724 if(added && nodeId > 0)
3740 if(added && nodeId > 0)
3754 UERROR(
"Adding cloud %d to viewer failed!", nodeId);
3774 std::string cloudName =
uFormat(
"features%d", nodeId);
3777 UERROR(
"Features cloud %d already added to map.", nodeId);
3784 UERROR(
"Node %d is not in the cache.", nodeId);
3790 UDEBUG(
"Features cloud %d already created.");
3794 if(iter->getWords3().size())
3796 UINFO(
"Create cloud from 3D words");
3797 QColor color = Qt::gray;
3800 color = (Qt::GlobalColor)(mapId+3 % 12 + 7 );
3804 if(!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty())
3810 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
3811 cloud->resize(iter->getWords3().size());
3813 UASSERT(iter->getWords().size() == iter->getWords3().size());
3815 UDEBUG(
"rgb.channels()=%d");
3816 if(!iter->getWords3().empty() && !iter->getWordsKpts().empty())
3819 if(iter.value().sensorData().cameraModels().size() == 1 && iter.value().sensorData().cameraModels().at(0).isValidForProjection())
3821 invLocalTransform = iter.value().sensorData().cameraModels()[0].localTransform().
inverse();
3823 else if(iter.value().sensorData().stereoCameraModel().isValidForProjection())
3825 invLocalTransform = iter.value().sensorData().stereoCameraModel().left().localTransform().
inverse();
3828 for(std::multimap<int, int>::const_iterator jter=iter->getWords().begin(); jter!=iter->getWords().end(); ++jter)
3830 const cv::Point3f & pt = iter->getWords3()[jter->second];
3832 (maxDepth == 0.0
f ||
3834 (iter.value().sensorData().cameraModels().size()<=1 &&
3837 (*cloud)[oi].
x = pt.x;
3838 (*cloud)[oi].y = pt.y;
3839 (*cloud)[oi].z = pt.z;
3840 const cv::KeyPoint & kpt = iter->getWordsKpts()[jter->second];
3841 int u = kpt.pt.x+0.5;
3842 int v = kpt.pt.y+0.5;
3847 if(rgb.channels() == 1)
3849 (*cloud)[oi].r = (*cloud)[oi].g = (*cloud)[oi].b = rgb.at<
unsigned char>(v, u);
3853 cv::Vec3b bgr = rgb.at<cv::Vec3b>(v, u);
3854 (*cloud)[oi].b = bgr.val[0];
3855 (*cloud)[oi].g = bgr.val[1];
3856 (*cloud)[oi].r = bgr.val[2];
3861 (*cloud)[oi].r = (*cloud)[oi].g = (*cloud)[oi].b = 255;
3870 UERROR(
"Adding features cloud %d to viewer failed!", nodeId);
3887 const std::map<int, Transform> & poses,
3888 const std::map<int, Transform> & groundTruth)
3891 if(groundTruth.size() && poses.size())
3893 float translational_rmse = 0.0f;
3894 float translational_mean = 0.0f;
3895 float translational_median = 0.0f;
3896 float translational_std = 0.0f;
3897 float translational_min = 0.0f;
3898 float translational_max = 0.0f;
3899 float rotational_rmse = 0.0f;
3900 float rotational_mean = 0.0f;
3901 float rotational_median = 0.0f;
3902 float rotational_std = 0.0f;
3903 float rotational_min = 0.0f;
3904 float rotational_max = 0.0f;
3911 translational_median,
3923 UINFO(
"translational_rmse=%f", translational_rmse);
3924 UINFO(
"translational_mean=%f", translational_mean);
3925 UINFO(
"translational_median=%f", translational_median);
3926 UINFO(
"translational_std=%f", translational_std);
3927 UINFO(
"translational_min=%f", translational_min);
3928 UINFO(
"translational_max=%f", translational_max);
3930 UINFO(
"rotational_rmse=%f", rotational_rmse);
3931 UINFO(
"rotational_mean=%f", rotational_mean);
3932 UINFO(
"rotational_median=%f", rotational_median);
3933 UINFO(
"rotational_std=%f", rotational_std);
3934 UINFO(
"rotational_min=%f", rotational_min);
3935 UINFO(
"rotational_max=%f", rotational_max);
3942 UINFO(
"Update visibility %d", nodeId);
3946 _ui->actionAnchor_clouds_to_ground_truth->isChecked() &&
3956 if(!pose.
isNull() || !visible)
3960 std::string cloudName =
uFormat(
"cloud%d", nodeId);
3961 if(visible && !viewerClouds.contains(cloudName) &&
_cachedSignatures.contains(nodeId))
3965 else if(viewerClouds.contains(cloudName))
3978 std::string scanName =
uFormat(
"scan%d", nodeId);
3979 if(visible && !viewerClouds.contains(scanName) &&
_cachedSignatures.contains(nodeId))
3983 else if(viewerClouds.contains(scanName))
4000 if(
_ui->dockWidget_graphViewer->isVisible())
4002 UDEBUG(
"Graph visible!");
4052 bool removed =
true;
4063 QMessageBox::information(
this, tr(
"Database saved!"), QString(msg.c_str()));
4067 std::string msg =
uFormat(
"Failed to rename temporary database from \"%s\" to \"%s\".",
4070 QMessageBox::critical(
this, tr(
"Closing failed!"), QString(msg.c_str()));
4075 std::string msg =
uFormat(
"Failed to overwrite the database \"%s\". The temporary database is still correctly saved at \"%s\".",
4078 QMessageBox::critical(
this, tr(
"Closing failed!"), QString(msg.c_str()));
4095 QMessageBox::information(
this, tr(
"Database updated!"), QString(msg.c_str()));
4115 if(applicationClosing)
4130 msg.prepend(tr(
"[ERROR] "));
4148 UERROR(
"Map received with code error %d!", event.
getCode());
4156 UINFO(
"Received map!");
4162 QApplication::processEvents();
4164 int addedSignatures = 0;
4165 std::map<int, int> mapIds;
4166 std::map<int, Transform> groundTruth;
4167 std::map<int, std::string> labels;
4168 for(std::map<int, Signature>::const_iterator iter = event.
getSignatures().begin();
4169 iter!=
event.getSignatures().end();
4172 mapIds.insert(std::make_pair(iter->first, iter->second.mapId()));
4173 if(!iter->second.getGroundTruthPose().isNull())
4175 groundTruth.insert(std::make_pair(iter->first, iter->second.getGroundTruthPose()));
4177 if(!iter->second.getLabel().empty())
4179 labels.insert(std::make_pair(iter->first, iter->second.getLabel()));
4182 (
_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty()))
4186 unsigned int count = 0;
4187 if(!iter->second.getWords3().empty())
4189 for(std::multimap<int, int>::const_iterator jter=iter->second.getWords().upper_bound(-1); jter!=iter->second.getWords().end(); ++jter)
4201 QApplication::processEvents();
4205 QApplication::processEvents();
4215 QApplication::processEvents();
4216 std::map<int, Transform> poses =
event.getPoses();
4219 if(
_ui->graphicsView_graphView->isVisible() &&
4232 UINFO(
"Map received is empty! Cannot update the map cloud...");
4262 _ui->graphicsView_graphView->setGlobalPath(event.
getPoses());
4276 QMessageBox * warn =
new QMessageBox(
4277 QMessageBox::Warning,
4278 tr(
"Setting goal failed!"),
4279 tr(
"Setting goal to location %1%2 failed. " 4281 "1) the robot is not yet localized in the map,\n" 4282 "2) the location doesn't exist in the map,\n" 4283 "3) the location is not linked to the global map or\n" 4284 "4) the location is too near of the current location (goal already reached).")
4289 warn->setAttribute(Qt::WA_DeleteOnClose,
true);
4294 QMessageBox * info =
new QMessageBox(
4295 QMessageBox::Information,
4296 tr(
"Goal detected!"),
4297 tr(
"Global path computed to %1%2 (%3 poses, %4 m).")
4304 info->setAttribute(Qt::WA_DeleteOnClose,
true);
4318 QMessageBox * warn =
new QMessageBox(
4319 QMessageBox::Warning,
4320 tr(
"Setting label failed!"),
4321 tr(
"Setting label %1 to location %2 failed. " 4323 "1) the location doesn't exist in the map,\n" 4324 "2) the location has already a label.").arg(label).arg(
id),
4327 warn->setAttribute(Qt::WA_DeleteOnClose,
true);
4333 _ui->widget_console->appendMsg(tr(
"Goal status received=%1").arg(status),
ULogger::kInfo);
4366 UDEBUG(
"General settings changed...");
4374 _ui->graphicsView_graphView->clearPosterior();
4380 UDEBUG(
"Cloud rendering settings changed...");
4394 UDEBUG(
"Logging settings changed...");
4414 if(parameters.size())
4416 for(rtabmap::ParametersMap::const_iterator iter = parameters.begin(); iter!=parameters.end(); ++iter)
4418 UDEBUG(
"Parameter changed: Key=%s Value=%s", iter->first.c_str(), iter->second.c_str());
4423 if(
uContains(parameters, Parameters::kRtabmapWorkingDirectory()))
4443 if(
uContains(parameters, Parameters::kRGBDLocalRadius()))
4445 _ui->graphicsView_graphView->setLocalRadius(
uStr2Float(parameters.at(Parameters::kRGBDLocalRadius())));
4465 _ui->imageView_source->clearFeatures();
4467 for(std::multimap<int, cv::KeyPoint>::const_iterator iter = refWords.begin(); iter != refWords.end(); ++iter )
4469 int id = iter->first;
4479 color = Qt::magenta;
4491 else if(refWords.count(
id) > 1)
4501 _ui->imageView_source->addFeature(iter->first, iter->second, 0, color);
4507 QList<QPair<cv::Point2f, cv::Point2f> > uniqueCorrespondences;
4508 if(loopWords.size())
4510 _ui->imageView_loopClosure->clearFeatures();
4512 for(std::multimap<int, cv::KeyPoint>::const_iterator iter = loopWords.begin(); iter != loopWords.end(); ++iter )
4514 int id = iter->first;
4524 color = Qt::magenta;
4526 if(
uValues(refWords,
id).size() == 1 &&
uValues(loopWords,
id).size() == 1)
4528 const cv::KeyPoint & a = refWords.find(
id)->second;
4529 const cv::KeyPoint & b = iter->second;
4530 uniqueCorrespondences.push_back(QPair<cv::Point2f, cv::Point2f>(a.pt, b.pt));
4538 else if(refWords.count(
id) > 1)
4548 _ui->imageView_loopClosure->addFeature(iter->first, iter->second, 0, color);
4553 if(refWords.size()>0)
4555 if((*refWords.rbegin()).first >
_lastId)
4557 _lastId = (*refWords.rbegin()).first;
4563 float scaleSource =
_ui->imageView_source->viewScale();
4564 float scaleLoop =
_ui->imageView_loopClosure->viewScale();
4565 UDEBUG(
"scale source=%f loop=%f", scaleSource, scaleLoop);
4567 float sourceMarginX = (
_ui->imageView_source->width() -
_ui->imageView_source->sceneRect().width()*scaleSource)/2.0
f;
4568 float sourceMarginY = (
_ui->imageView_source->height() -
_ui->imageView_source->sceneRect().height()*scaleSource)/2.0
f;
4569 float loopMarginX = (
_ui->imageView_loopClosure->width() -
_ui->imageView_loopClosure->sceneRect().width()*scaleLoop)/2.0
f;
4570 float loopMarginY = (
_ui->imageView_loopClosure->height() -
_ui->imageView_loopClosure->sceneRect().height()*scaleLoop)/2.0
f;
4577 deltaY =
_ui->label_matchId->height() +
_ui->imageView_source->height();
4581 deltaX =
_ui->imageView_source->width();
4584 if(refWords.size() && loopWords.size())
4586 _ui->imageView_source->clearLines();
4587 _ui->imageView_loopClosure->clearLines();
4590 for(QList<QPair<cv::Point2f, cv::Point2f> >::iterator iter = uniqueCorrespondences.begin();
4591 iter!=uniqueCorrespondences.end();
4595 _ui->imageView_source->addLine(
4598 (iter->second.x*scaleLoop+loopMarginX+deltaX-sourceMarginX)/scaleSource,
4599 (iter->second.y*scaleLoop+loopMarginY+deltaY-sourceMarginY)/scaleSource,
4600 _ui->imageView_source->getDefaultMatchingLineColor());
4602 _ui->imageView_loopClosure->addLine(
4603 (iter->first.x*scaleSource+sourceMarginX-deltaX-loopMarginX)/scaleLoop,
4604 (iter->first.y*scaleSource+sourceMarginY-deltaY-loopMarginY)/scaleLoop,
4607 _ui->imageView_loopClosure->getDefaultMatchingLineColor());
4609 _ui->imageView_source->update();
4610 _ui->imageView_loopClosure->update();
4615 for(std::map<int, Link>::const_iterator iter=signature.
getLandmarks().begin(); iter!=signature.
getLandmarks().end(); ++iter)
4630 cv::Vec3d rvec, tvec;
4631 tvec.val[0] = t.
x();
4632 tvec.val[1] = t.
y();
4633 tvec.val[2] = t.
z();
4636 cv::Rodrigues(R, rvec);
4641 std::vector< cv::Point3f > axisPoints;
4643 axisPoints.push_back(cv::Point3f(0, 0, 0));
4644 axisPoints.push_back(cv::Point3f(length, 0, 0));
4645 axisPoints.push_back(cv::Point3f(0, length, 0));
4646 axisPoints.push_back(cv::Point3f(0, 0, length));
4647 std::vector< cv::Point2f > imagePoints;
4648 projectPoints(axisPoints, rvec, tvec, model.
K(), model.
D(), imagePoints);
4650 cv::line(image, imagePoints[0], imagePoints[1], cv::Scalar(0, 0, 255), 3);
4651 cv::line(image, imagePoints[0], imagePoints[2], cv::Scalar(0, 255, 0), 3);
4652 cv::line(image, imagePoints[0], imagePoints[3], cv::Scalar(255, 0, 0), 3);
4653 cv::putText(image,
uNumber2Str(-iter->first), imagePoints[0], cv::FONT_HERSHEY_SIMPLEX, 0.75, cv::Scalar(0, 255, 255), 2);
4666 if(this->isVisible())
4679 if(this->isVisible())
4688 if((event->modifiers() & Qt::ControlModifier) && event->key() == Qt::Key_S)
4696 if (event->type() == QEvent::Resize && qobject_cast<QDockWidget*>(obj))
4698 this->setWindowModified(
true);
4700 else if(event->type() == QEvent::FileOpen )
4704 return QWidget::eventFilter(obj, event);
4711 _ui->actionMore_options->setChecked(
4768 QString name = (QDateTime::currentDateTime().toString(
"yyMMddhhmmsszzz") + (png?
".png":
".jpg"));
4769 _ui->statusbar->clearMessage();
4770 QPixmap figure = QPixmap::grabWidget(
this);
4776 msg = tr(
"Screen captured \"%1\"").arg(name);
4778 QBuffer buffer(&bytes);
4779 buffer.open(QIODevice::WriteOnly);
4780 figure.save(&buffer, png?
"PNG":
"JPEG");
4786 if(!dir.exists(targetDir))
4788 dir.mkdir(targetDir);
4790 targetDir += QDir::separator();
4791 targetDir +=
"Main_window";
4792 if(!dir.exists(targetDir))
4794 dir.mkdir(targetDir);
4796 targetDir += QDir::separator();
4798 figure.save(targetDir + name);
4799 msg = tr(
"Screen captured \"%1\"").arg(targetDir + name);
4802 _ui->widget_console->appendMsg(msg);
4804 return targetDir + name;
4809 QApplication::beep();
4820 this->setWindowModified(
true);
4825 if(parameters.size())
4827 for(ParametersMap::const_iterator iter= parameters.begin(); iter!=parameters.end(); ++iter)
4829 QString msg = tr(
"Parameter update \"%1\"=\"%2\"")
4830 .arg(iter->first.c_str())
4831 .arg(iter->second.c_str());
4832 _ui->widget_console->appendMsg(msg);
4833 UWARN(msg.toStdString().c_str());
4835 QMessageBox::StandardButton button = QMessageBox::question(
this,
4837 tr(
"Some parameters have been set on command line, do you " 4838 "want to set all other RTAB-Map's parameters to default?"),
4839 QMessageBox::Yes | QMessageBox::No,
4863 this->setWindowModified(
false);
4870 UERROR(
"This method can be called only in IDLE state.");
4884 if(QFile::exists(databasePath.c_str()))
4886 int r = QMessageBox::question(
this,
4887 tr(
"Creating temporary database"),
4888 tr(
"Cannot create a new database because the temporary database \"%1\" already exists. " 4889 "There may be another instance of RTAB-Map running with the same Working Directory or " 4890 "the last time RTAB-Map was not closed correctly. " 4891 "Do you want to recover the database (click Ignore to delete it and create a new one)?").arg(databasePath.c_str()),
4892 QMessageBox::Yes | QMessageBox::No | QMessageBox::Ignore, QMessageBox::No);
4894 if(r == QMessageBox::Ignore)
4896 if(QFile::remove(databasePath.c_str()))
4898 UINFO(
"Deleted temporary database \"%s\".", databasePath.c_str());
4902 UERROR(
"Temporary database \"%s\" could not be deleted!", databasePath.c_str());
4906 else if(r == QMessageBox::Yes)
4908 std::string errorMsg;
4910 progressDialog->setAttribute(Qt::WA_DeleteOnClose);
4912 progressDialog->show();
4920 QString newPath = QFileDialog::getSaveFileName(
this, tr(
"Save recovered database"),
_preferencesDialog->
getWorkingDirectory()+QDir::separator()+QString(
"recovered.db"), tr(
"RTAB-Map database files (*.db)"));
4921 if(newPath.isEmpty())
4925 if(QFileInfo(newPath).suffix() ==
"")
4929 if(QFile::exists(newPath))
4931 QFile::remove(newPath);
4933 QFile::rename(databasePath.c_str(), newPath);
4940 QMessageBox::warning(
this,
"Database recovery", tr(
"Database recovery failed: \"%1\".").arg(errorMsg.c_str()));
4967 UERROR(
"Database can only be opened in IDLE state.");
4971 std::string value = path.toStdString();
4992 if(parameters.size())
4997 parameters.insert(*iter);
5000 uInsert(parameters, overridedParameters);
5004 for(ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
5006 ParametersMap::iterator jter = currentParameters.find(iter->first);
5007 if(jter!=currentParameters.end() &&
5008 iter->second.compare(jter->second) != 0 &&
5009 iter->first.compare(Parameters::kRtabmapWorkingDirectory()) != 0)
5011 bool different =
true;
5029 differentParameters.insert(*iter);
5030 QString msg = tr(
"Parameter \"%1\": database=\"%2\" Preferences=\"%3\"")
5031 .arg(iter->first.c_str())
5032 .arg(iter->second.c_str())
5033 .arg(jter->second.c_str());
5034 _ui->widget_console->appendMsg(msg);
5035 UWARN(msg.toStdString().c_str());
5040 if(differentParameters.size())
5042 int r = QMessageBox::question(
this,
5043 tr(
"Update parameters..."),
5044 tr(
"The database is using %1 different parameter(s) than " 5045 "those currently set in Preferences. Do you want " 5046 "to use database's parameters?").arg(differentParameters.size()),
5047 QMessageBox::Yes | QMessageBox::No,
5049 if(r == QMessageBox::Yes)
5062 UERROR(
"File \"%s\" not valid.", value.c_str());
5070 UERROR(
"This method can be called only in INITIALIZED state.");
5077 QMessageBox::Button b = QMessageBox::question(
this,
5078 tr(
"Save database"),
5079 tr(
"Save the new database?"),
5080 QMessageBox::Save | QMessageBox::Cancel | QMessageBox::Discard,
5083 if(b == QMessageBox::Save)
5086 QString newName = QDateTime::currentDateTime().toString(
"yyMMdd-hhmmss");
5089 newPath = QFileDialog::getSaveFileName(
this, tr(
"Save database"), newPath, tr(
"RTAB-Map database files (*.db)"));
5090 if(newPath.isEmpty())
5095 if(QFileInfo(newPath).suffix() ==
"")
5102 else if(b != QMessageBox::Discard)
5116 UERROR(
"This method can be called only in IDLE state.");
5126 dbSettingsIn.beginGroup(
"DatabaseViewer");
5127 dbSettingsOut.beginGroup(
"DatabaseViewer");
5128 QStringList keys = dbSettingsIn.childKeys();
5129 for(QStringList::iterator iter = keys.begin(); iter!=keys.end(); ++iter)
5131 dbSettingsOut.setValue(*iter, dbSettingsIn.value(*iter));
5133 dbSettingsIn.endGroup();
5134 dbSettingsOut.endGroup();
5138 viewer->setWindowModality(Qt::WindowModal);
5139 viewer->setAttribute(Qt::WA_DeleteOnClose,
true);
5144 viewer->showMaximized();
5175 float detectionRate =
uStr2Float(parameters.at(Parameters::kRtabmapDetectionRate()));
5176 int bufferingSize =
uStr2Float(parameters.at(Parameters::kRtabmapImageBufferSize()));
5177 if(((detectionRate!=0.0
f && detectionRate <= inputRate) || (detectionRate > 0.0
f && inputRate == 0.0
f)) &&
5180 int button = QMessageBox::question(
this,
5181 tr(
"Incompatible frame rates!"),
5182 tr(
"\"Source/Input rate\" (%1 Hz) is equal to/higher than \"RTAB-Map/Detection rate\" (%2 Hz). As the " 5183 "source input is a directory of images/video/database, some images may be " 5184 "skipped by the detector. You may want to increase the \"RTAB-Map/Detection rate\" over " 5185 "the \"Source/Input rate\" to guaranty that all images are processed. Would you want to " 5186 "start the detection anyway?").arg(inputRate).arg(detectionRate),
5187 QMessageBox::Yes | QMessageBox::No);
5188 if(button == QMessageBox::No)
5195 if(bufferingSize != 0)
5197 int button = QMessageBox::question(
this,
5198 tr(
"Some images may be skipped!"),
5199 tr(
"\"RTAB-Map/Images buffer size\" is not infinite (size=%1). As the " 5200 "source input is a directory of images/video/database, some images may be " 5201 "skipped by the detector if the \"Source/Input rate\" (which is %2 Hz) is higher than the " 5202 "rate at which RTAB-Map can process the images. You may want to set the " 5203 "\"RTAB-Map/Images buffer size\" to 0 (infinite) to guaranty that all " 5204 "images are processed. Would you want to start the detection " 5205 "anyway?").arg(bufferingSize).arg(inputRate),
5206 QMessageBox::Yes | QMessageBox::No);
5207 if(button == QMessageBox::No)
5212 else if(inputRate == 0)
5214 int button = QMessageBox::question(
this,
5215 tr(
"Large number of images may be buffered!"),
5216 tr(
"\"RTAB-Map/Images buffer size\" is infinite. As the " 5217 "source input is a directory of images/video/database and " 5218 "that \"Source/Input rate\" is infinite too, a lot of images " 5219 "could be buffered at the same time (e.g., reading all images " 5220 "of a directory at once). This could make the GUI not responsive. " 5221 "You may want to set \"Source/Input rate\" at the rate at " 5222 "which the images have been recorded. " 5223 "Would you want to start the detection " 5224 "anyway?").arg(bufferingSize).arg(inputRate),
5225 QMessageBox::Yes | QMessageBox::No);
5226 if(button == QMessageBox::No)
5239 QMessageBox::warning(
this,
5241 tr(
"A camera is running, stop it first."));
5242 UWARN(
"_camera is not null... it must be stopped first");
5250 QMessageBox::warning(
this,
5252 tr(
"No sources are selected. See Preferences->Source panel."));
5253 UWARN(
"No sources are selected. See Preferences->Source panel.");
5297 if(
uStr2Bool(parameters.at(Parameters::kRGBDEnabled()).c_str()))
5302 UWARN(
"Camera is not calibrated!");
5307 int button = QMessageBox::question(
this,
5308 tr(
"Camera is not calibrated!"),
5309 tr(
"RTAB-Map in metric SLAM mode cannot run with an uncalibrated camera. Do you want to calibrate the camera now?"),
5310 QMessageBox::Yes | QMessageBox::No);
5311 if(button == QMessageBox::Yes)
5321 UERROR(
"OdomThread must be already deleted here?!");
5328 UERROR(
"ImuThread must be already deleted here?!");
5340 odomParameters.erase(Parameters::kRtabmapPublishRAMUsage());
5341 int odomStrategy = Parameters::defaultOdomStrategy();
5344 UDEBUG(
"Odom gravitySigma=%f", gravitySigma);
5345 if(gravitySigma >= 0.0)
5349 if(odomStrategy != 1)
5352 odomParameters.erase(Parameters::kVisCorType());
5362 QMessageBox::warning(
this, tr(
"Source IMU Path"),
5363 tr(
"IMU path is set but odometry chosen doesn't support IMU, ignoring IMU..."), QMessageBox::Ok);
5370 QMessageBox::warning(
this, tr(
"Source IMU Path"),
5406 _ui->actionReset_Odometry->setEnabled(
true);
5411 QMessageBox::information(
this,
5413 tr(
"Note that publishing statistics is disabled, " 5414 "progress will not be shown in the GUI."));
5420 #ifdef RTABMAP_OCTOMAP 5441 if(
_state ==
kPaused && (QApplication::keyboardModifiers() & Qt::ShiftModifier))
5461 UINFO(
"Sending pause event!");
5466 UINFO(
"Sending unpause event!");
5481 QMessageBox::StandardButton button = QMessageBox::question(
this, tr(
"Stopping process..."), tr(
"Are you sure you want to stop the process?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
5483 if(button != QMessageBox::Yes)
5503 _ui->actionReset_Odometry->setEnabled(
false);
5535 QMessageBox::information(
this,
5536 tr(
"No more images..."),
5537 tr(
"The camera has reached the end of the stream."));
5542 _ui->dockWidget_console->show();
5545 for(
int i = 0; i<
_refIds.size(); ++i)
5547 msgRef.append(QString::number(
_refIds[i]));
5552 msgLoop.append(
" ");
5555 _ui->widget_console->appendMsg(QString(
"IDs = [%1];").arg(msgRef));
5556 _ui->widget_console->appendMsg(QString(
"LoopIDs = [%1];").arg(msgLoop));
5567 int id = QInputDialog::getInt(
this, tr(
"Around which location?"), tr(
"Location ID (0=full map)"), 0, 0, 999999, 0, &ok);
5573 margin = QInputDialog::getInt(
this, tr(
"Depth around the location?"), tr(
"Margin"), 4, 1, 100, 1, &ok);
5578 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save File"),
_graphSavingFileName, tr(
"Graphiz file (*.dot)"));
5584 _ui->dockWidget_console->show();
5585 _ui->widget_console->appendMsg(QString(
"Graph saved... Tip:\nneato -Tpdf \"%1\" -o out.pdf").arg(
_graphSavingFileName));
5620 std::map<int, Transform> localTransforms;
5622 items.push_back(
"Robot (base frame)");
5623 items.push_back(
"Camera");
5624 items.push_back(
"Scan");
5626 QString item = QInputDialog::getItem(
this, tr(
"Export Poses"), tr(
"Frame: "), items,
_exportPosesFrame,
false, &ok);
5627 if(!ok || item.isEmpty())
5631 if(item.compare(
"Robot (base frame)") != 0)
5633 bool cameraFrame = item.compare(
"Camera") == 0;
5643 !
_cachedSignatures[iter->first].sensorData().cameraModels().at(0).localTransform().isNull()))
5645 localTransform =
_cachedSignatures[iter->first].sensorData().cameraModels().at(0).localTransform();
5647 else if(!
_cachedSignatures[iter->first].sensorData().stereoCameraModel().localTransform().isNull())
5649 localTransform =
_cachedSignatures[iter->first].sensorData().stereoCameraModel().localTransform();
5653 UWARN(
"Multi-camera is not supported (node %d)", iter->first);
5657 UWARN(
"Missing calibration for node %d", iter->first);
5662 if(!
_cachedSignatures[iter->first].sensorData().laserScanRaw().localTransform().isNull())
5664 localTransform =
_cachedSignatures[iter->first].sensorData().laserScanRaw().localTransform();
5666 else if(!
_cachedSignatures[iter->first].sensorData().laserScanCompressed().localTransform().isNull())
5668 localTransform =
_cachedSignatures[iter->first].sensorData().laserScanCompressed().localTransform();
5672 UWARN(
"Missing scan info for node %d", iter->first);
5675 if(!localTransform.
isNull())
5677 localTransforms.insert(std::make_pair(iter->first, localTransform));
5682 UWARN(
"Did not find node %d in cache", iter->first);
5685 if(localTransforms.empty())
5687 QMessageBox::warning(
this,
5689 tr(
"Could not find any \"%1\" frame, exporting in Robot frame instead.").arg(item));
5697 std::map<int, Transform> poses;
5698 std::multimap<int, Link> links;
5699 if(localTransforms.empty())
5707 for(std::map<int, Transform>::iterator iter=localTransforms.begin(); iter!=localTransforms.end(); ++iter)
5709 poses.insert(std::make_pair(iter->first,
_currentPosesMap.at(iter->first) * iter->second));
5715 std::multimap<int, Link>::iterator inserted = links.insert(*iter);
5716 int from = iter->second.from();
5717 int to = iter->second.to();
5718 inserted->second.setTransform(localTransforms.at(from).inverse()*iter->second.transform()*localTransforms.at(to));
5723 std::map<int, double> stamps;
5724 if(format == 1 || format == 10)
5726 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
5730 stamps.insert(std::make_pair(iter->first,
_cachedSignatures.value(iter->first).getStamp()));
5733 if(stamps.size()!=poses.size())
5735 QMessageBox::warning(
this, tr(
"Export poses..."), tr(
"RGB-D SLAM format: Poses (%1) and stamps (%2) have not the same size! Try again after updating the cache.")
5736 .arg(poses.size()).arg(stamps.size()));
5746 QString path = QFileDialog::getSaveFileName(
5750 format == 3?tr(
"TORO file (*.graph)"):format==4?tr(
"g2o file (*.g2o)"):tr(
"Text file (*.txt)"));
5754 if(QFileInfo(path).suffix() ==
"")
5775 QMessageBox::information(
this,
5776 tr(
"Export poses..."),
5777 tr(
"%1 saved to \"%2\".")
5778 .arg(format == 3?
"TORO graph":format == 4?
"g2o graph":
"Poses")
5783 QMessageBox::information(
this,
5784 tr(
"Export poses..."),
5785 tr(
"Failed to save %1 to \"%2\"!")
5786 .arg(format == 3?
"TORO graph":format == 4?
"g2o graph":
"poses")
5797 QMessageBox::warning(
this,
5798 tr(
"Post-processing..."),
5799 tr(
"Signatures must be cached in the GUI for post-processing. " 5800 "Check the option in Preferences->General Settings (GUI), then " 5801 "refresh the cache."));
5821 if(!detectMoreLoopClosures && !refineNeighborLinks && !refineLoopClosureLinks && !sba)
5823 UWARN(
"No post-processing selection...");
5829 UWARN(
"No nodes to process...");
5834 std::map<int, Transform> odomPoses;
5835 bool allDataAvailable =
true;
5836 for(std::map<int, Transform>::iterator iter =
_currentPosesMap.lower_bound(1);
5843 UWARN(
"Node %d missing.", iter->first);
5844 allDataAvailable =
false;
5846 else if(!jter.value().getPose().isNull())
5848 odomPoses.insert(std::make_pair(iter->first, jter.value().getPose()));
5852 if(!allDataAvailable)
5854 QMessageBox::warning(
this, tr(
"Not all data available in the GUI..."),
5855 tr(
"Some data missing in the cache to respect the constraints chosen. " 5856 "Try \"Edit->Download all clouds\" to update the cache and try again."));
5868 if(refineNeighborLinks)
5872 if(refineLoopClosureLinks)
5885 bool optimizeFromGraphEnd = Parameters::defaultRGBDOptimizeFromGraphEnd();
5886 float optimizeMaxError = Parameters::defaultRGBDOptimizeMaxError();
5887 int optimizeIterations = Parameters::defaultOptimizerIterations();
5888 bool reextractFeatures = Parameters::defaultRGBDLoopClosureReextractFeatures();
5889 Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), optimizeFromGraphEnd);
5890 Parameters::parse(parameters, Parameters::kRGBDOptimizeMaxError(), optimizeMaxError);
5891 Parameters::parse(parameters, Parameters::kOptimizerIterations(), optimizeIterations);
5892 Parameters::parse(parameters, Parameters::kRGBDLoopClosureReextractFeatures(), reextractFeatures);
5895 int loopClosuresAdded = 0;
5896 std::multimap<int, int> checkedLoopClosures;
5897 if(detectMoreLoopClosures)
5901 bool loopCovLimited = Parameters::defaultRGBDLoopCovLimited();
5902 Parameters::parse(parameters, Parameters::kRGBDLoopCovLimited(), loopCovLimited);
5903 std::vector<double> odomMaxInf;
5909 UASSERT(detectLoopClosureIterations>0);
5914 _progressDialog->
appendText(tr(
"Looking for more loop closures, clustering poses... (iteration=%1/%2, radius=%3 m angle=%4 degrees)")
5915 .arg(n+1).arg(detectLoopClosureIterations).arg(clusterRadius).arg(clusterAngle));
5920 clusterAngle*CV_PI/180.0);
5923 _progressDialog->
appendText(tr(
"Looking for more loop closures, clustering poses... found %1 clusters.").arg(clusters.size()));
5924 QApplication::processEvents();
5927 std::set<int> addedLinks;
5928 for(std::multimap<int, int>::iterator iter=clusters.begin(); iter!= clusters.end() && !
_progressCanceled; ++iter, ++i)
5930 int from = iter->first;
5931 int to = iter->second;
5932 if(iter->first < iter->second)
5934 from = iter->second;
5941 if((interSession && mapIdFrom != mapIdTo) ||
5942 (intraSession && mapIdFrom == mapIdTo))
5944 bool alreadyChecked =
false;
5945 for(std::multimap<int, int>::iterator jter = checkedLoopClosures.lower_bound(from);
5946 !alreadyChecked && jter!=checkedLoopClosures.end() && jter->first == from;
5949 if(to == jter->second)
5951 alreadyChecked =
true;
5958 if(addedLinks.find(from) == addedLinks.end() &&
5959 addedLinks.find(to) == addedLinks.end() &&
5962 checkedLoopClosures.insert(std::make_pair(from, to));
5966 UERROR(
"Didn't find signature %d", from);
5970 UERROR(
"Didn't find signature %d", to);
5982 if(parameters.find(Parameters::kRegStrategy()) != parameters.end() &&
5983 parameters.at(Parameters::kRegStrategy()).compare(
"1") == 0)
5989 if(reextractFeatures)
5997 UWARN(
"\"%s\" is false and signatures (%d and %d) don't have raw " 5998 "images. Update the cache.",
5999 Parameters::kRGBDLoopClosureReextractFeatures().c_str());
6004 signatureFrom.
sensorData().
setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
6006 signatureTo.
sensorData().
setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
6009 else if(!reextractFeatures && signatureFrom.
getWords().empty() && signatureTo.
getWords().empty())
6011 UWARN(
"\"%s\" is false and signatures (%d and %d) don't have words, " 6012 "registration will not be possible. Set \"%s\" to true.",
6013 Parameters::kRGBDLoopClosureReextractFeatures().c_str(),
6016 Parameters::kRGBDLoopClosureReextractFeatures().c_str());
6019 delete registration;
6020 if(!transform.isNull())
6023 bool updateConstraint =
true;
6025 if(odomMaxInf.size() == 6 && information.cols==6 && information.rows==6)
6027 for(
int i=0; i<6; ++i)
6029 if(information.at<
double>(i,i) > odomMaxInf[i])
6031 information.at<
double>(i,i) = odomMaxInf[i];
6035 if(optimizeMaxError > 0.0
f && optimizeIterations > 0)
6044 fromId = iter->first;
6050 const Link * maxLinearLink = 0;
6051 const Link * maxAngularLink = 0;
6052 float maxLinearError = 0.0f;
6053 float maxAngularError = 0.0f;
6054 std::map<int, Transform> poses;
6055 std::multimap<int, Link> links;
6060 UASSERT(poses.find(fromId) != poses.end());
6061 UASSERT_MSG(poses.find(from) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", from, (
int)poses.size(), (int)links.size()).c_str());
6062 UASSERT_MSG(poses.find(to) != poses.end(),
uFormat(
"id=%d poses=%d links=%d", to, (
int)poses.size(), (int)links.size()).c_str());
6064 poses = optimizer->
optimize(fromId, poses, links);
6068 float maxLinearErrorRatio = 0.0f;
6069 float maxAngularErrorRatio = 0.0f;
6073 maxLinearErrorRatio,
6074 maxAngularErrorRatio,
6081 UINFO(
"Max optimization linear error = %f m (link %d->%d)", maxLinearError, maxLinearLink->
from(), maxLinearLink->
to());
6082 if(maxLinearErrorRatio > optimizeMaxError)
6084 msg =
uFormat(
"Rejecting edge %d->%d because " 6085 "graph error is too large after optimization (%f m for edge %d->%d with ratio %f > std=%f m). " 6090 maxLinearLink->
from(),
6091 maxLinearLink->
to(),
6092 maxLinearErrorRatio,
6094 Parameters::kRGBDOptimizeMaxError().c_str(),
6098 else if(maxAngularLink)
6100 UINFO(
"Max optimization angular error = %f deg (link %d->%d)", maxAngularError*180.0
f/
M_PI, maxAngularLink->
from(), maxAngularLink->
to());
6101 if(maxAngularErrorRatio > optimizeMaxError)
6103 msg =
uFormat(
"Rejecting edge %d->%d because " 6104 "graph error is too large after optimization (%f deg for edge %d->%d with ratio %f > std=%f deg). " 6108 maxAngularError*180.0
f/
M_PI,
6109 maxAngularLink->
from(),
6110 maxAngularLink->
to(),
6111 maxAngularErrorRatio,
6113 Parameters::kRGBDOptimizeMaxError().c_str(),
6120 msg =
uFormat(
"Rejecting edge %d->%d because graph optimization has failed!",
6126 UWARN(
"%s", msg.c_str());
6128 QApplication::processEvents();
6129 updateConstraint =
false;
6133 if(updateConstraint)
6135 UINFO(
"Added new loop closure between %d and %d.", from, to);
6136 addedLinks.insert(from);
6137 addedLinks.insert(to);
6140 ++loopClosuresAdded;
6141 _progressDialog->
appendText(tr(
"Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size()));
6149 QApplication::processEvents();
6152 _progressDialog->
appendText(tr(
"Iteration %1/%2: Detected %3 loop closures!").arg(n+1).arg(detectLoopClosureIterations).arg(addedLinks.size()/2));
6153 if(addedLinks.size() == 0)
6158 if(n+1 < detectLoopClosureIterations)
6162 QApplication::processEvents();
6166 std::map<int, rtabmap::Transform> posesOut;
6167 std::multimap<int, rtabmap::Link> linksOut;
6168 std::map<int, rtabmap::Transform> optimizedPoses;
6176 optimizedPoses = optimizer->
optimize(fromId, posesOut, linksOut);
6181 UINFO(
"Added %d loop closures.", loopClosuresAdded);
6188 if(refineLoopClosureLinks)
6194 QApplication::processEvents();
6201 int type = iter->second.type();
6202 int from = iter->second.from();
6203 int to = iter->second.to();
6210 QApplication::processEvents();
6214 UERROR(
"Didn't find signature %d",from);
6218 UERROR(
"Didn't find signature %d", to);
6237 Link newLink(from, to, iter->second.type(), transform, info.
covariance.inv());
6238 iter->second = newLink;
6242 QString str = tr(
"Cannot refine link %1->%2 (%3").arg(from).arg(to).arg(info.
rejectedMsg.c_str());
6244 UWARN(
"%s", str.toStdString().c_str());
6253 str = tr(
"Cannot refine link %1->%2 (Intermediate node detected!)").arg(from).arg(to);
6257 str = tr(
"Cannot refine link %1->%2 (scans empty!)").arg(from).arg(to);
6261 UWARN(
"%s", str.toStdString().c_str());
6275 std::map<int, rtabmap::Transform> posesOut;
6276 std::multimap<int, rtabmap::Link> linksOut;
6277 std::map<int, rtabmap::Transform> optimizedPoses;
6285 optimizedPoses = optimizer->
optimize(fromId, posesOut, linksOut);
6293 .arg(optimizedPoses.size()).arg(linksOut.size()).arg(sbaIterations));
6294 QApplication::processEvents();
6296 QApplication::processEvents();
6299 uInsert(parametersSBA, std::make_pair(Parameters::kOptimizerIterations(),
uNumber2Str(sbaIterations)));
6300 uInsert(parametersSBA, std::make_pair(Parameters::kg2oPixelVariance(),
uNumber2Str(sbaVariance)));
6302 std::map<int, Transform> newPoses = sbaOptimizer->
optimizeBA(optimizedPoses.begin()->first, optimizedPoses, linksOut,
_cachedSignatures.toStdMap(), sbaRematchFeatures);
6303 delete sbaOptimizer;
6306 optimizedPoses = newPoses;
6352 QMessageBox::warning(
this, tr(
"Depth Calibration"), tr(
"No data in cache. Try to refresh the cache."));
6358 QMessageBox::StandardButton button;
6361 button = QMessageBox::question(
this,
6362 tr(
"Deleting memory..."),
6363 tr(
"The remote database and log files will be deleted. Are you sure you want to continue? (This cannot be reverted)"),
6364 QMessageBox::Yes|QMessageBox::No,
6369 button = QMessageBox::question(
this,
6370 tr(
"Deleting memory..."),
6371 tr(
"The current database and log files will be deleted. Are you sure you want to continue? (This cannot be reverted)"),
6372 QMessageBox::Yes|QMessageBox::No,
6376 if(button != QMessageBox::Yes)
6397 #if defined(Q_WS_MAC) 6400 args <<
"tell application \"Finder\"";
6404 args <<
"select POSIX file \""+filePath+
"\"";
6407 QProcess::startDetached(
"osascript", args);
6408 #elif defined(Q_WS_WIN) 6410 args <<
"/select," << QDir::toNativeSeparators(filePath);
6411 QProcess::startDetached(
"explorer", args);
6413 UERROR(
"Only works on Mac and Windows");
6534 UINFO(
"Sending a goal...");
6536 QString text = QInputDialog::getText(
this, tr(
"Send a goal"), tr(
"Goal location ID or label: "), QLineEdit::Normal,
"", &ok);
6537 if(ok && !text.isEmpty())
6548 UINFO(
"Sending waypoints...");
6550 QString text = QInputDialog::getText(
this, tr(
"Send waypoints"), tr(
"Waypoint IDs or labels (separated by spaces): "), QLineEdit::Normal,
"", &ok);
6551 if(ok && !text.isEmpty())
6553 QStringList wp = text.split(
' ');
6556 QMessageBox::warning(
this, tr(
"Send waypoints"), tr(
"At least two waypoints should be set. For only one goal, use send goal action."));
6572 int id = goal.toInt(&ok);
6573 _ui->graphicsView_graphView->setGlobalPath(std::vector<std::pair<int, Transform> >());
6574 UINFO(
"Posting event with goal %s", goal.toStdString().c_str());
6588 UINFO(
"Cancelling goal...");
6596 UINFO(
"Labelling current location...");
6598 QString
label = QInputDialog::getText(
this, tr(
"Label current location"), tr(
"Label: "), QLineEdit::Normal,
"", &ok);
6599 if(ok && !label.isEmpty())
6608 QString path = QFileDialog::getOpenFileName(
this, tr(
"Select file"), dir, tr(
"RTAB-Map database files (*.db)"));
6622 UINFO(
"Update cache...");
6630 std::list<Signature*> signaturesList;
6631 driver->
loadSignatures(std::list<int>(ids.begin(), ids.end()), signaturesList);
6632 std::map<int, Signature> signatures;
6634 for(std::list<Signature *>::iterator iter=signaturesList.begin(); iter!=signaturesList.end(); ++iter)
6636 signatures.insert(std::make_pair((*iter)->id(), *(*iter)));
6644 QMessageBox::warning(
this, tr(
"Update cache"), tr(
"Failed to open database \"%1\"").arg(path));
6653 items.append(
"Local map optimized");
6654 items.append(
"Local map not optimized");
6655 items.append(
"Global map optimized");
6656 items.append(
"Global map not optimized");
6659 QString item = QInputDialog::getItem(
this, tr(
"Download map"), tr(
"Options:"), items, 2,
false, &ok);
6662 bool optimized=
false, global=
false;
6663 if(item.compare(
"Local map optimized") == 0)
6667 else if(item.compare(
"Local map not optimized") == 0)
6671 else if(item.compare(
"Global map optimized") == 0)
6676 else if(item.compare(
"Global map not optimized") == 0)
6682 UFATAL(
"Item \"%s\" not found?!?", item.toStdString().c_str());
6685 UINFO(
"Download clouds...");
6689 .arg(global?
"true":
"false").arg(optimized?
"true":
"false"));
6697 items.append(
"Local map optimized");
6698 items.append(
"Local map not optimized");
6699 items.append(
"Global map optimized");
6700 items.append(
"Global map not optimized");
6703 QString item = QInputDialog::getItem(
this, tr(
"Download graph"), tr(
"Options:"), items, 2,
false, &ok);
6706 bool optimized=
false, global=
false;
6707 if(item.compare(
"Local map optimized") == 0)
6711 else if(item.compare(
"Local map not optimized") == 0)
6715 else if(item.compare(
"Global map optimized") == 0)
6720 else if(item.compare(
"Global map not optimized") == 0)
6726 UFATAL(
"Item \"%s\" not found?!?", item.toStdString().c_str());
6729 UINFO(
"Download the graph...");
6733 .arg(global?
"true":
"false").arg(optimized?
"true":
"false"));
6766 _ui->widget_mapVisibility->clear();
6774 _ui->statsToolBox->clear();
6776 _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(
false);
6777 _ui->actionPost_processing->setEnabled(
false);
6778 _ui->actionSave_point_cloud->setEnabled(
false);
6779 _ui->actionExport_cameras_in_Bundle_format_out->setEnabled(
false);
6780 _ui->actionDepth_Calibration->setEnabled(
false);
6781 _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(
false);
6782 _ui->actionExport_octomap->setEnabled(
false);
6783 _ui->actionView_high_res_point_cloud->setEnabled(
false);
6790 _ui->label_stats_loopClosuresDetected->setText(
"0");
6791 _ui->label_stats_loopClosuresReactivatedDetected->setText(
"0");
6792 _ui->label_stats_loopClosuresRejected->setText(
"0");
6796 _ui->label_refId->clear();
6797 _ui->label_matchId->clear();
6798 _ui->graphicsView_graphView->clearAll();
6799 _ui->imageView_source->clear();
6800 _ui->imageView_loopClosure->clear();
6801 _ui->imageView_odometry->clear();
6802 _ui->imageView_source->setBackgroundColor(
_ui->imageView_source->getDefaultBackgroundColor());
6803 _ui->imageView_loopClosure->setBackgroundColor(
_ui->imageView_loopClosure->getDefaultBackgroundColor());
6804 _ui->imageView_odometry->setBackgroundColor(
_ui->imageView_odometry->getDefaultBackgroundColor());
6805 #ifdef RTABMAP_OCTOMAP 6819 QDesktopServices::openUrl(QUrl(
"http://wiki.ros.org/rtabmap_ros"));
6823 QDesktopServices::openUrl(QUrl(
"https://github.com/introlab/rtabmap/wiki"));
6831 QString format =
"hh:mm:ss";
6832 _ui->label_elapsedTime->setText((QTime().fromString(
_ui->label_elapsedTime->text(), format).addMSecs(
_elapsedTime->restart())).toString(format));
6838 QList<int> curvesPerFigure;
6839 QStringList curveNames;
6840 _ui->statsToolBox->getFiguresSetup(curvesPerFigure, curveNames);
6842 QStringList curvesPerFigureStr;
6843 for(
int i=0; i<curvesPerFigure.size(); ++i)
6845 curvesPerFigureStr.append(QString::number(curvesPerFigure[i]));
6847 for(
int i=0; i<curveNames.size(); ++i)
6849 curveNames[i].replace(
' ',
'_');
6860 if(!curvesPerFigure.isEmpty())
6862 QStringList curvesPerFigureList = curvesPerFigure.split(
" ");
6863 QStringList curvesNamesList = curveNames.split(
" ");
6866 for(
int i=0; i<curvesPerFigureList.size(); ++i)
6869 int count = curvesPerFigureList[i].toInt(&ok);
6872 QMessageBox::warning(
this,
"Loading failed",
"Corrupted figures setup...");
6877 _ui->statsToolBox->addCurve(curvesNamesList[j++].replace(
'_',
' '));
6878 for(
int k=1; k<count && j<curveNames.size(); ++k)
6880 _ui->statsToolBox->addCurve(curvesNamesList[j++].replace(
'_',
' '),
false);
6903 _ui->dockWidget_posterior->setVisible(
false);
6904 _ui->dockWidget_likelihood->setVisible(
false);
6905 _ui->dockWidget_rawlikelihood->setVisible(
false);
6906 _ui->dockWidget_statsV2->setVisible(
false);
6907 _ui->dockWidget_console->setVisible(
false);
6908 _ui->dockWidget_loopClosureViewer->setVisible(
false);
6909 _ui->dockWidget_mapVisibility->setVisible(
false);
6910 _ui->dockWidget_graphViewer->setVisible(
false);
6911 _ui->dockWidget_odometry->setVisible(
true);
6912 _ui->dockWidget_cloudViewer->setVisible(
true);
6913 _ui->dockWidget_imageView->setVisible(
true);
6915 _ui->toolBar_2->setVisible(
true);
6916 _ui->statusbar->setVisible(
false);
6928 items << QString(
"Synchronize with map update") << QString(
"Synchronize with odometry update");
6930 QString item = QInputDialog::getItem(
this, tr(
"Select synchronization behavior"), tr(
"Sync:"), items, 0,
false, &ok);
6931 if(ok && !item.isEmpty())
6933 if(item.compare(
"Synchronize with map update") == 0)
6944 int r = QMessageBox::question(
this, tr(
"Hard drive or RAM?"), tr(
"Save in RAM? Images will be saved on disk when clicking auto screen capture again."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
6945 if(r == QMessageBox::No || r == QMessageBox::Yes)
6951 _ui->actionAuto_screen_capture->setChecked(
false);
6954 r = QMessageBox::question(
this, tr(
"Save in JPEG?"), tr(
"Save in JPEG format? Otherwise they are saved in PNG."), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
6955 if(r == QMessageBox::No || r == QMessageBox::Yes)
6961 _ui->actionAuto_screen_capture->setChecked(
false);
6967 _ui->actionAuto_screen_capture->setChecked(
false);
6974 if(!dir.exists(targetDir))
6976 dir.mkdir(targetDir);
6978 targetDir += QDir::separator();
6979 targetDir +=
"Main_window";
6980 if(!dir.exists(targetDir))
6982 dir.mkdir(targetDir);
6984 targetDir += QDir::separator();
6998 QApplication::processEvents();
7008 QDesktopServices::openUrl(QUrl::fromLocalFile(this->
captureScreen()));
7013 QRect rect = this->geometry();
7017 if(
float(rect.width())/
float(rect.height()) >
float(w)/float(h))
7019 rect.setWidth(w*(rect.height()/h));
7020 rect.setHeight((rect.height()/h)*h);
7024 rect.setHeight(h*(rect.width()/w));
7025 rect.setWidth((rect.width()/w)*w);
7034 this->setGeometry(rect);
7080 int width = QInputDialog::getInt(
this, tr(
"Aspect ratio"), tr(
"Width (pixels):"), this->geometry().width(), 100, 10000, 100, &ok);
7083 int height = QInputDialog::getInt(
this, tr(
"Aspect ratio"), tr(
"Height (pixels):"), this->geometry().height(), 100, 10000, 100, &ok);
7093 float gridCellSize = 0.05f;
7095 gridCellSize = (float)QInputDialog::getDouble(
this, tr(
"Grid cell size"), tr(
"Size (m):"), (double)gridCellSize, 0.01, 1, 2, &ok);
7102 float xMin=0.0f, yMin=0.0f;
7104 #ifdef RTABMAP_OCTOMAP 7118 cv::Mat map8U(pixels.rows, pixels.cols, CV_8U);
7120 for (
int i = 0; i < pixels.rows; ++i)
7122 for (
int j = 0; j < pixels.cols; ++j)
7124 char v = pixels.at<
char>(i, j);
7138 map8U.at<
unsigned char>(i, j) = gray;
7144 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save to ..."),
"grid.png", tr(
"Image (*.png *.bmp)"));
7147 if(QFileInfo(path).suffix() !=
"png" && QFileInfo(path).suffix() !=
"bmp")
7153 QImage img = image.mirrored(
false,
true).transformed(QTransform().
rotate(-90));
7154 QPixmap::fromImage(img).save(path);
7156 QDesktopServices::openUrl(QUrl::fromLocalFile(path));
7168 std::map<int, Transform> poses =
_ui->widget_mapVisibility->getVisiblePoses();
7173 for(std::map<int, Transform>::iterator iter = poses.begin(); iter!=poses.end(); ++iter)
7178 iter->second = gtIter->second;
7182 UWARN(
"Not found ground truth pose for node %d", iter->first);
7205 std::map<int, Transform> poses =
_ui->widget_mapVisibility->getVisiblePoses();
7210 for(std::map<int, Transform>::iterator iter = poses.begin(); iter!=poses.end(); ++iter)
7215 iter->second = gtIter->second;
7219 UWARN(
"Not found ground truth pose for node %d", iter->first);
7238 #ifdef RTABMAP_OCTOMAP 7241 QString path = QFileDialog::getSaveFileName(
7245 tr(
"Octomap file (*.bt)"));
7251 QMessageBox::information(
this,
7252 tr(
"Export octomap..."),
7253 tr(
"Octomap successfully saved to \"%1\".")
7258 QMessageBox::information(
this,
7259 tr(
"Export octomap..."),
7260 tr(
"Failed to save octomap to \"%1\"!")
7267 UERROR(
"Empty octomap.");
7270 UERROR(
"Cannot export octomap, RTAB-Map is not built with it.");
7278 QMessageBox::warning(
this, tr(
"Export images..."), tr(
"Cannot export images, the cache is empty!"));
7281 std::map<int, Transform> poses =
_ui->widget_mapVisibility->getVisiblePoses();
7285 QMessageBox::warning(
this, tr(
"Export images..."), tr(
"There is no map!"));
7289 QStringList formats;
7290 formats.push_back(
"jpg");
7291 formats.push_back(
"png");
7293 QString ext = QInputDialog::getItem(
this, tr(
"Which RGB format?"), tr(
"Format:"), formats, 0,
false, &ok);
7299 QString path = QFileDialog::getExistingDirectory(
this, tr(
"Select directory where to save images..."), this->
getWorkingDirectory());
7311 dir.mkdir(QString(
"%1/left").arg(path));
7312 dir.mkdir(QString(
"%1/right").arg(path));
7315 std::string cameraName =
"calibration";
7333 if(model.save(path.toStdString()))
7335 UINFO(
"Saved stereo calibration \"%s\"", (path.toStdString()+
"/"+cameraName).c_str());
7339 UERROR(
"Failed saving calibration \"%s\"", (path.toStdString()+
"/"+cameraName).c_str());
7348 dir.mkdir(QString(
"%1/rgb").arg(path));
7349 dir.mkdir(QString(
"%1/depth").arg(path));
7354 UERROR(
"Only one camera calibration can be saved at this time (%d detected)", (
int)data.
cameraModels().size());
7358 std::string cameraName =
"calibration";
7366 if(model.save(path.toStdString()))
7368 UINFO(
"Saved calibration \"%s\"", (path.toStdString()+
"/"+cameraName).c_str());
7372 UERROR(
"Failed saving calibration \"%s\"", (path.toStdString()+
"/"+cameraName).c_str());
7378 QMessageBox::warning(
this,
7379 tr(
"Export images..."),
7380 tr(
"Data in the cache don't seem to have images (tested node %1). Calibration file will not be saved. Try refreshing the cache (with clouds).").arg(poses.rbegin()->first));
7387 unsigned int saved = 0;
7388 for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
7390 int id = iter->first;
7401 cv::imwrite(QString(
"%1/left/%2.%3").arg(path).arg(
id).arg(ext).toStdString(), data.
imageRaw());
7402 cv::imwrite(QString(
"%1/right/%2.%3").arg(path).arg(
id).arg(ext).toStdString(), data.
rightRaw());
7403 info = tr(
"Saved left/%1.%2 and right/%1.%2.").arg(
id).arg(ext);
7407 cv::imwrite(QString(
"%1/rgb/%2.%3").arg(path).arg(
id).arg(ext).toStdString(), data.
imageRaw());
7409 info = tr(
"Saved rgb/%1.%2 and depth/%1.png.").arg(
id).arg(ext);
7413 cv::imwrite(QString(
"%1/%2.%3").arg(path).arg(
id).arg(ext).toStdString(), data.
imageRaw());
7414 info = tr(
"Saved %1.%2.").arg(
id).arg(ext);
7418 info = tr(
"No images saved for node %1!").arg(
id);
7424 QApplication::processEvents();
7427 if(saved!=poses.size())
7448 std::map<int, Transform> posesIn =
_ui->widget_mapVisibility->getVisiblePoses();
7453 for(std::map<int, Transform>::iterator iter = posesIn.begin(); iter!=posesIn.end(); ++iter)
7458 iter->second = gtIter->second;
7462 UWARN(
"Not found ground truth pose for node %d", iter->first);
7467 std::map<int, Transform> poses;
7468 for(std::map<int, Transform>::iterator iter=posesIn.begin(); iter!=posesIn.end(); ++iter)
7475 UWARN(
"Missing image in cache for node %d", iter->first);
7477 else if((
_cachedSignatures[iter->first].sensorData().cameraModels().size() == 1 &&
_cachedSignatures[iter->first].sensorData().cameraModels().at(0).isValidForProjection()) ||
7478 _cachedSignatures[iter->first].sensorData().stereoCameraModel().isValidForProjection())
7480 poses.insert(*iter);
7484 UWARN(
"Missing calibration for node %d", iter->first);
7489 UWARN(
"Did not find node %d in cache", iter->first);
7503 QMessageBox::warning(
this, tr(
"Exporting cameras..."), tr(
"No poses exported because of missing images. Try refreshing the cache (with clouds)."));
7509 UINFO(
"reset odometry");
7515 UINFO(
"trigger a new map");
7526 int r = QMessageBox::question(
this, tr(
"Hard drive or RAM?"), tr(
"Save in RAM?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
7528 if(r == QMessageBox::No || r == QMessageBox::Yes)
7530 bool recordInRAM = r == QMessageBox::Yes;
7535 _dataRecorder->setWindowTitle(tr(
"Data recorder (%1)").arg(path));
7546 _ui->actionData_recorder->setEnabled(
false);
7550 QMessageBox::warning(
this, tr(
""), tr(
"Cannot initialize the data recorder!"));
7551 UERROR(
"Cannot initialize the data recorder!");
7560 UERROR(
"Only one recorder at the same time.");
7566 _ui->actionData_recorder->setEnabled(
true);
7584 _ui->label_source->setVisible(!monitoring);
7585 _ui->label_stats_source->setVisible(!monitoring);
7586 _ui->actionNew_database->setVisible(!monitoring);
7587 _ui->actionOpen_database->setVisible(!monitoring);
7588 _ui->actionClose_database->setVisible(!monitoring);
7589 _ui->actionEdit_database->setVisible(!monitoring);
7590 _ui->actionStart->setVisible(!monitoring);
7591 _ui->actionStop->setVisible(!monitoring);
7592 _ui->actionDump_the_memory->setVisible(!monitoring);
7593 _ui->actionDump_the_prediction_matrix->setVisible(!monitoring);
7594 _ui->actionGenerate_map->setVisible(!monitoring);
7595 _ui->actionUpdate_cache_from_database->setVisible(monitoring);
7596 _ui->actionData_recorder->setVisible(!monitoring);
7597 _ui->menuSelect_source->menuAction()->setVisible(!monitoring);
7598 _ui->doubleSpinBox_stats_imgRate->setVisible(!monitoring);
7599 _ui->doubleSpinBox_stats_imgRate_label->setVisible(!monitoring);
7601 if(wasMonitoring != monitoring)
7603 _ui->toolBar->setVisible(!monitoring);
7604 _ui->toolBar->toggleViewAction()->setVisible(!monitoring);
7606 QList<QAction*> actions =
_ui->menuTools->actions();
7607 for(
int i=0; i<actions.size(); ++i)
7609 if(actions.at(i)->isSeparator())
7611 actions.at(i)->setVisible(!monitoring);
7614 actions =
_ui->menuFile->actions();
7615 if(actions.size()==16)
7617 if(actions.at(2)->isSeparator())
7619 actions.at(2)->setVisible(!monitoring);
7623 UWARN(
"Menu File separators have not the same order.");
7625 if(actions.at(12)->isSeparator())
7627 actions.at(12)->setVisible(!monitoring);
7631 UWARN(
"Menu File separators have not the same order.");
7636 UWARN(
"Menu File actions size has changed (%d)", actions.size());
7638 actions =
_ui->menuProcess->actions();
7639 if(actions.size()>=2)
7641 if(actions.at(1)->isSeparator())
7643 actions.at(1)->setVisible(!monitoring);
7647 UWARN(
"Menu File separators have not the same order.");
7652 UWARN(
"Menu File separators have not the same order.");
7660 _ui->actionNew_database->setEnabled(
true);
7661 _ui->actionOpen_database->setEnabled(
true);
7662 _ui->actionClose_database->setEnabled(
false);
7663 _ui->actionEdit_database->setEnabled(
true);
7664 _ui->actionStart->setEnabled(
false);
7665 _ui->actionPause->setEnabled(
false);
7666 _ui->actionPause->setChecked(
false);
7667 _ui->actionPause->setToolTip(tr(
"Pause"));
7668 _ui->actionStop->setEnabled(
false);
7669 _ui->actionPause_on_match->setEnabled(
true);
7670 _ui->actionPause_on_local_loop_detection->setEnabled(
true);
7671 _ui->actionPause_when_a_loop_hypothesis_is_rejected->setEnabled(
true);
7672 _ui->actionDump_the_memory->setEnabled(
false);
7673 _ui->actionDump_the_prediction_matrix->setEnabled(
false);
7674 _ui->actionDelete_memory->setEnabled(
false);
7677 _ui->actionGenerate_map->setEnabled(
false);
7682 #ifdef RTABMAP_OCTOMAP 7685 _ui->actionExport_octomap->setEnabled(
false);
7689 _ui->actionDownload_all_clouds->setEnabled(
false);
7690 _ui->actionDownload_graph->setEnabled(
false);
7691 _ui->menuSelect_source->setEnabled(
true);
7692 _ui->actionLabel_current_location->setEnabled(
false);
7693 _ui->actionSend_goal->setEnabled(
false);
7694 _ui->actionCancel_goal->setEnabled(
false);
7695 _ui->toolBar->findChild<QAction*>(
"toolbar_source")->setEnabled(
true);
7696 _ui->actionTrigger_a_new_map->setEnabled(
false);
7697 _ui->doubleSpinBox_stats_imgRate->setEnabled(
true);
7698 _ui->statusbar->clearMessage();
7705 _ui->actionStart->setEnabled(
false);
7706 _ui->actionPause->setEnabled(
false);
7707 _ui->actionStop->setEnabled(
false);
7712 _ui->actionNew_database->setEnabled(
false);
7713 _ui->actionOpen_database->setEnabled(
false);
7714 _ui->actionClose_database->setEnabled(
false);
7715 _ui->actionEdit_database->setEnabled(
false);
7720 _ui->actionNew_database->setEnabled(
false);
7721 _ui->actionOpen_database->setEnabled(
false);
7722 _ui->actionClose_database->setEnabled(
true);
7723 _ui->actionEdit_database->setEnabled(
false);
7724 _ui->actionStart->setEnabled(
true);
7725 _ui->actionPause->setEnabled(
false);
7726 _ui->actionPause->setChecked(
false);
7727 _ui->actionPause->setToolTip(tr(
"Pause"));
7728 _ui->actionStop->setEnabled(
false);
7729 _ui->actionPause_on_match->setEnabled(
true);
7730 _ui->actionPause_on_local_loop_detection->setEnabled(
true);
7731 _ui->actionPause_when_a_loop_hypothesis_is_rejected->setEnabled(
true);
7732 _ui->actionDump_the_memory->setEnabled(
true);
7733 _ui->actionDump_the_prediction_matrix->setEnabled(
true);
7737 _ui->actionGenerate_map->setEnabled(
true);
7742 #ifdef RTABMAP_OCTOMAP 7745 _ui->actionExport_octomap->setEnabled(
false);
7749 _ui->actionDownload_all_clouds->setEnabled(
true);
7750 _ui->actionDownload_graph->setEnabled(
true);
7751 _ui->menuSelect_source->setEnabled(
true);
7752 _ui->actionLabel_current_location->setEnabled(
true);
7753 _ui->actionSend_goal->setEnabled(
true);
7754 _ui->actionCancel_goal->setEnabled(
true);
7755 _ui->toolBar->findChild<QAction*>(
"toolbar_source")->setEnabled(
true);
7756 _ui->actionTrigger_a_new_map->setEnabled(
true);
7757 _ui->doubleSpinBox_stats_imgRate->setEnabled(
true);
7758 _ui->statusbar->clearMessage();
7764 _ui->actionStart->setEnabled(
false);
7769 _ui->actionNew_database->setEnabled(
false);
7770 _ui->actionOpen_database->setEnabled(
false);
7771 _ui->actionClose_database->setEnabled(
false);
7772 _ui->actionEdit_database->setEnabled(
false);
7773 _ui->actionStart->setEnabled(
false);
7774 _ui->actionPause->setEnabled(
true);
7775 _ui->actionPause->setChecked(
false);
7776 _ui->actionPause->setToolTip(tr(
"Pause"));
7777 _ui->actionStop->setEnabled(
true);
7778 _ui->actionPause_on_match->setEnabled(
true);
7779 _ui->actionPause_on_local_loop_detection->setEnabled(
true);
7780 _ui->actionPause_when_a_loop_hypothesis_is_rejected->setEnabled(
true);
7781 _ui->actionDump_the_memory->setEnabled(
false);
7782 _ui->actionDump_the_prediction_matrix->setEnabled(
false);
7783 _ui->actionDelete_memory->setEnabled(
false);
7784 _ui->actionPost_processing->setEnabled(
false);
7785 _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(
false);
7786 _ui->actionGenerate_map->setEnabled(
false);
7787 _ui->menuExport_poses->setEnabled(
false);
7788 _ui->actionSave_point_cloud->setEnabled(
false);
7789 _ui->actionView_high_res_point_cloud->setEnabled(
false);
7790 _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(
false);
7791 _ui->actionExport_octomap->setEnabled(
false);
7792 _ui->actionExport_cameras_in_Bundle_format_out->setEnabled(
false);
7793 _ui->actionDepth_Calibration->setEnabled(
false);
7794 _ui->actionDownload_all_clouds->setEnabled(
false);
7795 _ui->actionDownload_graph->setEnabled(
false);
7796 _ui->menuSelect_source->setEnabled(
false);
7797 _ui->actionLabel_current_location->setEnabled(
true);
7798 _ui->actionSend_goal->setEnabled(
true);
7799 _ui->actionCancel_goal->setEnabled(
true);
7800 _ui->toolBar->findChild<QAction*>(
"toolbar_source")->setEnabled(
false);
7801 _ui->actionTrigger_a_new_map->setEnabled(
true);
7802 _ui->doubleSpinBox_stats_imgRate->setEnabled(
true);
7803 _ui->statusbar->showMessage(tr(
"Detecting..."));
7805 _ui->label_elapsedTime->setText(
"00:00:00");
7825 _ui->actionPause->setToolTip(tr(
"Pause"));
7826 _ui->actionPause->setChecked(
false);
7827 _ui->statusbar->showMessage(tr(
"Detecting..."));
7828 _ui->actionDump_the_memory->setEnabled(
false);
7829 _ui->actionDump_the_prediction_matrix->setEnabled(
false);
7830 _ui->actionDelete_memory->setEnabled(
false);
7831 _ui->actionPost_processing->setEnabled(
false);
7832 _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(
false);
7833 _ui->actionGenerate_map->setEnabled(
false);
7834 _ui->menuExport_poses->setEnabled(
false);
7835 _ui->actionSave_point_cloud->setEnabled(
false);
7836 _ui->actionView_high_res_point_cloud->setEnabled(
false);
7837 _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(
false);
7838 _ui->actionExport_octomap->setEnabled(
false);
7839 _ui->actionExport_cameras_in_Bundle_format_out->setEnabled(
false);
7840 _ui->actionDepth_Calibration->setEnabled(
false);
7841 _ui->actionDownload_all_clouds->setEnabled(
false);
7842 _ui->actionDownload_graph->setEnabled(
false);
7859 _ui->actionPause->setToolTip(tr(
"Continue (shift-click for step-by-step)"));
7860 _ui->actionPause->setChecked(
true);
7861 _ui->statusbar->showMessage(tr(
"Paused..."));
7862 _ui->actionDump_the_memory->setEnabled(
true);
7863 _ui->actionDump_the_prediction_matrix->setEnabled(
true);
7864 _ui->actionDelete_memory->setEnabled(
false);
7867 _ui->actionGenerate_map->setEnabled(
true);
7872 #ifdef RTABMAP_OCTOMAP 7875 _ui->actionExport_octomap->setEnabled(
false);
7879 _ui->actionDownload_all_clouds->setEnabled(
true);
7880 _ui->actionDownload_graph->setEnabled(
true);
7896 _ui->actionPause->setEnabled(
true);
7897 _ui->actionPause->setChecked(
false);
7898 _ui->actionPause->setToolTip(tr(
"Pause"));
7899 _ui->actionPause_on_match->setEnabled(
true);
7900 _ui->actionPause_on_local_loop_detection->setEnabled(
true);
7901 _ui->actionPause_when_a_loop_hypothesis_is_rejected->setEnabled(
true);
7902 _ui->actionReset_Odometry->setEnabled(
true);
7903 _ui->actionPost_processing->setEnabled(
false);
7904 _ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(
false);
7905 _ui->menuExport_poses->setEnabled(
false);
7906 _ui->actionSave_point_cloud->setEnabled(
false);
7907 _ui->actionView_high_res_point_cloud->setEnabled(
false);
7908 _ui->actionExport_2D_Grid_map_bmp_png->setEnabled(
false);
7909 _ui->actionExport_octomap->setEnabled(
false);
7910 _ui->actionExport_cameras_in_Bundle_format_out->setEnabled(
false);
7911 _ui->actionDepth_Calibration->setEnabled(
false);
7912 _ui->actionDelete_memory->setEnabled(
true);
7913 _ui->actionDownload_all_clouds->setEnabled(
true);
7914 _ui->actionDownload_graph->setEnabled(
true);
7915 _ui->actionTrigger_a_new_map->setEnabled(
true);
7916 _ui->actionLabel_current_location->setEnabled(
true);
7917 _ui->actionSend_goal->setEnabled(
true);
7918 _ui->actionCancel_goal->setEnabled(
true);
7919 _ui->statusbar->showMessage(tr(
"Monitoring..."));
7926 _ui->actionPause->setToolTip(tr(
"Continue"));
7927 _ui->actionPause->setChecked(
true);
7928 _ui->actionPause->setEnabled(
true);
7929 _ui->actionPause_on_match->setEnabled(
true);
7930 _ui->actionPause_on_local_loop_detection->setEnabled(
true);
7931 _ui->actionPause_when_a_loop_hypothesis_is_rejected->setEnabled(
true);
7932 _ui->actionReset_Odometry->setEnabled(
true);
7939 #ifdef RTABMAP_OCTOMAP 7942 _ui->actionExport_octomap->setEnabled(
false);
7946 _ui->actionDelete_memory->setEnabled(
true);
7947 _ui->actionDownload_all_clouds->setEnabled(
true);
7948 _ui->actionDownload_graph->setEnabled(
true);
7949 _ui->actionTrigger_a_new_map->setEnabled(
true);
7950 _ui->actionLabel_current_location->setEnabled(
true);
7951 _ui->actionSend_goal->setEnabled(
true);
7952 _ui->actionCancel_goal->setEnabled(
true);
7953 _ui->statusbar->showMessage(tr(
"Monitoring paused..."));
int getOctomapTreeDepth() const
const std::map< int, Transform > & getPoses() const
static void setPrintThreadId(bool printThreadId)
int UTILITE_EXP uStr2Int(const std::string &str)
const std::string & getInfo() const
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
double getCloudFilteringAngle() const
int getCloudColorScheme(int index) const
std::set< int > _cachedEmptyClouds
bool RTABMAP_EXP isFinite(const cv::Point3f &pt)
virtual void openPreferences()
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
bool isSourceDatabaseStampsUsed() const
void setAutoClose(bool on, int delayedClosingTimeMsec=-1)
int getIMUFilteringStrategy() const
bool update(const std::map< int, Transform > &poses)
double sbaVariance() const
int getNoiseMinNeighbors() const
void incrementStep(int steps=1)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP subtractFiltering(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &substractCloud, float radiusSearch, int minNeighborsInRadius=1)
DepthCalibrationDialog * _depthCalibrationDialog
virtual void processStats(const rtabmap::Statistics &stat)
void setAspectRatio(int w, int h)
std::vector< cv::Point2f > refCorners
Camera * createCamera(bool useRawImages=false, bool useColor=true)
void changeImgRateSetting()
double getScanMinRange(int index) const
void saveMainWindowState(const QMainWindow *mainWindow)
int getGeneralLoggerPauseLevel() const
void updateParameters(const ParametersMap ¶meters, bool setOtherParametersToDefault=false)
void clearRawData(bool images=true, bool scan=true, bool userData=true)
QString getIMUPath() const
int getScanNormalKSearch() const
static void createPipe(const UEventsSender *sender, const UEventsHandler *receiver, const std::string &eventName)
bool isOdomOnlyInliersShown() const
bool getGridMapShown() const
void applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags)
std::map< int, CameraModel > localBundleModels
void setStereoExposureCompensation(bool enabled)
const std::map< int, std::string > & labels() const
Transform transformGroundTruth
virtual ParametersMap getCustomParameters()
const cv::Vec4d & orientation() const
float getCellSize() const
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
void exportBundler(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const QMap< int, Signature > &signatures, const ParametersMap ¶meters)
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
bool isCloudMeshingQuad() const
double getSubtractFilteringRadius() const
void setCancelButtonVisible(bool visible)
bool init(const std::string &path)
int getGeneralLoggerLevel() const
virtual Camera * createCamera()
double getCeilingFilteringHeight() const
bool isIMUGravityShown(int index) const
const LaserScan & laserScanCompressed() const
QString _newDatabasePathOutput
const Transform & getGroundTruthPose() const
const cv::Mat & R() const
double UTILITE_EXP uStr2Double(const std::string &str)
void updateCameraFrustum(const Transform &pose, const StereoCameraModel &model)
double getIMUGravityLength(int index) const
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
rtabmap::ParametersMap getAllParameters() const
double getMarkerLength() const
pcl::IndicesPtr RTABMAP_EXP passThrough(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, const std::string &axis, float min, float max, bool negative=false)
bool isRefineNeighborLinks() const
virtual size_t memoryUsage() const
virtual void showEvent(QShowEvent *anEvent)
void setCloudVisibility(const std::string &id, bool isVisible)
void setAspectRatio1080p()
bool uIsInBounds(const T &value, const T &low, const T &high)
void addOrUpdateCoordinate(const std::string &id, const Transform &transform, double scale, bool foreground=false)
virtual std::map< int, Transform > optimizeBA(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, CameraModel > &models, std::map< int, cv::Point3f > &points3DMap, const std::map< int, std::map< int, FeatureBA > > &wordReferences, std::set< int > *outliers=0)
void setMaxDepth(int maxDepth)
void addOrUpdateText(const std::string &id, const std::string &text, const Transform &position, double scale, const QColor &color, bool foreground=true)
bool intraSession() const
Transform transformFiltered
std::map< int, float > _cachedLocalizationsCount
void setMonitoringState(bool monitoringState)
Transform computeTransformation(const Signature &from, const Signature &to, Transform guess=Transform::getIdentity(), RegistrationInfo *info=0) const
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
const Statistics & getStats() const
const std::map< int, float > & likelihood() const
void getAllNodeIds(std::set< int > &ids, bool ignoreChildren=false, bool ignoreBadSignatures=false) const
double getSourceScanForceGroundNormalsUp() const
PreferencesDialog * _preferencesDialog
std::map< int, cv::Point3f > localMap
void removeFrustum(const std::string &id)
double getSourceScanRangeMin() const
int proximityDetectionId() const
double getSourceScanRangeMax() const
pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr RTABMAP_EXP laserScanToPointCloudRGBNormal(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=100, unsigned char g=100, unsigned char b=100)
std::pair< std::string, std::string > ParametersPair
int getKpMaxFeatures() const
const Signature & getLastSignatureData() const
bool imageHighestHypShown() const
bool UTILITE_EXP uStr2Bool(const char *str)
const std::map< int, float > & posterior() const
bool removeCloud(const std::string &id)
void noMoreImagesReceived()
bool isStatisticsPublished() const
std::vector< int > RTABMAP_EXP filterNotUsedVerticesFromMesh(const pcl::PointCloud< pcl::PointXYZRGBNormal > &cloud, const std::vector< pcl::Vertices > &polygons, pcl::PointCloud< pcl::PointXYZRGBNormal > &outputCloud, std::vector< pcl::Vertices > &outputPolygons)
virtual QString getIniFilePath() const
rtabmap::CameraThread * _camera
float inliersMeanDistance
void enableBilateralFiltering(float sigmaS, float sigmaR)
OdometryInfo copyWithoutData() const
bool _autoScreenCaptureOdomSync
void rtabmapLabelErrorReceived(int id, const QString &label)
virtual void stopDetection()
QString getWorkingDirectory() const
int getOctomapRenderingType() const
void timeLimitChanged(float)
bool isSourceRGBDColorOnly() const
const std::multimap< int, Link > & getConstraints() const
float UTILITE_EXP uStr2Float(const std::string &str)
std::vector< float > getCloudRoiRatios(int index) const
bool addOccupancyGridMap(const cv::Mat &map8U, float resolution, float xMin, float yMin, float opacity)
void setRGBDImage(const cv::Mat &rgb, const cv::Mat &depth, const CameraModel &model, bool clearPreviousData=true)
QString _openedDatabasePath
std::multimap< int, Link > _currentLinksMap
void viewClouds(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, int > &mapIds, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const QString &workingDirectory, const ParametersMap ¶meters)
const cv::Mat & F() const
rtabmap::OdometryThread * _odomThread
std::map< std::string, std::string > ParametersMap
virtual void openDatabase()
void imgRateChanged(double)
virtual void changeState(MainWindow::State state)
double getGeneralInputRate() const
void setData(const Signature &sA, const Signature &sB)
int getCloudMeshingTriangleSize()
float timeParticleFiltering
void setCameraModels(const std::vector< CameraModel > &models)
int getSourceScanDownsampleStep() const
const QColor & getDefaultBackgroundColor() const
void setData(const QMap< int, float > &dataMap, const QMap< int, int > &weightsMap)
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
void setWorkingDirectory(const QString &path)
std::vector< int > inliersIDs
rtabmap::LoopClosureViewer * loopClosureViewer() const
void selectRealSense2Stereo()
void selectStereoFlyCapture2()
Some conversion functions.
bool isLocalizationsCountGraphView() const
virtual void openPreferencesSource()
void setupMainLayout(bool vertical)
virtual void keyPressEvent(QKeyEvent *event)
void updateNodeVisibility(int, bool)
double getScanMaxRange(int index) const
unsigned long getMemoryUsed() const
std::string getExtension()
void setImageRate(float imageRate)
static void setTreadIdFilter(const std::set< unsigned long > &ids)
const LaserScan & laserScanRaw() const
bool isGraphsShown() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
std::vector< std::string > getGeneralLoggerThreads() const
std::vector< CameraModel > _rectCameraModels
const Transform & groundTruth() const
const cv::Mat & imageRaw() const
QMap< int, QString > _exportPosesFileName
void removeLine(const std::string &id)
int localBundleConstraints
static void setLevel(ULogger::Level level)
virtual void saveConfigGUI()
long _createdCloudsMemoryUsage
const std::string & getGoalLabel() const
void stateChanged(MainWindow::State)
const std::map< int, int > & weights() const
static bool isAvailable(Optimizer::Type type)
void RTABMAP_EXP computeMaxGraphErrors(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, float &maxLinearErrorRatio, float &maxAngularErrorRatio, float &maxLinearError, float &maxAngularError, const Link **maxLinearErrorLink=0, const Link **maxAngularErrorLink=0)
virtual void pauseDetection()
void drawLandmarks(cv::Mat &image, const Signature &signature)
pcl::PointCloud< pcl::Normal >::Ptr RTABMAP_EXP computeFastOrganizedNormals2D(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, int searchK=5, float searchRadius=0.0f, const Eigen::Vector3f &viewPoint=Eigen::Vector3f(0, 0, 0))
bool isGroundTruthAligned() const
std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > createAndAddCloudToMap(int nodeId, const Transform &pose, int mapId)
pcl::IndicesPtr RTABMAP_EXP extractIndices(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, bool negative)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP laserScanToPointCloud(const LaserScan &laserScan, const Transform &transform=Transform())
double rotVariance(bool minimum=true) const
double getCloudVoxelSizeScan(int index) const
bool isLandmarksShown() const
Transform getIMULocalTransform() const
void post(UEvent *event, bool async=true) const
bool isOdomDisabled() const
const std::vector< cv::KeyPoint > & getWordsKpts() const
double getCloudOpacity(int index) const
virtual void resetOdometry()
const State & state() const
void rtabmapGlobalPathEventReceived(const rtabmap::RtabmapGlobalPathEvent &event)
void updateView(const Transform &AtoB=Transform(), const ParametersMap ¶meters=ParametersMap())
void loadMainWindowState(QMainWindow *mainWindow, bool &maximized, bool &statusBarShown)
bool addCloudTextureMesh(const std::string &id, const pcl::TextureMesh::Ptr &textureMesh, const cv::Mat &texture, const Transform &pose=Transform::getIdentity())
int getGeneralLoggerEventLevel() const
bool isSubtractFiltering() const
void setAspectRatio240p()
std::map< int, Transform > _currentPosesMap
Transform _odometryCorrection
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud< pcl::PointXYZ > &cloud, const Transform &transform=Transform(), bool filterNaNs=true)
std::pair< int, std::pair< std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr >, pcl::IndicesPtr > > _previousCloud
PreferencesDialog::Src getSourceDriver() const
void addOrUpdateLine(const std::string &id, const Transform &from, const Transform &to, const QColor &color, bool arrow=false, bool foreground=false)
void saveCustomConfig(const QString §ion, const QString &key, const QString &value)
bool openConnection(const std::string &url, bool overwritten=false)
#define UASSERT(condition)
QString getSourceDistortionModel() const
bool update(const std::map< int, Transform > &poses)
void setColorOnly(bool colorOnly)
void statsReceived(const rtabmap::Statistics &)
void clearOccupancyGridRaw()
std::map< int, LaserScan > _createdScans
double landmarkVisSize() const
double getPlanningTime() const
void processCameraInfo(const rtabmap::CameraInfo &info)
Wrappers of STL for convenient functions.
const std::map< std::string, float > & data() const
double getSourceScanNormalsRadius() const
bool isSourceMirroring() const
virtual void resizeEvent(QResizeEvent *anEvent)
void setLoopClosureViewer(rtabmap::LoopClosureViewer *loopClosureViewer)
Optimizer::Type sbaType() const
void addToCache(int nodeId, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &ground, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &obstacles, const pcl::PointXYZ &viewPoint)
float timeStereoExposureCompensation
const Transform & pose() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP laserScanToPointCloudRGB(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=100, unsigned char g=100, unsigned char b=100)
const std::map< int, Transform > & addedNodes() const
bool isValidForProjection() const
virtual bool isCalibrated() const =0
virtual bool handleEvent(UEvent *anEvent)
const CameraModel & left() const
void notifyNoMoreImages()
void setAspectRatio16_9()
double getFloorFilteringHeight() const
float getDetectionRate() const
void mappingModeChanged(bool)
LaserScan RTABMAP_EXP commonFiltering(const LaserScan &scan, int downsamplingStep, float rangeMin=0.0f, float rangeMax=0.0f, float voxelSize=0.0f, int normalK=0, float normalRadius=0.0f, float groundNormalsUp=0.0f)
void selectSourceDriver(Src src)
void changeDetectionRateSetting()
void calibrate(const std::map< int, Transform > &poses, const QMap< int, Signature > &cachedSignatures, const QString &workingDirectory, const ParametersMap ¶meters)
void rtabmapEventInitReceived(int status, const QString &info)
const cv::Mat & depthOrRightCompressed() const
const std::multimap< int, int > & getWords() const
bool isBilateralFiltering() const
static void setPrintTime(bool printTime)
#define ULOGGER_DEBUG(...)
void setDecimation(int decimation)
static Odometry * create(const ParametersMap ¶meters=ParametersMap())
std::vector< int > cornerInliers
bool isPosteriorGraphView() const
bool isSourceStereoDepthGenerated() const
void removeAllCoordinates(const std::string &prefix="")
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack)
#define UASSERT_MSG(condition, msg_str)
double getScanNormalRadiusSearch() const
void closeConnection(bool save=true, const std::string &outputUrl="")
bool isTimeUsedInFigures() const
void addToCache(int nodeId, const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty)
virtual std::string getClassName() const =0
pcl::PointCloud< pcl::PointXYZINormal >::Ptr RTABMAP_EXP laserScanToPointCloudINormal(const LaserScan &laserScan, const Transform &transform=Transform(), float intensity=0.0f)
double getCloudFilteringRadius() const
void loadNodeData(Signature *signature, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const
void loadSignatures(const std::list< int > &ids, std::list< Signature * > &signatures, std::set< int > *loadedFromTrash=0)
void setScanParameters(bool fromDepth, int downsampleStep=1, float rangeMin=0.0f, float rangeMax=0.0f, float voxelSize=0.0f, int normalsK=0, int normalsRadius=0.0f, float groundNormalsUp=0.0f)
void dataRecorderDestroyed()
void cameraInfoReceived(const rtabmap::CameraInfo &)
bool isLabelsShown() const
rtabmap::OctoMap * _octomap
float getFrustumScale() const
const cv::Vec3d linearAcceleration() const
double getNoiseRadius() const
int getDownsamplingStepScan(int index) const
bool isCloudMeshingTexture() const
double getSourceScanVoxelSize() const
const cv::Mat & T() const
std::map< int, Transform > optimize(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, std::list< std::map< int, Transform > > *intermediateGraphes=0, double *finalError=0, int *iterationsDone=0)
void setAspectRatio480p()
const cv::Mat & E() const
PdfPlotCurve * _likelihoodCurve
Transform RTABMAP_EXP calcRMSE(const std::map< int, Transform > &groundTruth, const std::map< int, Transform > &poses, float &translational_rmse, float &translational_mean, float &translational_median, float &translational_std, float &translational_min, float &translational_max, float &rotational_rmse, float &rotational_mean, float &rotational_median, float &rotational_std, float &rotational_min, float &rotational_max)
rtabmap::IMUThread * _imuThread
std::vector< double > RTABMAP_EXP getMaxOdomInf(const std::multimap< int, Link > &links)
static void registerCurrentThread(const std::string &name)
int sbaIterations() const
double clusterAngle() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP cloudRGBFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >())
static void setType(Type type, const std::string &fileName=kDefaultLogFileName, bool append=true)
int getCloudDecimation(int index) const
void cameraInfoProcessed()
void loopClosureThrChanged(qreal)
void removeOccupancyGridMap()
std::map< int, Transform > localBundlePoses
std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > _cachedClouds
bool isWordsCountGraphView() const
void setCloudPointSize(const std::string &id, int size)
static void setEventLevel(ULogger::Level eventSentLevel)
int getScanPointSize(int index) const
void openWorkingDirectory()
int getOctomapPointSize() const
bool isIMUAccShown() const
bool isSourceStereoExposureCompensation() const
void anchorCloudsToGroundTruth()
std::map< int, std::string > _currentLabels
void printLoopClosureIds()
virtual void closeEvent(QCloseEvent *event)
int getSourceImageDecimation() const
const RtabmapColorOcTree * octree() const
void changeTimeLimitSetting()
cv::Mat RTABMAP_EXP computeNormals(const cv::Mat &laserScan, int searchK, float searchRadius)
bool isMarkerDetection() const
void setMaximumSteps(int steps)
bool isCloudMeshing() const
rtabmap::ProgressDialog * progressDialog()
void exportPoses(int format)
void updateCameraTargetPosition(const Transform &pose)
void updateParameters(const rtabmap::ParametersMap ¶meters)
void saveWindowGeometry(const QWidget *window)
Transform localTransform() const
void addOrUpdateFrustum(const std::string &id, const Transform &pose, const Transform &localTransform, double scale, const QColor &color=QColor(), float fovX=1.1, float fovY=0.85)
bool isCacheSavedInFigures() const
float icpStructuralDistribution
bool sbaRematchFeatures() const
bool isFeaturesShown(int index) const
void processRtabmapLabelErrorEvent(int id, const QString &label)
std::list< std::string > uSplitNumChar(const std::string &str)
const cv::Mat & depthOrRightRaw() const
const OdometryInfo & info() const
DiscreteDepthDistortionModel RTABMAP_EXP calibrate(const std::map< int, rtabmap::SensorData > &sequence, const std::map< int, rtabmap::Transform > &trajectory, const pcl::PointCloud< pcl::PointXYZ >::Ptr &map, double coneRadius=0.02, double coneStdevThresh=0.03)
const std::map< int, Link > & getLandmarks() const
const QColor & getBackgroundColor() const
void exportPosesRGBDSLAMMotionCapture()
int getCloudPointSize(int index) const
void setDistortionModel(const std::string &path)
int loopClosureId() const
std::vector< pcl::Vertices > RTABMAP_EXP organizedFastMesh(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, double angleTolerance, bool quad, int trianglePixelSize, const Eigen::Vector3f &viewpoint=Eigen::Vector3f(0, 0, 0))
CloudViewer * _cloudViewer
bool openDatabase(const QString &path)
const QMap< std::string, Transform > & getAddedClouds() const
virtual void deleteMemory()
PdfPlotCurve * _posteriorCurve
int getSubtractFilteringMinPts() const
float inliersDistribution
bool isScansShown(int index) const
void setMirroringEnabled(bool enabled)
bool _autoScreenCaptureRAM
void setBackgroundColor(const QColor &color)
bool uContains(const std::list< V > &list, const V &value)
double getCloudMeshingAngle() const
bool updateFrustumPose(const std::string &id, const Transform &pose)
void exportClouds(const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, int > &mapIds, const QMap< int, Signature > &cachedSignatures, const std::map< int, std::pair< pcl::PointCloud< pcl::PointXYZRGB >::Ptr, pcl::IndicesPtr > > &cachedClouds, const std::map< int, LaserScan > &cachedScans, const QString &workingDirectory, const ParametersMap ¶meters)
std::multimap< int, int > RTABMAP_EXP radiusPosesClustering(const std::map< int, Transform > &poses, float radius, float angle)
bool isFrustumsShown(int index) const
const Transform & loopClosureTransform() const
virtual void triggerNewMap()
double getScanCeilingFilteringHeight() const
bool RTABMAP_EXP exportPoses(const std::string &filePath, int format, const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints=std::multimap< int, Link >(), const std::map< int, double > &stamps=std::map< int, double >(), const ParametersMap ¶meters=ParametersMap())
void rtabmapEvent3DMapProcessed()
std::map< int, Transform > _currentGTPosesMap
void setMonitoringState(bool pauseChecked=false)
void setCameraLockZ(bool enabled=true)
void setPose(const Transform &pose)
static DBDriver * create(const ParametersMap ¶meters=ParametersMap())
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
void exportBundlerFormat()
std::map< int, pcl::PointCloud< pcl::PointXYZRGB >::Ptr > _createdFeatures
void setImageDecimation(int decimation)
int getNormalKSearch() const
QMap< int, Signature > _cachedSignatures
void selectStereoDC1394()
bool isVerticalLayoutUsed() const
void registerToEventsManager()
static void initGuiResource()
bool addCloud(const std::string &id, const pcl::PCLPointCloud2Ptr &binaryCloud, const Transform &pose, bool rgb, bool hasNormals, bool hasIntensity, const QColor &color=QColor(), int viewport=1)
bool getCloudVisibility(const std::string &id)
double transVariance(bool minimum=true) const
static std::string getType(const std::string ¶mKey)
virtual void clearTheCache()
QMap< QString, QByteArray > _autoScreenCaptureCachedImages
MainWindow(PreferencesDialog *prefDialog=0, QWidget *parent=0, bool showSplashScreen=true)
void uSleep(unsigned int ms)
const std::map< int, Transform > & poses() const
void getConnectedGraph(int fromId, const std::map< int, Transform > &posesIn, const std::multimap< int, Link > &linksIn, std::map< int, Transform > &posesOut, std::multimap< int, Link > &linksOut) const
bool isValidForProjection() const
double getScanOpacity(int index) const
void setCloudViewer(rtabmap::CloudViewer *cloudViewer)
pcl::IndicesPtr RTABMAP_EXP radiusFiltering(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, float radiusSearch, int minNeighborsInRadius)
virtual void moveEvent(QMoveEvent *anEvent)
void processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap &event)
cv::Mat RTABMAP_EXP convertMap2Image8U(const cv::Mat &map8S, bool pgmFormat=false)
PdfPlotCurve * _rawLikelihoodCurve
static const ParametersMap & getDefaultParameters()
void updateMapCloud(const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, const std::map< int, int > &mapIds, const std::map< int, std::string > &labels, const std::map< int, Transform > &groundTruths, bool verboseProgress=false, std::map< std::string, float > *stats=0)
const std::vector< std::pair< int, Transform > > & getPoses() const
double getOdomF2MGravitySigma() const
QString loadCustomConfig(const QString §ion, const QString &key)
const std::vector< CameraModel > & cameraModels() const
std::string getParameter(const std::string &key) const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr createCloud(unsigned int treeDepth=0, std::vector< int > *obstacleIndices=0, std::vector< int > *emptyIndices=0, std::vector< int > *groundIndices=0, bool originalRefPoints=true, std::vector< int > *frontierIndices=0, std::vector< double > *cloudProb=0) const
void addOrUpdateGraph(const std::string &id, const pcl::PointCloud< pcl::PointXYZ >::Ptr &graph, const QColor &color=Qt::gray)
virtual bool odomProvided() const
std::vector< V > uValues(const std::multimap< K, V > &mm)
rtabmap::OccupancyGrid * _occupancyGrid
virtual void setDefaultViews()
static Registration * create(const ParametersMap ¶meters)
const Transform & localTransform() const
void setStereoToDepth(bool enabled)
QString getWorkingDirectory() const
virtual void startDetection()
std::map< int, float > _cachedWordsCount
bool isSourceScanFromDepth() const
const std::vector< cv::Point3f > & getWords3() const
virtual bool closeDatabase()
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
std::multimap< int, cv::KeyPoint > words
SensorData & sensorData()
void saveWidgetState(const QWidget *widget)
QString captureScreen(bool cacheInRAM=false, bool png=true)
float icpStructuralComplexity
T uNormSquared(const std::vector< T > &v)
void detectionRateChanged(double)
const CameraInfo & info() const
void updateCameraFrustums(const Transform &pose, const std::vector< CameraModel > &models)
const CameraModel & right() const
bool getGeneralLoggerPrintThreadId() const
std::map< int, int > _currentMapIds
std::list< K > uKeysList(const std::multimap< K, V > &mm)
std::multimap< int, Link >::iterator RTABMAP_EXP findLink(std::multimap< int, Link > &links, int from, int to, bool checkBothWays=true)
void postGoal(const QString &goal)
int getFeaturesPointSize(int index) const
void showCloseButton(bool visible=true)
void processRtabmapEventInit(int status, const QString &info)
bool writeBinary(const std::string &path)
static void addHandler(UEventsHandler *handler)
QString _defaultOpenDatabasePath
double getNormalRadiusSearch() const
bool RTABMAP_EXP databaseRecovery(const std::string &corruptedDatabase, bool keepCorruptedDatabase=true, std::string *errorMsg=0, ProgressState *progressState=0)
const std::multimap< int, Link > & constraints() const
bool isCloudsKept() const
pcl::PointCloud< pcl::PointNormal >::Ptr RTABMAP_EXP laserScanToPointCloudNormal(const LaserScan &laserScan, const Transform &transform=Transform())
bool isSavedMaximized() const
const QMap< std::string, Transform > & getAddedFrustums() const
static const std::map< std::string, float > & defaultData()
QString getSourceDriverStr() const
const std::set< std::string > & getAddedLines() const
double clusterRadius() const
bool isOctomapUpdated() const
ParametersMap getLastParameters() const
void setCurrentPanelToSource()
virtual void downloadPoseGraph()
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
void setAspectRatioCustom()
void loadWindowGeometry(QWidget *window)
void setBackfaceCulling(bool enabled, bool frontfaceCulling)
double getBilateralSigmaR() const
void setAspectRatio360p()
ProgressDialog * _progressDialog
PostProcessingDialog * _postProcessingDialog
int currentGoalId() const
float timeImageDecimation
AboutDialog * _aboutDialog
void setCameraTargetFollow(bool enabled=true)
ExportBundlerDialog * _exportBundlerDialog
bool isPriorIgnored() const
bool getGeneralLoggerPrintTime() const
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
void setAspectRatio16_10()
bool isFramesShown() const
std::vector< int > matchesIDs
const cv::Mat & imageCompressed() const
bool interSession() const
bool isCloudFiltering() const
std::vector< cv::Point2f > newCorners
bool isImagesKept() const
bool isOctomapShown() const
void setCloudColorIndex(const std::string &id, int index)
int getOdomStrategy() const
void parseParameters(const ParametersMap ¶meters)
Transform alignPosesToGroundTruth(const std::map< int, Transform > &poses, const std::map< int, Transform > &groundTruth)
void removeCoordinate(const std::string &id)
double getBilateralSigmaS() const
bool init(const QString &path, bool recordInRAM=true)
double getScanFloorFilteringHeight() const
cv::Mat RTABMAP_EXP cvtDepthFromFloat(const cv::Mat &depth32F)
bool isDepthFilteringAvailable() const
const SensorData & data() const
bool _processingStatistics
const std::string & label() const
void exportPosesRGBDSLAM()
double getLoopThr() const
bool isDetectMoreLoopClosures() const
cv::Mat createProjectionMap(float &xMin, float &yMin, float &gridCellSize, float minGridSize=0.0f, unsigned int treeDepth=0)
bool addOctomap(const OctoMap *octomap, unsigned int treeDepth=0, bool volumeRepresentation=true)
float timeBilateralFiltering
bool addCloudMesh(const std::string &id, const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const std::vector< pcl::Vertices > &polygons, const Transform &pose=Transform::getIdentity())
pcl::PointCloud< pcl::PointXYZI >::Ptr RTABMAP_EXP laserScanToPointCloudI(const LaserScan &laserScan, const Transform &transform=Transform(), float intensity=0.0f)
QString _graphSavingFileName
void join(bool killFirst=false)
virtual bool eventFilter(QObject *obj, QEvent *event)
GLM_FUNC_DECL genType::value_type length(genType const &x)
double getSubtractFilteringAngle() const
void processOdometry(const rtabmap::OdometryEvent &odom, bool dataIgnored)
void rtabmapEvent3DMapReceived(const rtabmap::RtabmapEvent3DMap &event)
void selectOpenniCvAsus()
double getCloudMaxDepth(int index) const
void appendText(const QString &text, const QColor &color=Qt::black)
void setAspectRatio720p()
void createAndAddScanToMap(int nodeId, const Transform &pose, int mapId)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
void loadWidgetState(QWidget *widget)
void rtabmapGoalStatusEventReceived(int status)
const Transform & mapCorrection() const
const std::vector< int > & localPath() const
int getGeneralLoggerType() const
int getSourceScanNormalsK() const
void drawKeypoints(const std::multimap< int, cv::KeyPoint > &refWords, const std::multimap< int, cv::KeyPoint > &loopWords)
QVector< int > _loopClosureIds
const Transform & localTransform() const
bool isCloudsShown(int index) const
const double & bearing() const
float RTABMAP_EXP computePathLength(const std::vector< std::pair< int, Transform > > &path, unsigned int fromIndex=0, unsigned int toIndex=0)
bool notifyWhenNewGlobalPathIsReceived() const
std::string UTILITE_EXP uFormat(const char *fmt,...)
int getOdomRegistrationApproach() const
std::string UTILITE_EXP uNumber2Str(unsigned int number)
ExportCloudsDialog * _exportCloudsDialog
cv::Mat getMap(float &xMin, float &yMin) const
bool getPose(const std::string &id, Transform &pose)
void createAndAddFeaturesToMap(int nodeId, const Transform &pose, int mapId)
int getScanColorScheme(int index) const
bool isOctomap2dGrid() const
bool _autoScreenCapturePNG
virtual size_t size() const
int getOdomQualityWarnThr() const
virtual QString getTmpIniFilePath() const
DataRecorder * _dataRecorder
const std::map< int, Transform > & addedNodes() const
static Optimizer * create(const ParametersMap ¶meters)
LoopClosureViewer * _loopClosureViewer
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
virtual void newDatabase()
void updateSelectSourceMenu()
void processRtabmapGlobalPathEvent(const rtabmap::RtabmapGlobalPathEvent &event)
void updateCacheFromDatabase()
rtabmap::CloudViewer * cloudViewer() const
bool isRefineLoopClosureLinks() const
void setFeatures(const std::vector< cv::KeyPoint > &keypoints, const std::vector< cv::Point3f > &keypoints3D, const cv::Mat &descriptors)
bool imageRejectedShown() const
bool updateCloudPose(const std::string &id, const Transform &pose)
int getOdomBufferSize() const
void odometryReceived(const rtabmap::OdometryEvent &, bool)
float getTimeLimit() const
virtual void downloadAllClouds()
void setCloudOpacity(const std::string &id, double opacity=1.0)
bool hasIntensity() const
double getGridMapOpacity() const
std::map< int, float > RTABMAP_EXP findNearestNodes(const std::map< int, rtabmap::Transform > &nodes, const rtabmap::Transform &targetPose, int k)
GLM_FUNC_DECL detail::tmat4x4< T, P > orientation(detail::tvec3< T, P > const &Normal, detail::tvec3< T, P > const &Up)
double getCloudMinDepth(int index) const
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
void selectScreenCaptureFormat(bool checked)
const Transform & localTransform() const
const std::map< int, float > & rawLikelihood() const
void processRtabmapGoalStatusEvent(int status)
bool _processingDownloadedMap
void enableIMUFiltering(int filteringStrategy=1, const ParametersMap ¶meters=ParametersMap())
const std::map< int, Signature > & getSignatures() const
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 &cloud, bool filterNaNs=true, bool is2D=false, const Transform &transform=Transform())
const double & stamp() const