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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019