10 #ifndef CGRAPHSLAMENGINE_IMPL_H 11 #define CGRAPHSLAMENGINE_IMPL_H 13 namespace mrpt {
namespace graphslam {
15 template<
class GRAPH_T>
17 template<
class GRAPH_T>
23 template<
class GRAPH_T>
35 m_optimizer(optimizer),
36 m_enable_visuals(win_manager != NULL),
37 m_config_fname(config_file),
38 m_rawlog_fname(rawlog_fname),
41 m_win_manager(win_manager),
42 m_paused_message(
"Program is paused. Press \"p/P\" to resume."),
43 m_text_index_paused_message(345),
44 m_odometry_color(0, 0, 255),
45 m_GT_color(0, 255, 0),
46 m_estimated_traj_color(255, 165, 0),
47 m_optimized_map_color(255, 0, 0),
48 m_current_constraint_type_color(255, 255, 255),
49 m_robot_model_size(1),
50 m_graph_section(
"graph_sec"),
51 m_class_name(
"CGraphSlamEngine"),
52 m_is_first_time_node_reg(true)
57 template<
class GRAPH_T>
66 for (
fstreams_out_it it = m_out_streams.begin(); it != m_out_streams.end();
68 if ((it->second)->fileOpenCorrectly()) {
70 (it->second)->close();
77 CImage::IMAGES_PATH_BASE = m_img_prev_path_base;
92 template<
class GRAPH_T>
93 typename GRAPH_T::global_pose_t
98 return m_node_reg->getCurrentRobotPosEstimation();
103 template<
class GRAPH_T>
105 typename GRAPH_T::global_poses_t* graph_poses)
const {
109 *graph_poses = m_graph.nodes;
113 template<
class GRAPH_T>
115 std::set<mrpt::utils::TNodeID>* nodes_set)
const {
118 m_graph.getAllNodes(*nodes_set);
123 template<
class GRAPH_T>
126 using namespace mrpt;
132 m_time_logger.setName(m_class_name);
133 this->logging_enable_keep_record =
true;
134 this->setLoggerName(m_class_name);
146 m_supported_constraint_types.push_back(
"CPosePDFGaussianInf");
147 m_supported_constraint_types.push_back(
"CPose3DPDFGaussianInf");
150 const string c_str(
c.GetRuntimeClass()->className);
153 m_supported_constraint_types.begin(),
154 m_supported_constraint_types.end(),
155 c_str) != m_supported_constraint_types.end());
162 "Given graph class " << c_str <<
163 " has not been tested consistently yet." <<
164 "Proceed at your own risk.");
169 m_current_constraint_type = c_str;
170 m_current_constraint_type =
"Constraints: " + m_current_constraint_type;
174 if (m_enable_visuals) {
175 m_win = m_win_manager->win;
176 m_win_observer = m_win_manager->observer;
180 m_win_observer = NULL;
189 m_observation_only_dataset =
false;
190 m_request_to_exit =
false;
196 m_GT_poses_index = 0;
200 m_node_reg->setGraphPtr(&m_graph);
201 m_edge_reg->setGraphPtr(&m_graph);
202 m_optimizer->setGraphPtr(&m_graph);
206 if (m_enable_visuals) {
207 m_node_reg->setWindowManagerPtr(m_win_manager);
208 m_edge_reg->setWindowManagerPtr(m_win_manager);
209 m_optimizer->setWindowManagerPtr(m_win_manager);
210 m_edge_counter.setWindowManagerPtr(m_win_manager);
214 m_node_reg->setCriticalSectionPtr(&m_graph_section);
215 m_edge_reg->setCriticalSectionPtr(&m_graph_section);
216 m_optimizer->setCriticalSectionPtr(&m_graph_section);
220 this->loadParams(m_config_fname);
222 if (!m_enable_visuals) {
224 m_visualize_odometry_poses = 0;
227 m_visualize_estimated_trajectory = 0;
228 m_visualize_SLAM_metric = 0;
229 m_enable_curr_pos_viewport = 0;
230 m_enable_range_viewport = 0;
231 m_enable_intensity_viewport = 0;
234 m_use_GT = !m_fname_GT.empty();
238 this->alignOpticalWithMRPTFrame();
242 this->readGTFile(m_fname_GT, &m_GT_poses);
249 "Ground truth file was not provided. Switching the related visualization parameters off...");
251 m_visualize_SLAM_metric = 0;
255 if (m_enable_visuals) {
256 m_win_manager->assignTextMessageParameters(&m_offset_y_timestamp,
257 &m_text_index_timestamp);
260 if (m_visualize_map) {
261 this->initMapVisualization();
266 if (m_enable_visuals) {
268 if (m_visualize_odometry_poses) {
269 this->initOdometryVisualization();
272 if (m_visualize_GT) {
273 this->initGTVisualization();
276 this->initEstimatedTrajectoryVisualization();
278 if (m_enable_curr_pos_viewport) {
279 this->initCurrPosViewport();
286 m_img_prev_path_base = CImage::IMAGES_PATH_BASE;
290 std::string m_img_external_storage_dir = rawlog_dir + rawlog_fname_noext
292 CImage::IMAGES_PATH_BASE = m_img_external_storage_dir;
297 if (m_enable_range_viewport) {
298 this->initRangeImageViewport();
300 if (m_enable_intensity_viewport) {
301 this->initIntensityImageViewport();
305 if (m_enable_visuals) {
306 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
308 CAxisPtr
obj = CAxis::Create();
309 obj->setFrequency(5);
310 obj->enableTickMarks();
311 obj->setAxisLimits(-10,-10,-10, 10,10,10);
312 obj->setName(
"axis");
315 m_win->unlockAccess3DScene();
316 m_win->forceRepaint();
320 if (m_enable_visuals) {
323 m_keystroke_pause_exec =
"p";
324 m_keystroke_odometry =
"o";
325 m_keystroke_GT =
"g";
326 m_keystroke_estimated_trajectory =
"t";
327 m_keystroke_map =
"m";
330 m_win_observer->registerKeystroke(m_keystroke_pause_exec,
331 "Pause/Resume program execution");
332 m_win_observer->registerKeystroke(m_keystroke_odometry,
333 "Toggle Odometry visualization");
334 m_win_observer->registerKeystroke(m_keystroke_GT,
335 "Toggle Ground-Truth visualization");
336 m_win_observer->registerKeystroke(m_keystroke_estimated_trajectory,
337 "Toggle Estimated trajectory visualization");
338 m_win_observer->registerKeystroke(m_keystroke_map,
339 "Toggle Map visualization");
343 vector<string> vec_edge_types;
344 vec_edge_types.push_back(
"Odometry");
345 vec_edge_types.push_back(
"ICP2D");
346 vec_edge_types.push_back(
"ICP3D");
349 cit != vec_edge_types.end(); ++cit) {
350 m_edge_counter.addEdgeType(*cit);
354 if (m_enable_visuals) {
356 double offset_y_total_edges, offset_y_loop_closures;
357 int text_index_total_edges, text_index_loop_closures;
359 m_win_manager->assignTextMessageParameters(
360 &offset_y_total_edges,
361 &text_index_total_edges);
365 map<string, double> name_to_offset_y;
366 map<string, int> name_to_text_index;
368 it != vec_edge_types.end();
370 m_win_manager->assignTextMessageParameters(
371 &name_to_offset_y[*it],
372 &name_to_text_index[*it]);
375 m_win_manager->assignTextMessageParameters(
376 &offset_y_loop_closures,
377 &text_index_loop_closures);
380 m_edge_counter.setTextMessageParams(
381 name_to_offset_y, name_to_text_index,
382 offset_y_total_edges, text_index_total_edges,
383 offset_y_loop_closures, text_index_loop_closures);
387 if (m_enable_visuals) {
388 m_win_manager->assignTextMessageParameters(
389 &m_offset_y_current_constraint_type,
390 &m_text_index_current_constraint_type);
391 m_win_manager->addTextMessage(m_offset_x_left,
392 -m_offset_y_current_constraint_type,
393 m_current_constraint_type,
394 TColorf(m_current_constraint_type_color),
395 m_text_index_current_constraint_type);
400 if (m_enable_visuals) {
402 m_time_logger.enter(
"Visuals");
403 m_node_reg->initializeVisuals();
404 m_edge_reg->initializeVisuals();
405 m_optimizer->initializeVisuals();
406 m_time_logger.leave(
"Visuals");
424 gridmap->insertionOptions.maxOccupancyUpdateCertainty = 0.8f;
425 gridmap->insertionOptions.maxDistanceInsertion = 5;
426 gridmap->insertionOptions.wideningBeamsWithDistance =
true;
427 gridmap->insertionOptions.decimation = 2;
429 m_gridmap_cached = gridmap;
430 m_map_is_cached =
false;
439 octomap->insertionOptions.setOccupancyThres(0.5);
440 octomap->insertionOptions.setProbHit(0.7);
441 octomap->insertionOptions.setProbMiss(0.4);
442 octomap->insertionOptions.setClampingThresMin(0.1192);
443 octomap->insertionOptions.setClampingThresMax(0.971);
445 m_octomap_cached = octomap;
446 m_map_is_cached =
false;
452 m_info_params.setRawlogFile(m_rawlog_fname);
453 m_info_params.parseFile();
455 int num_of_objects = std::atoi(
456 m_info_params.fields[
"Overall number of objects"].c_str());
457 m_GT_poses_step = m_GT_poses.size() / num_of_objects;
462 catch (std::exception& e) {
467 m_curr_deformation_energy = 0;
468 if (m_visualize_SLAM_metric) {
469 this->initSlamMetricVisualization();
473 if (m_enable_visuals) {
474 this->m_win->addTextMessage(
477 m_text_index_paused_message);
484 template<
class GRAPH_T>
486 mrpt::obs::CObservationPtr& observation,
487 size_t& rawlog_entry) {
490 CActionCollectionPtr action;
491 CSensoryFramePtr observations;
493 return this->_execGraphSlamStep(action, observations, observation,
497 template<
class GRAPH_T>
499 mrpt::obs::CActionCollectionPtr& action,
500 mrpt::obs::CSensoryFramePtr& observations,
501 mrpt::obs::CObservationPtr& observation,
502 size_t& rawlog_entry) {
506 using namespace mrpt;
514 m_time_logger.enter(
"proc_time");
517 format(
"\nConfig file is not read yet.\nExiting... \n"));
522 m_init_timestamp = getTimeStamp(action, observations, observation);
525 if (observation.present()) {
527 m_observation_only_dataset =
true;
533 m_observation_only_dataset =
false;
536 action->getFirstMovementEstimationMean(increment_pose_3d);
537 pose_t increment_pose(increment_pose_3d);
538 m_curr_odometry_only_pose += increment_pose;
546 bool registered_new_node;
549 m_time_logger.enter(
"node_registrar");
550 registered_new_node = m_node_reg->updateState(
551 action, observations, observation);
552 m_time_logger.leave(
"node_registrar");
556 CObservation2DRangeScanPtr scan =
557 getObservation<CObservation2DRangeScan>(observations, observation);
558 if (scan.present()) {
559 m_last_laser_scan2D = scan;
561 if (!m_first_laser_scan2D) {
562 m_first_laser_scan2D = m_last_laser_scan2D;
567 if (registered_new_node) {
571 if (m_is_first_time_node_reg) {
574 if (m_graph.nodeCount() != 2) {
576 <<
" but got [" << m_graph.nodeCount() <<
"]");
579 m_is_first_time_node_reg =
false;
581 m_nodes_to_laser_scans2D.insert(
582 make_pair(m_nodeID_max, m_first_laser_scan2D));
589 m_edge_counter.addEdge(
"Odometry");
591 this->monitorNodeRegistration(registered_new_node,
592 "NodeRegistrationDecider");
600 m_time_logger.enter(
"edge_registrar");
601 m_edge_reg->updateState(
605 m_time_logger.leave(
"edge_registrar");
607 this->monitorNodeRegistration(registered_new_node,
608 "EdgeRegistrationDecider");
613 m_time_logger.enter(
"optimizer");
614 m_optimizer->updateState(
618 m_time_logger.leave(
"optimizer");
620 this->monitorNodeRegistration(registered_new_node,
621 "GraphSlamOptimizer");
624 m_curr_timestamp = getTimeStamp(action, observations, observation);
626 if (observation.present()) {
632 CObservationOdometryPtr obs_odometry =
633 static_cast<CObservationOdometryPtr
>(observation);
635 m_curr_odometry_only_pose =
pose_t(obs_odometry->odometry);
636 m_odometry_poses.push_back(m_curr_odometry_only_pose);
639 m_last_laser_scan3D =
640 static_cast<mrpt::obs::CObservation3DRangeScanPtr
>(observation);
647 ASSERT_(observations.present());
651 action->getFirstMovementEstimationMean(increment_pose_3d);
652 pose_t increment_pose(increment_pose_3d);
653 m_curr_odometry_only_pose += increment_pose;
654 m_odometry_poses.push_back(m_curr_odometry_only_pose);
657 if (registered_new_node) {
659 this->execDijkstraNodesEstimation();
662 m_nodes_to_laser_scans2D[m_nodeID_max] = m_last_laser_scan2D;
664 if (m_enable_visuals && m_visualize_map) {
667 bool full_update =
true;
668 this->updateMapVisualization(m_nodes_to_laser_scans2D, full_update);
672 if (m_enable_visuals) {
673 this->updateAllVisuals();
677 std::map<std::string, int> edge_types_to_nums;
678 m_edge_reg->getEdgesStats(&edge_types_to_nums);
679 if (edge_types_to_nums.size()) {
681 edge_types_to_nums.begin(); it != edge_types_to_nums.end();
686 m_edge_counter.setLoopClosureEdgesManually(it->second);
689 m_edge_counter.setEdgesManually(it->first, it->second);
696 if (m_enable_curr_pos_viewport) {
697 updateCurrPosViewport();
700 if (m_enable_visuals) {
701 bool full_update =
true;
702 m_time_logger.enter(
"Visuals");
703 this->updateEstimatedTrajectoryVisualization(full_update);
704 m_time_logger.leave(
"Visuals");
710 m_time_logger.enter(
"SLAM_metric");
711 this->computeSlamMetric(m_nodeID_max, m_GT_poses_index);
712 m_time_logger.leave(
"SLAM_metric");
713 if (m_visualize_SLAM_metric) {
714 m_time_logger.enter(
"Visuals");
715 this->updateSlamMetricVisualization();
716 m_time_logger.leave(
"Visuals");
721 m_map_is_cached =
false;
728 m_time_logger.enter(
"Visuals");
732 if (m_enable_visuals) {
734 m_win_manager->addTextMessage(m_offset_x_left, -m_offset_y_timestamp,
737 m_text_index_timestamp );
740 m_win_manager->addTextMessage(m_offset_x_left, -m_offset_y_timestamp,
743 m_text_index_timestamp );
748 if (m_visualize_odometry_poses && m_odometry_poses.size()) {
749 this->updateOdometryVisualization();
756 if (m_enable_visuals) {
757 this->updateGTVisualization();
759 m_GT_poses_index += m_GT_poses_step;
762 if (m_observation_only_dataset) {
763 if (rawlog_entry % 2 == 0) {
764 if (m_enable_visuals) {
765 this->updateGTVisualization();
767 m_GT_poses_index += m_GT_poses_step;
772 if (m_enable_visuals) {
773 this->updateGTVisualization();
775 m_GT_poses_index += m_GT_poses_step;
782 if (m_enable_range_viewport && m_last_laser_scan3D.get()!=NULL) {
783 this->updateRangeImageViewport();
786 if (m_enable_intensity_viewport && m_last_laser_scan3D.get()!=NULL) {
787 this->updateIntensityImageViewport();
792 if (m_enable_visuals) {
793 this->queryObserverForEvents();
795 m_time_logger.leave(
"Visuals");
800 m_time_logger.leave(
"proc_time");
802 return !m_request_to_exit;
806 template<
class GRAPH_T>
810 m_time_logger.enter(
"dijkstra_nodes_estimation");
811 m_graph.dijkstra_nodes_estimate();
812 m_time_logger.leave(
"dijkstra_nodes_estimation");
817 template<
class GRAPH_T>
823 using namespace mrpt;
827 0 : m_nodeID_max + 1);
830 ASSERTMSG_(listed_nodeCount == m_graph.nodeCount(),
831 format(
"listed_nodeCount [%lu] != nodeCount() [%lu]",
832 static_cast<unsigned long>(listed_nodeCount),
833 static_cast<unsigned long>(m_graph.nodeCount())));
836 if (listed_nodeCount != m_graph.nodeCount()) {
838 " illegally added new nodes to the graph " <<
839 ", wanted to see [" << listed_nodeCount <<
"] but saw [" 840 << m_graph.nodeCount() <<
"]");
842 class_name.c_str()));
848 template<
class GRAPH_T>
850 mrpt::maps::COccupancyGridMap2DPtr map,
859 if (!m_map_is_cached){
862 map->copyMapContentFrom(*m_gridmap_cached);
865 if (acquisition_time) {
866 *acquisition_time = m_map_acq_time;
871 template<
class GRAPH_T>
873 mrpt::maps::COctoMapPtr map,
878 if (!m_map_is_cached){
881 map =
dynamic_cast<mrpt::maps::COctoMapPtr
>(m_octomap_cached->duplicate());
885 if (acquisition_time) {
886 *acquisition_time = m_map_acq_time;
892 template<
class GRAPH_T>
896 using namespace mrpt;
903 if (!constraint_t::is_3D()) {
905 mrpt::maps::COccupancyGridMap2DPtr gridmap = m_gridmap_cached;
912 it = m_nodes_to_laser_scans2D.begin();
913 it != m_nodes_to_laser_scans2D.end(); ++it) {
915 const TNodeID& curr_node = it->first;
918 const mrpt::obs::CObservation2DRangeScanPtr& curr_laser_scan = it->second;
920 format(
"LaserScan of nodeID: %lu is not present.",
921 static_cast<unsigned long>(curr_node)));
924 CPose3D scan_pose = getLSPoseForGridMapVisualization(curr_node);
927 gridmap->insertObservation(curr_laser_scan.pointer(), &scan_pose);
930 m_map_is_cached =
true;
935 THROW_EXCEPTION(
"Not Implemented Yet. Method is to compute a COctoMap");
943 template<
class GRAPH_T>
950 mrpt::format(
"\nConfiguration file not found: \n%s\n", fname.c_str()));
958 m_user_decides_about_output_dir = cfg_file.
read_bool(
959 "GeneralConfiguration",
960 "user_decides_about_output_dir",
963 "GeneralConfiguration",
964 "ground_truth_file_format",
968 int min_verbosity_level = cfg_file.
read_int(
969 "GeneralConfiguration",
972 this->setMinLoggingLevel(VerbosityLevel(min_verbosity_level));
979 "VisualizationParameters",
984 m_visualize_odometry_poses = cfg_file.
read_bool(
985 "VisualizationParameters",
986 "visualize_odometry_poses",
988 m_visualize_estimated_trajectory = cfg_file.
read_bool(
989 "VisualizationParameters",
990 "visualize_estimated_trajectory",
995 "VisualizationParameters",
996 "visualize_ground_truth",
999 m_visualize_SLAM_metric = cfg_file.
read_bool(
1000 "VisualizationParameters",
1001 "visualize_SLAM_metric",
1005 m_enable_curr_pos_viewport = cfg_file.
read_bool(
1006 "VisualizationParameters",
1007 "enable_curr_pos_viewport",
1009 m_enable_range_viewport = cfg_file.
read_bool(
1010 "VisualizationParameters",
1011 "enable_range_viewport",
1013 m_enable_intensity_viewport = cfg_file.
read_bool(
1014 "VisualizationParameters",
1015 "enable_intensity_viewport",
1018 m_node_reg->loadParams(fname);
1019 m_edge_reg->loadParams(fname);
1020 m_optimizer->loadParams(fname);
1022 m_has_read_config =
true;
1025 template<
class GRAPH_T>
1030 this->getParamsAsString(&str);
1035 template<
class GRAPH_T>
1040 using namespace std;
1042 stringstream ss_out;
1044 ss_out <<
"\n------------[ Graphslam_engine Problem Parameters ]------------" 1046 ss_out <<
"Config filename = " 1047 << m_config_fname << std::endl;
1049 ss_out <<
"Ground Truth File format = " 1050 << m_GT_file_format << std::endl;
1051 ss_out <<
"Ground Truth filename = " 1052 << m_fname_GT << std::endl;
1054 ss_out <<
"Visualize odometry = " 1055 << ( m_visualize_odometry_poses ?
"TRUE" :
"FALSE" ) << std::endl;
1056 ss_out <<
"Visualize estimated trajectory = " 1057 << ( m_visualize_estimated_trajectory ?
"TRUE" :
"FALSE" ) << std::endl;
1058 ss_out <<
"Visualize map = " 1059 << ( m_visualize_map ?
"TRUE" :
"FALSE" ) << std::endl;
1060 ss_out <<
"Visualize Ground Truth = " 1061 << ( m_visualize_GT ?
"TRUE" :
"FALSE" ) << std::endl;
1063 ss_out <<
"Visualize SLAM metric plot = " 1064 << ( m_visualize_SLAM_metric ?
"TRUE" :
"FALSE" ) << std::endl;
1066 ss_out <<
"Enable curr. position viewport = " 1067 << ( m_enable_curr_pos_viewport ?
"TRUE" :
"FALSE" ) << endl;
1068 ss_out <<
"Enable range img viewport = " 1069 << ( m_enable_range_viewport ?
"TRUE" :
"FALSE" ) << endl;
1070 ss_out <<
"Enable intensity img viewport = " 1071 << ( m_enable_intensity_viewport ?
"TRUE" :
"FALSE" ) << endl;
1073 ss_out <<
"-----------------------------------------------------------" 1075 ss_out << std::endl;
1078 *params_out = ss_out.str();
1083 template<
class GRAPH_T>
1086 std::cout << getParamsAsString();
1088 m_node_reg->printParams();
1089 m_edge_reg->printParams();
1090 m_optimizer->printParams();
1095 template<
class GRAPH_T>
1100 using namespace std;
1106 #if defined(MRPT_OS_APPLE) 1117 ASSERTMSG_(m_out_streams[fname]->fileOpenCorrectly(),
1119 "\nError while trying to open %s\n", fname.c_str()) );
1123 m_out_streams[fname]->printf(
"# Mobile Robot Programming Toolkit (MRPT)\n");
1124 m_out_streams[fname]->printf(
"# http::/www.mrpt.org\n");
1125 m_out_streams[fname]->printf(
"# GraphSlamEngine Application\n");
1126 m_out_streams[fname]->printf(
"# Automatically generated file - %s: %s\n",
1128 cur_date_str.c_str());
1129 m_out_streams[fname]->printf(
"%s\n\n", sep.c_str());
1134 template<
class GRAPH_T>
1140 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1141 COpenGLViewportPtr viewp_range;
1143 viewp_range = scene->createViewport(
"viewp_range");
1145 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1146 viewp_range->setViewportPosition(
x,
y, h,
w);
1148 m_win->unlockAccess3DScene();
1149 m_win->forceRepaint();
1154 template<
class GRAPH_T>
1158 m_time_logger.enter(
"Visuals");
1160 m_node_reg->updateVisuals();
1161 m_edge_reg->updateVisuals();
1162 m_optimizer->updateVisuals();
1164 m_time_logger.leave(
"Visuals");
1168 template<
class GRAPH_T>
1175 if (m_last_laser_scan3D->hasRangeImage) {
1182 m_last_laser_scan3D->load();
1183 range2D = m_last_laser_scan3D->rangeImage * (1.0f/5.0);
1184 img.setFromMatrix(range2D);
1186 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1187 COpenGLViewportPtr viewp_range = scene->getViewport(
"viewp_range");
1188 viewp_range->setImageView(
img);
1189 m_win->unlockAccess3DScene();
1190 m_win->forceRepaint();
1197 template<
class GRAPH_T>
1203 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1204 COpenGLViewportPtr viewp_intensity;
1206 viewp_intensity = scene->createViewport(
"viewp_intensity");
1208 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1209 viewp_intensity->setViewportPosition(
x,
y,
w, h);
1211 m_win->unlockAccess3DScene();
1212 m_win->forceRepaint();
1216 template<
class GRAPH_T>
1222 if (m_last_laser_scan3D->hasIntensityImage) {
1226 m_last_laser_scan3D->load();
1227 img = m_last_laser_scan3D->intensityImage;
1229 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1230 COpenGLViewportPtr viewp_intensity = scene->getViewport(
"viewp_intensity");
1231 viewp_intensity->setImageView(
img);
1232 m_win->unlockAccess3DScene();
1233 m_win->forceRepaint();
1240 template<
class GRAPH_T>
1243 return this->initRobotModelVisualizationInternal(
p);
1246 template<
class GRAPH_T>
1253 template<
class GRAPH_T>
1260 template<
class GRAPH_T>
1267 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1268 COpenGLViewportPtr viewp= scene->createViewport(
"curr_robot_pose_viewport");
1270 viewp->setCloneView(
"main");
1272 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1273 viewp->setViewportPosition(
x,
y, h,
w);
1274 viewp->setTransparent(
false);
1275 viewp->getCamera().setAzimuthDegrees(90);
1276 viewp->getCamera().setElevationDegrees(90);
1277 viewp->setCustomBackgroundColor(
TColorf(205, 193, 197, 255));
1278 viewp->getCamera().setZoomDistance(30);
1279 viewp->getCamera().setOrthogonal();
1281 m_win->unlockAccess3DScene();
1282 m_win->forceRepaint();
1289 template<
class GRAPH_T>
1299 global_pose_t curr_robot_pose = this->getCurrentRobotPosEstimation();
1301 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1302 COpenGLViewportPtr viewp = scene->getViewport(
"curr_robot_pose_viewport");
1303 viewp->getCamera().setPointingAt(
CPose3D(curr_robot_pose));
1305 m_win->unlockAccess3DScene();
1306 m_win->forceRepaint();
1312 template<
class GRAPH_T>
1315 std::vector<mrpt::poses::CPose2D>* gt_poses,
1316 std::vector<mrpt::system::TTimeStamp>* gt_timestamps ) {
1318 using namespace std;
1324 format(
"\nGround-truth file %s was not found.\n" 1325 "Either specify a valid ground-truth filename or set set the " 1326 "m_visualize_GT flag to false\n", fname_GT.c_str()));
1330 ASSERTMSG_(gt_poses,
"\nNo valid std::vector<pose_t>* was given\n");
1335 for (
size_t line_num = 0; file_GT.
readLine(curr_line); line_num++) {
1336 vector<string> curr_tokens;
1340 ASSERTMSG_(curr_tokens.size() == constraint_t::state_length + 1,
1341 "\nGround Truth File doesn't seem to contain data as generated by the " 1342 "GridMapNavSimul application.\n Either specify the GT file format or set " 1343 "visualize_ground_truth to false in the .ini file\n");
1346 if (gt_timestamps) {
1348 gt_timestamps->push_back(timestamp);
1353 atof(curr_tokens[1].c_str()),
1354 atof(curr_tokens[2].c_str()),
1355 atof(curr_tokens[3].c_str()) );
1356 gt_poses->push_back(curr_pose);
1363 template<
class GRAPH_T>
1366 std::vector<mrpt::poses::CPose3D>* gt_poses,
1367 std::vector<mrpt::system::TTimeStamp>* gt_timestamps ) {
1371 template<
class GRAPH_T>
1374 std::vector<mrpt::poses::CPose2D>* gt_poses,
1375 std::vector<mrpt::system::TTimeStamp>* gt_timestamps) {
1377 using namespace std;
1384 format(
"\nGround-truth file %s was not found.\n" 1385 "Either specify a valid ground-truth filename or set set the " 1386 "m_visualize_GT flag to false\n", fname_GT.c_str()));
1390 "\nreadGTFileRGBD_TUM: Couldn't openGT file\n");
1391 ASSERTMSG_(gt_poses,
"No valid std::vector<pose_t>* was given");
1396 for (
size_t i = 0; file_GT.
readLine(curr_line) ; i++) {
1397 if (curr_line.at(0) !=
'#') {
1405 vector<string> curr_tokens;
1410 "\nGround Truth File doesn't seem to contain data as specified in RGBD_TUM related " 1411 "datasets.\n Either specify correct the GT file format or set " 1412 "visualize_ground_truth to false in the .ini file\n");
1416 quat.
r(atof(curr_tokens[7].c_str()));
1417 quat.x(atof(curr_tokens[4].c_str()));
1418 quat.y(atof(curr_tokens[5].c_str()));
1419 quat.z(atof(curr_tokens[6].c_str()));
1424 curr_coords[0] = atof(curr_tokens[1].c_str());
1425 curr_coords[1] = atof(curr_tokens[2].c_str());
1426 curr_coords[2] = atof(curr_tokens[3].c_str());
1435 pose_diff = curr_pose;
1438 for (; file_GT.
readLine(curr_line) ;) {
1439 vector<string> curr_tokens;
1442 "\nGround Truth File doesn't seem to contain data as specified in RGBD_TUM related " 1443 "datasets.\n Either specify correct the GT file format or set " 1444 "visualize_ground_truth to false in the .ini file\n");
1447 if (gt_timestamps) {
1449 gt_timestamps->push_back(timestamp);
1454 quat.
r(atof(curr_tokens[7].c_str()));
1455 quat.
x(atof(curr_tokens[4].c_str()));
1456 quat.
y(atof(curr_tokens[5].c_str()));
1457 quat.
z(atof(curr_tokens[6].c_str()));
1462 curr_coords[0] = atof(curr_tokens[1].c_str());
1463 curr_coords[1] = atof(curr_tokens[2].c_str());
1464 curr_coords[2] = atof(curr_tokens[3].c_str());
1472 curr_pose.x() -= pose_diff.x();
1473 curr_pose.y() -= pose_diff.y();
1474 curr_pose.phi() -= pose_diff.phi();
1476 gt_poses->push_back(curr_pose);
1484 template<
class GRAPH_T>
1487 using namespace std;
1498 const double tmpz[] = {
1499 cos(anglez), -sin(anglez), 0,
1500 sin(anglez), cos(anglez), 0,
1507 const double tmpy[] = {
1508 cos(angley), 0, sin(angley),
1510 -sin(angley), 0, cos(angley) };
1516 const double tmpx[] = {
1518 0, cos(anglex), -sin(anglex),
1519 0, sin(anglex), cos(anglex) };
1522 stringstream ss_out;
1523 ss_out <<
"\nConstructing the rotation matrix for the GroundTruth Data..." 1525 m_rot_TUM_to_MRPT = rotz * roty * rotx;
1527 ss_out <<
"Rotation matrices for optical=>MRPT transformation" << endl;
1528 ss_out <<
"rotz: " << endl << rotz << endl;
1529 ss_out <<
"roty: " << endl << roty << endl;
1530 ss_out <<
"rotx: " << endl << rotx << endl;
1531 ss_out <<
"Full rotation matrix: " << endl << m_rot_TUM_to_MRPT << endl;
1538 template<
class GRAPH_T>
1543 "\nqueryObserverForEvents method was called even though no Observer object was provided\n");
1546 std::map<std::string, bool> events_occurred;
1547 m_win_observer->returnEventsStruct(&events_occurred);
1548 m_request_to_exit = events_occurred.find(
"Ctrl+c")->second;
1551 if (events_occurred[m_keystroke_odometry]) {
1552 this->toggleOdometryVisualization();
1555 if (events_occurred[m_keystroke_GT]) {
1556 this->toggleGTVisualization();
1559 if (events_occurred[m_keystroke_map]) {
1560 this->toggleMapVisualization();
1563 if (events_occurred[m_keystroke_estimated_trajectory]) {
1564 this->toggleEstimatedTrajectoryVisualization();
1567 if (events_occurred[m_keystroke_pause_exec]) {
1568 this->togglePause();
1573 m_node_reg->notifyOfWindowEvents(events_occurred);
1574 m_edge_reg->notifyOfWindowEvents(events_occurred);
1575 m_optimizer->notifyOfWindowEvents(events_occurred);
1580 template<
class GRAPH_T>
1588 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1590 if (m_visualize_odometry_poses) {
1591 CRenderizablePtr
obj = scene->getByName(
"odometry_poses_cloud");
1592 obj->setVisibility(!
obj->isVisible());
1594 obj = scene->getByName(
"robot_odometry_poses");
1595 obj->setVisibility(!
obj->isVisible());
1598 dumpVisibilityErrorMsg(
"visualize_odometry_poses");
1601 m_win->unlockAccess3DScene();
1602 m_win->forceRepaint();
1606 template<
class GRAPH_T>
1614 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1616 if (m_visualize_GT) {
1618 CRenderizablePtr
obj = scene->getByName(
"GT_cloud");
1619 obj->setVisibility(!
obj->isVisible());
1621 obj = scene->getByName(
"robot_GT");
1622 obj->setVisibility(!
obj->isVisible());
1625 dumpVisibilityErrorMsg(
"visualize_ground_truth");
1628 m_win->unlockAccess3DScene();
1629 m_win->forceRepaint();
1633 template<
class GRAPH_T>
1637 using namespace std;
1642 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1648 num_of_nodes = m_graph.nodeCount();
1652 stringstream scan_name(
"");
1654 for (
int node_cnt = 0; node_cnt != num_of_nodes; ++node_cnt) {
1657 scan_name <<
"laser_scan_";
1658 scan_name << node_cnt;
1660 CRenderizablePtr
obj = scene->getByName(scan_name.str());
1663 obj->setVisibility(!
obj->isVisible());
1666 m_win->unlockAccess3DScene();
1667 m_win->forceRepaint();
1671 template<
class GRAPH_T>
1679 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1681 if (m_visualize_estimated_trajectory) {
1683 CRenderizablePtr
obj = scene->getByName(
"estimated_traj_setoflines");
1684 obj->setVisibility(!
obj->isVisible());
1686 obj = scene->getByName(
"robot_estimated_traj");
1687 obj->setVisibility(!
obj->isVisible());
1690 dumpVisibilityErrorMsg(
"visualize_estimated_trajectory");
1693 m_win->unlockAccess3DScene();
1694 m_win->forceRepaint();
1698 template<
class GRAPH_T>
1705 <<
"Make sure that the corresponding visualization flag (" 1707 <<
") is set to true in the .ini file.");
1713 template<
class GRAPH_T>
1715 const mrpt::obs::CActionCollectionPtr action,
1716 const mrpt::obs::CSensoryFramePtr observations,
1717 const mrpt::obs::CObservationPtr observation) {
1723 ASSERTMSG_(action.present() || observation.present(),
1724 "Neither action or observation contains valid data.");
1727 if (observation.present()) {
1728 timestamp = observation->timestamp;
1732 timestamp = action->get(0).timestamp;
1737 sens_it != observations->end(); ++sens_it) {
1738 timestamp = (*sens_it)->timestamp;
1749 template<
class GRAPH_T>
1755 template<
class GRAPH_T>
1759 CSetOfObjectsPtr map_obj = CSetOfObjects::Create();
1760 map_obj->setName(
"map");
1761 COpenGLScenePtr& scene = this->m_win->get3DSceneAndLock();
1762 scene->insert(map_obj);
1763 this->m_win->unlockAccess3DScene();
1764 this->m_win->forceRepaint();
1767 template<
class GRAPH_T>
1771 mrpt::obs::CObservation2DRangeScanPtr>& nodes_to_laser_scans2D,
1772 bool full_update ) {
1778 using namespace std;
1780 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1781 CSetOfObjectsPtr map_obj;
1783 CRenderizablePtr
obj = scene->getByName(
"map");
1784 map_obj =
static_cast<CSetOfObjectsPtr
>(
obj);
1789 map_update_timer.
Tic();
1792 std::set<mrpt::utils::TNodeID> nodes_set;
1797 m_graph.getAllNodes(nodes_set);
1803 nodes_set.insert(m_nodeID_max);
1809 node_it = nodes_set.begin();
1810 node_it != nodes_set.end(); ++node_it) {
1813 stringstream scan_name(
"");
1814 scan_name <<
"laser_scan_";
1815 scan_name << *node_it;
1818 CObservation2DRangeScanPtr scan_content;
1821 nodes_to_laser_scans2D.find(*node_it);
1824 if (search != nodes_to_laser_scans2D.end() &&
1825 (search->second.get()!=NULL)) {
1826 scan_content = search->second;
1829 this->decimateLaserScan(*scan_content, &scan_decimated,
1834 CRenderizablePtr
obj = map_obj->getByName(scan_name.str());
1835 CSetOfObjectsPtr scan_obj =
static_cast<CSetOfObjectsPtr
>(
obj);
1837 scan_obj = CSetOfObjects::Create();
1844 scan_obj->setName(scan_name.str());
1845 this->setObjectPropsFromNodeID(*node_it, scan_obj);
1851 stringstream prev_scan_name(
"");
1852 prev_scan_name <<
"laser_scan_" << *node_it - 1;
1853 CRenderizablePtr prev_obj = map_obj->getByName(prev_scan_name.str());
1855 scan_obj->setVisibility(prev_obj->isVisible());
1859 map_obj->insert(scan_obj);
1862 scan_obj =
static_cast<CSetOfObjectsPtr
>(scan_obj);
1867 scan_obj->setPose(scan_pose);
1876 m_win->unlockAccess3DScene();
1877 m_win->forceRepaint();
1879 double elapsed_time = map_update_timer.
Tac();
1884 template<
class GRAPH_T>
1887 mrpt::opengl::CSetOfObjectsPtr& viz_object) {
1889 viz_object->setColor_u8(m_optimized_map_color);
1893 template<
class GRAPH_T>
1897 const int keep_every_n_entries ) {
1901 size_t scan_size = laser_scan_in.
scan.
size();
1904 std::vector<float> new_scan(scan_size);
1905 std::vector<char> new_validRange(scan_size);
1906 size_t new_scan_size = 0;
1907 for (
size_t i=0; i != scan_size; i++) {
1908 if (i % keep_every_n_entries == 0) {
1909 new_scan[new_scan_size] = laser_scan_in.
scan[i];
1910 new_validRange[new_scan_size] = laser_scan_in.
validRange[i];
1914 laser_scan_out->
loadFromVectors(new_scan_size, &new_scan[0], &new_validRange[0]);
1919 template<
class GRAPH_T>
1929 "Visualization of data was requested but no CDisplayWindow3D pointer was provided");
1932 CPointCloudPtr GT_cloud = CPointCloud::Create();
1933 GT_cloud->setPointSize(1.0);
1934 GT_cloud->enablePointSmooth();
1935 GT_cloud->enableColorFromX(
false);
1936 GT_cloud->enableColorFromY(
false);
1937 GT_cloud->enableColorFromZ(
false);
1938 GT_cloud->setColor_u8(m_GT_color);
1939 GT_cloud->setName(
"GT_cloud");
1942 CSetOfObjectsPtr robot_model = this->setCurrentPositionModel(
1945 m_robot_model_size);
1948 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1949 scene->insert(GT_cloud);
1950 scene->insert(robot_model);
1951 m_win->unlockAccess3DScene();
1953 m_win_manager->assignTextMessageParameters(
1956 m_win_manager->addTextMessage(m_offset_x_left, -m_offset_y_GT,
1961 m_win->forceRepaint();
1966 template<
class GRAPH_T>
1974 if (m_visualize_GT &&
1975 m_GT_poses_index < m_GT_poses.size()) {
1977 "Visualization of data was requested but no CDisplayWindow3D pointer was given");
1979 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
1981 CRenderizablePtr
obj = scene->getByName(
"GT_cloud");
1982 CPointCloudPtr GT_cloud =
static_cast<CPointCloudPtr
>(
obj);
1986 GT_cloud->insertPoint(
p.x(),
p.y(),
p.z());
1989 obj = scene->getByName(
"robot_GT");
1990 CSetOfObjectsPtr robot_obj =
static_cast<CSetOfObjectsPtr
>(
obj);
1991 robot_obj->setPose(
p);
1992 m_win->unlockAccess3DScene();
1993 m_win->forceRepaint();
1999 template<
class GRAPH_T>
2008 CPointCloudPtr odometry_poses_cloud = CPointCloud::Create();
2009 odometry_poses_cloud->setPointSize(1.0);
2010 odometry_poses_cloud->enablePointSmooth();
2011 odometry_poses_cloud->enableColorFromX(
false);
2012 odometry_poses_cloud->enableColorFromY(
false);
2013 odometry_poses_cloud->enableColorFromZ(
false);
2014 odometry_poses_cloud->setColor_u8(m_odometry_color);
2015 odometry_poses_cloud->setName(
"odometry_poses_cloud");
2018 CSetOfObjectsPtr robot_model = this->setCurrentPositionModel(
2019 "robot_odometry_poses",
2021 m_robot_model_size);
2024 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
2025 scene->insert(odometry_poses_cloud);
2026 scene->insert(robot_model);
2027 m_win->unlockAccess3DScene();
2029 m_win_manager->assignTextMessageParameters(
2030 &m_offset_y_odometry,
2031 &m_text_index_odometry);
2032 m_win_manager->addTextMessage(m_offset_x_left, -m_offset_y_odometry,
2035 m_text_index_odometry );
2037 m_win->forceRepaint();
2042 template<
class GRAPH_T>
2047 "Visualization of data was requested but no CDisplayWindow3D pointer was given");
2050 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
2053 CRenderizablePtr
obj = scene->getByName(
"odometry_poses_cloud");
2054 CPointCloudPtr odometry_poses_cloud =
static_cast<CPointCloudPtr
>(
obj);
2057 odometry_poses_cloud->insertPoint(
2063 obj = scene->getByName(
"robot_odometry_poses");
2064 CSetOfObjectsPtr robot_obj =
static_cast<CSetOfObjectsPtr
>(
obj);
2065 robot_obj->setPose(
p);
2067 m_win->unlockAccess3DScene();
2068 m_win->forceRepaint();
2073 template<
class GRAPH_T>
2081 CSetOfLinesPtr estimated_traj_setoflines = CSetOfLines::Create();
2082 estimated_traj_setoflines->setColor_u8(m_estimated_traj_color);
2083 estimated_traj_setoflines->setLineWidth(1.5);
2084 estimated_traj_setoflines->setName(
"estimated_traj_setoflines");
2087 estimated_traj_setoflines->appendLine(
2093 CSetOfObjectsPtr robot_model = this->setCurrentPositionModel(
2094 "robot_estimated_traj",
2095 m_estimated_traj_color,
2096 m_robot_model_size);
2099 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
2100 if (m_visualize_estimated_trajectory) {
2101 scene->insert(estimated_traj_setoflines);
2103 scene->insert(robot_model);
2104 m_win->unlockAccess3DScene();
2106 if (m_visualize_estimated_trajectory) {
2107 m_win_manager->assignTextMessageParameters( &m_offset_y_estimated_traj,
2108 &m_text_index_estimated_traj);
2109 m_win_manager->addTextMessage(m_offset_x_left, -m_offset_y_estimated_traj,
2111 TColorf(m_estimated_traj_color),
2112 m_text_index_estimated_traj );
2116 m_win->forceRepaint();
2121 template<
class GRAPH_T>
2129 ASSERT_(m_graph.nodeCount() != 0);
2131 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
2133 CRenderizablePtr
obj;
2134 if (m_visualize_estimated_trajectory) {
2136 obj = scene->getByName(
"estimated_traj_setoflines");
2137 CSetOfLinesPtr estimated_traj_setoflines =
2138 static_cast<CSetOfLinesPtr
>(
obj);
2142 std::set<mrpt::utils::TNodeID> nodes_set;
2145 this->getNodeIDsOfEstimatedTrajectory(&nodes_set);
2146 estimated_traj_setoflines->clear();
2148 estimated_traj_setoflines->appendLine(
2153 nodes_set.insert(m_graph.nodeCount()-1);
2159 it = nodes_set.begin();
2160 it != nodes_set.end(); ++it) {
2164 estimated_traj_setoflines->appendLineStrip(
2173 obj = scene->getByName(
"robot_estimated_traj");
2174 CSetOfObjectsPtr robot_obj =
static_cast<CSetOfObjectsPtr
>(
obj);
2175 pose_t curr_estimated_pos = m_graph.nodes[m_graph.nodeCount()-1];
2176 robot_obj->setPose(curr_estimated_pos);
2179 m_win->unlockAccess3DScene();
2180 m_win->forceRepaint();
2187 template<
class GRAPH_T>
2191 this->setRawlogFile(rawlog_fname);
2192 this->initTRGBDInfoFileParams();
2194 template<
class GRAPH_T>
2197 this->initTRGBDInfoFileParams();
2199 template<
class GRAPH_T>
2203 template<
class GRAPH_T>
2212 info_fname = dir + name_prefix + rawlog_filename + name_suffix;
2215 template<
class GRAPH_T>
2219 fields[
"Overall number of objects"] =
"";
2220 fields[
"Observations format"] =
"";
2223 template<
class GRAPH_T>
2226 using namespace std;
2232 "\nTRGBDInfoFileParams::parseFile: Couldn't open info file\n");
2235 size_t line_cnt = 0;
2241 if (curr_line.size() == 0)
2246 while (info_file.
readLine(curr_line)) {
2248 vector<string> curr_tokens;
2259 it != fields.end(); ++it) {
2261 it->second = value_part;
2271 template<
class GRAPH_T>
2283 fname =
"output_graph.graph";
2287 m_graph.saveToTextFile(fname);
2292 template<
class GRAPH_T>
2297 "\nsave3DScene was called even though enable_visuals flag is off.\nExiting...\n");
2301 COpenGLScenePtr scene = m_win->get3DSceneAndLock();
2303 if (!scene.present()) {
2311 CPlanarLaserScanPtr laser_scan;
2314 scene->removeObject(laser_scan);
2324 fname =
"output_scene.3DScene";
2328 scene->saveToFile(fname);
2330 m_win->unlockAccess3DScene();
2331 m_win->forceRepaint();
2336 template<
class GRAPH_T>
2344 if ( m_graph.nodeCount() < 4 ) {
2349 m_nodeID_to_gt_indices[nodeID] = gt_index;
2356 double trans_diff = 0;
2357 double rot_diff = 0;
2359 size_t indices_size = m_nodeID_to_gt_indices.size();
2362 m_curr_deformation_energy = 0;
2368 m_nodeID_to_gt_indices.begin();
2376 pose_t prev_node_pos = m_graph.nodes[prev_it->first];
2377 pose_t prev_gt_pos = m_GT_poses[prev_it->second];
2383 index_it = start_it;
2384 index_it != m_nodeID_to_gt_indices.end();
2386 curr_node_pos = m_graph.nodes[index_it->first];
2387 curr_gt_pos = m_GT_poses[index_it->second];
2389 node_delta_pos = curr_node_pos - prev_node_pos;
2390 gt_delta = curr_gt_pos - prev_gt_pos;
2392 trans_diff = gt_delta.distanceTo(node_delta_pos);
2393 rot_diff = this->accumulateAngleDiffs(gt_delta, node_delta_pos);
2395 m_curr_deformation_energy += (pow(trans_diff, 2) + pow(rot_diff, 2));
2396 m_curr_deformation_energy /= indices_size;
2399 m_deformation_energy_vec.push_back(m_curr_deformation_energy);
2401 prev_node_pos = curr_node_pos;
2402 prev_gt_pos = curr_gt_pos;
2410 template<
class GRAPH_T>
2416 template<
class GRAPH_T>
2430 template<
class GRAPH_T>
2433 using namespace std;
2439 ASSERT_(m_visualize_SLAM_metric);
2442 m_win_plot =
new CDisplayWindowPlots(
"Evolution of SLAM metric - Deformation Energy (1:1000)", 400, 300);
2445 m_win_plot->setPos(20, 50);
2448 m_win_plot->hold_off();
2449 m_win_plot->enableMousePanZoom(
true);
2454 template<
class GRAPH_T>
2458 ASSERT_(m_win_plot && m_visualize_SLAM_metric);
2461 std::vector<double>
x(m_deformation_energy_vec.size(), 0);
2462 std::vector<double>
y(m_deformation_energy_vec.size(), 0);
2463 for (
size_t i = 0; i !=
x.size(); i++) {
2465 y[i] = m_deformation_energy_vec[i]*1000;
2468 m_win_plot->plot(
x,
y,
"r-1",
2469 "Deformation Energy (x1000)");
2474 xmax = std::max_element(
x.begin(),
x.end());
2475 ymax = std::max_element(
y.begin(),
y.end());
2477 m_win_plot->axis( xmax !=
x.end()? -(*xmax/12) : -1,
2478 (xmax !=
x.end()? *xmax : 1),
2480 (ymax !=
y.end()? *ymax : 1) ) ;
2486 template<
class GRAPH_T>
2489 using namespace std;
2493 stringstream results_ss;
2494 results_ss <<
"Summary: " << std::endl;
2495 results_ss << this->header_sep << std::endl;
2496 results_ss <<
"\tProcessing time: " <<
2497 m_time_logger.getMeanTime(
"proc_time") << std::endl;;
2498 results_ss <<
"\tDataset Grab time: " << m_dataset_grab_time << std::endl;
2499 results_ss <<
"\tReal-time capable: " <<
2500 (m_time_logger.getMeanTime(
"proc_time") < m_dataset_grab_time ?
2501 "TRUE":
"FALSE") << std::endl;
2502 results_ss << m_edge_counter.getAsString();
2503 results_ss <<
"\tNum of Nodes: " << m_graph.nodeCount() << std::endl;;
2506 std::string config_params = this->getParamsAsString();
2509 const std::string time_res = m_time_logger.getStatsAsText();
2510 const std::string output_res = this->getLogAsString();
2513 report_str->clear();
2515 *report_str += results_ss.str();
2516 *report_str += this->report_sep;
2518 *report_str += config_params;
2519 *report_str += this->report_sep;
2521 *report_str += time_res;
2522 *report_str += this->report_sep;
2524 *report_str += output_res;
2525 *report_str += this->report_sep;
2530 template<
class GRAPH_T>
2532 std::map<std::string, int>* node_stats,
2533 std::map<std::string, int>* edge_stats,
2536 using namespace std;
2539 ASSERTMSG_(node_stats,
"Invalid pointer to node_stats is given");
2540 ASSERTMSG_(edge_stats,
"Invalid pointer to edge_stats is given");
2542 if (m_nodeID_max == 0) {
2547 (*node_stats)[
"nodes_total"] = m_nodeID_max + 1;
2551 it != m_edge_counter.end();
2553 (*edge_stats)[it->first] = it->second;
2556 (*edge_stats)[
"loop_closures"] = m_edge_counter.getLoopClosureEdges();
2557 (*edge_stats)[
"edges_total"] = m_edge_counter.getTotalNumOfEdges();
2561 *timestamp = m_curr_timestamp;
2568 template<
class GRAPH_T>
2574 using namespace mrpt;
2577 format(
"Output directory \"%s\" doesn't exist",
2578 output_dir_fname.c_str()));
2589 fname = output_dir_fname +
"/" + m_class_name + ext;
2592 this->initResultsFile(fname);
2595 this->getDescriptiveReport(&report_str);
2596 m_out_streams[fname]->printf(
"%s", report_str.c_str());
2600 fname = output_dir_fname +
"/" +
"node_registrar" + ext;
2601 this->initResultsFile(fname);
2602 m_node_reg->getDescriptiveReport(&report_str);
2603 m_out_streams[fname]->printf(
"%s", report_str.c_str());
2607 fname = output_dir_fname +
"/" +
"edge_registrar" + ext;
2608 this->initResultsFile(fname);
2609 m_edge_reg->getDescriptiveReport(&report_str);
2610 m_out_streams[fname]->printf(
"%s", report_str.c_str());
2614 fname = output_dir_fname +
"/" +
"optimizer" + ext;
2615 this->initResultsFile(fname);
2616 m_optimizer->getDescriptiveReport(&report_str);
2617 m_out_streams[fname]->printf(
"%s", report_str.c_str());
2622 const std::string desc(
"# File includes the evolution of the SLAM metric. Implemented metric computes the \"deformation energy\" that is needed to transfer the estimated trajectory into the ground-truth trajectory (computed as sum of the difference between estimated trajectory and ground truth consecutive poses See \"A comparison of SLAM algorithms based on a graph of relations - W.Burgard et al.\", for more details on the metric.\n");
2624 fname = output_dir_fname +
"/" +
"SLAM_evaluation_metric" + ext;
2625 this->initResultsFile(fname);
2627 m_out_streams[fname]->printf(
"%s\n", desc.c_str());
2629 vec_it = m_deformation_energy_vec.begin();
2630 vec_it != m_deformation_energy_vec.end(); ++vec_it) {
2631 m_out_streams[fname]->printf(
"%f\n", *vec_it);
2637 template<
class GRAPH_T>
2638 mrpt::opengl::CSetOfObjectsPtr
2642 const size_t model_size,
2643 const pose_t& init_pose) {
2646 ASSERTMSG_(!model_name.empty(),
"Model name provided is empty.");
2648 mrpt::opengl::CSetOfObjectsPtr
model =
2649 this->initRobotModelVisualization();
2650 model->setName(model_name);
2651 model->setColor_u8(model_color);
2652 model->setScale(model_size);
2653 model->setPose(init_pose);
2659 template<
class GRAPH_T>
2661 std::vector<double>* vec_out)
const {
2665 *vec_out = m_deformation_energy_vec;
void updateOdometryVisualization()
Update odometry-only cloud with latest odometry estimation.
#define ASSERT_EQUAL_(__A, __B)
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
void updateMapVisualization(const std::map< mrpt::utils::TNodeID, mrpt::obs::CObservation2DRangeScanPtr > &nodes_to_laser_scans2D, bool full_update=false)
Update the map visualization based on the current graphSLAM state.
A class acquiring a CCriticalSection at its constructor, and releasing it at destructor.
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
void queryObserverForEvents()
Query the observer instance for any user events.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
void parseFile()
Parse the RGBD information file to gain information about the rawlog file contents.
void save3DScene(const std::string *fname_in=NULL) const
Wrapper method around the COpenGLScene::saveToFile method.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
void updateGTVisualization()
Display the next ground truth position in the visualization window.
Create a GUI window and display plots with MATLAB-like interfaces and commands.
void computeMap() const
Compute the map of the environment based on the recorded measurements.
void toggleMapVisualization()
void computeSlamMetric(mrpt::utils::TNodeID nodeID, size_t gt_index)
Compare the SLAM result (estimated trajectory) with the GT path.
virtual void getNodeIDsOfEstimatedTrajectory(std::set< mrpt::utils::TNodeID > *nodes_set) const
Return the list of nodeIDs which make up robot trajectory.
A class for storing images as grayscale or RGB bitmaps.
mrpt::system::TTimeStamp BASE_IMPEXP getCurrentTime()
Returns the current (UTC) system time.
void updateSlamMetricVisualization()
Update the displayPlots window with the new information with regards to the metric.
T y() const
Return y coordinate of the quaternion.
Interface for implementing node registration classes.
void initOdometryVisualization()
This class allows loading and storing values and vectors of different types from ".ini" files easily.
void BASE_IMPEXP pause(const std::string &msg=std::string("Press any key to continue...")) MRPT_NO_THROWS
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
#define THROW_EXCEPTION(msg)
static mrpt::system::TTimeStamp getTimeStamp(const mrpt::obs::CActionCollectionPtr action, const mrpt::obs::CSensoryFramePtr observations, const mrpt::obs::CObservationPtr observation)
Fill the TTimestamp in a consistent manner.
bool BASE_IMPEXP fileExists(const std::string &fileName)
Test if a given file (or directory) exists.
bool execGraphSlamStep(mrpt::obs::CObservationPtr &observation, size_t &rawlog_entry)
Wrapper method around _execGraphSlamStep.
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
global_pose_t getCurrentRobotPosEstimation() const
Query CGraphSlamEngine instance for the current estimated robot position.
void initRangeImageViewport()
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
double pitch() const
Get the PITCH angle (in radians)
Interface for implementing edge registration classes.
double yaw() const
Get the YAW angle (in radians)
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans. ...
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
CSetOfObjectsPtr OPENGL_IMPEXP CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner.
std::string BASE_IMPEXP timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM.
std::string BASE_IMPEXP fileNameStripInvalidChars(const std::string &filename, const char replacement_to_invalid_chars='_')
Replace invalid filename chars by underscores ('_') or any other user-given char. ...
const Scalar * const_iterator
mrpt::opengl::CSetOfObjectsPtr setCurrentPositionModel(const std::string &model_name, const mrpt::utils::TColor &model_color=mrpt::utils::TColor(0, 0, 0), const size_t model_size=1, const pose_t &init_pose=pose_t())
Set the opengl model that indicates the latest position of the trajectory at hand.
const_iterator find(const KEY &key) const
void initGTVisualization()
void Tic()
Starts the stopwatch.
GLsizei GLsizei GLuint * obj
GLubyte GLubyte GLubyte GLubyte w
virtual void monitorNodeRegistration(bool registered=false, std::string class_name="Class")
Assert that the given nodes number matches the registered graph nodes, otherwise throw exception...
void loadParams(const std::string &fname)
Read the configuration variables from the .ini file specified by the user.
std::deque< CObservationPtr >::const_iterator const_iterator
You can use CSensoryFrame::begin to get a iterator to the first element.
mrpt::system::TTimeStamp BASE_IMPEXP getCurrentLocalTime()
Returns the current (local) time.
virtual void getRobotEstimatedTrajectory(typename GRAPH_T::global_poses_t *graph_poses) const
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
void updateAllVisuals()
Wrapper around the deciders/optimizer updateVisuals methods.
GRAPH_T::constraint_t constraint_t
Type of graph constraints.
static double accumulateAngleDiffs(const mrpt::poses::CPose2D &p1, const mrpt::poses::CPose2D &p2)
This base provides a set of functions for maths stuff.
static const std::string report_sep
virtual void setObjectPropsFromNodeID(const mrpt::utils::TNodeID nodeID, mrpt::opengl::CSetOfObjectsPtr &viz_object)
Set the properties of the map visual object based on the nodeID that it was produced by...
T r() const
Return r coordinate of the quaternion.
GRAPH_T::constraint_t::type_value pose_t
Type of underlying poses (2D/3D).
uint64_t TNodeID
The type for node IDs in graphs of different types.
void alignOpticalWithMRPTFrame()
void initTRGBDInfoFileParams()
This CStream derived class allow using a file as a write-only, binary stream.
void execDijkstraNodesEstimation()
Wrapper around the GRAPH_T::dijkstra_nodes_estimate.
void updateIntensityImageViewport()
In RGB-D TUM Datasets update the Intensity image displayed in a seperate viewport.
void BASE_IMPEXP sleep(int time_ms) MRPT_NO_THROWS
An OS-independent method for sending the current thread to "sleep" for a given period of time...
This class implements a high-performance stopwatch.
This namespace contains representation of robot actions and observations.
virtual void getAs3DObject(mrpt::opengl::CSetOfObjectsPtr &outObj) const MRPT_OVERRIDE
Returns a 3D object representing the map.
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< char > > validRange
It's false (=0) on no reflected rays, referenced to elements in scan.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
This object renders a 2D laser scan by means of three elements: the points, the line along end-points...
virtual void updateCurrPosViewport()
Update the viewport responsible for displaying the graph-building procedure in the estimated position...
CGraphSlamEngine(const std::string &config_file, const std::string &rawlog_fname="", const std::string &fname_GT="", mrpt::graphslam::CWindowManager *win_manager=NULL, mrpt::graphslam::deciders::CNodeRegistrationDecider< GRAPH_T > *node_reg=NULL, mrpt::graphslam::deciders::CEdgeRegistrationDecider< GRAPH_T > *edge_reg=NULL, mrpt::graphslam::optimizers::CGraphSlamOptimizer< GRAPH_T > *optimizer=NULL)
Constructor of CGraphSlamEngine class template.
#define MRPT_LOG_WARN_STREAM(__CONTENTS)
uint64_t TNodeID
The type for node IDs in graphs of different types.
void updateEstimatedTrajectoryVisualization(bool full_update=false)
Update the Esstimated robot trajectory with the latest estimated robot position.
CSetOfObjectsPtr OPENGL_IMPEXP RobotPioneer()
Returns a representation of a Pioneer II mobile base.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
void initEstimatedTrajectoryVisualization()
GLsizei const GLchar ** string
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
mrpt::opengl::CSetOfObjectsPtr initRobotModelVisualizationInternal(const mrpt::poses::CPose2D &p_unused)
Method to help overcome the partial template specialization restriction of C++.
virtual ~CGraphSlamEngine()
Default Destructor.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
void getDescriptiveReport(std::string *report_str) const
Fill the provided string with a detailed report of the class state.
double roll() const
Get the ROLL angle (in radians)
static const std::string header_sep
Separator string to be used in debugging messages.
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
void toggleEstimatedTrajectoryVisualization()
std::map< std::string, mrpt::utils::CFileOutputStream * >::iterator fstreams_out_it
Map for iterating over output file streams.
void initIntensityImageViewport()
void toggleOdometryVisualization()
static COccupancyGridMap2DPtr Create()
void saveGraph(const std::string *fname_in=NULL) const
Wrapper method around the GRAPH_T::saveToTextFile method.
mrpt::opengl::CSetOfObjectsPtr initRobotModelVisualization()
void initMapVisualization()
void printParams() const
Print the problem parameters to the console for verification.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GRAPH_T::global_pose_t global_pose_t
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
static void readGTFile(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=NULL)
Parse the ground truth .txt file and fill in the corresponding gt_poses vector.
T x() const
Return x coordinate of the quaternion.
#define MRPT_LOG_INFO_STREAM(__CONTENTS)
GLdouble GLdouble GLdouble r
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
std::string BASE_IMPEXP dateTimeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC time): YEAR/MONTH/DAY,HH:MM:SS.MMM.
void setRawlogFile(const std::string &rawlog_fname)
std::map< std::string, int >::const_iterator const_iterator
const double & phi() const
Get the phi angle of the 2D pose (in radians)
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
void decimateLaserScan(mrpt::obs::CObservation2DRangeScan &laser_scan_in, mrpt::obs::CObservation2DRangeScan *laser_scan_out, const int keep_every_n_entries=2)
Cut down on the size of the given laser scan.
void getDeformationEnergyVector(std::vector< double > *vec_out) const
Fill the given vector with the deformation energy values computed for the SLAM evaluation metric...
The namespace for 3D scene representation and rendering.
double Tac()
Stops the stopwatch.
A RGB color - floats in the range [0,1].
A matrix of dynamic size.
#define ASSERT_FILE_EXISTS_(FIL)
void loadFromVectors(size_t nRays, const float *scanRanges, const char *scanValidity)
std::string BASE_IMPEXP trim(const std::string &str)
Removes leading and trailing spaces.
virtual mrpt::poses::CPose3D getLSPoseForGridMapVisualization(const mrpt::utils::TNodeID nodeID) const
return the 3D Pose of a LaserScan that is to be visualized.
Classes for creating GUI windows for 2D and 3D visualization.
void toggleGTVisualization()
bool getGraphSlamStats(std::map< std::string, int > *node_stats, std::map< std::string, int > *edge_stats, mrpt::system::TTimeStamp *timestamp=NULL)
Fill the given maps with stats regarding the overall execution of graphslam.
std::string getParamsAsString() const
Wrapper around getParamsAsString.
bool BASE_IMPEXP directoryExists(const std::string &fileName)
Test if a given directory exists (it fails if the given path refers to an existing file)...
static void readGTFileRGBD_TUM(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=NULL)
Parse the ground truth .txt file and fill in the corresponding m_GT_poses vector. ...
double BASE_IMPEXP timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds...
An observation of the current (cumulative) odometry for a wheeled robot.
A quaternion, which can represent a 3D rotation as pair , with a real part "r" and a 3D vector ...
mrpt::utils::ContainerReadOnlyProxyAccessor< std::vector< float > > scan
The range values of the scan, in meters. Must have same length than validRange.
std::string BASE_IMPEXP extractFileName(const std::string &filePath)
Extract just the name (without extension) of a filename from a complete path plus name plus extension...
T z() const
Return z coordinate of the quaternion.
bool BASE_IMPEXP strCmpI(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case insensitive)
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
void initCurrPosViewport()
#define ASSERTMSG_(f, __ERROR_MSG)
#define MRPT_LOG_ERROR_STREAM(__CONTENTS)
void BASE_IMPEXP tokenize(const std::string &inString, const std::string &inDelimiters, std::deque< std::string > &outTokens, bool skipBlankTokens=true) MRPT_NO_THROWS
Tokenizes a string according to a set of delimiting characters.
bool insertObservation(const mrpt::obs::CObservation *obs, const mrpt::poses::CPose3D *robotPose=NULL)
Insert the observation information into this map.
Internal auxiliary classes.
void dumpVisibilityErrorMsg(std::string viz_flag, int sleep_time=500)
Wrapper method that used for printing error messages in a consistent manner.
void rpy(T &roll, T &pitch, T &yaw) const
Return the yaw, pitch & roll angles associated to quaternion.
void initSlamMetricVisualization()
std::string BASE_IMPEXP extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension...
virtual bool _execGraphSlamStep(mrpt::obs::CActionCollectionPtr &action, mrpt::obs::CSensoryFramePtr &observations, mrpt::obs::CObservationPtr &observation, size_t &rawlog_entry)
Main class method responsible for parsing each measurement and for executing graphSLAM.
void updateRangeImageViewport()
In RGB-D TUM Datasets update the Range image displayed in a seperate viewport.
Class acts as a container for storing pointers to mrpt::gui::CDisplayWindow3D, mrpt::graphslam::CWind...
void generateReportFiles(const std::string &output_dir_fname_in)
Generate and write to a corresponding report for each of the respective self/decider/optimizer classe...
void getMap(mrpt::maps::COccupancyGridMap2DPtr map, mrpt::system::TTimeStamp *acquisition_time=NULL) const
static COctoMapPtr Create()
void initResultsFile(const std::string &fname)
Automate the creation and initialization of a results file relevant to the application.
void initClass()
General initialization method to call from the Class Constructors.