22 template <
class GRAPH_T>
    24 template <
class GRAPH_T>
    27 template <
class GRAPH_T>
    29     const std::string& config_file, 
const std::string& rawlog_fname,
    34     : m_node_reg(node_reg),
    36       m_optimizer(optimizer),
    37       m_enable_visuals(win_manager != nullptr),
    38       m_config_fname(config_file),
    39       m_rawlog_fname(rawlog_fname),
    42       m_win_manager(win_manager),
    43       m_paused_message(
"Program is paused. Press \"p/P\" to resume."),
    44       m_text_index_paused_message(345),  
    45       m_odometry_color(0, 0, 255),
    46       m_GT_color(0, 255, 0),
    47       m_estimated_traj_color(255, 165, 0),
    48       m_optimized_map_color(255, 0, 0),
    49       m_current_constraint_type_color(255, 255, 255),
    50       m_robot_model_size(1),
    51       m_class_name(
"CGraphSlamEngine"),
    52       m_is_first_time_node_reg(true)
    57 template <
class GRAPH_T>
    68 template <
class GRAPH_T>
    69 typename GRAPH_T::global_pose_t
    72     std::lock_guard<std::mutex> graph_lock(m_graph_section);
    73     return m_node_reg->getCurrentRobotPosEstimation();
    76 template <
class GRAPH_T>
    77 typename GRAPH_T::global_poses_t
    80     std::lock_guard<std::mutex> graph_lock(m_graph_section);
    84 template <
class GRAPH_T>
    86     std::set<mrpt::graphs::TNodeID>* nodes_set)
 const    89     m_graph.getAllNodes(*nodes_set);
    92 template <
class GRAPH_T>
   101     m_time_logger.setName(m_class_name);
   102     this->logging_enable_keep_record = 
true;
   103     this->setLoggerName(m_class_name);
   115         m_supported_constraint_types.push_back(
"CPosePDFGaussianInf");
   116         m_supported_constraint_types.push_back(
"CPose3DPDFGaussianInf");
   119         const string c_str(c.GetRuntimeClass()->className);
   123                  m_supported_constraint_types.begin(),
   124                  m_supported_constraint_types.end(),
   125                  c_str) != m_supported_constraint_types.end());
   134                 "Given graph class " << c_str
   135                                      << 
" has not been tested consistently yet."   136                                      << 
"Proceed at your own risk.");
   141         m_current_constraint_type = c_str;
   142         m_current_constraint_type = 
"Constraints: " + m_current_constraint_type;
   146     if (m_enable_visuals)
   148         m_win = m_win_manager->win;
   149         m_win_observer = m_win_manager->observer;
   154         m_win_observer = 
nullptr;
   163     m_observation_only_dataset = 
false;
   164     m_request_to_exit = 
false;
   170     m_GT_poses_index = 0;
   174     m_node_reg->setGraphPtr(&m_graph);
   175     m_edge_reg->setGraphPtr(&m_graph);
   176     m_optimizer->setGraphPtr(&m_graph);
   180     if (m_enable_visuals)
   182         m_node_reg->setWindowManagerPtr(m_win_manager);
   183         m_edge_reg->setWindowManagerPtr(m_win_manager);
   184         m_optimizer->setWindowManagerPtr(m_win_manager);
   185         m_edge_counter.setWindowManagerPtr(m_win_manager);
   189     m_node_reg->setCriticalSectionPtr(&m_graph_section);
   190     m_edge_reg->setCriticalSectionPtr(&m_graph_section);
   191     m_optimizer->setCriticalSectionPtr(&m_graph_section);
   195     this->loadParams(m_config_fname);
   197     if (!m_enable_visuals)
   200         m_visualize_odometry_poses = 0;
   203         m_visualize_estimated_trajectory = 0;
   204         m_visualize_SLAM_metric = 0;
   205         m_enable_curr_pos_viewport = 0;
   206         m_enable_range_viewport = 0;
   207         m_enable_intensity_viewport = 0;
   210     m_use_GT = !m_fname_GT.empty();
   216             this->alignOpticalWithMRPTFrame();
   221             this->readGTFile(m_fname_GT, &m_GT_poses);
   229             "Ground truth file was not provided. Switching the related "   230             "visualization parameters off...");
   232         m_visualize_SLAM_metric = 0;
   236     if (m_enable_visuals)
   238         m_win_manager->assignTextMessageParameters(
   239             &m_offset_y_timestamp, &m_text_index_timestamp);
   244         this->initMapVisualization();
   249     if (m_enable_visuals)
   252         if (m_visualize_odometry_poses)
   254             this->initOdometryVisualization();
   259             this->initGTVisualization();
   262         this->initEstimatedTrajectoryVisualization();
   264         if (m_enable_curr_pos_viewport)
   266             this->initCurrPosViewport();
   276         std::string rawlog_fname_noext =
   279         m_img_external_storage_dir =
   280             rawlog_dir + rawlog_fname_noext + 
"_Images/";
   287         if (m_enable_range_viewport)
   289             this->initRangeImageViewport();
   291         if (m_enable_intensity_viewport)
   293             this->initIntensityImageViewport();
   297     if (m_enable_visuals)
   302         obj->setFrequency(5);
   303         obj->enableTickMarks();
   304         obj->setAxisLimits(-10, -10, -10, 10, 10, 10);
   305         obj->setName(
"axis");
   308         m_win->unlockAccess3DScene();
   309         m_win->forceRepaint();
   313     if (m_enable_visuals)
   316         m_keystroke_pause_exec = 
"p";
   317         m_keystroke_odometry = 
"o";
   318         m_keystroke_GT = 
"g";
   319         m_keystroke_estimated_trajectory = 
"t";
   320         m_keystroke_map = 
"m";
   323         m_win_observer->registerKeystroke(
   324             m_keystroke_pause_exec, 
"Pause/Resume program execution");
   325         m_win_observer->registerKeystroke(
   326             m_keystroke_odometry, 
"Toggle Odometry visualization");
   327         m_win_observer->registerKeystroke(
   328             m_keystroke_GT, 
"Toggle Ground-Truth visualization");
   329         m_win_observer->registerKeystroke(
   330             m_keystroke_estimated_trajectory,
   331             "Toggle Estimated trajectory visualization");
   332         m_win_observer->registerKeystroke(
   333             m_keystroke_map, 
"Toggle Map visualization");
   337     vector<string> vec_edge_types;
   338     vec_edge_types.emplace_back(
"Odometry");
   339     vec_edge_types.emplace_back(
"ICP2D");
   340     vec_edge_types.emplace_back(
"ICP3D");
   342     for (
auto cit = vec_edge_types.begin(); cit != vec_edge_types.end(); ++cit)
   344         m_edge_counter.addEdgeType(*cit);
   348     if (m_enable_visuals)
   351         double offset_y_total_edges, offset_y_loop_closures;
   352         int text_index_total_edges, text_index_loop_closures;
   354         m_win_manager->assignTextMessageParameters(
   355             &offset_y_total_edges, &text_index_total_edges);
   358         map<string, double> name_to_offset_y;
   359         map<string, int> name_to_text_index;
   360         for (
auto it = vec_edge_types.begin(); it != vec_edge_types.end(); ++it)
   362             m_win_manager->assignTextMessageParameters(
   363                 &name_to_offset_y[*it], &name_to_text_index[*it]);
   366         m_win_manager->assignTextMessageParameters(
   367             &offset_y_loop_closures, &text_index_loop_closures);
   370         m_edge_counter.setTextMessageParams(
   371             name_to_offset_y, name_to_text_index, offset_y_total_edges,
   372             text_index_total_edges, offset_y_loop_closures,
   373             text_index_loop_closures);
   377     if (m_enable_visuals)
   379         m_win_manager->assignTextMessageParameters(
   380             &m_offset_y_current_constraint_type,
   381             &m_text_index_current_constraint_type);
   382         m_win_manager->addTextMessage(
   383             m_offset_x_left, -m_offset_y_current_constraint_type,
   384             m_current_constraint_type,
   386             m_text_index_current_constraint_type);
   390     if (m_enable_visuals)
   392         std::lock_guard<std::mutex> graph_lock(m_graph_section);
   393         m_time_logger.enter(
"Visuals");
   394         m_node_reg->initializeVisuals();
   395         m_edge_reg->initializeVisuals();
   396         m_optimizer->initializeVisuals();
   397         m_time_logger.leave(
"Visuals");
   416         gridmap->insertionOptions.maxOccupancyUpdateCertainty = 0.8f;
   417         gridmap->insertionOptions.maxDistanceInsertion = 5;
   418         gridmap->insertionOptions.wideningBeamsWithDistance = 
