MRPT  1.9.9
CGraphSlamEngine.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #ifndef GRAPHSLAMENGINE_H
11 #define GRAPHSLAMENGINE_H
12 
13 #include <mrpt/maps/CSimpleMap.h>
15 #include <mrpt/maps/COctoMap.h>
20 #include <mrpt/obs/CAction.h>
23 #include <mrpt/obs/CSensoryFrame.h>
24 #include <mrpt/obs/obs_utils.h>
25 #include <mrpt/poses/CPose2D.h>
26 #include <mrpt/poses/CPose3D.h>
28 #include <mrpt/img/TColor.h>
30 
35 
36 #include <string>
37 #include <map>
38 #include <set>
39 
40 namespace mrpt::graphslam
41 {
42 /**\brief Main file for the GraphSlamEngine.
43  *
44  * ## Description
45  *
46  * Given a dataset of measurements build a graph of nodes (keyframes) and
47  * constraints (edges) and solve it to find an estimation of the actual robot
48  * trajectory.
49  *
50  * // TODO - change this description
51  * The template arguments are listed below:
52  * - \em GRAPH_T: The type of Graph to be constructed and optimized. Currently
53  * CGraphSlamEngine works only with CPosePDFGaussianInf GRAPH_T instances.
54  * - \em NODE_REGISTRAR: Class responsible of adding new nodes in the graph.
55  * Class should at least implement the deciders::CNodeRegistrationDecider
56  * interface provided in CNodeRegistrationDecider.h file.
57  * - \em EDGE_REGISTRAR: Class responsible of adding new edges in the graph.
58  * Class should at least implement the deciders::CEdgeRegistrationDecider
59  * interface provided in CEdgeRegistrationDecider.h file.
60  * - \em OPTIMIZER: Class responsible of optimizing the graph. Class should at
61  * least implement the optimizers::CGraphSlamOptimizer interface provided
62  * in CGraphSlamOptimizer.h file.
63  *
64  * \note The GRAPH_T resource is accessed after having locked the relevant
65  * section
66  * \em m_graph_section. Critical section is also <em> locked prior to the calls
67  * to the deciders/optimizers </em>.
68  *
69  * ### .ini Configuration Parameters
70  *
71  * \htmlinclude graphslam-engine_config_params_preamble.txt
72  *
73  * - \b output_dir_fname
74  * + \a Section : GeneralConfiguration
75  * + \a Default value : 1 (mrpt::system::LVL_INFO)
76  * + \a Required : FALSE
77  *
78  * - \b user_decides_about_output_dir
79  * + \a Section : GeneralConfiguration
80  * + \a Default value : FALSE
81  * + \a Required : FALSE
82  * + \a Description : If flag true and in case of name conflict with output
83  * directory of the
84  * previous execution, a command-line is presented to the user to decide what
85  * to do about the new output directory. By default output directory from
86  * previous run is overwritten by the directory of the current run.
87  *
88  * - \b ground_truth_file_format
89  * + \a Section : GeneralConfiguration
90  * + \a Default value : NavSimul
91  * + \a Required : FALSE
92  * + \a Description : Specify the format of the ground-truth file if one is
93  * provided. Currently CGraphSlamEngine supports ground truth files generated
94  * by the GridMapNavSimul tool or ground truth files corresponding to
95  * RGBD-TUM datasets.
96  * + \a Available Options: NavSimul, RGBD_TUM
97  *
98  * - \b class_verbosity
99  * + \a Section : GeneralConfiguration
100  * + \a Default value : 1 (mrpt::system::LVL_INFO)
101  * + \a Required : FALSE
102  *
103  *
104  * - \b visualize_map
105  * + \a Section : VisualizationParameters
106  * + \a Default value : TRUE
107  * + \a Required : FALSE
108  *
109  * - \b visualize_odometry_poses
110  * + \a Section : VisualizationParameters
111  * + \a Default value : TRUE
112  * + \a Required : FALSE
113  *
114  * - \b visualize_estimated_trajectory
115  * + \a Section : VisualizationParameters
116  * + \a Default value : TRUE
117  * + \a Required : FALSE
118  *
119  * - \b visualize_GT
120  * + \a Section : VisualizationParameters
121  * + \a Default value : TRUE
122  * + \a Required : FALSE
123  *
124  * - \b visualize_SLAM_metric
125  * + \a Section : VisualizationParameters
126  * + \a Default value : TRUE
127  * + \a Required : FALSE
128  *
129  * - \b enable_curr_pos_viewport
130  * + \a Section : VisualizationParameters
131  * + \a Default value : TRUE
132  * + \a Required : FALSE
133  * + \a Description : Applicable only when dealing with RGB-D datasets
134  *
135  * - \b enable_range_viewport
136  * + \a Section : VisualizationParameters
137  * + \a Default value : TRUE
138  * + \a Required : FALSE
139  * + \a Description : Applicable only when dealing with RGB-D datasets
140  *
141  * - \b enable_intensity_viewport
142  * + \a Section : VisualizationParameters
143  * + \a Default value : FALSE
144  * + \a Required : FALSE
145  * + \a Description : Applicable only when dealing with RGB-D datasets
146  *
147  *
148  * \note Implementation can be found in the file \em CGraphSlamEngine_impl.h
149  * \ingroup mrpt_graphslam_grp
150  */
151 template <class GRAPH_T = typename mrpt::graphs::CNetworkOfPoses2DInf>
153 {
154  public:
155  /**\brief Handy typedefs */
156  /**\{*/
157  /**\brief Map for managing output file streams.*/
158  using fstreams_out = std::map<std::string, mrpt::io::CFileOutputStream>;
159  /**\brief Map for iterating over output file streams.*/
161 
162  /**\brief Type of graph constraints */
163  using constraint_t = typename GRAPH_T::constraint_t;
164  /**\brief Type of underlying poses (2D/3D). */
165  using pose_t = typename GRAPH_T::constraint_t::type_value;
166  using global_pose_t = typename GRAPH_T::global_pose_t;
167  using nodes_to_scans2D_t = std::map<
169  /**\}*/
170 
171  /**\brief Constructor of CGraphSlamEngine class template.
172  *
173  * // TODO - remove the deprecated arguments
174  * \param[in] config_file .ini file containing the configuration
175  * parameters for the CGraphSlamEngine as well as the deciders/optimizer
176  * classes that CGraphSlamEngine is using
177  * \param[in] win_manager CwindowManager instance that includes a pointer
178  * to a CDisplayWindow3D and a CWindowObserver instance for properly
179  * interacting with the display window
180  * \param[in] rawlog_fname .rawlog dataset file, containing the robot
181  * measurements. CGraphSlamEngine supports both
182  * <a href="http://www.mrpt.org/Rawlog_Format"> MRPT rwalog formats </a>
183  * but in order for graphSLAM to work as expected the rawlog foromat has to
184  * be supported by the every decider/optimizer class that
185  * CGraphSlamEngine makes use of.
186  * \param[in] fname_GT Textfile containing the ground truth path of the
187  * robot. Currently the class can read ground truth files corresponding
188  * either to <em>RGBD - TUM datasets</em> or to rawlog files generated with
189  * the \em GridMapNavSimul MRPT application.
190  * // TODO add the deciders/optimizer
191  *
192  *
193  * \note If a nullptr CWindowManager pointer is porovided, the application
194  * runs on <em> headless mode </em>. In this case, no visual feedback is
195  * given but application receives a big boost in performance
196  */
198  const std::string& config_file, const std::string& rawlog_fname = "",
199  const std::string& fname_GT = "",
200  mrpt::graphslam::CWindowManager* win_manager = NULL,
202  NULL,
204  NULL,
206  NULL);
207  /**\brief Default Destructor. */
208  virtual ~CGraphSlamEngine();
209 
210  // Public function definitions
211  //////////////////////////////////////////////////////////////
212  /**\brief Query CGraphSlamEngine instance for the current estimated robot
213  * position
214  */
216  /***\brief Get the estimated trajectory of the robot given by the running
217  * graphSLAM algorithm.
218  * @returns Current list of nodes registered in the graph
219  */
220  virtual typename GRAPH_T::global_poses_t getRobotEstimatedTrajectory()
221  const;
222  /**\brief Return the list of nodeIDs which make up robot trajectory
223  * \sa updateEstimatedTrajectoryVisualization
224  */
225  virtual void getNodeIDsOfEstimatedTrajectory(
226  std::set<mrpt::graphs::TNodeID>* nodes_set) const;
227  /**\brief Wrapper method around the GRAPH_T::saveToTextFile method.
228  * Method saves the graph in the format used by TORO & HoG-man strategies
229  *
230  * \param[in] fname_in Name of the generated graph file - Defaults to
231  * "output_graph" if not
232  * set by the user
233  *
234  * \sa save3DScene, http://www.mrpt.org/Robotics_file_formats
235  */
236  void saveGraph(const std::string* fname_in = nullptr) const;
237  /**\brief Wrapper method around the COpenGLScene::saveToFile method.
238  *
239  * \param[in] Name of the generated graph file - Defaults to "output_graph"
240  * if not
241  * set by the user
242  *
243  * \sa saveGraph
244  */
245  void save3DScene(const std::string* fname_in = nullptr) const;
246  /**\brief Read the configuration variables from the <em>.ini file</em>
247  * specified by
248  * the user.
249  * Method is automatically called, upon CGraphSlamEngine initialization
250  *
251  */
252  void loadParams(const std::string& fname);
253  /**\brief Fill in the provided string with the class configuration
254  * parameters.
255  *
256  * \sa printParams
257  */
258  void getParamsAsString(std::string* params_out) const;
259  /**\brief Wrapper around getParamsAsString.
260  * Returns the generated string instead of passing it as an argument to the
261  * call
262  *
263  * \sa printParams
264  */
266  /** \name Map computation and acquisition methods
267  * \brief Fill the given map based on the observations that have been
268  * recorded so far.
269  */
270  /**\{*/
271  /* \brief Method is a wrapper around the computeMap method
272  * \param[out] map Pointer to the map instance that is
273  * to be filled
274  * \param[out] acquisition_time Timestamp that the map was computed at.
275  * This does not (necessarily) matches with the query time since the
276  * cached version is used as long as a new node has not been registered
277  * since the last time the gridmap was computed.
278  *
279  * \sa computeMap
280  */
281  void getMap(
283  mrpt::system::TTimeStamp* acquisition_time = NULL) const;
284  void getMap(
286  mrpt::system::TTimeStamp* acquisition_time = NULL) const;
287  /**\brief Compute the map of the environment based on the
288  * recorded measurements.
289  *
290  * \warning Currently only mrpt::obs::2DRangeScans are supported
291  * \sa getMap
292  */
293  void computeMap() const;
294  /**\}*/
295  /**\brief Print the problem parameters to the console for verification.
296  *
297  * Method is a wrapper around CGraphSlamEngine::getParamsAsString method
298  * \sa getParamsAsString
299  */
300  void printParams() const;
301  /**\brief Wrapper method around _execGraphSlamStep.
302  *
303  * Handy for not having to specify any action/observations objects
304  * \return False if the user has requested to exit the graphslam execution
305  * (e.g. pressed ctrl-c), True otherwise
306  */
307  bool execGraphSlamStep(
308  mrpt::obs::CObservation::Ptr& observation, size_t& rawlog_entry);
309  /**\brief Main class method responsible for parsing each measurement and
310  * for executing graphSLAM.
311  *
312  * \note Method reads each measurement seperately, so the application that
313  * invokes it is responsibe for fetching the measurements (e.g. from a
314  * rawlog file).
315  *
316  * \return False if the user has requested to exit the graphslam execution
317  * (e.g. pressed ctrl-c), True otherwise
318  **/
319  virtual bool _execGraphSlamStep(
321  mrpt::obs::CSensoryFrame::Ptr& observations,
322  mrpt::obs::CObservation::Ptr& observation, size_t& rawlog_entry);
323 
324  /**\brief Return a reference to the underlying GRAPH_T instance. */
325  const GRAPH_T& getGraph() const { return m_graph; }
326  /**\brief Return the filename of the used rawlog file.*/
328  /**\name ground-truth parsing methods */
329  /**\{*/
330  /**\brief Parse the ground truth .txt file and fill in the corresponding
331  * gt_poses vector.
332  *
333  * It is assumed that the rawlog, thererfore the groundtruth file has been
334  * generated using the <em>GridMapNavSimul</em> MRPT application. If not
335  * user should abide the ground-truth file format to that of the files
336  * generated by the GridMapNavSimul app.
337  *
338  * \sa readGTFileRGBD_TUM
339  *
340  * \param[in] fname_GT Ground truth filename from which the measurements
341  * are to be read
342  * \param[out] gt_poses std::vector which is to contain the 2D ground truth
343  * poses.
344  * \param[out] gt_timestamps std::vector which is to contain the timestamps
345  * for the corresponding ground truth poses. Ignore this argument if
346  * timestamps are not needed.
347  */
348  static void readGTFile(
349  const std::string& fname_GT,
350  std::vector<mrpt::poses::CPose2D>* gt_poses,
351  std::vector<mrpt::system::TTimeStamp>* gt_timestamps = NULL);
352  static void readGTFile(
353  const std::string& fname_GT,
354  std::vector<mrpt::poses::CPose3D>* gt_poses,
355  std::vector<mrpt::system::TTimeStamp>* gt_timestamps = NULL);
356  /**\brief Parse the ground truth .txt file and fill in the corresponding
357  * m_GT_poses vector. The poses returned are given with regards to the
358  * MRPT reference frame.
359  *
360  * It is assumed that the groundtruth file has been generated using the
361  * <em>rgbd_dataset2rawlog</em> MRPT tool.
362  *
363  * \param[in] fname_GT Ground truth filename from which the measurements
364  * are to be read
365  * \param[out] gt_poses std::vector which is to contain the
366  * 2D ground truth poses.
367  * \param[out] gt_timestamps std::vector which is to contain the timestamps
368  * for the corresponding ground truth poses. Ignore this argument if
369  * timestamps are not needed.
370  *
371  * \sa readGTFile,
372  * http://www.mrpt.org/Collection_of_Kinect_RGBD_datasets_with_ground_truth_CVPR_TUM_2011
373  */
374  static void readGTFileRGBD_TUM(
375  const std::string& fname_GT,
376  std::vector<mrpt::poses::CPose2D>* gt_poses,
377  std::vector<mrpt::system::TTimeStamp>* gt_timestamps = NULL);
378 
379  /**\}*/
380 
381  /**\brief Generate and write to a corresponding report for each of the
382  * respective self/decider/optimizer classes.
383  *
384  * \param[in] output_dir_fname directory name to generate the files in.
385  * Directory must be crated prior to this call
386  *
387  * \sa getDescriptiveReport, CGraphSlamHandler::initOutputDir
388  */
389  void generateReportFiles(const std::string& output_dir_fname_in);
390  /**\brief Fill the given vector with the deformation energy values computed
391  * for the SLAM evaluation metric
392  *
393  * \param[out] vec_out deformation energy vector to be filled
394  * \sa m_deformation_energy_vec
395  */
396  void getDeformationEnergyVector(std::vector<double>* vec_out) const;
397  /**\brief Fill the given maps with stats regarding the overall execution of
398  * graphslam.
399  */
400  bool getGraphSlamStats(
401  std::map<std::string, int>* node_stats,
402  std::map<std::string, int>* edge_stats,
403  mrpt::system::TTimeStamp* timestamp = NULL);
404 
405  /**\name pause/resume execution */
406  /**\{ */
407  bool isPaused() const { return m_is_paused; }
408  void togglePause()
409  {
410  if (isPaused())
411  {
412  this->resumeExec();
413  }
414  else
415  {
416  this->pauseExec();
417  }
418  }
419  void resumeExec() const
420  {
421  if (!isPaused())
422  {
423  return;
424  }
425  MRPT_LOG_INFO_STREAM("Program resumed.");
426  m_is_paused = false;
427 
428  if (m_enable_visuals)
429  {
430  this->m_win->addTextMessage(
431  0.3, 0.8, "", mrpt::img::TColorf(1.0, 0, 0),
433  }
434  }
435 
436  void pauseExec()
437  {
438  if (isPaused())
439  {
440  return;
441  }
443  "Program is paused. "
444  << "Press \"" << m_keystroke_pause_exec << " or \""
446  << "\" in the dipslay window to resume");
447  m_is_paused = true;
448  if (m_enable_visuals)
449  {
450  this->m_win->addTextMessage(
451  0.3, 0.8, m_paused_message, mrpt::img::TColorf(1.0, 0, 0),
453  }
454 
455  while (this->isPaused())
456  {
457  std::this_thread::sleep_for(1s);
458  this->queryObserverForEvents();
459  }
460  }
461  /**\} */
462 
463  protected:
464  // Private function definitions
465  //////////////////////////////////////////////////////////////
466  /**\brief General initialization method to call from the Class
467  * Constructors.
468  *
469  * \note Method is automatically called in the class constructor
470  */
471  void initClass();
472  /**\brief Automate the creation and initialization of a results file
473  * relevant to
474  * the application.
475  *
476  * Open the file (corresponding to the provided filename) and write an
477  * introductory message.
478  *
479  * \sa CGraphSlamHandler::initOutputDir
480  */
481  void initResultsFile(const std::string& fname);
482  /**\brief Fill the provided string with a detailed report of the class state
483  *
484  * Report includes the following:
485  * - Timing of important methods
486  * - Properties fo class at the current time
487  * - Logging of commands until current time
488  *
489  * \note Decider/Optimizer classes should also implement a
490  * getDescriptiveReport
491  * method for printing information on their part of the execution.
492  */
493  void getDescriptiveReport(std::string* report_str) const;
494  /** \name Initialization of Visuals
495  * Methods used for initializing various visualization features relevant to
496  * the application at hand. If the visual feature is specified by the user
497  * (via the .ini file) and if it is relevant to the application then the
498  * corresponding method is called in the initClass class method
499  */
500  /**\{*/
502 
503  void initRangeImageViewport();
505 
507  /**\brief Method to help overcome the partial template specialization
508  * restriction of C++. Apply polymorphism by overloading function arguments
509  * instead
510  */
511  /**\{ */
513  const mrpt::poses::CPose2D& p_unused);
515  const mrpt::poses::CPose3D& p_unused);
516  /**\} */
517 
518  void initCurrPosViewport();
519  void initGTVisualization();
523  /**\}*/
524 
525  /** \name Update of Visuals
526  * Methods used for updating various visualization features relevant to
527  * the application at hand. If relevant to the application at hand update
528  * is periodically scheduled inside the execGraphSlam method
529  */
530  /**\{*/
531  /**\brief Wrapper around the deciders/optimizer updateVisuals methods
532  */
533  void updateAllVisuals();
534  /**\brief In RGB-D TUM Datasets update the Range image displayed in a
535  * seperate viewport
536  */
538  /**\brief In RGB-D TUM Datasets update the Intensity image displayed in a
539  * seperate viewport
540  */
542  /**\brief Update the viewport responsible for displaying the graph-building
543  * procedure in the estimated position of the robot
544  */
545  virtual void updateCurrPosViewport();
546  /**\brief return the 3D Pose of a LaserScan that is to be visualized.
547  *
548  * Used during the computeMap call for the occupancy gridmap
549  */
551  const mrpt::graphs::TNodeID nodeID) const;
552  /**\brief Set the properties of the map visual object based on the nodeID
553  * that
554  * it was produced by.
555  * Derived classes may override this method if they want to have different
556  * visual properties (color, shape etc.) for different nodeIDs.
557  *
558  * \note Base class method sets only the color of the object
559  */
560  virtual void setObjectPropsFromNodeID(
561  const mrpt::graphs::TNodeID nodeID,
563  void initMapVisualization();
564  /**\brief Update the map visualization based on the current graphSLAM
565  * state.
566  *
567  * Map is produced by arranging the range scans based on the estimated
568  * robot trajectory.
569  *
570  * \sa updateEstimatedTrajectoryVisualization
571  */
573  const std::map<
575  nodes_to_laser_scans2D,
576  bool full_update = false);
577  /**\brief Display the next ground truth position in the visualization
578  * window.
579  *
580  * \sa updateOdometryVisualization
581  */
582  void updateGTVisualization();
583  /**\brief Update odometry-only cloud with latest odometry estimation.
584  *
585  * \sa updateGTVisualization
586  * */
588  /**\brief Update the Esstimated robot trajectory with the latest estimated
589  * robot position.
590  *
591  * Update CSetOfLines visualization object with the latest graph node
592  * position. If full update is asked, method clears the CSetOfLines
593  * object and redraws all the lines based on the updated (optimized)
594  * positions of the nodes
595  */
596  void updateEstimatedTrajectoryVisualization(bool full_update = false);
597  /**\brief Update the displayPlots window with the new information with
598  * regards to the metric
599  */
601  /**\}*/
602  /** \name Toggling of Visuals
603  * Methods used for toggling various visualization features relevant to
604  * the application at hand.
605  */
606  /**\{*/
608  void toggleGTVisualization();
609  void toggleMapVisualization();
611  /**\}*/
612 
613  /**\brief Cut down on the size of the given laser scan.
614  *
615  * Handy for reducing the size of the resulting mrpt::opengl::CSetOfObjects
616  * that would be inserted in the visualization scene. Increase the
617  * decimation rate - keep-every_n_entries - to reduce the computational
618  * cost of updating the map visualization
619  *
620  * \sa updateMapVisualization
621  */
622  void decimateLaserScan(
623  mrpt::obs::CObservation2DRangeScan& laser_scan_in,
624  mrpt::obs::CObservation2DRangeScan* laser_scan_out,
625  const int keep_every_n_entries = 2);
626  void alignOpticalWithMRPTFrame(); // TODO - either use it or remove it
627  /**\brief Query the observer instance for any user events.
628  *
629  * Query the given observer for any events (keystrokes, mouse clicks,
630  * that may have occurred in the CDisplayWindow3D and fill in the
631  * corresponding class variables
632  */
633  inline void queryObserverForEvents();
634 
635  /** \brief Compare the SLAM result (estimated trajectory) with the GT path.
636  *
637  * See <a
638  * href="http://europa.informatik.uni-freiburg.de/files/burgard09iros.pdf">
639  * A Comparison of SLAM Algorithms Based on a Graph of Relations</a>
640  * for more details on this.
641  */
642  void computeSlamMetric(mrpt::graphs::TNodeID nodeID, size_t gt_index);
643 
644  /**\brief Wrapper method that used for printing error messages in a
645  * consistent manner
646  *
647  * Makes use of the COutputLogger instance. Prints error message when
648  * toggling illegal visual features in the display window
649  */
651  std::string viz_flag, int sleep_time = 500 /* ms */);
652  // TODO - move this to a different module - to be accessed globally
653  /**\brief Fill the TTimestamp in a consistent manner.
654  *
655  * Method can be used in both MRPT Rawlog formats
656  *
657  * \param[in] action_ptr Pointer to the action (action-observations format)
658  * \param[in] observations Pointer to list of observations
659  * (action-observations format)
660  * \param[in] observation Pointer to single observation (observation-only
661  * format)
662  *
663  * \note if both action_ptr and observation_ptr contains valid timestamps,
664  * the
665  * action is preferred.
666  *
667  * \return mrpt::system::TTimeStamp
668  */
671  const mrpt::obs::CSensoryFrame::Ptr observations,
672  const mrpt::obs::CObservation::Ptr observation);
673  // TODO - move these somewhere else.
674  /**\name Class specific supplementary functions.
675  */
676  /**\{*/
677  static double accumulateAngleDiffs(
678  const mrpt::poses::CPose2D& p1, const mrpt::poses::CPose2D& p2);
679  static double accumulateAngleDiffs(
680  const mrpt::poses::CPose3D& p1, const mrpt::poses::CPose3D& p2);
681  /**\}*/
682  /**\brief Set the opengl model that indicates the latest position of the
683  * trajectory at hand
684  *
685  * \param[in] model_name Name of the resulting opengl object.
686  * \param[in] model_color Color of the object.
687  * \param[in] model_size Scaling of the object.
688  * \param[in] init_pose Initial position of the object.
689  *
690  * \todo Use an airplane/quad model for 3D operations
691  *
692  * \returns CSetOfObjects::Ptr instance.
693  *
694  * \note Different model is used depending on whether we are running 2D or
695  * 3D SLAM.
696  */
698  const std::string& model_name,
699  const mrpt::img::TColor& model_color = mrpt::img::TColor(0, 0, 0),
700  const size_t model_size = 1, const pose_t& init_pose = pose_t());
701 
702  /**\brief Assert that the given nodes number matches the registered graph
703  * nodes, otherwise throw exception
704  *
705  * \note Method locks the graph internally.
706  *
707  * \raise logic_error if the expected node count mismatches with the
708  * graph current node count.
709  */
710  virtual void monitorNodeRegistration(
711  bool registered = false, std::string class_name = "Class");
712  /**\brief Wrapper around the GRAPH_T::dijkstra_nodes_estimate
713  *
714  * Update the global position of the nodes
715  */
717 
718  // VARIABLES
719  //////////////////////////////////////////////////////////////
720  mrpt::system::CTimeLogger m_time_logger; /**<Time logger instance */
721 
722  /**\brief The graph object to be built and optimized. */
723  GRAPH_T m_graph;
724 
725  /**\name Decider/Optimizer instances. Delegating the GRAPH_T tasks to these
726  * classes makes up for a modular and configurable design
727  */
728  /**\{*/
732  /**\}*/
733 
734  /**\brief Determine if we are to enable visualization support or not. */
735  const bool m_enable_visuals;
736 
738 
739  /**\brief Rawlog file from which to read the measurements.
740  *
741  * If string is empty, process is to be run online
742  */
744 
746 
747  /**\brief Counter for reading back the GT_poses. */
749  /**\brief Rate at which to read the GT poses. */
751 
753 
756 
757  /**\brief keeps track of the out fstreams so that they can be closed (if
758  * still open) in the class Dtor.
759  */
761 
762  /**\name Visualization - related objects */
763  /**\{*/
767  /**\brief DisplayPlots instance for visualizing the evolution of the SLAM
768  * metric
769  */
771  /**\}*/
772 
773  /** \name Visualization - related flags
774  * \brief Flags for visualizing various trajectories/objects of interest.
775  *
776  * These are set from the .ini configuration file. The actual visualization
777  * of these objects can be overriden if the user issues the corresponding
778  * keystrokes in the CDisplayWindow3D. In order for them to have any
779  * effect, a pointer to CDisplayWindow3D has to be given first.
780  */
781  /**\{*/
790  /**\}*/
791 
792  /**\brief Indicated if program is temporarily paused by the user
793  */
794  mutable bool m_is_paused;
795 
796  /**\brief Message to be displayed while paused. */
798 
799  /**\name textMessage - related Parameters
800  * Parameters relevant to the textMessages appearing in the visualization
801  * window. These are divided into
802  * - Y offsets: vertical position of the textMessage, starting from the top
803  * side.
804  * - Indices: Unique ID number of each textMessage, used for updating it
805  */
806  /**\{*/
807  /**\brief Offset from the \a left side of the canvas.
808  * Common for all the messages that are displayed on that side.
809  */
811 
818 
825  /**\}*/
826 
827  /**\name User available keystrokes
828  * Keystrokes for toggling the corresponding objects in the CDisplayWindow
829  * upon user press
830  */
831  /**\{*/
837  /**\}*/
838 
839  /**\brief Instance to keep track of all the edges + visualization related
840  * operations
841  */
843 
844  /**\brief Flag for specifying if we are going to use ground truth data at
845  * all.
846  *
847  * This is set to true either if the evolution of the SLAM metric or the
848  * ground truth visualization is set to true.
849  */
850  bool m_use_GT;
851 
852  // pose_t vectors
853  std::vector<pose_t> m_odometry_poses;
854  std::vector<pose_t> m_GT_poses;
855 
857 
858  /**\brief Map of NodeIDs to their corresponding LaserScans.
859  */
861  /**\brief Last laser scan that the current class instance received.
862  */
864  /**\brief First recorded laser scan - assigned to the root */
866  /**\brief Last laser scan that the current class instance received.
867  */
869 
870  /**\name Trajectories colors */
871  /**\{*/
877  /**\}*/
878 
879  // frame transformation from the RGBD_TUM GrountTruth to the MRPT
880  // reference frame
881  // TODO - either use it or lose it...
883  /** How big are the robots going to be in the scene */
885  /**\brief Internal counter for querying for the number of nodeIDs.
886  *
887  * Handy for not locking the m_graph resource
888  */
890  /** Mark graph modification/accessing explicitly for multithreaded
891  * implementation
892  */
893  mutable std::mutex m_graph_section;
894 
895  // keep track of the storage directory for the 3DRangeScan depth/range
896  // images
899 
900  /**\name Slam Metric related variables */
901  /**\{*/
902  /**\brief Map from nodeIDs to their corresponding closest GT pose index.
903  * Keep track of the nodeIDs instead of the node positions as the latter
904  * are about to change in the Edge Registration / Loop closing procedures
905  */
906  std::map<mrpt::graphs::TNodeID, size_t> m_nodeID_to_gt_indices;
908  std::vector<double> m_deformation_energy_vec;
909  /**\}*/
910 
911  /**\brief Struct responsible for keeping the parameters of the .info file
912  * in RGBD related datasets
913  */
915  {
917  TRGBDInfoFileParams(const std::string& rawlog_fname);
919 
921  /**\brief Parse the RGBD information file to gain information about the
922  * rawlog
923  * file contents
924  */
925  void parseFile();
926  void setRawlogFile(const std::string& rawlog_fname);
927 
928  /**\brief Format for the parameters in the info file:
929  * <em>string literal - related value</em> (kept in a string
930  * representation)
931  */
932  std::map<std::string, std::string> fields;
933 
935 
937 
938  /**\brief Time it took to record the dataset.
939  * Processing time should (at least) be equal to the grab time for the
940  * algorithm to run in real-time
941  */
943 
944  /**\brief First recorded timestamp in the dataset. */
946  /**\brief Current dataset timestamp */
948  /**\brief Current robot position based solely on odometry */
950 
951  /**\brief Indicate whether the user wants to exit the application (e.g.
952  * pressed by pressign ctrl-c)
953  */
955 
956  /**\name Map-related objects
957  * \brief Cached version and corresponding flag of map
958  */
959  /**\{*/
961  /**\brief Acquired map in CSimpleMap representation */
964  /**\brief Indicates if the map is cached.
965  *
966  *\note Common var for both 2D and 3D maps.
967  */
968  mutable bool m_map_is_cached;
969  /**\brief Timestamp at which the map was computed
970  *
971  *\note Common var for both 2D and 3D maps.
972  */
974  /**\}*/
975 
977  /**\brief Track the first node registration occurance
978  *
979  * Handy so that we can assign a measurement to the root node as well.
980  */
982 
983  /**\brief MRPT CNetworkOfPoses constraint classes that are currently
984  * supported
985  */
986  std::vector<std::string> m_supported_constraint_types;
987  /**\brief Type of constraint currently in use.
988  */
990 
991  /**\brief Separator string to be used in debugging messages
992  */
993  static const std::string header_sep;
994  static const std::string report_sep;
995 };
996 }
997 // pseudo-split the definition and implementation of template
998 #include "CGraphSlamEngine_impl.h"
999 
1000 #endif /* end of include guard: GRAPHSLAMENGINE_H */
1001 
1002 
Main file for the GraphSlamEngine.
virtual void getNodeIDsOfEstimatedTrajectory(std::set< mrpt::graphs::TNodeID > *nodes_set) const
Return the list of nodeIDs which make up robot trajectory.
void computeMap() const
Compute the map of the environment based on the recorded measurements.
fstreams_out m_out_streams
keeps track of the out fstreams so that they can be closed (if still open) in the class Dtor.
virtual void updateCurrPosViewport()
Update the viewport responsible for displaying the graph-building procedure in the estimated position...
virtual mrpt::poses::CPose3D getLSPoseForGridMapVisualization(const mrpt::graphs::TNodeID nodeID) const
return the 3D Pose of a LaserScan that is to be visualized.
void initClass()
General initialization method to call from the Class Constructors.
mrpt::graphslam::CWindowObserver * m_win_observer
mrpt::system::TTimeStamp m_init_timestamp
First recorded timestamp in the dataset.
void updateAllVisuals()
Wrapper around the deciders/optimizer updateVisuals methods.
typename GRAPH_T::global_pose_t global_pose_t
pose_t m_curr_odometry_only_pose
Current robot position based solely on odometry.
void loadParams(const std::string &fname)
Read the configuration variables from the .ini file specified by the user.
typename GRAPH_T::constraint_t::type_value pose_t
Type of underlying poses (2D/3D).
mrpt::graphslam::deciders::CEdgeRegistrationDecider< GRAPH_T > * m_edge_reg
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.
mrpt::graphs::TNodeID m_nodeID_max
Internal counter for querying for the number of nodeIDs.
double m_offset_x_left
Offset from the left side of the canvas.
size_t m_GT_poses_step
Rate at which to read the GT poses.
static void readGTFile(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=NULL)
Parse the ground truth .txt file and fill in the corresponding gt_poses vector.
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.
std::map< mrpt::graphs::TNodeID, mrpt::obs::CObservation2DRangeScan::Ptr > nodes_to_scans2D_t
void updateGTVisualization()
Display the next ground truth position in the visualization window.
void queryObserverForEvents()
Query the observer instance for any user events.
mrpt::obs::CObservation3DRangeScan::Ptr m_last_laser_scan3D
Last laser scan that the current class instance received.
mrpt::graphslam::optimizers::CGraphSlamOptimizer< GRAPH_T > * m_optimizer
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.
bool m_is_first_time_node_reg
Track the first node registration occurance.
struct mrpt::graphslam::CGraphSlamEngine::TRGBDInfoFileParams m_info_params
const GRAPH_T & getGraph() const
Return a reference to the underlying GRAPH_T instance.
double m_dataset_grab_time
Time it took to record the dataset.
CGraphSlamEngine(const std::string &config_file, const std::string &rawlog_fname="", const std::string &fname_GT="", mrpt::graphslam::CWindowManager *win_manager=NULL, mrpt::graphslam::deciders::CNodeRegistrationDecider< GRAPH_T > *node_reg=NULL, mrpt::graphslam::deciders::CEdgeRegistrationDecider< GRAPH_T > *edge_reg=NULL, mrpt::graphslam::optimizers::CGraphSlamOptimizer< GRAPH_T > *optimizer=NULL)
Constructor of CGraphSlamEngine class template.
mrpt::math::CMatrixDouble33 m_rot_TUM_to_MRPT
bool m_use_GT
Flag for specifying if we are going to use ground truth data at all.
mrpt::gui::CDisplayWindow3D * m_win
void computeSlamMetric(mrpt::graphs::TNodeID nodeID, size_t gt_index)
Compare the SLAM result (estimated trajectory) with the GT path.
void initResultsFile(const std::string &fname)
Automate the creation and initialization of a results file relevant to the application.
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.
std::string m_rawlog_fname
Rawlog file from which to read the measurements.
std::vector< double > m_deformation_energy_vec
virtual GRAPH_T::global_poses_t getRobotEstimatedTrajectory() const
GRAPH_T m_graph
The graph object to be built and optimized.
mrpt::graphslam::detail::CEdgeCounter m_edge_counter
Instance to keep track of all the edges + visualization related operations.
const bool m_enable_visuals
Determine if we are to enable visualization support or not.
std::string m_current_constraint_type
Type of constraint currently in use.
void getDeformationEnergyVector(std::vector< double > *vec_out) const
Fill the given vector with the deformation energy values computed for the SLAM evaluation metric.
bool m_map_is_cached
Indicates if the map is cached.
mrpt::system::TTimeStamp m_map_acq_time
Timestamp at which the map was computed.
static void readGTFileRGBD_TUM(const std::string &fname_GT, std::vector< mrpt::poses::CPose2D > *gt_poses, std::vector< mrpt::system::TTimeStamp > *gt_timestamps=NULL)
Parse the ground truth .txt file and fill in the corresponding m_GT_poses vector.
std::mutex m_graph_section
Mark graph modification/accessing explicitly for multithreaded implementation.
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::system::TTimeStamp m_curr_timestamp
Current dataset timestamp.
static double accumulateAngleDiffs(const mrpt::poses::CPose2D &p1, const mrpt::poses::CPose2D &p2)
size_t m_GT_poses_index
Counter for reading back the GT_poses.
void updateOdometryVisualization()
Update odometry-only cloud with latest odometry estimation.
void updateEstimatedTrajectoryVisualization(bool full_update=false)
Update the Esstimated robot trajectory with the latest estimated robot position.
bool m_is_paused
Indicated if program is temporarily paused by the user.
void dumpVisibilityErrorMsg(std::string viz_flag, int sleep_time=500)
Wrapper method that used for printing error messages in a consistent manner.
typename GRAPH_T::constraint_t constraint_t
Type of graph constraints.
size_t m_robot_model_size
How big are the robots going to be in the scene.
bool getGraphSlamStats(std::map< std::string, int > *node_stats, std::map< std::string, int > *edge_stats, mrpt::system::TTimeStamp *timestamp=NULL)
Fill the given maps with stats regarding the overall execution of graphslam.
mrpt::opengl::CSetOfObjects::Ptr initRobotModelVisualization()
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.
void save3DScene(const std::string *fname_in=nullptr) const
Wrapper method around the COpenGLScene::saveToFile method.
void execDijkstraNodesEstimation()
Wrapper around the GRAPH_T::dijkstra_nodes_estimate.
mrpt::gui::CDisplayWindowPlots * m_win_plot
DisplayPlots instance for visualizing the evolution of the SLAM metric.
mrpt::maps::COccupancyGridMap2D::Ptr m_gridmap_cached
mrpt::graphslam::deciders::CNodeRegistrationDecider< GRAPH_T > * m_node_reg
typename fstreams_out::iterator fstreams_out_it
Map for iterating over output file streams.
virtual ~CGraphSlamEngine()
Default Destructor.
const std::string m_paused_message
Message to be displayed while paused.
static const std::string report_sep
std::map< std::string, mrpt::io::CFileOutputStream > fstreams_out
Handy typedefs.
void updateSlamMetricVisualization()
Update the displayPlots window with the new information with regards to the metric.
std::string getRawlogFname()
Return the filename of the used rawlog file.
mrpt::obs::CObservation2DRangeScan::Ptr m_last_laser_scan2D
Last laser scan that the current class instance received.
bool execGraphSlamStep(mrpt::obs::CObservation::Ptr &observation, size_t &rawlog_entry)
Wrapper method around _execGraphSlamStep.
mrpt::maps::CSimpleMap m_simple_map_cached
Acquired map in CSimpleMap representation.
bool m_request_to_exit
Indicate whether the user wants to exit the application (e.g.
void getDescriptiveReport(std::string *report_str) const
Fill the provided string with a detailed report of the class state.
mrpt::opengl::CSetOfObjects::Ptr initRobotModelVisualizationInternal(const mrpt::poses::CPose2D &p_unused)
Method to help overcome the partial template specialization restriction of C++.
void updateIntensityImageViewport()
In RGB-D TUM Datasets update the Intensity image displayed in a seperate viewport.
mrpt::obs::CObservation2DRangeScan::Ptr m_first_laser_scan2D
First recorded laser scan - assigned to the root.
mrpt::graphslam::CWindowManager * m_win_manager
std::vector< std::string > m_supported_constraint_types
MRPT CNetworkOfPoses constraint classes that are currently supported.
std::vector< pose_t > m_odometry_poses
void saveGraph(const std::string *fname_in=nullptr) const
Wrapper method around the GRAPH_T::saveToTextFile method.
std::string getParamsAsString() const
Wrapper around getParamsAsString.
mrpt::img::TColor m_current_constraint_type_color
global_pose_t getCurrentRobotPosEstimation() const
Query CGraphSlamEngine instance for the current estimated robot position.
mrpt::maps::COctoMap::Ptr m_octomap_cached
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...
std::map< mrpt::graphs::TNodeID, size_t > m_nodeID_to_gt_indices
Map from nodeIDs to their corresponding closest GT pose index.
mrpt::system::CTimeLogger m_time_logger
Time logger instance.
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 const std::string header_sep
Separator string to be used in debugging messages.
void getMap(mrpt::maps::COccupancyGridMap2D::Ptr map, mrpt::system::TTimeStamp *acquisition_time=NULL) const
nodes_to_scans2D_t m_nodes_to_laser_scans2D
Map of NodeIDs to their corresponding LaserScans.
void printParams() const
Print the problem parameters to the console for verification.
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...
Monitor events in the visualization window.
Interface for implementing node registration classes.
Generic class for tracking the total number of edges for different tpes of edges and for storing visu...
Definition: CEdgeCounter.h:29
Interface for implementing graphSLAM optimizer classes.
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time.
void addTextMessage(const double x, const double y, const std::string &text, const mrpt::img::TColorf &color=mrpt::img::TColorf(1.0, 1.0, 1.0), const size_t unique_index=0, const mrpt::opengl::TOpenGLFont font=mrpt::opengl::MRPT_GLUT_BITMAP_TIMES_ROMAN_24)
Add 2D text messages overlapped to the 3D rendered scene.
Create a GUI window and display plots with MATLAB-like interfaces and commands.
std::shared_ptr< COccupancyGridMap2D > Ptr
std::shared_ptr< COctoMap > Ptr
Definition: COctoMap.h:38
This class stores a sequence of <Probabilistic Pose,SensoryFrame> pairs, thus a "metric map" can be t...
Definition: CSimpleMap.h:34
std::shared_ptr< CActionCollection > Ptr
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
std::shared_ptr< CObservation2DRangeScan > Ptr
std::shared_ptr< CObservation3DRangeScan > Ptr
std::shared_ptr< CObservation > Ptr
Definition: CObservation.h:45
std::shared_ptr< CSensoryFrame > Ptr
Definition: CSensoryFrame.h:54
std::shared_ptr< CSetOfObjects > Ptr
Definition: CSetOfObjects.h:28
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
Definition: CPose2D.h:39
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:87
Versatile class for consistent logging and management of output messages.
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X),...
Scalar * iterator
Definition: eigen_plugins.h:26
GLdouble s
Definition: glext.h:3676
GLsizei const GLchar ** string
Definition: glext.h:4101
std::string upperCase(const std::string &str)
Returns a upper-case version of a string.
mrpt::Clock::time_point TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
Definition: datetime.h:40
uint64_t TNodeID
A generic numeric type for unique IDs of nodes or entities.
Definition: TNodeID.h:16
SLAM methods related to graphs of pose constraints.
Struct responsible for keeping the parameters of the .info file in RGBD related datasets.
std::map< std::string, std::string > fields
Format for the parameters in the info file: string literal - related value (kept in a string represen...
void parseFile()
Parse the RGBD information file to gain information about the rawlog file contents.
A RGB color - 8bit.
Definition: TColor.h:21
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
#define MRPT_LOG_INFO_STREAM(__CONTENTS)
#define MRPT_LOG_WARN_STREAM(__CONTENTS)



Page generated by Doxygen 1.9.1 for MRPT 1.9.9 Git: 814d80880 Fri Aug 24 01:51:28 2018 +0200 at mar 26 may 2026 12:30:59 CEST