10 #ifndef CGRAPHSLAMENGINE_IMPL_H
11 #define CGRAPHSLAMENGINE_IMPL_H
26 template <
class GRAPH_T>
28 template <
class GRAPH_T>
34 template <
class GRAPH_T>
46 : m_node_reg(node_reg),
48 m_optimizer(optimizer),
49 m_enable_visuals(win_manager != nullptr),
50 m_config_fname(config_file),
51 m_rawlog_fname(rawlog_fname),
54 m_win_manager(win_manager),
55 m_paused_message(
"Program is paused. Press \"p/P\" to resume."),
56 m_text_index_paused_message(345),
57 m_odometry_color(0, 0, 255),
58 m_GT_color(0, 255, 0),
59 m_estimated_traj_color(255, 165, 0),
60 m_optimized_map_color(255, 0, 0),
61 m_current_constraint_type_color(255, 255, 255),
62 m_robot_model_size(1),
63 m_class_name(
"CGraphSlamEngine"),
64 m_is_first_time_node_reg(true)
69 template <
class GRAPH_T>
76 "In Destructor: Deleting CGraphSlamEngine instance...");
96 template <
class GRAPH_T>
97 typename GRAPH_T::global_pose_t
100 std::lock_guard<std::mutex> graph_lock(m_graph_section);
101 return m_node_reg->getCurrentRobotPosEstimation();
104 template <
class GRAPH_T>
105 typename GRAPH_T::global_poses_t
108 std::lock_guard<std::mutex> graph_lock(m_graph_section);
109 return m_graph.nodes;
112 template <
class GRAPH_T>
114 std::set<mrpt::graphs::TNodeID>* nodes_set)
const
117 m_graph.getAllNodes(*nodes_set);
120 template <
class GRAPH_T>
124 using namespace mrpt;
129 m_time_logger.setName(m_class_name);
130 this->logging_enable_keep_record =
true;
131 this->setLoggerName(m_class_name);
143 m_supported_constraint_types.push_back(
"CPosePDFGaussianInf");
144 m_supported_constraint_types.push_back(
"CPose3DPDFGaussianInf");
147 const string c_str(
c.GetRuntimeClass()->className);
151 m_supported_constraint_types.begin(),
152 m_supported_constraint_types.end(),
153 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)
176 m_win = m_win_manager->win;
177 m_win_observer = m_win_manager->observer;
182 m_win_observer =
nullptr;
190 m_win_plot =
nullptr;
192 m_observation_only_dataset =
false;
193 m_request_to_exit =
false;
199 m_GT_poses_index = 0;
203 m_node_reg->setGraphPtr(&m_graph);
204 m_edge_reg->setGraphPtr(&m_graph);
205 m_optimizer->setGraphPtr(&m_graph);
209 if (m_enable_visuals)
211 m_node_reg->setWindowManagerPtr(m_win_manager);
212 m_edge_reg->setWindowManagerPtr(m_win_manager);
213 m_optimizer->setWindowManagerPtr(m_win_manager);
214 m_edge_counter.setWindowManagerPtr(m_win_manager);
218 m_node_reg->setCriticalSectionPtr(&m_graph_section);
219 m_edge_reg->setCriticalSectionPtr(&m_graph_section);
220 m_optimizer->setCriticalSectionPtr(&m_graph_section);
224 this->loadParams(m_config_fname);
226 if (!m_enable_visuals)
229 m_visualize_odometry_poses = 0;
232 m_visualize_estimated_trajectory = 0;
233 m_visualize_SLAM_metric = 0;
234 m_enable_curr_pos_viewport = 0;
235 m_enable_range_viewport = 0;
236 m_enable_intensity_viewport = 0;
239 m_use_GT = !m_fname_GT.empty();
245 this->alignOpticalWithMRPTFrame();
250 this->readGTFile(m_fname_GT, &m_GT_poses);
258 "Ground truth file was not provided. Switching the related "
259 "visualization parameters off...");
261 m_visualize_SLAM_metric = 0;
265 if (m_enable_visuals)
267 m_win_manager->assignTextMessageParameters(
268 &m_offset_y_timestamp, &m_text_index_timestamp);
273 this->initMapVisualization();
278 if (m_enable_visuals)
281 if (m_visualize_odometry_poses)
283 this->initOdometryVisualization();
288 this->initGTVisualization();
291 this->initEstimatedTrajectoryVisualization();
293 if (m_enable_curr_pos_viewport)
295 this->initCurrPosViewport();
308 m_img_external_storage_dir =
309 rawlog_dir + rawlog_fname_noext +
"_Images/";
316 if (m_enable_range_viewport)
318 this->initRangeImageViewport();
320 if (m_enable_intensity_viewport)
322 this->initIntensityImageViewport();
326 if (m_enable_visuals)
331 obj->setFrequency(5);
332 obj->enableTickMarks();
333 obj->setAxisLimits(-10, -10, -10, 10, 10, 10);
334 obj->setName(
"axis");
337 m_win->unlockAccess3DScene();
338 m_win->forceRepaint();
342 if (m_enable_visuals)
345 m_keystroke_pause_exec =
"p";
346 m_keystroke_odometry =
"o";
347 m_keystroke_GT =
"g";
348 m_keystroke_estimated_trajectory =
"t";
349 m_keystroke_map =
"m";
352 m_win_observer->registerKeystroke(
353 m_keystroke_pause_exec,
"Pause/Resume program execution");
354 m_win_observer->registerKeystroke(
355 m_keystroke_odometry,
"Toggle Odometry visualization");
356 m_win_observer->registerKeystroke(
357 m_keystroke_GT,
"Toggle Ground-Truth visualization");
358 m_win_observer->registerKeystroke(
359 m_keystroke_estimated_trajectory,
360 "Toggle Estimated trajectory visualization");
361 m_win_observer->registerKeystroke(
362 m_keystroke_map,
"Toggle Map visualization");
366 vector<string> vec_edge_types;
367 vec_edge_types.push_back(
"Odometry");
368 vec_edge_types.push_back(
"ICP2D");
369 vec_edge_types.push_back(
"ICP3D");
372 cit != vec_edge_types.end(); ++cit)
374 m_edge_counter.addEdgeType(*cit);
378 if (m_enable_visuals)
381 double offset_y_total_edges, offset_y_loop_closures;
382 int text_index_total_edges, text_index_loop_closures;
384 m_win_manager->assignTextMessageParameters(
385 &offset_y_total_edges, &text_index_total_edges);
388 map<string, double> name_to_offset_y;
389 map<string, int> name_to_text_index;
391 it != vec_edge_types.end(); ++it)
393 m_win_manager->assignTextMessageParameters(
394 &name_to_offset_y[*it], &name_to_text_index[*it]);
397 m_win_manager->assignTextMessageParameters(
398 &offset_y_loop_closures, &text_index_loop_closures);
401 m_edge_counter.setTextMessageParams(
402 name_to_offset_y, name_to_text_index, offset_y_total_edges,
403 text_index_total_edges, offset_y_loop_closures,
404 text_index_loop_closures);
408 if (m_enable_visuals)
410 m_win_manager->assignTextMessageParameters(
411 &m_offset_y_current_constraint_type,
412 &m_text_index_current_constraint_type);
413 m_win_manager->addTextMessage(
414 m_offset_x_left, -m_offset_y_current_constraint_type,
415 m_current_constraint_type,
417 m_text_index_current_constraint_type);
421 if (m_enable_visuals)
423 std::lock_guard<std::mutex> graph_lock(m_graph_section);
424 m_time_logger.enter(
"Visuals");
425 m_node_reg->initializeVisuals();
426 m_edge_reg->initializeVisuals();
427 m_optimizer->initializeVisuals();
428 m_time_logger.leave(
"Visuals");
436 mrpt::make_aligned_shared<mrpt::maps::COccupancyGridMap2D>();
447 gridmap->insertionOptions.maxOccupancyUpdateCertainty = 0.8f;
448 gridmap->insertionOptions.maxDistanceInsertion = 5;
449 gridmap->insertionOptions.wideningBeamsWithDistance =
true;
450 gridmap->insertionOptions.decimation = 2;
452 m_gridmap_cached = gridmap;
453 m_map_is_cached =
false;
459 mrpt::make_aligned_shared<mrpt::maps::COctoMap>();
463 octomap->insertionOptions.setOccupancyThres(0.5);
464 octomap->insertionOptions.setProbHit(0.7);
465 octomap->insertionOptions.setProbMiss(0.4);
466 octomap->insertionOptions.setClampingThresMin(0.1192);
467 octomap->insertionOptions.setClampingThresMax(0.971);
470 m_map_is_cached =
false;
477 m_info_params.setRawlogFile(m_rawlog_fname);
478 m_info_params.parseFile();
480 int num_of_objects = std::atoi(
481 m_info_params.fields[
"Overall number of objects"].c_str());
482 m_GT_poses_step = m_GT_poses.size() / num_of_objects;
485 "Overall number of objects in rawlog: " << num_of_objects);
487 "Setting the Ground truth read step to: " << m_GT_poses_step);
489 catch (std::exception& e)
495 m_curr_deformation_energy = 0;
496 if (m_visualize_SLAM_metric)
498 this->initSlamMetricVisualization();
502 if (m_enable_visuals)
504 this->m_win->addTextMessage(
506 m_text_index_paused_message);
512 template <
class GRAPH_T>
521 return this->_execGraphSlamStep(
522 action, observations, observation, rawlog_entry);
525 template <
class GRAPH_T>
534 using namespace mrpt;
541 m_time_logger.enter(
"proc_time");
545 format(
"\nConfig file is not read yet.\nExiting... \n"));
551 m_init_timestamp = getTimeStamp(action, observations, observation);
557 m_observation_only_dataset =
true;
563 m_observation_only_dataset =
false;
566 action->getFirstMovementEstimationMean(increment_pose_3d);
567 pose_t increment_pose(increment_pose_3d);
568 m_curr_odometry_only_pose += increment_pose;
576 bool registered_new_node;
578 std::lock_guard<std::mutex> graph_lock(m_graph_section);
579 m_time_logger.enter(
"node_registrar");
580 registered_new_node =
581 m_node_reg->updateState(action, observations, observation);
582 m_time_logger.leave(
"node_registrar");
587 getObservation<CObservation2DRangeScan>(observations, observation);
590 m_last_laser_scan2D = scan;
592 if (!m_first_laser_scan2D)
594 m_first_laser_scan2D = m_last_laser_scan2D;
599 if (registered_new_node)
603 if (m_is_first_time_node_reg)
605 std::lock_guard<std::mutex> graph_lock(m_graph_section);
607 if (m_graph.nodeCount() != 2)
610 "Expected [2] new registered nodes"
611 <<
" but got [" << m_graph.nodeCount() <<
"]");
615 m_nodes_to_laser_scans2D.insert(
616 make_pair(m_nodeID_max, m_first_laser_scan2D));
618 m_is_first_time_node_reg =
false;
625 m_edge_counter.addEdge(
"Odometry");
627 this->monitorNodeRegistration(
628 registered_new_node,
"NodeRegistrationDecider");
634 std::lock_guard<std::mutex> graph_lock(m_graph_section);
636 m_time_logger.enter(
"edge_registrar");
637 m_edge_reg->updateState(action, observations, observation);
638 m_time_logger.leave(
"edge_registrar");
640 this->monitorNodeRegistration(
641 registered_new_node,
"EdgeRegistrationDecider");
644 std::lock_guard<std::mutex> graph_lock(m_graph_section);
646 m_time_logger.enter(
"optimizer");
647 m_optimizer->updateState(action, observations, observation);
648 m_time_logger.leave(
"optimizer");
650 this->monitorNodeRegistration(registered_new_node,
"GraphSlamOptimizer");
653 m_curr_timestamp = getTimeStamp(action, observations, observation);
664 std::dynamic_pointer_cast<CObservationOdometry>(observation);
666 m_curr_odometry_only_pose =
pose_t(obs_odometry->odometry);
667 m_odometry_poses.push_back(m_curr_odometry_only_pose);
671 m_last_laser_scan3D =
672 std::dynamic_pointer_cast<mrpt::obs::CObservation3DRangeScan>(
684 action->getFirstMovementEstimationMean(increment_pose_3d);
685 pose_t increment_pose(increment_pose_3d);
686 m_curr_odometry_only_pose += increment_pose;
687 m_odometry_poses.push_back(m_curr_odometry_only_pose);
690 if (registered_new_node)
692 this->execDijkstraNodesEstimation();
695 m_nodes_to_laser_scans2D[m_nodeID_max] = m_last_laser_scan2D;
697 if (m_enable_visuals && m_visualize_map)
699 std::lock_guard<std::mutex> graph_lock(m_graph_section);
701 bool full_update =
true;
702 this->updateMapVisualization(m_nodes_to_laser_scans2D, full_update);
706 if (m_enable_visuals)
708 this->updateAllVisuals();
712 std::map<std::string, int> edge_types_to_nums;
713 m_edge_reg->getEdgesStats(&edge_types_to_nums);
714 if (edge_types_to_nums.size())
717 edge_types_to_nums.begin();
718 it != edge_types_to_nums.end(); ++it)
723 m_edge_counter.setLoopClosureEdgesManually(it->second);
727 m_edge_counter.setEdgesManually(it->first, it->second);
734 if (m_enable_curr_pos_viewport)
736 updateCurrPosViewport();
739 if (m_enable_visuals)
741 bool full_update =
true;
742 m_time_logger.enter(
"Visuals");
743 this->updateEstimatedTrajectoryVisualization(full_update);
744 m_time_logger.leave(
"Visuals");
751 m_time_logger.enter(
"SLAM_metric");
752 this->computeSlamMetric(m_nodeID_max, m_GT_poses_index);
753 m_time_logger.leave(
"SLAM_metric");
754 if (m_visualize_SLAM_metric)
756 m_time_logger.enter(
"Visuals");
757 this->updateSlamMetricVisualization();
758 m_time_logger.leave(
"Visuals");
763 m_map_is_cached =
false;
770 m_time_logger.enter(
"Visuals");
774 if (m_enable_visuals)
778 m_win_manager->addTextMessage(
779 m_offset_x_left, -m_offset_y_timestamp,
781 "Simulated time: %s",
784 m_text_index_timestamp);
788 m_win_manager->addTextMessage(
789 m_offset_x_left, -m_offset_y_timestamp,
794 m_text_index_timestamp);
799 if (m_visualize_odometry_poses && m_odometry_poses.size())
801 this->updateOdometryVisualization();
810 if (m_enable_visuals)
812 this->updateGTVisualization();
815 m_GT_poses_index += m_GT_poses_step;
819 if (m_observation_only_dataset)
821 if (rawlog_entry % 2 == 0)
823 if (m_enable_visuals)
825 this->updateGTVisualization();
828 m_GT_poses_index += m_GT_poses_step;
835 if (m_enable_visuals)
837 this->updateGTVisualization();
840 m_GT_poses_index += m_GT_poses_step;
848 if (m_enable_range_viewport && m_last_laser_scan3D)
850 this->updateRangeImageViewport();
853 if (m_enable_intensity_viewport && m_last_laser_scan3D)
855 this->updateIntensityImageViewport();
860 if (m_enable_visuals)
862 this->queryObserverForEvents();
864 m_time_logger.leave(
"Visuals");
866 m_dataset_grab_time =
868 m_time_logger.leave(
"proc_time");
870 return !m_request_to_exit;
874 template <
class GRAPH_T>
878 std::lock_guard<std::mutex> graph_lock(m_graph_section);
879 m_time_logger.enter(
"dijkstra_nodes_estimation");
880 m_graph.dijkstra_nodes_estimate();
881 m_time_logger.leave(
"dijkstra_nodes_estimation");
885 template <
class GRAPH_T>
890 using namespace mrpt;
892 std::lock_guard<std::mutex> graph_lock(m_graph_section);
893 size_t listed_nodeCount =
899 listed_nodeCount == m_graph.nodeCount(),
901 "listed_nodeCount [%lu] != nodeCount() [%lu]",
902 static_cast<unsigned long>(listed_nodeCount),
903 static_cast<unsigned long>(m_graph.nodeCount())));
907 if (listed_nodeCount != m_graph.nodeCount())
910 class_name <<
" illegally added new nodes to the graph "
911 <<
", wanted to see [" << listed_nodeCount
912 <<
"] but saw [" << m_graph.nodeCount() <<
"]");
914 format(
"Illegal node registration by %s.", class_name.c_str()));
920 template <
class GRAPH_T>
929 map = mrpt::make_aligned_shared<mrpt::maps::COccupancyGridMap2D>();
933 if (!m_map_is_cached)
937 map->copyMapContentFrom(*m_gridmap_cached);
940 if (acquisition_time)
942 *acquisition_time = m_map_acq_time;
947 template <
class GRAPH_T>
955 if (!m_map_is_cached)
964 if (acquisition_time)
966 *acquisition_time = m_map_acq_time;
972 template <
class GRAPH_T>
977 using namespace mrpt;
981 std::lock_guard<std::mutex> graph_lock(m_graph_section);
983 if (!constraint_t::is_3D())
993 it = m_nodes_to_laser_scans2D.begin();
994 it != m_nodes_to_laser_scans2D.end(); ++it)
1003 "LaserScan of nodeID: %lu is not present.",
1004 static_cast<unsigned long>(curr_node)));
1007 CPose3D scan_pose = getLSPoseForGridMapVisualization(curr_node);
1010 gridmap->insertObservation(curr_laser_scan.get(), &scan_pose);
1013 m_map_is_cached =
true;
1019 THROW_EXCEPTION(
"Not Implemented Yet. Method is to compute a COctoMap");
1026 template <
class GRAPH_T>
1033 mrpt::format(
"\nConfiguration file not found: \n%s\n", fname.c_str()));
1041 m_user_decides_about_output_dir = cfg_file.
read_bool(
1042 "GeneralConfiguration",
"user_decides_about_output_dir",
false,
false);
1044 "GeneralConfiguration",
"ground_truth_file_format",
"NavSimul",
false);
1047 int min_verbosity_level =
1048 cfg_file.
read_int(
"GeneralConfiguration",
"class_verbosity", 1,
false);
1056 "VisualizationParameters",
"visualize_map",
true,
false);
1059 m_visualize_odometry_poses = cfg_file.
read_bool(
1060 "VisualizationParameters",
"visualize_odometry_poses",
true,
false);
1061 m_visualize_estimated_trajectory = cfg_file.
read_bool(
1062 "VisualizationParameters",
"visualize_estimated_trajectory",
true,
1067 "VisualizationParameters",
"visualize_ground_truth",
true,
false);
1069 m_visualize_SLAM_metric = cfg_file.
read_bool(
1070 "VisualizationParameters",
"visualize_SLAM_metric",
true,
false);
1073 m_enable_curr_pos_viewport = cfg_file.
read_bool(
1074 "VisualizationParameters",
"enable_curr_pos_viewport",
true,
false);
1075 m_enable_range_viewport = cfg_file.
read_bool(
1076 "VisualizationParameters",
"enable_range_viewport",
false,
false);
1077 m_enable_intensity_viewport = cfg_file.
read_bool(
1078 "VisualizationParameters",
"enable_intensity_viewport",
false,
false);
1080 m_node_reg->loadParams(fname);
1081 m_edge_reg->loadParams(fname);
1082 m_optimizer->loadParams(fname);
1084 m_has_read_config =
true;
1087 template <
class GRAPH_T>
1093 this->getParamsAsString(&str);
1098 template <
class GRAPH_T>
1103 using namespace std;
1105 stringstream ss_out;
1108 <<
"\n------------[ Graphslam_engine Problem Parameters ]------------"
1110 ss_out <<
"Config filename = " << m_config_fname
1113 ss_out <<
"Ground Truth File format = " << m_GT_file_format
1115 ss_out <<
"Ground Truth filename = " << m_fname_GT << std::endl;
1117 ss_out <<
"Visualize odometry = "
1118 << (m_visualize_odometry_poses ?
"TRUE" :
"FALSE") << std::endl;
1119 ss_out <<
"Visualize estimated trajectory = "
1120 << (m_visualize_estimated_trajectory ?
"TRUE" :
"FALSE")
1122 ss_out <<
"Visualize map = "
1123 << (m_visualize_map ?
"TRUE" :
"FALSE") << std::endl;
1124 ss_out <<
"Visualize Ground Truth = "
1125 << (m_visualize_GT ?
"TRUE" :
"FALSE") << std::endl;
1127 ss_out <<
"Visualize SLAM metric plot = "
1128 << (m_visualize_SLAM_metric ?
"TRUE" :
"FALSE") << std::endl;
1130 ss_out <<
"Enable curr. position viewport = "
1131 << (m_enable_curr_pos_viewport ?
"TRUE" :
"FALSE") << endl;
1132 ss_out <<
"Enable range img viewport = "
1133 << (m_enable_range_viewport ?
"TRUE" :
"FALSE") << endl;
1134 ss_out <<
"Enable intensity img viewport = "
1135 << (m_enable_intensity_viewport ?
"TRUE" :
"FALSE") << endl;
1137 ss_out <<
"-----------------------------------------------------------"
1139 ss_out << std::endl;
1142 *params_out = ss_out.str();
1147 template <
class GRAPH_T>
1151 std::cout << getParamsAsString();
1153 m_node_reg->printParams();
1154 m_edge_reg->printParams();
1155 m_optimizer->printParams();
1160 template <
class GRAPH_T>
1164 using namespace std;
1170 #if defined(__APPLE__)
1180 m_out_streams[fname].open(fname);
1182 m_out_streams[fname].fileOpenCorrectly(),
1183 mrpt::format(
"\nError while trying to open %s\n", fname.c_str()));
1187 m_out_streams[fname].printf(
"# Mobile Robot Programming Toolkit (MRPT)\n");
1188 m_out_streams[fname].printf(
"# http::/www.mrpt.org\n");
1189 m_out_streams[fname].printf(
"# GraphSlamEngine Application\n");
1190 m_out_streams[fname].printf(
1191 "# Automatically generated file - %s: %s\n", time_spec.c_str(),
1192 cur_date_str.c_str());
1193 m_out_streams[fname].printf(
"%s\n\n", sep.c_str());
1198 template <
class GRAPH_T>
1208 viewp_range = scene->createViewport(
"viewp_range");
1210 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1211 viewp_range->setViewportPosition(
x,
y, h,
w);
1213 m_win->unlockAccess3DScene();
1214 m_win->forceRepaint();
1219 template <
class GRAPH_T>
1223 std::lock_guard<std::mutex> graph_lock(m_graph_section);
1224 m_time_logger.enter(
"Visuals");
1226 m_node_reg->updateVisuals();
1227 m_edge_reg->updateVisuals();
1228 m_optimizer->updateVisuals();
1230 m_time_logger.leave(
"Visuals");
1234 template <
class GRAPH_T>
1242 if (m_last_laser_scan3D->hasRangeImage)
1250 m_last_laser_scan3D->load();
1251 range2D = m_last_laser_scan3D->rangeImage *
1253 img.setFromMatrix(range2D);
1257 viewp_range->setImageView(
img);
1258 m_win->unlockAccess3DScene();
1259 m_win->forceRepaint();
1265 template <
class GRAPH_T>
1275 viewp_intensity = scene->createViewport(
"viewp_intensity");
1277 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1278 viewp_intensity->setViewportPosition(
x,
y,
w, h);
1280 m_win->unlockAccess3DScene();
1281 m_win->forceRepaint();
1285 template <
class GRAPH_T>
1292 if (m_last_laser_scan3D->hasIntensityImage)
1297 m_last_laser_scan3D->load();
1298 img = m_last_laser_scan3D->intensityImage;
1302 scene->getViewport(
"viewp_intensity");
1303 viewp_intensity->setImageView(
img);
1304 m_win->unlockAccess3DScene();
1305 m_win->forceRepaint();
1311 template <
class GRAPH_T>
1316 return this->initRobotModelVisualizationInternal(
p);
1319 template <
class GRAPH_T>
1328 template <
class GRAPH_T>
1336 template <
class GRAPH_T>
1345 scene->createViewport(
"curr_robot_pose_viewport");
1347 viewp->setCloneView(
"main");
1349 m_win_manager->assignViewportParameters(&
x, &
y, &
w, &h);
1350 viewp->setViewportPosition(
x,
y, h,
w);
1351 viewp->setTransparent(
false);
1352 viewp->getCamera().setAzimuthDegrees(90);
1353 viewp->getCamera().setElevationDegrees(90);
1354 viewp->setCustomBackgroundColor(
1356 viewp->getCamera().setZoomDistance(30);
1357 viewp->getCamera().setOrthogonal();
1359 m_win->unlockAccess3DScene();
1360 m_win->forceRepaint();
1365 template <
class GRAPH_T>
1375 global_pose_t curr_robot_pose = this->getCurrentRobotPosEstimation();
1379 viewp->getCamera().setPointingAt(
CPose3D(curr_robot_pose));
1381 m_win->unlockAccess3DScene();
1382 m_win->forceRepaint();
1388 template <
class GRAPH_T>
1390 const std::string& fname_GT, std::vector<mrpt::poses::CPose2D>* gt_poses,
1391 std::vector<mrpt::system::TTimeStamp>* gt_timestamps )
1394 using namespace std;
1401 "\nGround-truth file %s was not found.\n"
1402 "Either specify a valid ground-truth filename or set set the "
1403 "m_visualize_GT flag to false\n",
1408 ASSERTDEBMSG_(gt_poses,
"\nNo valid std::vector<pose_t>* was given\n");
1413 for (
size_t line_num = 0; file_GT.
readLine(curr_line); line_num++)
1415 vector<string> curr_tokens;
1420 curr_tokens.size() == constraint_t::state_length + 1,
1421 "\nGround Truth File doesn't seem to contain data as generated by "
1423 "GridMapNavSimul application.\n Either specify the GT file format "
1425 "visualize_ground_truth to false in the .ini file\n");
1431 gt_timestamps->push_back(timestamp);
1436 atof(curr_tokens[1].c_str()), atof(curr_tokens[2].c_str()),
1437 atof(curr_tokens[3].c_str()));
1438 gt_poses->push_back(curr_pose);
1445 template <
class GRAPH_T>
1447 const std::string& fname_GT, std::vector<mrpt::poses::CPose3D>* gt_poses,
1448 std::vector<mrpt::system::TTimeStamp>* gt_timestamps )
1453 template <
class GRAPH_T>
1455 const std::string& fname_GT, std::vector<mrpt::poses::CPose2D>* gt_poses,
1456 std::vector<mrpt::system::TTimeStamp>* gt_timestamps )
1459 using namespace std;
1467 "\nGround-truth file %s was not found.\n"
1468 "Either specify a valid ground-truth filename or set set the "
1469 "m_visualize_GT flag to false\n",
1475 "\nreadGTFileRGBD_TUM: Couldn't openGT file\n");
1476 ASSERTDEBMSG_(gt_poses,
"No valid std::vector<pose_t>* was given");
1481 for (
size_t i = 0; file_GT.
readLine(curr_line); i++)
1483 if (curr_line.at(0) !=
'#')
1492 vector<string> curr_tokens;
1497 curr_tokens.size() == 8,
1498 "\nGround Truth File doesn't seem to contain data as specified in "
1500 "datasets.\n Either specify correct the GT file format or set "
1501 "visualize_ground_truth to false in the .ini file\n");
1505 quat.
r(atof(curr_tokens[7].c_str()));
1506 quat.
x(atof(curr_tokens[4].c_str()));
1507 quat.
y(atof(curr_tokens[5].c_str()));
1508 quat.
z(atof(curr_tokens[6].c_str()));
1513 curr_coords[0] = atof(curr_tokens[1].c_str());
1514 curr_coords[1] = atof(curr_tokens[2].c_str());
1515 curr_coords[2] = atof(curr_tokens[3].c_str());
1518 pose_t curr_pose(curr_coords[0], curr_coords[1],
y);
1521 pose_diff = curr_pose;
1524 for (; file_GT.
readLine(curr_line);)
1528 curr_tokens.size() == 8,
1529 "\nGround Truth File doesn't seem to contain data as specified in "
1531 "datasets.\n Either specify correct the GT file format or set "
1532 "visualize_ground_truth to false in the .ini file\n");
1538 gt_timestamps->push_back(timestamp);
1542 quat.
r(atof(curr_tokens[7].c_str()));
1543 quat.
x(atof(curr_tokens[4].c_str()));
1544 quat.
y(atof(curr_tokens[5].c_str()));
1545 quat.
z(atof(curr_tokens[6].c_str()));
1549 curr_coords[0] = atof(curr_tokens[1].c_str());
1550 curr_coords[1] = atof(curr_tokens[2].c_str());
1551 curr_coords[2] = atof(curr_tokens[3].c_str());
1554 pose_t p(curr_coords[0], curr_coords[1],
y);
1556 p.x() -= pose_diff.x();
1557 p.y() -= pose_diff.y();
1558 p.phi() -= pose_diff.phi();
1560 gt_poses->push_back(
p);
1568 template <
class GRAPH_T>
1572 using namespace std;
1582 const double tmpz[] = {
1583 cos(anglez), -sin(anglez), 0, sin(anglez), cos(anglez), 0, 0, 0, 1};
1589 const double tmpy[] = {cos(angley), 0, sin(angley), 0, 1, 0,
1590 -sin(angley), 0, cos(angley)};
1596 const double tmpx[] = {
1597 1, 0, 0, 0, cos(anglex), -sin(anglex), 0, sin(anglex), cos(anglex)};
1600 stringstream ss_out;
1601 ss_out <<
"\nConstructing the rotation matrix for the GroundTruth Data..."
1603 m_rot_TUM_to_MRPT = rotz * roty * rotx;
1605 ss_out <<
"Rotation matrices for optical=>MRPT transformation" << endl;
1606 ss_out <<
"rotz: " << endl << rotz << endl;
1607 ss_out <<
"roty: " << endl << roty << endl;
1608 ss_out <<
"rotx: " << endl << rotx << endl;
1609 ss_out <<
"Full rotation matrix: " << endl << m_rot_TUM_to_MRPT << endl;
1616 template <
class GRAPH_T>
1623 "\nqueryObserverForEvents method was called even though no Observer "
1624 "object was provided\n");
1626 std::map<std::string, bool> events_occurred;
1627 m_win_observer->returnEventsStruct(&events_occurred);
1628 m_request_to_exit = events_occurred.find(
"Ctrl+c")->second;
1631 if (events_occurred[m_keystroke_odometry])
1633 this->toggleOdometryVisualization();
1636 if (events_occurred[m_keystroke_GT])
1638 this->toggleGTVisualization();
1641 if (events_occurred[m_keystroke_map])
1643 this->toggleMapVisualization();
1646 if (events_occurred[m_keystroke_estimated_trajectory])
1648 this->toggleEstimatedTrajectoryVisualization();
1651 if (events_occurred[m_keystroke_pause_exec])
1653 this->togglePause();
1658 m_node_reg->notifyOfWindowEvents(events_occurred);
1659 m_edge_reg->notifyOfWindowEvents(events_occurred);
1660 m_optimizer->notifyOfWindowEvents(events_occurred);
1665 template <
class GRAPH_T>
1675 if (m_visualize_odometry_poses)
1678 obj->setVisibility(!
obj->isVisible());
1680 obj = scene->getByName(
"robot_odometry_poses");
1681 obj->setVisibility(!
obj->isVisible());
1685 dumpVisibilityErrorMsg(
"visualize_odometry_poses");
1688 m_win->unlockAccess3DScene();
1689 m_win->forceRepaint();
1693 template <
class GRAPH_T>
1706 obj->setVisibility(!
obj->isVisible());
1708 obj = scene->getByName(
"robot_GT");
1709 obj->setVisibility(!
obj->isVisible());
1713 dumpVisibilityErrorMsg(
"visualize_ground_truth");
1716 m_win->unlockAccess3DScene();
1717 m_win->forceRepaint();
1721 template <
class GRAPH_T>
1726 using namespace std;
1735 std::lock_guard<std::mutex> graph_lock(m_graph_section);
1736 num_of_nodes = m_graph.nodeCount();
1740 stringstream scan_name(
"");
1742 for (
int node_cnt = 0; node_cnt != num_of_nodes; ++node_cnt)
1746 scan_name <<
"laser_scan_";
1747 scan_name << node_cnt;
1754 obj->setVisibility(!
obj->isVisible());
1757 m_win->unlockAccess3DScene();
1758 m_win->forceRepaint();
1762 template <
class GRAPH_T>
1772 if (m_visualize_estimated_trajectory)
1775 obj->setVisibility(!
obj->isVisible());
1777 obj = scene->getByName(
"robot_estimated_traj");
1778 obj->setVisibility(!
obj->isVisible());
1782 dumpVisibilityErrorMsg(
"visualize_estimated_trajectory");
1785 m_win->unlockAccess3DScene();
1786 m_win->forceRepaint();
1790 template <
class GRAPH_T>
1797 "Cannot toggle visibility of specified object.\n"
1798 <<
"Make sure that the corresponding visualization flag (" << viz_flag
1799 <<
") is set to true in the .ini file.");
1800 std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
1805 template <
class GRAPH_T>
1817 action || observation,
1818 "Neither action or observation contains valid data.");
1823 timestamp = observation->timestamp;
1828 timestamp = action->get(0)->timestamp;
1834 observations->begin();
1835 sens_it != observations->end(); ++sens_it)
1837 timestamp = (*sens_it)->timestamp;
1849 template <
class GRAPH_T>
1857 template <
class GRAPH_T>
1863 map_obj->setName(
"map");
1865 scene->insert(map_obj);
1866 this->m_win->unlockAccess3DScene();
1867 this->m_win->forceRepaint();
1870 template <
class GRAPH_T>
1874 nodes_to_laser_scans2D,
1881 using namespace std;
1887 map_obj = std::dynamic_pointer_cast<CSetOfObjects>(
obj);
1892 map_update_timer.
Tic();
1895 std::set<mrpt::graphs::TNodeID> nodes_set;
1902 m_graph.getAllNodes(nodes_set);
1909 nodes_set.insert(m_nodeID_max);
1916 node_it != nodes_set.end(); ++node_it)
1919 stringstream scan_name(
"");
1920 scan_name <<
"laser_scan_";
1921 scan_name << *node_it;
1927 search = nodes_to_laser_scans2D.find(*node_it);
1930 if (search != nodes_to_laser_scans2D.end() && search->second)
1932 scan_content = search->second;
1935 this->decimateLaserScan(
1936 *scan_content, &scan_decimated,
1944 std::dynamic_pointer_cast<CSetOfObjects>(
obj);
1947 scan_obj = mrpt::make_aligned_shared<CSetOfObjects>();
1954 scan_obj->setName(scan_name.str());
1955 this->setObjectPropsFromNodeID(*node_it, scan_obj);
1963 stringstream prev_scan_name(
"");
1964 prev_scan_name <<
"laser_scan_" << *node_it - 1;
1966 map_obj->getByName(prev_scan_name.str());
1969 scan_obj->setVisibility(prev_obj->isVisible());
1973 map_obj->insert(scan_obj);
1977 scan_obj = std::dynamic_pointer_cast<CSetOfObjects>(scan_obj);
1982 scan_obj->setPose(scan_pose);
1987 "Laser scans of NodeID " << *node_it <<
"are empty/invalid");
1992 m_win->unlockAccess3DScene();
1993 m_win->forceRepaint();
1995 double elapsed_time = map_update_timer.
Tac();
1997 "updateMapVisualization took: " << elapsed_time <<
"s");
2001 template <
class GRAPH_T>
2007 viz_object->setColor_u8(m_optimized_map_color);
2011 template <
class GRAPH_T>
2015 const int keep_every_n_entries )
2019 size_t scan_size = laser_scan_in.
scan.
size();
2022 std::vector<float> new_scan(
2024 std::vector<char> new_validRange(scan_size);
2025 size_t new_scan_size = 0;
2026 for (
size_t i = 0; i != scan_size; i++)
2028 if (i % keep_every_n_entries == 0)
2030 new_scan[new_scan_size] = laser_scan_in.
scan[i];
2031 new_validRange[new_scan_size] = laser_scan_in.
validRange[i];
2036 new_scan_size, &new_scan[0], &new_validRange[0]);
2041 template <
class GRAPH_T>
2052 "Visualization of data was requested but no CDisplayWindow3D pointer "
2057 GT_cloud->setPointSize(1.0);
2058 GT_cloud->enablePointSmooth();
2059 GT_cloud->enableColorFromX(
false);
2060 GT_cloud->enableColorFromY(
false);
2061 GT_cloud->enableColorFromZ(
false);
2062 GT_cloud->setColor_u8(m_GT_color);
2063 GT_cloud->setName(
"GT_cloud");
2069 m_robot_model_size);
2073 scene->insert(GT_cloud);
2074 scene->insert(robot_model);
2075 m_win->unlockAccess3DScene();
2077 m_win_manager->assignTextMessageParameters(
2080 m_win_manager->addTextMessage(
2081 m_offset_x_left, -m_offset_y_GT,
mrpt::format(
"Ground truth path"),
2085 m_win->forceRepaint();
2090 template <
class GRAPH_T>
2099 if (m_visualize_GT && m_GT_poses_index < m_GT_poses.size())
2103 "Visualization of data was requested but no CDisplayWindow3D "
2104 "pointer was given");
2113 GT_cloud->insertPoint(
p.x(),
p.y(),
p.z());
2116 obj = scene->getByName(
"robot_GT");
2118 std::dynamic_pointer_cast<CSetOfObjects>(
obj);
2119 robot_obj->setPose(
p);
2120 m_win->unlockAccess3DScene();
2121 m_win->forceRepaint();
2127 template <
class GRAPH_T>
2137 mrpt::make_aligned_shared<CPointCloud>();
2138 odometry_poses_cloud->setPointSize(1.0);
2139 odometry_poses_cloud->enablePointSmooth();
2140 odometry_poses_cloud->enableColorFromX(
false);
2141 odometry_poses_cloud->enableColorFromY(
false);
2142 odometry_poses_cloud->enableColorFromZ(
false);
2143 odometry_poses_cloud->setColor_u8(m_odometry_color);
2144 odometry_poses_cloud->setName(
"odometry_poses_cloud");
2148 "robot_odometry_poses", m_odometry_color, m_robot_model_size);
2152 scene->insert(odometry_poses_cloud);
2153 scene->insert(robot_model);
2154 m_win->unlockAccess3DScene();
2156 m_win_manager->assignTextMessageParameters(
2157 &m_offset_y_odometry,
2158 &m_text_index_odometry);
2159 m_win_manager->addTextMessage(
2160 m_offset_x_left, -m_offset_y_odometry,
mrpt::format(
"Odometry path"),
2162 m_text_index_odometry);
2164 m_win->forceRepaint();
2169 template <
class GRAPH_T>
2176 "Visualization of data was requested but no CDisplayWindow3D pointer "
2185 std::dynamic_pointer_cast<CPointCloud>(
obj);
2188 odometry_poses_cloud->insertPoint(
p.x(),
p.y(),
p.z());
2191 obj = scene->getByName(
"robot_odometry_poses");
2193 std::dynamic_pointer_cast<CSetOfObjects>(
obj);
2194 robot_obj->setPose(
p);
2196 m_win->unlockAccess3DScene();
2197 m_win->forceRepaint();
2202 template <
class GRAPH_T>
2211 mrpt::make_aligned_shared<CSetOfLines>();
2212 estimated_traj_setoflines->setColor_u8(m_estimated_traj_color);
2213 estimated_traj_setoflines->setLineWidth(1.5);
2214 estimated_traj_setoflines->setName(
"estimated_traj_setoflines");
2217 estimated_traj_setoflines->appendLine(
2224 "robot_estimated_traj", m_estimated_traj_color, m_robot_model_size);
2228 if (m_visualize_estimated_trajectory)
2230 scene->insert(estimated_traj_setoflines);
2232 scene->insert(robot_model);
2233 m_win->unlockAccess3DScene();
2235 if (m_visualize_estimated_trajectory)
2237 m_win_manager->assignTextMessageParameters(
2238 &m_offset_y_estimated_traj,
2239 &m_text_index_estimated_traj);
2240 m_win_manager->addTextMessage(
2241 m_offset_x_left, -m_offset_y_estimated_traj,
2244 m_text_index_estimated_traj);
2247 m_win->forceRepaint();
2252 template <
class GRAPH_T>
2260 std::lock_guard<std::mutex> graph_lock(m_graph_section);
2266 if (m_visualize_estimated_trajectory)
2269 obj = scene->getByName(
"estimated_traj_setoflines");
2271 std::dynamic_pointer_cast<CSetOfLines>(
obj);
2275 std::set<mrpt::graphs::TNodeID> nodes_set;
2279 this->getNodeIDsOfEstimatedTrajectory(&nodes_set);
2280 estimated_traj_setoflines->clear();
2282 estimated_traj_setoflines->appendLine(
2288 nodes_set.insert(m_graph.nodeCount() - 1);
2294 it != nodes_set.end(); ++it)
2298 estimated_traj_setoflines->appendLineStrip(
p.x(),
p.y(),
p.z());
2304 obj = scene->getByName(
"robot_estimated_traj");
2306 std::dynamic_pointer_cast<CSetOfObjects>(
obj);
2307 pose_t curr_estimated_pos = m_graph.nodes[m_graph.nodeCount() - 1];
2308 robot_obj->setPose(curr_estimated_pos);
2310 m_win->unlockAccess3DScene();
2311 m_win->forceRepaint();
2317 template <
class GRAPH_T>
2321 this->setRawlogFile(rawlog_fname);
2322 this->initTRGBDInfoFileParams();
2324 template <
class GRAPH_T>
2327 this->initTRGBDInfoFileParams();
2329 template <
class GRAPH_T>
2334 template <
class GRAPH_T>
2343 info_fname = dir + name_prefix + rawlog_filename + name_suffix;
2346 template <
class GRAPH_T>
2350 fields[
"Overall number of objects"] =
"";
2351 fields[
"Observations format"] =
"";
2354 template <
class GRAPH_T>
2358 using namespace std;
2364 "\nTRGBDInfoFileParams::parseFile: Couldn't open info file\n");
2367 size_t line_cnt = 0;
2374 if (curr_line.size() == 0)
break;
2378 while (info_file.
readLine(curr_line))
2381 vector<string> curr_tokens;
2392 it != fields.end(); ++it)
2396 it->second = value_part;
2405 template <
class GRAPH_T>
2419 fname =
"output_graph.graph";
2423 "Saving generated graph in VERTEX/EDGE format: " << fname);
2424 m_graph.saveToTextFile(fname);
2429 template <
class GRAPH_T>
2436 "\nsave3DScene was called even though enable_visuals flag is "
2437 "off.\nExiting...\n");
2445 "Could not fetch 3D Scene. Display window must already be closed.");
2456 "Removing CPlanarLaserScan from generated 3DScene...");
2457 scene->removeObject(laser_scan);
2469 fname =
"output_scene.3DScene";
2473 scene->saveToFile(fname);
2475 m_win->unlockAccess3DScene();
2476 m_win->forceRepaint();
2481 template <
class GRAPH_T>
2490 if (m_graph.nodeCount() < 4)
2496 m_nodeID_to_gt_indices[nodeID] = gt_index;
2503 double trans_diff = 0;
2504 double rot_diff = 0;
2506 size_t indices_size = m_nodeID_to_gt_indices.size();
2509 m_curr_deformation_energy = 0;
2515 m_nodeID_to_gt_indices.begin();
2523 pose_t prev_node_pos = m_graph.nodes[prev_it->first];
2524 pose_t prev_gt_pos = m_GT_poses[prev_it->second];
2531 index_it != m_nodeID_to_gt_indices.end(); index_it++)
2533 curr_node_pos = m_graph.nodes[index_it->first];
2534 curr_gt_pos = m_GT_poses[index_it->second];
2536 node_delta_pos = curr_node_pos - prev_node_pos;
2537 gt_delta = curr_gt_pos - prev_gt_pos;
2539 trans_diff = gt_delta.distanceTo(node_delta_pos);
2540 rot_diff = this->accumulateAngleDiffs(gt_delta, node_delta_pos);
2542 m_curr_deformation_energy += (pow(trans_diff, 2) + pow(rot_diff, 2));
2543 m_curr_deformation_energy /= indices_size;
2546 m_deformation_energy_vec.push_back(m_curr_deformation_energy);
2548 prev_node_pos = curr_node_pos;
2549 prev_gt_pos = curr_gt_pos;
2553 "Total deformation energy: " << m_curr_deformation_energy);
2558 template <
class GRAPH_T>
2564 template <
class GRAPH_T>
2578 template <
class GRAPH_T>
2582 using namespace std;
2591 "Evolution of SLAM metric - Deformation Energy (1:1000)", 400, 300);
2593 m_win_plot->setPos(20, 50);
2596 m_win_plot->hold_off();
2597 m_win_plot->enableMousePanZoom(
true);
2602 template <
class GRAPH_T>
2607 ASSERTDEB_(m_win_plot && m_visualize_SLAM_metric);
2610 std::vector<double>
x(m_deformation_energy_vec.size(), 0);
2611 std::vector<double>
y(m_deformation_energy_vec.size(), 0);
2612 for (
size_t i = 0; i !=
x.size(); i++)
2615 y[i] = m_deformation_energy_vec[i] * 1000;
2620 "Deformation Energy (x1000)");
2625 xmax = std::max_element(
x.begin(),
x.end());
2626 ymax = std::max_element(
y.begin(),
y.end());
2629 xmax !=
x.end() ? -(*xmax / 12) : -1,
2630 (xmax !=
x.end() ? *xmax : 1),
2632 (ymax !=
y.end() ? *ymax : 1));
2637 template <
class GRAPH_T>
2642 using namespace std;
2645 stringstream results_ss;
2646 results_ss <<
"Summary: " << std::endl;
2647 results_ss << this->header_sep << std::endl;
2648 results_ss <<
"\tProcessing time: "
2649 << m_time_logger.getMeanTime(
"proc_time") << std::endl;
2651 results_ss <<
"\tDataset Grab time: " << m_dataset_grab_time << std::endl;
2652 results_ss <<
"\tReal-time capable: "
2653 << (m_time_logger.getMeanTime(
"proc_time") < m_dataset_grab_time
2657 results_ss << m_edge_counter.getAsString();
2658 results_ss <<
"\tNum of Nodes: " << m_graph.nodeCount() << std::endl;
2662 std::string config_params = this->getParamsAsString();
2665 const std::string time_res = m_time_logger.getStatsAsText();
2666 const std::string output_res = this->getLogAsString();
2669 report_str->clear();
2671 *report_str += results_ss.str();
2672 *report_str += this->report_sep;
2674 *report_str += config_params;
2675 *report_str += this->report_sep;
2677 *report_str += time_res;
2678 *report_str += this->report_sep;
2680 *report_str += output_res;
2681 *report_str += this->report_sep;
2686 template <
class GRAPH_T>
2688 std::map<std::string, int>* node_stats,
2689 std::map<std::string, int>* edge_stats,
2693 using namespace std;
2696 ASSERTDEBMSG_(node_stats,
"Invalid pointer to node_stats is given");
2697 ASSERTDEBMSG_(edge_stats,
"Invalid pointer to edge_stats is given");
2699 if (m_nodeID_max == 0)
2705 (*node_stats)[
"nodes_total"] = m_nodeID_max + 1;
2709 it != m_edge_counter.cend(); ++it)
2711 (*edge_stats)[it->first] = it->second;
2714 (*edge_stats)[
"loop_closures"] = m_edge_counter.getLoopClosureEdges();
2715 (*edge_stats)[
"edges_total"] = m_edge_counter.getTotalNumOfEdges();
2720 *timestamp = m_curr_timestamp;
2727 template <
class GRAPH_T>
2733 using namespace mrpt;
2738 "Output directory \"%s\" doesn't exist", output_dir_fname.c_str()));
2742 std::lock_guard<std::mutex> graph_lock(m_graph_section);
2750 fname = output_dir_fname +
"/" + m_class_name + ext;
2753 this->initResultsFile(fname);
2754 this->getDescriptiveReport(&report_str);
2755 m_out_streams[fname].printf(
"%s", report_str.c_str());
2758 const std::string time_res = m_time_logger.getStatsAsText();
2759 fname = output_dir_fname +
"/" +
"timings" + ext;
2760 this->initResultsFile(fname);
2761 m_out_streams[fname].printf(
"%s", time_res.c_str());
2765 fname = output_dir_fname +
"/" +
"node_registrar" + ext;
2766 this->initResultsFile(fname);
2767 m_node_reg->getDescriptiveReport(&report_str);
2768 m_out_streams[fname].printf(
"%s", report_str.c_str());
2772 fname = output_dir_fname +
"/" +
"edge_registrar" + ext;
2773 this->initResultsFile(fname);
2774 m_edge_reg->getDescriptiveReport(&report_str);
2775 m_out_streams[fname].printf(
"%s", report_str.c_str());
2779 fname = output_dir_fname +
"/" +
"optimizer" + ext;
2780 this->initResultsFile(fname);
2781 m_optimizer->getDescriptiveReport(&report_str);
2782 m_out_streams[fname].printf(
"%s", report_str.c_str());
2789 "# File includes the evolution of the SLAM metric. Implemented "
2790 "metric computes the \"deformation energy\" that is needed to "
2791 "transfer the estimated trajectory into the ground-truth "
2792 "trajectory (computed as sum of the difference between estimated "
2793 "trajectory and ground truth consecutive poses See \"A comparison "
2794 "of SLAM algorithms based on a graph of relations - W.Burgard et "
2795 "al.\", for more details on the metric.\n");
2797 fname = output_dir_fname +
"/" +
"SLAM_evaluation_metric" + ext;
2798 this->initResultsFile(fname);
2800 m_out_streams[fname].printf(
"%s\n", desc.c_str());
2802 m_deformation_energy_vec.begin();
2803 vec_it != m_deformation_energy_vec.end(); ++vec_it)
2805 m_out_streams[fname].printf(
"%f\n", *vec_it);
2811 template <
class GRAPH_T>
2815 const size_t model_size,
const pose_t& init_pose)
2819 ASSERTDEBMSG_(!model_name.empty(),
"Model name provided is empty.");
2822 this->initRobotModelVisualization();
2823 model->setName(model_name);
2824 model->setColor_u8(model_color);
2825 model->setScale(model_size);
2826 model->setPose(init_pose);
2832 template <
class GRAPH_T>
2834 std::vector<double>* vec_out)
const
2839 *vec_out = m_deformation_energy_vec;