true;
   419         gridmap->insertionOptions.decimation = 2;
   421         m_gridmap_cached = gridmap;
   422         m_map_is_cached = 
false;
   431         octomap->insertionOptions.setOccupancyThres(0.5);
   432         octomap->insertionOptions.setProbHit(0.7);
   433         octomap->insertionOptions.setProbMiss(0.4);
   434         octomap->insertionOptions.setClampingThresMin(0.1192);
   435         octomap->insertionOptions.setClampingThresMax(0.971);
   438         m_map_is_cached = 
false;
   445         m_info_params.setRawlogFile(m_rawlog_fname);
   446         m_info_params.parseFile();
   448         int num_of_objects = std::atoi(
   449             m_info_params.fields[
"Overall number of objects"].c_str());
   450         m_GT_poses_step = m_GT_poses.size() / num_of_objects;
   453             "Overall number of objects in rawlog: " << num_of_objects);
   455             "Setting the Ground truth read step to: " << m_GT_poses_step);
   457     catch (
const std::exception& e)
   463     m_curr_deformation_energy = 0;
   464     if (m_visualize_SLAM_metric)
   466         this->initSlamMetricVisualization();
   470     if (m_enable_visuals)
   472         this->m_win->addTextMessage(0.5, 0.3, 
"", m_text_index_paused_message);
   478 template <
class GRAPH_T>
   487     return this->_execGraphSlamStep(
   488         action, observations, observation, rawlog_entry);
   491 template <
class GRAPH_T>
   500     using namespace mrpt;
   507     m_time_logger.enter(
"proc_time");
   510         m_has_read_config, 
"\nConfig file is not read yet.\nExiting... \n");
   516         m_init_timestamp = getTimeStamp(action, observations, observation);
   522             m_observation_only_dataset = 
true;  
   528             m_observation_only_dataset = 
false;
   531             action->getFirstMovementEstimationMean(increment_pose_3d);
   532             pose_t increment_pose(increment_pose_3d);
   533             m_curr_odometry_only_pose += increment_pose;
   541     bool registered_new_node;
   543         std::lock_guard<std::mutex> graph_lock(m_graph_section);
   544         m_time_logger.enter(
"node_registrar");
   545         registered_new_node =
   546             m_node_reg->updateState(action, observations, observation);
   547         m_time_logger.leave(
"node_registrar");
   552             getObservation<CObservation2DRangeScan>(observations, observation);
   555             m_last_laser_scan2D = scan;
   557             if (!m_first_laser_scan2D)
   559                 m_first_laser_scan2D = m_last_laser_scan2D;
   564     if (registered_new_node)
   568         if (m_is_first_time_node_reg)
   570             std::lock_guard<std::mutex> graph_lock(m_graph_section);
   572             if (m_graph.nodeCount() != 2)
   575                     "Expected [2] new registered nodes"   576                     << 
" but got [" << m_graph.nodeCount() << 
"]");
   580             m_nodes_to_laser_scans2D.insert(
   581                 make_pair(m_nodeID_max, m_first_laser_scan2D));
   583             m_is_first_time_node_reg = 
false;
   590         m_edge_counter.addEdge(
"Odometry");
   592     this->monitorNodeRegistration(
   593         registered_new_node, 
"NodeRegistrationDecider");
   599         std::lock_guard<std::mutex> graph_lock(m_graph_section);
   601         m_time_logger.enter(
"edge_registrar");
   602         m_edge_reg->updateState(action, observations, observation);
   603         m_time_logger.leave(
"edge_registrar");
   605     this->monitorNodeRegistration(
   606         registered_new_node, 
"EdgeRegistrationDecider");
   609         std::lock_guard<std::mutex> graph_lock(m_graph_section);
   611         m_time_logger.enter(
"optimizer");
   612         m_optimizer->updateState(action, observations, observation);
   613         m_time_logger.leave(
"optimizer");
   615     this->monitorNodeRegistration(registered_new_node, 
"GraphSlamOptimizer");
   618     m_curr_timestamp = getTimeStamp(action, observations, observation);
   631             m_curr_odometry_only_pose = 
pose_t(obs_odometry->odometry);
   632             m_odometry_poses.push_back(m_curr_odometry_only_pose);
   636             m_last_laser_scan3D =
   649         action->getFirstMovementEstimationMean(increment_pose_3d);
   650         pose_t increment_pose(increment_pose_3d);
   651         m_curr_odometry_only_pose += increment_pose;
   652         m_odometry_poses.push_back(m_curr_odometry_only_pose);
   655     if (registered_new_node)
   657         this->execDijkstraNodesEstimation();
   660         m_nodes_to_laser_scans2D[m_nodeID_max] = m_last_laser_scan2D;
   662         if (m_enable_visuals && m_visualize_map)
   664             std::lock_guard<std::mutex> graph_lock(m_graph_section);
   666             bool full_update = 
true;
   667             this->updateMapVisualization(m_nodes_to_laser_scans2D, full_update);
   671         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             for (
auto it = edge_types_to_nums.begin();
   682                  it != edge_types_to_nums.end(); ++it)
   687                     m_edge_counter.setLoopClosureEdgesManually(it->second);
   691                     m_edge_counter.setEdgesManually(it->first, it->second);
   698         if (m_enable_curr_pos_viewport)
   700             updateCurrPosViewport();
   703         if (m_enable_visuals)
   705             bool full_update = 
true;  
   706             m_time_logger.enter(
"Visuals");
   707             this->updateEstimatedTrajectoryVisualization(full_update);
   708             m_time_logger.leave(
"Visuals");
   715             m_time_logger.enter(
"SLAM_metric");
   716             this->computeSlamMetric(m_nodeID_max, m_GT_poses_index);
   717             m_time_logger.leave(
"SLAM_metric");
   718             if (m_visualize_SLAM_metric)
   720                 m_time_logger.enter(
"Visuals");
   721                 this->updateSlamMetricVisualization();
   722                 m_time_logger.leave(
"Visuals");
   727         m_map_is_cached = 
false;
   734     m_time_logger.enter(
"Visuals");
   738     if (m_enable_visuals)
   742             m_win_manager->addTextMessage(
   743                 m_offset_x_left, -m_offset_y_timestamp,
   745                     "Simulated time: %s",
   748                  m_text_index_timestamp);
   752             m_win_manager->addTextMessage(
   753                 m_offset_x_left, -m_offset_y_timestamp,
   758                  m_text_index_timestamp);
   763     if (m_visualize_odometry_poses && m_odometry_poses.size())
   765         this->updateOdometryVisualization();
   774             if (m_enable_visuals)
   776                 this->updateGTVisualization();  
   779             m_GT_poses_index += m_GT_poses_step;
   783             if (m_observation_only_dataset)
   785                 if (rawlog_entry % 2 == 0)
   787                     if (m_enable_visuals)
   789                         this->updateGTVisualization();  
   792                     m_GT_poses_index += m_GT_poses_step;
   799                 if (m_enable_visuals)
   801                     this->updateGTVisualization();  
   804                 m_GT_poses_index += m_GT_poses_step;
   812         if (m_enable_range_viewport && m_last_laser_scan3D)
   814             this->updateRangeImageViewport();
   817         if (m_enable_intensity_viewport && m_last_laser_scan3D)
   819             this->updateIntensityImageViewport();
   824     if (m_enable_visuals)
   826         this->queryObserverForEvents();
   828     m_time_logger.leave(
"Visuals");
   830     m_dataset_grab_time =
   832     m_time_logger.leave(
"proc_time");
   834     return !m_request_to_exit;
   838 template <
class GRAPH_T>
   842         std::lock_guard<std::mutex> graph_lock(m_graph_section);
   843         m_time_logger.enter(
"dijkstra_nodes_estimation");
   844         m_graph.dijkstra_nodes_estimate();
   845         m_time_logger.leave(
"dijkstra_nodes_estimation");
   849 template <
class GRAPH_T>
   851     bool registered , std::string class_name )
   854     using namespace mrpt;
   856     std::lock_guard<std::mutex> graph_lock(m_graph_section);
   857     size_t listed_nodeCount =
   863             listed_nodeCount == m_graph.nodeCount(),
   865                 "listed_nodeCount [%lu] != nodeCount() [%lu]",
   866                 static_cast<unsigned long>(listed_nodeCount),
   867                 static_cast<unsigned long>(m_graph.nodeCount())));
   871         if (listed_nodeCount != m_graph.nodeCount())
   874                 class_name << 
" illegally added new nodes to the graph "   875                            << 
", wanted to see [" << listed_nodeCount
   876                            << 
"] but saw [" << m_graph.nodeCount() << 
"]");
   878                 format(
"Illegal node registration by %s.", class_name.c_str()));
   884 template <
class GRAPH_T>
   897     if (!m_map_is_cached)
   901     map->copyMapContentFrom(*m_gridmap_cached);
   904     if (acquisition_time)
   906         *acquisition_time = m_map_acq_time;
   911 template <
class GRAPH_T>
   919     if (!m_map_is_cached)
   928     if (acquisition_time)
   930         *acquisition_time = m_map_acq_time;
   936 template <
class GRAPH_T>
   941     using namespace mrpt;
   945     std::lock_guard<std::mutex> graph_lock(m_graph_section);
   947     if (!constraint_t::is_3D())
   955         for (
auto it = m_nodes_to_laser_scans2D.begin();
   956              it != m_nodes_to_laser_scans2D.end(); ++it)
   965                                      "LaserScan of nodeID: %lu is not present.",
   966                                      static_cast<unsigned long>(curr_node)));
   969             CPose3D scan_pose = getLSPoseForGridMapVisualization(curr_node);
   972             gridmap->insertObservation(*curr_laser_scan, &scan_pose);
   975         m_map_is_cached = 
true;
   981         THROW_EXCEPTION(
"Not Implemented Yet. Method is to compute a COctoMap");
   988 template <
class GRAPH_T>
   995         mrpt::format(
"\nConfiguration file not found: \n%s\n", fname.c_str()));
  1001     m_user_decides_about_output_dir = cfg_file.
read_bool(
  1002         "GeneralConfiguration", 
"user_decides_about_output_dir", 
false, 
false);
  1004         "GeneralConfiguration", 
"ground_truth_file_format", 
"NavSimul", 
false);
  1007     int min_verbosity_level =
  1008         cfg_file.
read_int(
"GeneralConfiguration", 
"class_verbosity", 1, 
false);
  1015         "VisualizationParameters", 
"visualize_map", 
true, 
false);
  1018     m_visualize_odometry_poses = cfg_file.
read_bool(
  1019         "VisualizationParameters", 
"visualize_odometry_poses", 
true, 
false);
  1020     m_visualize_estimated_trajectory = cfg_file.
read_bool(
  1021         "VisualizationParameters", 
"visualize_estimated_trajectory", 
true,
  1026         "VisualizationParameters", 
"visualize_ground_truth", 
true, 
false);
  1028     m_visualize_SLAM_metric = cfg_file.
read_bool(
  1029         "VisualizationParameters", 
"visualize_SLAM_metric", 
true, 
false);
  1032     m_enable_curr_pos_viewport = cfg_file.
read_bool(
  1033         "VisualizationParameters", 
"enable_curr_pos_viewport", 
true, 
false);
  1034     m_enable_range_viewport = cfg_file.
read_bool(
  1035         "VisualizationParameters", 
"enable_range_viewport", 
false, 
false);
  1036     m_enable_intensity_viewport = cfg_file.
read_bool(
  1037         "VisualizationParameters", 
"enable_intensity_viewport", 
false, 
false);
  1039     m_node_reg->loadParams(fname);
  1040     m_edge_reg->loadParams(fname);
  1041     m_optimizer->loadParams(fname);
  1043     m_has_read_config = 
true;
  1046 template <
class GRAPH_T>
  1052     this->getParamsAsString(&str);
  1057 template <
class GRAPH_T>
  1062     using namespace std;
  1064     stringstream ss_out;
  1067         << 
"\n------------[ Graphslam_engine Problem Parameters ]------------"  1069     ss_out << 
"Config filename                 = " << m_config_fname
  1072     ss_out << 
"Ground Truth File format        = " << m_GT_file_format
  1074     ss_out << 
"Ground Truth filename           = " << m_fname_GT << std::endl;
  1076     ss_out << 
"Visualize odometry              = "  1077            << (m_visualize_odometry_poses ? 
"TRUE" : 
"FALSE") << std::endl;
  1078     ss_out << 
"Visualize estimated trajectory  = "  1079            << (m_visualize_estimated_trajectory ? 
"TRUE" : 
"FALSE")
  1081     ss_out << 
"Visualize map                   = "  1082            << (m_visualize_map ? 
"TRUE" : 
"FALSE") << std::endl;
  1083     ss_out << 
"Visualize Ground Truth          = "  1084            << (m_visualize_GT ? 
"TRUE" : 
"FALSE") << std::endl;
  1086     ss_out << 
"Visualize SLAM metric plot      = "  1087            << (m_visualize_SLAM_metric ? 
"TRUE" : 
"FALSE") << std::endl;
  1089     ss_out << 
"Enable curr. position viewport  = "  1090            << (m_enable_curr_pos_viewport ? 
"TRUE" : 
"FALSE") << endl;
  1091     ss_out << 
"Enable range img viewport       = "  1092            << (m_enable_range_viewport ? 
"TRUE" : 
"FALSE") << endl;
  1093     ss_out << 
"Enable intensity img viewport   = "  1094            << (m_enable_intensity_viewport ? 
"TRUE" : 
"FALSE") << endl;
  1096     ss_out << 
"-----------------------------------------------------------"  1098     ss_out << std::endl;
  1101     *params_out = ss_out.str();
  1106 template <
class GRAPH_T>
  1110     std::cout << getParamsAsString();
  1112     m_node_reg->printParams();
  1113     m_edge_reg->printParams();
  1114     m_optimizer->printParams();
  1119 template <
class GRAPH_T>
  1123     using namespace std;
  1130     std::string time_spec = 
"UTC Time";
  1134     m_out_streams[fname].open(fname);
  1136         m_out_streams[fname].fileOpenCorrectly(),
  1137         mrpt::format(
"\nError while trying to open %s\n", fname.c_str()));
  1139     const std::string sep(80, 
'#');
  1141     m_out_streams[fname].printf(
"# Mobile Robot Programming Toolkit (MRPT)\n");
  1142     m_out_streams[fname].printf(
"# http::/www.mrpt.org\n");
  1143     m_out_streams[fname].printf(
"# GraphSlamEngine Application\n");
  1144     m_out_streams[fname].printf(
  1145         "# Automatically generated file - %s: %s\n", time_spec.c_str(),
  1146         cur_date_str.c_str());
  1147     m_out_streams[fname].printf(
"%s\n\n", sep.c_str());
  1152 template <
class GRAPH_T>
  1162     viewp_range = scene->createViewport(
"viewp_range");
  1164     m_win_manager->assignViewportParameters(&x, &y, &w, &h);
  1165     viewp_range->setViewportPosition(x, y, h, w);
  1167     m_win->unlockAccess3DScene();
  1168     m_win->forceRepaint();
  1173 template <
class GRAPH_T>
  1177     std::lock_guard<std::mutex> graph_lock(m_graph_section);
  1178     m_time_logger.enter(
"Visuals");
  1180     m_node_reg->updateVisuals();
  1181     m_edge_reg->updateVisuals();
  1182     m_optimizer->updateVisuals();
  1184     m_time_logger.leave(
"Visuals");
  1188 template <
class GRAPH_T>
  1196     if (m_last_laser_scan3D->hasRangeImage)
  1204         m_last_laser_scan3D->load();
  1206             m_last_laser_scan3D->rangeImage, 
false );
  1210         viewp_range->setImageView(img);
  1211         m_win->unlockAccess3DScene();
  1212         m_win->forceRepaint();
  1218 template <
class GRAPH_T>
  1228     viewp_intensity = scene->createViewport(
"viewp_intensity");
  1230     m_win_manager->assignViewportParameters(&x, &y, &w, &h);
  1231     viewp_intensity->setViewportPosition(x, y, w, h);
  1233     m_win->unlockAccess3DScene();
  1234     m_win->forceRepaint();
  1238 template <
class GRAPH_T>
  1245     if (m_last_laser_scan3D->hasIntensityImage)
  1250         m_last_laser_scan3D->load();
  1251         img = m_last_laser_scan3D->intensityImage;
  1255             scene->getViewport(
"viewp_intensity");
  1256         viewp_intensity->setImageView(img);
  1257         m_win->unlockAccess3DScene();
  1258         m_win->forceRepaint();
  1264 template <
class GRAPH_T>
  1269     return this->initRobotModelVisualizationInternal(p);
  1272 template <
class GRAPH_T>
  1281 template <
class GRAPH_T>
  1289 template <
class GRAPH_T>
  1298         scene->createViewport(
"curr_robot_pose_viewport");
  1300     viewp->setCloneView(
"main");
  1302     m_win_manager->assignViewportParameters(&x, &y, &w, &h);
  1303     viewp->setViewportPosition(x, y, h, w);
  1304     viewp->setTransparent(
false);
  1305     viewp->getCamera().setAzimuthDegrees(90);
  1306     viewp->getCamera().setElevationDegrees(90);
  1307     viewp->setCustomBackgroundColor(
  1309     viewp->getCamera().setZoomDistance(30);
  1310     viewp->getCamera().setOrthogonal();
  1312     m_win->unlockAccess3DScene();
  1313     m_win->forceRepaint();
  1318 template <
class GRAPH_T>
  1328     global_pose_t curr_robot_pose = this->getCurrentRobotPosEstimation();
  1332     viewp->getCamera().setPointingAt(
CPose3D(curr_robot_pose));
  1334     m_win->unlockAccess3DScene();
  1335     m_win->forceRepaint();
  1341 template <
class GRAPH_T>
  1343     const std::string& fname_GT, std::vector<mrpt::poses::CPose2D>* gt_poses,
  1344     std::vector<mrpt::system::TTimeStamp>* gt_timestamps)
  1347     using namespace std;
  1354             "\nGround-truth file %s was not found.\n"  1355             "Either specify a valid ground-truth filename or set set the "  1356             "m_visualize_GT flag to false\n",
  1361     ASSERTDEBMSG_(gt_poses, 
"\nNo valid std::vector<pose_t>* was given\n");
  1366     for (
size_t line_num = 0; file_GT.
readLine(curr_line); line_num++)
  1368         vector<string> curr_tokens;
  1373             curr_tokens.size() == constraint_t::state_length + 1,
  1374             "\nGround Truth File doesn't seem to contain data as generated by "  1376             "GridMapNavSimul application.\n Either specify the GT file format "  1378             "visualize_ground_truth to false in the .ini file\n");
  1385             gt_timestamps->push_back(timestamp);
  1390             atof(curr_tokens[1].c_str()), atof(curr_tokens[2].c_str()),
  1391             atof(curr_tokens[3].c_str()));
  1392         gt_poses->push_back(curr_pose);
  1399 template <
class GRAPH_T>
  1401     const std::string& fname_GT, std::vector<mrpt::poses::CPose3D>* gt_poses,
  1402     std::vector<mrpt::system::TTimeStamp>* gt_timestamps)
  1407 template <
class GRAPH_T>
  1409     const std::string& fname_GT, std::vector<mrpt::poses::CPose2D>* gt_poses,
  1410     std::vector<mrpt::system::TTimeStamp>* gt_timestamps)
  1413     using namespace std;
  1421             "\nGround-truth file %s was not found.\n"  1422             "Either specify a valid ground-truth filename or set set the "  1423             "m_visualize_GT flag to false\n",
  1429         "\nreadGTFileRGBD_TUM: Couldn't openGT file\n");
  1430     ASSERTDEBMSG_(gt_poses, 
"No valid std::vector<pose_t>* was given");
  1435     for (
size_t i = 0; file_GT.
readLine(curr_line); i++)
  1437         if (curr_line.at(0) != 
'#')
  1446     vector<string> curr_tokens;
  1451         curr_tokens.size() == 8,
  1452         "\nGround Truth File doesn't seem to contain data as specified in "  1454         "datasets.\n Either specify correct the GT file format or set "  1455         "visualize_ground_truth to false in the .ini file\n");
  1459     quat.
r(atof(curr_tokens[7].c_str()));
  1460     quat.x(atof(curr_tokens[4].c_str()));
  1461     quat.y(atof(curr_tokens[5].c_str()));
  1462     quat.z(atof(curr_tokens[6].c_str()));
  1467     curr_coords[0] = atof(curr_tokens[1].c_str());
  1468     curr_coords[1] = atof(curr_tokens[2].c_str());
  1469     curr_coords[2] = atof(curr_tokens[3].c_str());
  1472     pose_t curr_pose(curr_coords[0], curr_coords[1], y);
  1475     pose_diff = curr_pose;
  1478     for (; file_GT.
readLine(curr_line);)
  1482             curr_tokens.size() == 8,
  1483             "\nGround Truth File doesn't seem to contain data as specified in "  1485             "datasets.\n Either specify correct the GT file format or set "  1486             "visualize_ground_truth to false in the .ini file\n");
  1493             gt_timestamps->push_back(timestamp);
  1497         quat.r(atof(curr_tokens[7].c_str()));
  1498         quat.x(atof(curr_tokens[4].c_str()));
  1499         quat.y(atof(curr_tokens[5].c_str()));
  1500         quat.z(atof(curr_tokens[6].c_str()));
  1504         curr_coords[0] = atof(curr_tokens[1].c_str());
  1505         curr_coords[1] = atof(curr_tokens[2].c_str());
  1506         curr_coords[2] = atof(curr_tokens[3].c_str());
  1509         pose_t gt_pose(curr_coords[0], curr_coords[1], y);
  1511         gt_pose.x() -= pose_diff.x();
  1512         gt_pose.y() -= pose_diff.y();
  1513         gt_pose.phi() -= pose_diff.phi();
  1515         gt_poses->push_back(gt_pose);
  1523 template <
class GRAPH_T>
  1527     using namespace std;
  1536     double anglez = 0.0_deg;
  1537     const double tmpz[] = {
  1538         cos(anglez), -sin(anglez), 0, sin(anglez), cos(anglez), 0, 0, 0, 1};
  1542     double angley = 0.0_deg;
  1544     const double tmpy[] = {cos(angley),  0, sin(angley), 0, 1, 0,
  1545                            -sin(angley), 0, cos(angley)};
  1550     double anglex = 0.0_deg;
  1551     const double tmpx[] = {
  1552         1, 0, 0, 0, cos(anglex), -sin(anglex), 0, sin(anglex), cos(anglex)};
  1555     stringstream ss_out;
  1556     ss_out << 
"\nConstructing the rotation matrix for the GroundTruth Data..."  1558     m_rot_TUM_to_MRPT = rotz * roty * rotx;
  1560     ss_out << 
"Rotation matrices for optical=>MRPT transformation" << endl;
  1561     ss_out << 
"rotz: " << endl << rotz << endl;
  1562     ss_out << 
"roty: " << endl << roty << endl;
  1563     ss_out << 
"rotx: " << endl << rotx << endl;
  1564     ss_out << 
"Full rotation matrix: " << endl << m_rot_TUM_to_MRPT << endl;
  1571 template <
class GRAPH_T>
  1578         "\nqueryObserverForEvents method was called even though no Observer "  1579         "object was provided\n");
  1581     std::map<std::string, bool> events_occurred;
  1582     m_win_observer->returnEventsStruct(&events_occurred);
  1583     m_request_to_exit = events_occurred.find(
"Ctrl+c")->second;
  1586     if (events_occurred[m_keystroke_odometry])
  1588         this->toggleOdometryVisualization();
  1591     if (events_occurred[m_keystroke_GT])
  1593         this->toggleGTVisualization();
  1596     if (events_occurred[m_keystroke_map])
  1598         this->toggleMapVisualization();
  1601     if (events_occurred[m_keystroke_estimated_trajectory])
  1603         this->toggleEstimatedTrajectoryVisualization();
  1606     if (events_occurred[m_keystroke_pause_exec])
  1608         this->togglePause();
  1613     m_node_reg->notifyOfWindowEvents(events_occurred);
  1614     m_edge_reg->notifyOfWindowEvents(events_occurred);
  1615     m_optimizer->notifyOfWindowEvents(events_occurred);
  1620 template <
class GRAPH_T>
  1630     if (m_visualize_odometry_poses)
  1633         obj->setVisibility(!obj->isVisible());
  1635         obj = scene->getByName(
"robot_odometry_poses");
  1636         obj->setVisibility(!obj->isVisible());
  1640         dumpVisibilityErrorMsg(
"visualize_odometry_poses");
  1643     m_win->unlockAccess3DScene();
  1644     m_win->forceRepaint();
  1648 template <
class GRAPH_T>
  1661         obj->setVisibility(!obj->isVisible());
  1663         obj = scene->getByName(
"robot_GT");
  1664         obj->setVisibility(!obj->isVisible());
  1668         dumpVisibilityErrorMsg(
"visualize_ground_truth");
  1671     m_win->unlockAccess3DScene();
  1672     m_win->forceRepaint();
  1676 template <
class GRAPH_T>
  1681     using namespace std;
  1690         std::lock_guard<std::mutex> graph_lock(m_graph_section);
  1691         num_of_nodes = m_graph.nodeCount();
  1695     stringstream scan_name(
"");
  1697     for (
int node_cnt = 0; node_cnt != num_of_nodes; ++node_cnt)
  1701         scan_name << 
"laser_scan_";
  1702         scan_name << node_cnt;
  1709             obj->setVisibility(!obj->isVisible());
  1712     m_win->unlockAccess3DScene();
  1713     m_win->forceRepaint();
  1717 template <
class GRAPH_T>
  1727     if (m_visualize_estimated_trajectory)
  1730         obj->setVisibility(!obj->isVisible());
  1732         obj = scene->getByName(
"robot_estimated_traj");
  1733         obj->setVisibility(!obj->isVisible());
  1737         dumpVisibilityErrorMsg(
"visualize_estimated_trajectory");
  1740     m_win->unlockAccess3DScene();
  1741     m_win->forceRepaint();
  1745 template <
class GRAPH_T>
  1747     std::string viz_flag, 
int sleep_time)
  1752         "Cannot toggle visibility of specified object.\n"  1753         << 
"Make sure that the corresponding visualization flag (" << viz_flag
  1754         << 
") is set to true in the .ini file.");
  1755     std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
  1760 template <
class GRAPH_T>
  1772         action || observation,
  1773         "Neither action or observation contains valid data.");
  1778         timestamp = observation->timestamp;
  1783         timestamp = action->get(0)->timestamp;
  1788             for (
auto sens_it = observations->begin();
  1789                  sens_it != observations->end(); ++sens_it)
  1791                 timestamp = (*sens_it)->timestamp;
  1803 template <
class GRAPH_T>
  1811 template <
class GRAPH_T>
  1817     map_obj->setName(
"map");
  1819     scene->insert(map_obj);
  1820     this->m_win->unlockAccess3DScene();
  1821     this->m_win->forceRepaint();
  1824 template <
class GRAPH_T>
  1828         nodes_to_laser_scans2D,
  1835     using namespace std;
  1846     map_update_timer.
Tic();
  1849     std::set<mrpt::graphs::TNodeID> nodes_set;
  1856             m_graph.getAllNodes(nodes_set);
  1863             nodes_set.insert(m_nodeID_max);
  1871         stringstream scan_name(
"");
  1872         scan_name << 
"laser_scan_";
  1873         scan_name << node_it;
  1877         auto search = nodes_to_laser_scans2D.find(node_it);
  1880         if (search != nodes_to_laser_scans2D.end() && search->second)
  1882             scan_content = search->second;
  1885             this->decimateLaserScan(
  1886                 *scan_content, &scan_decimated,
  1897                 scan_obj = std::make_shared<CSetOfObjects>();
  1902                 m.getAs3DObject(scan_obj);
  1904                 scan_obj->setName(scan_name.str());
  1905                 this->setObjectPropsFromNodeID(node_it, scan_obj);
  1913                     stringstream prev_scan_name(
"");
  1914                     prev_scan_name << 
"laser_scan_" << node_it - 1;
  1916                         map_obj->getByName(prev_scan_name.str());
  1919                         scan_obj->setVisibility(prev_obj->isVisible());
  1923                 map_obj->insert(scan_obj);
  1927                 scan_obj = std::dynamic_pointer_cast<
CSetOfObjects>(scan_obj);
  1932             scan_obj->setPose(scan_pose);
  1937                 "Laser scans of NodeID " << node_it << 
"are  empty/invalid");
  1942     m_win->unlockAccess3DScene();
  1943     m_win->forceRepaint();
  1945     double elapsed_time = map_update_timer.
Tac();
  1947         "updateMapVisualization took: " << elapsed_time << 
"s");
  1951 template <
class GRAPH_T>
  1957     viz_object->setColor_u8(m_optimized_map_color);
  1961 template <
class GRAPH_T>
  1965     const int keep_every_n_entries )
  1972     std::vector<float> new_scan(
  1974     std::vector<char> new_validRange(scan_size);
  1975     size_t new_scan_size = 0;
  1976     for (
size_t i = 0; i != scan_size; i++)
  1978         if (i % keep_every_n_entries == 0)
  1980             new_scan[new_scan_size] = laser_scan_in.
getScanRange(i);
  1981             new_validRange[new_scan_size] =
  1987         new_scan_size, &new_scan[0], &new_validRange[0]);
  1992 template <
class GRAPH_T>
  2003         "Visualization of data was requested but no CDisplayWindow3D pointer "  2008     GT_cloud->setPointSize(1.0);
  2009     GT_cloud->enableColorFromX(
false);
  2010     GT_cloud->enableColorFromY(
false);
  2011     GT_cloud->enableColorFromZ(
false);
  2012     GT_cloud->setColor_u8(m_GT_color);
  2013     GT_cloud->setName(
"GT_cloud");
  2017         "robot_GT", m_GT_color, m_robot_model_size);
  2021     scene->insert(GT_cloud);
  2022     scene->insert(robot_model);
  2023     m_win->unlockAccess3DScene();
  2025     m_win_manager->assignTextMessageParameters(
  2026         &m_offset_y_GT, &m_text_index_GT);
  2027     m_win_manager->addTextMessage(
  2028         m_offset_x_left, -m_offset_y_GT, 
"Ground truth path",
  2030     m_win->forceRepaint();
  2035 template <
class GRAPH_T>
  2044     if (m_visualize_GT && m_GT_poses_index < m_GT_poses.size())
  2048             "Visualization of data was requested but no CDisplayWindow3D "  2049             "pointer was given");
  2058         GT_cloud->insertPoint(p.x(), p.y(), p.z());
  2061         obj = scene->getByName(
"robot_GT");
  2064         robot_obj->setPose(p);
  2065         m_win->unlockAccess3DScene();
  2066         m_win->forceRepaint();
  2072 template <
class GRAPH_T>
  2082     odometry_poses_cloud->setPointSize(1.0);
  2083     odometry_poses_cloud->enableColorFromX(
false);
  2084     odometry_poses_cloud->enableColorFromY(
false);
  2085     odometry_poses_cloud->enableColorFromZ(
false);
  2086     odometry_poses_cloud->setColor_u8(m_odometry_color);
  2087     odometry_poses_cloud->setName(
"odometry_poses_cloud");
  2091         "robot_odometry_poses", m_odometry_color, m_robot_model_size);
  2095     scene->insert(odometry_poses_cloud);
  2096     scene->insert(robot_model);
  2097     m_win->unlockAccess3DScene();
  2099     m_win_manager->assignTextMessageParameters(
  2100         &m_offset_y_odometry, &m_text_index_odometry);
  2101     m_win_manager->addTextMessage(
  2102         m_offset_x_left, -m_offset_y_odometry, 
"Odometry path",
  2105     m_win->forceRepaint();
  2110 template <
class GRAPH_T>
  2117         "Visualization of data was requested but no CDisplayWindow3D pointer "  2129     odometry_poses_cloud->insertPoint(p.x(), p.y(), p.z());
  2132     obj = scene->getByName(
"robot_odometry_poses");
  2135     robot_obj->setPose(p);
  2137     m_win->unlockAccess3DScene();
  2138     m_win->forceRepaint();
  2143 template <
class GRAPH_T>
  2152         std::make_shared<CSetOfLines>();
  2153     estimated_traj_setoflines->setColor_u8(m_estimated_traj_color);
  2154     estimated_traj_setoflines->setLineWidth(1.5);
  2155     estimated_traj_setoflines->setName(
"estimated_traj_setoflines");
  2158     estimated_traj_setoflines->appendLine(
  2165         "robot_estimated_traj", m_estimated_traj_color, m_robot_model_size);
  2169     if (m_visualize_estimated_trajectory)
  2171         scene->insert(estimated_traj_setoflines);
  2173     scene->insert(robot_model);
  2174     m_win->unlockAccess3DScene();
  2176     if (m_visualize_estimated_trajectory)
  2178         m_win_manager->assignTextMessageParameters(
  2179             &m_offset_y_estimated_traj, &m_text_index_estimated_traj);
  2180         m_win_manager->addTextMessage(
  2181             m_offset_x_left, -m_offset_y_estimated_traj, 
"Estimated trajectory",
  2183             m_text_index_estimated_traj);
  2186     m_win->forceRepaint();
  2191 template <
class GRAPH_T>
  2199     std::lock_guard<std::mutex> graph_lock(m_graph_section);
  2205     if (m_visualize_estimated_trajectory)
  2208         obj = scene->getByName(
"estimated_traj_setoflines");
  2214         std::set<mrpt::graphs::TNodeID> nodes_set;
  2218                 this->getNodeIDsOfEstimatedTrajectory(&nodes_set);
  2219                 estimated_traj_setoflines->clear();
  2221                 estimated_traj_setoflines->appendLine(
  2227                 nodes_set.insert(m_graph.nodeCount() - 1);
  2231         for (
unsigned long it : nodes_set)
  2235             estimated_traj_setoflines->appendLineStrip(p.x(), p.y(), p.z());
  2241     obj = scene->getByName(
"robot_estimated_traj");
  2244     pose_t curr_estimated_pos = m_graph.nodes[m_graph.nodeCount() - 1];
  2245     robot_obj->setPose(curr_estimated_pos);
  2247     m_win->unlockAccess3DScene();
  2248     m_win->forceRepaint();
  2252 template <
class GRAPH_T>
  2254     const std::string& rawlog_fname)
  2256     this->setRawlogFile(rawlog_fname);
  2257     this->initTRGBDInfoFileParams();
  2259 template <
class GRAPH_T>
  2262     this->initTRGBDInfoFileParams();
  2265 template <
class GRAPH_T>
  2267     const std::string& rawlog_fname)
  2272     std::string name_prefix = 
"rawlog_";
  2273     std::string name_suffix = 
"_info.txt";
  2274     info_fname = 
dir + name_prefix + rawlog_filename + name_suffix;
  2277 template <
class GRAPH_T>
  2281     fields[
"Overall number of objects"] = 
"";
  2282     fields[
"Observations format"] = 
"";
  2285 template <
class GRAPH_T>
  2289     using namespace std;
  2295         "\nTRGBDInfoFileParams::parseFile: Couldn't open info file\n");
  2298     size_t line_cnt = 0;
  2305         if (curr_line.size() == 0) 
break;
  2309     while (info_file.
readLine(curr_line))
  2312         vector<string> curr_tokens;
  2322         for (
auto it = fields.begin(); it != fields.end(); ++it)
  2326                 it->second = value_part;
  2334 template <
class GRAPH_T>
  2347         fname = 
"output_graph.graph";
  2351         "Saving generated graph in VERTEX/EDGE format: " << fname);
  2352     m_graph.saveToTextFile(fname);
  2357 template <
class GRAPH_T>
  2363         "\nsave3DScene was called even though enable_visuals flag is "  2364         "off.\nExiting...\n");
  2372             "Could not fetch 3D Scene. Display window must already be closed.");
  2383                 "Removing CPlanarLaserScan from generated 3DScene...");
  2384             scene->removeObject(laser_scan);
  2396         fname = 
"output_scene.3DScene";
  2400     scene->saveToFile(fname);
  2402     m_win->unlockAccess3DScene();
  2403     m_win->forceRepaint();
  2408 template <
class GRAPH_T>
  2417     if (m_graph.nodeCount() < 4)
  2423     m_nodeID_to_gt_indices[nodeID] = gt_index;
  2430     double trans_diff = 0;
  2431     double rot_diff = 0;
  2433     size_t indices_size = m_nodeID_to_gt_indices.size();
  2436     m_curr_deformation_energy = 0;
  2439     auto start_it = m_nodeID_to_gt_indices.begin();
  2443     auto prev_it = start_it;
  2445     pose_t prev_node_pos = m_graph.nodes[prev_it->first];
  2446     pose_t prev_gt_pos = m_GT_poses[prev_it->second];
  2451     for (
auto index_it = start_it; index_it != m_nodeID_to_gt_indices.end();
  2454         curr_node_pos = m_graph.nodes[index_it->first];
  2455         curr_gt_pos = m_GT_poses[index_it->second];
  2457         node_delta_pos = curr_node_pos - prev_node_pos;
  2458         gt_delta = curr_gt_pos - prev_gt_pos;
  2460         trans_diff = gt_delta.distanceTo(node_delta_pos);
  2461         rot_diff = this->accumulateAngleDiffs(gt_delta, node_delta_pos);
  2463         m_curr_deformation_energy += (pow(trans_diff, 2) + pow(rot_diff, 2));
  2464         m_curr_deformation_energy /= indices_size;
  2467         m_deformation_energy_vec.push_back(m_curr_deformation_energy);
  2469         prev_node_pos = curr_node_pos;
  2470         prev_gt_pos = curr_gt_pos;
  2474         "Total deformation energy: " << m_curr_deformation_energy);
  2479 template <
class GRAPH_T>
  2485 template <
class GRAPH_T>
  2499 template <
class GRAPH_T>
  2509     m_win_plot = std::make_unique<mrpt::gui::CDisplayWindowPlots>(
  2510         "Evolution of SLAM metric - Deformation Energy (1:1000)", 400, 300);
  2512     m_win_plot->setPos(20, 50);
  2515     m_win_plot->hold_off();
  2516     m_win_plot->enableMousePanZoom(
true);
  2521 template <
class GRAPH_T>
  2526     ASSERTDEB_(m_win_plot && m_visualize_SLAM_metric);
  2529     std::vector<double> x(m_deformation_energy_vec.size(), 0);
  2530     std::vector<double> y(m_deformation_energy_vec.size(), 0);
  2531     for (
size_t i = 0; i != x.size(); i++)
  2534         y[i] = m_deformation_energy_vec[i] * 1000;
  2537     m_win_plot->plot(x, y, 
"r-1", 
"Deformation Energy (x1000)");
  2541     std::vector<double>::const_iterator xmax, ymax;
  2542     xmax = std::max_element(x.begin(), x.end());
  2543     ymax = std::max_element(y.begin(), y.end());
  2546          xmax != x.end() ? -(*xmax / 12) : -1,
  2547          (xmax != x.end() ? *xmax : 1),
  2549          (ymax != y.end() ? *ymax : 1));
  2554 template <
class GRAPH_T>
  2556     std::string* report_str)
 const  2559     using namespace std;
  2562     stringstream results_ss;
  2563     results_ss << 
"Summary: " << std::endl;
  2564     results_ss << this->header_sep << std::endl;
  2565     results_ss << 
"\tProcessing time: "  2566                << m_time_logger.getMeanTime(
"proc_time") << std::endl;
  2568     results_ss << 
"\tDataset Grab time: " << m_dataset_grab_time << std::endl;
  2569     results_ss << 
"\tReal-time capable: "  2570                << (m_time_logger.getMeanTime(
"proc_time") < m_dataset_grab_time
  2574     results_ss << m_edge_counter.getAsString();
  2575     results_ss << 
"\tNum of Nodes: " << m_graph.nodeCount() << std::endl;
  2579     std::string config_params = this->getParamsAsString();
  2582     const std::string time_res = m_time_logger.getStatsAsText();
  2583     const std::string output_res = this->getLogAsString();
  2586     report_str->clear();
  2588     *report_str += results_ss.str();
  2589     *report_str += this->report_sep;
  2591     *report_str += config_params;
  2592     *report_str += this->report_sep;
  2594     *report_str += time_res;
  2595     *report_str += this->report_sep;
  2597     *report_str += output_res;
  2598     *report_str += this->report_sep;
  2603 template <
class GRAPH_T>
  2605     std::map<std::string, int>* node_stats,
  2609     using namespace std;
  2612     ASSERTDEBMSG_(node_stats, 
"Invalid pointer to node_stats is given");
  2613     ASSERTDEBMSG_(edge_stats, 
"Invalid pointer to edge_stats is given");
  2615     if (m_nodeID_max == 0)
  2621     (*node_stats)[
"nodes_total"] = m_nodeID_max + 1;
  2624     for (
auto it = m_edge_counter.cbegin(); it != m_edge_counter.cend(); ++it)
  2626         (*edge_stats)[it->first] = it->second;
  2629     (*edge_stats)[
"loop_closures"] = m_edge_counter.getLoopClosureEdges();
  2630     (*edge_stats)[
"edges_total"] = m_edge_counter.getTotalNumOfEdges();
  2635         *timestamp = m_curr_timestamp;
  2642 template <
class GRAPH_T>
  2644     const std::string& output_dir_fname)
  2648     using namespace mrpt;
  2653             "Output directory \"%s\" doesn't exist", output_dir_fname.c_str()));
  2656     std::lock_guard<std::mutex> graph_lock(m_graph_section);
  2658     std::string report_str;
  2660     const std::string ext = 
".log";
  2664         fname = output_dir_fname + 
"/" + m_class_name + ext;
  2667         this->initResultsFile(fname);
  2668         this->getDescriptiveReport(&report_str);
  2669         m_out_streams[fname].printf(
"%s", report_str.c_str());
  2672         const std::string time_res = m_time_logger.getStatsAsText();
  2673         fname = output_dir_fname + 
"/" + 
"timings" + ext;
  2674         this->initResultsFile(fname);
  2675         m_out_streams[fname].printf(
"%s", time_res.c_str());
  2679         fname = output_dir_fname + 
"/" + 
"node_registrar" + ext;
  2680         this->initResultsFile(fname);
  2681         m_node_reg->getDescriptiveReport(&report_str);
  2682         m_out_streams[fname].printf(
"%s", report_str.c_str());
  2686         fname = output_dir_fname + 
"/" + 
"edge_registrar" + ext;
  2687         this->initResultsFile(fname);
  2688         m_edge_reg->getDescriptiveReport(&report_str);
  2689         m_out_streams[fname].printf(
"%s", report_str.c_str());
  2693         fname = output_dir_fname + 
"/" + 
"optimizer" + ext;
  2694         this->initResultsFile(fname);
  2695         m_optimizer->getDescriptiveReport(&report_str);
  2696         m_out_streams[fname].printf(
"%s", report_str.c_str());
  2702         const std::string desc(
  2703             "# File includes the evolution of the SLAM metric.  Implemented "  2704             "metric computes the \"deformation energy\" that is needed to "  2705             "transfer the estimated trajectory into the ground-truth "  2706             "trajectory (computed as sum of the difference between estimated "  2707             "trajectory and ground truth consecutive poses See \"A comparison "  2708             "of SLAM algorithms based on a graph of relations - W.Burgard et "  2709             "al.\", for more details on the metric.\n");
  2711         fname = output_dir_fname + 
"/" + 
"SLAM_evaluation_metric" + ext;
  2712         this->initResultsFile(fname);
  2714         m_out_streams[fname].printf(
"%s\n", desc.c_str());
  2715         for (
auto vec_it = m_deformation_energy_vec.begin();
  2716              vec_it != m_deformation_energy_vec.end(); ++vec_it)
  2718             m_out_streams[fname].printf(
"%f\n", *vec_it);
  2724 template <
class GRAPH_T>
  2728         const size_t model_size, 
const pose_t& init_pose)
  2731         this->initRobotModelVisualization();
  2732     model->setName(model_name);
  2733     model->setColor_u8(model_color);
  2734     model->setScale(model_size);
  2735     model->setPose(init_pose);
  2740 template <
class GRAPH_T>
  2742     std::vector<double>* vec_out)
 const  2744     *vec_out = m_deformation_energy_vec;
 void updateOdometryVisualization()
Update odometry-only cloud with latest odometry estimation. 
 
mrpt::opengl::CSetOfObjects::Ptr setCurrentPositionModel(const std::string &model_name, const mrpt::img::TColor &model_color=mrpt::img::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. 
 
double Tac() noexcept
Stops the stopwatch. 
 
typename GRAPH_T::global_pose_t global_pose_t
 
virtual void getNodeIDsOfEstimatedTrajectory(std::set< mrpt::graphs::TNodeID > *nodes_set) const
Return the list of nodeIDs which make up robot trajectory. 
 
CGraphSlamEngine(const std::string &config_file, const std::string &rawlog_fname="", const std::string &fname_GT="", mrpt::graphslam::CWindowManager *win_manager=nullptr, mrpt::graphslam::deciders::CNodeRegistrationDecider< GRAPH_T > *node_reg=nullptr, mrpt::graphslam::deciders::CEdgeRegistrationDecider< GRAPH_T > *edge_reg=nullptr, mrpt::graphslam::optimizers::CGraphSlamOptimizer< GRAPH_T > *optimizer=nullptr)
Constructor of CGraphSlamEngine class template. 
 
void queryObserverForEvents()
Query the observer instance for any user events. 
 
void updateMapVisualization(const std::map< mrpt::graphs::TNodeID, mrpt::obs::CObservation2DRangeScan::Ptr > &nodes_to_laser_scans2D, bool full_update=false)
Update the map visualization based on the current graphSLAM state. 
 
static time_point fromDouble(const double t) noexcept
Create a timestamp from its double representation. 
 
void parseFile()
Parse the RGBD information file to gain information about the rawlog file contents. 
 
void save3DScene(const std::string *fname_in=nullptr) const
Wrapper method around the COpenGLScene::saveToFile method. 
 
VerbosityLevel
Enumeration of available verbosity levels. 
 
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
 
bool getGraphSlamStats(std::map< std::string, int > *node_stats, std::map< std::string, int > *edge_stats, mrpt::system::TTimeStamp *timestamp=nullptr)
Fill the given maps with stats regarding the overall execution of graphslam. 
 
const_iterator find(const KEY &key) const
 
A set of object, which are referenced to the coordinates framework established in this object...
 
void updateGTVisualization()
Display the next ground truth position in the visualization window. 
 
#define THROW_EXCEPTION(msg)
 
void computeMap() const
Compute the map of the environment based on the recorded measurements. 
 
void toggleMapVisualization()
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
app setMinLoggingLevel(mrpt::system::LVL_ERROR)
 
mrpt::system::TTimeStamp getCurrentTime()
Returns the current (UTC) system time. 
 
void updateSlamMetricVisualization()
Update the displayPlots window with the new information with regards to the metric. 
 
Interface for implementing node registration classes. 
 
void initOdometryVisualization()
 
This class allows loading and storing values and vectors of different types from ".ini" files easily. 
 
bool fileExists(const std::string &fileName)
Test if a given file (or directory) exists. 
 
A high-performance stopwatch, with typical resolution of nanoseconds. 
 
A range or depth 3D scan measurement, as from a time-of-flight range camera or a structured-light dep...
 
global_pose_t getCurrentRobotPosEstimation() const
 
void initRangeImageViewport()
 
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 timeToString(const mrpt::system::TTimeStamp t)
Convert a timestamp into this textual form (UTC): HH:MM:SS.MMMMMM. 
 
virtual void setObjectPropsFromNodeID(const mrpt::graphs::TNodeID nodeID, mrpt::opengl::CSetOfObjects::Ptr &viz_object)
Set the properties of the map visual object based on the nodeID that it was produced by...
 
std::string fileNameStripInvalidChars(const std::string &filename, const char replacement_to_invalid_chars='_')
Replace invalid filename chars by underscores ('_') or any other user-given char. ...
 
static Ptr Create(Args &&... args)
 
void initGTVisualization()
 
#define MRPT_LOG_WARN_STREAM(__CONTENTS)
 
size_t getScanSize() const
Get number of scan rays. 
 
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters. 
 
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. 
 
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
 
void computeSlamMetric(mrpt::graphs::TNodeID nodeID, size_t gt_index)
Compare the SLAM result (estimated trajectory) with the GT path. 
 
void updateAllVisuals()
Wrapper around the deciders/optimizer updateVisuals methods. 
 
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1...
 
SLAM methods related to graphs of pose 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
 
T r() const
Return r (real part) coordinate of the quaternion. 
 
typename GRAPH_T::constraint_t::type_value pose_t
Type of underlying poses (2D/3D). 
 
void alignOpticalWithMRPTFrame()
 
void initTRGBDInfoFileParams()
 
double phi() const
Get the phi angle of the 2D pose (in radians) 
 
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. 
 
#define ASSERTDEB_EQUAL_(__A, __B)
 
This namespace contains representation of robot actions and observations. 
 
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...
 
void setFromMatrix(const MAT &m, bool matrix_is_normalized=true)
Set the image from a matrix, interpreted as grayscale intensity values, in the range [0...
 
#define IS_CLASS(obj, class_name)
True if the given reference to object (derived from mrpt::rtti::CObject) is of the given class...
 
mrpt::opengl::CSetOfObjects::Ptr initRobotModelVisualizationInternal(const mrpt::poses::CPose2D &p_unused)
Method to help overcome the partial template specialization restriction of C++. 
 
void updateEstimatedTrajectoryVisualization(bool full_update=false)
Update the Esstimated robot trajectory with the latest estimated robot position. 
 
#define MRPT_LOG_DEBUG_STREAM(__CONTENTS)
Use: MRPT_LOG_DEBUG_STREAM("Var=" << value << " foo=" << foo_var); 
 
void initEstimatedTrajectoryVisualization()
 
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range. 
 
void saveGraph(const std::string *fname_in=nullptr) const
Wrapper method around the GRAPH_T::saveToTextFile method. 
 
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. 
 
CSetOfObjects::Ptr RobotPioneer()
Returns a representation of a Pioneer II mobile base. 
 
virtual mrpt::poses::CPose3D getLSPoseForGridMapVisualization(const mrpt::graphs::TNodeID nodeID) const
return the 3D Pose of a LaserScan that is to be visualized. 
 
void toggleEstimatedTrajectoryVisualization()
 
void initIntensityImageViewport()
 
void pause(const std::string &msg=std::string("Press any key to continue...")) noexcept
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
 
void toggleOdometryVisualization()
 
virtual bool _execGraphSlamStep(mrpt::obs::CActionCollection::Ptr &action, mrpt::obs::CSensoryFrame::Ptr &observations, mrpt::obs::CObservation::Ptr &observation, size_t &rawlog_entry)
Main class method responsible for parsing each measurement and for executing graphSLAM. 
 
mrpt::opengl::CSetOfObjects::Ptr initRobotModelVisualization()
 
#define MRPT_LOG_INFO_STREAM(__CONTENTS)
 
#define ASSERTDEBMSG_(f, __ERROR_MSG)
 
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. 
 
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
 
virtual GRAPH_T::global_poses_t getRobotEstimatedTrajectory() const
 
static mrpt::system::TTimeStamp getTimeStamp(const mrpt::obs::CActionCollection::Ptr action, const mrpt::obs::CSensoryFrame::Ptr observations, const mrpt::obs::CObservation::Ptr observation)
Fill the TTimestamp in a consistent manner. 
 
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 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)
 
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug. 
 
static Ptr Create(Args &&... args)
 
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
 
CSetOfObjects::Ptr CornerXYZ(float scale=1.0)
Returns three arrows representing a X,Y,Z 3D corner. 
 
const float & getScanRange(const size_t i) const
The range values of the scan, in meters. 
 
An RGBA color - floats in the range [0,1]. 
 
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. 
 
static void readGTFileRGBD_TUM(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=nullptr)
Parse the ground truth .txt file and fill in the corresponding m_GT_poses vector. ...
 
uint64_t TNodeID
A generic numeric type for unique IDs of nodes or entities. 
 
typename GRAPH_T::constraint_t constraint_t
Type of graph constraints. 
 
void loadFromVectors(size_t nRays, const float *scanRanges, const char *scanValidity)
 
std::string trim(const std::string &str)
Removes leading and trailing spaces. 
 
bool execGraphSlamStep(mrpt::obs::CObservation::Ptr &observation, size_t &rawlog_entry)
Wrapper method around _execGraphSlamStep. 
 
void toggleGTVisualization()
 
std::string getParamsAsString() const
Wrapper around getParamsAsString. 
 
bool directoryExists(const std::string &fileName)
Test if a given directory exists (it fails if the given path refers to an existing file)...
 
double 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...
 
static uint64_t getCurrentTime() noexcept
 
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 ...
 
void Tic() noexcept
Starts the stopwatch. 
 
std::string extractFileName(const std::string &filePath)
Extract just the name (without extension) of a filename from a complete path plus name plus extension...
 
#define ASSERT_FILE_EXISTS_(FIL)
 
static void readGTFile(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=nullptr)
Parse the ground truth .txt file and fill in the corresponding gt_poses vector. 
 
A set of independent lines (or segments), one line with its own start and end positions (X...
 
#define MRPT_LOG_ERROR_STREAM(__CONTENTS)
 
bool strCmpI(const std::string &s1, const std::string &s2)
Return true if the two strings are equal (case insensitive) 
 
void initCurrPosViewport()
 
~CGraphSlamEngine() override
 
static void setImagesPathBase(const std::string &path)
 
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 initSlamMetricVisualization()
 
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable. 
 
std::string extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension...
 
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...
 
bool insertObservation(const mrpt::obs::CObservation &obs, const mrpt::poses::CPose3D *robotPose=nullptr)
Insert the observation information into this map. 
 
A class for storing images as grayscale or RGB bitmaps. 
 
void getMap(mrpt::maps::COccupancyGridMap2D::Ptr map, mrpt::system::TTimeStamp *acquisition_time=nullptr) const
 
A cloud of points, all with the same color or each depending on its value along a particular coordina...
 
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. 
 
static const std::string & getImagesPathBase()
By default, ".". 
 
bool getScanRangeValidity(const size_t i) const
It's false (=0) on no reflected rays, referenced to elements in scan.