CGraphSlamHandler_ROS_impl.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-2016, 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 #pragma once
11 
12 #include <mrpt/ros1bridge/time.h>
13 #include <mrpt/ros1bridge/laser_scan.h>
14 #include <mrpt/ros1bridge/pose.h>
15 #include <mrpt/ros1bridge/map.h>
16 
17 namespace mrpt
18 {
19 namespace graphslam
20 {
21 namespace apps
22 {
23 // From:
24 // https://answers.ros.org/question/364561/tfcreatequaternionfromyaw-equivalent-in-ros2/
25 static inline auto createQuaternionMsgFromYaw(double yaw)
26 {
28  q.setRPY(0, 0, yaw);
29  return tf2::toMsg(q);
30 }
31 
32 // static member variables
33 template <class GRAPH_T>
34 const std::string CGraphSlamHandler_ROS<GRAPH_T>::sep_header(40, '=');
35 
36 template <class GRAPH_T>
37 const std::string CGraphSlamHandler_ROS<GRAPH_T>::sep_subheader(20, '-');
38 
39 // Ctor
40 template <class GRAPH_T>
42  mrpt::system::COutputLogger* logger,
43  TUserOptionsChecker<GRAPH_T>* options_checker, ros::NodeHandle* nh_in)
44  : parent_t(logger, options_checker, /*enable_visuals=*/false), m_nh(nh_in)
45 {
46  using namespace mrpt::obs;
47 
48  ASSERT_(m_nh);
49 
50  // TODO - does this affect?
51  // Previous value = 0;
52  m_queue_size = 1;
53 
54  // variables initialization/assignment
55  m_pub_seq = 0;
56  m_stats_pub_seq = 0;
57  this->resetReceivedFlags();
58 
59  // measurements initialization
60  m_mrpt_odom = CObservationOdometry::Create();
61  m_mrpt_odom->hasEncodersInfo = false;
62  m_mrpt_odom->hasVelocities = false;
64 
66 
67  // Thu Nov 3 23:36:49 EET 2016, Nikos Koukis
68  // WARNING: ROS Server Parameters have not been read yet. Make sure you know
69  // what to initialize at this stage!
70 }
71 
72 template <class GRAPH_T>
74 {
75 }
76 
77 template <class GRAPH_T>
79 {
80  this->readROSParameters();
81 
82  ASSERT_(!this->m_ini_fname.empty());
83  parent_t::readConfigFname(this->m_ini_fname);
84 }
85 
86 template <class GRAPH_T>
88 {
89  // misc
90  {
91  std::string ns = "misc/";
92 
93  // enable/disable visuals
94  bool m_disable_MRPT_visuals;
95  m_nh->param<bool>(
96  ns + "disable_MRPT_visuals", m_disable_MRPT_visuals, false);
97  this->m_enable_visuals = !m_disable_MRPT_visuals;
98 
99  // verbosity level
100  int lvl;
101  m_nh->param<int>(ns + "verbosity", lvl, static_cast<int>(LVL_INFO));
102  m_min_logging_level = static_cast<VerbosityLevel>(lvl);
103  this->m_logger->setMinLoggingLevel(m_min_logging_level);
104  }
105  // deciders, optimizer
106  {
107  std::string ns = "deciders_optimizers/";
108  m_nh->param<std::string>(ns + "NRD", m_node_reg, "CFixedIntervalsNRD");
109  m_nh->param<std::string>(ns + "ERD", m_edge_reg, "CICPCriteriaERD");
110  m_nh->param<std::string>(ns + "GSO", m_optimizer, "CLevMarqGSO");
111  }
112  // filenames
113  {
114  std::string ns = "files/";
115 
116  // configuration file - mandatory
117  std::string config_param_path = ns + "config";
118  bool found_config = m_nh->getParam(ns + "config", this->m_ini_fname);
119  ASSERTMSG_(
120  found_config, mrpt::format(
121  "Configuration file was not set. Set %s and try "
122  "again.\nExiting...",
123  config_param_path.c_str()));
124 
125  // ground-truth file
126  m_nh->getParam(ns + "ground_truth", this->m_gt_fname);
127  }
128 
129  // TF Frame IDs
130  // names of the frames of the corresponding robot parts
131  {
132  std::string ns = "frame_IDs/";
133 
134  m_nh->param<std::string>(ns + "anchor_frame", m_anchor_frame_id, "map");
135  m_nh->param<std::string>(
136  ns + "base_link_frame", m_base_link_frame_id, "base_link");
137  m_nh->param<std::string>(
138  ns + "odometry_frame", m_odom_frame_id, "odom");
139  }
140 
141  // ASSERT that the given user options are valid
142  // Fill the TuserOptionsChecker related structures
143  this->m_options_checker->createDeciderOptimizerMappings();
144  this->m_options_checker->populateDeciderOptimizerProperties();
145  this->verifyUserInput();
146 
147  this->m_logger->logFmt(
148  LVL_DEBUG, "Successfully read parameters from ROS Parameter Server");
149 
150  // Visuals initialization
151  if (this->m_enable_visuals)
152  {
153  this->initVisualization();
154  }
155 } // end of readROSParameters
156 
157 template <class GRAPH_T>
159 {
160 }
161 
162 template <class GRAPH_T>
164 {
165  this->m_logger->logFmt(
166  LVL_WARN, "Initializing CGraphSlamEngine_ROS instance...");
167  this->m_engine = new CGraphSlamEngine_ROS<GRAPH_T>(
168  m_nh, this->m_ini_fname,
169  /*rawlog_fname=*/"", this->m_gt_fname, this->m_win_manager,
170  this->m_options_checker->node_regs_map[m_node_reg](),
171  this->m_options_checker->edge_regs_map[m_edge_reg](),
172  this->m_options_checker->optimizers_map[m_optimizer]());
173  this->m_logger->logFmt(
174  LVL_WARN, "Successfully initialized CGraphSlamEngine_ROS instance.");
175 }
176 
177 template <class GRAPH_T>
179 {
180  this->m_options_checker->node_regs_map[m_node_reg]();
181  this->m_options_checker->edge_regs_map[m_edge_reg]();
182  this->m_options_checker->optimizers_map[m_optimizer]();
183 
184  this->m_logger->logFmt(
185  LVL_WARN, "Initializing CGraphSlamEngine_MR instance...");
186  this->m_engine = new CGraphSlamEngine_MR<GRAPH_T>(
187  m_nh, this->m_ini_fname,
188  /*rawlog_fname=*/"", this->m_gt_fname, this->m_win_manager,
189  this->m_options_checker->node_regs_map[m_node_reg](),
190  this->m_options_checker->edge_regs_map[m_edge_reg](),
191  this->m_options_checker->optimizers_map[m_optimizer]());
192  this->m_logger->logFmt(
193  LVL_WARN, "Successfully initialized CGraphSlamEngine_MR instance.");
194 }
195 
196 template <class GRAPH_T>
198 {
199  using namespace std;
200 
201  ASSERT_(str_out);
202 
203  stringstream ss("");
204 
205  ss << "ROS Parameters: " << endl;
206  ss << sep_header << endl;
207  ss << endl;
208 
209  ss << "Deciders / Optimizers = " << endl;
210  ss << sep_subheader << endl;
211  ss << "Node Registration Decider = " << m_node_reg << endl;
212  ss << "Edge Registration Decider = " << m_edge_reg << endl;
213  ss << "GraphSLAM Optimizer = " << m_optimizer << endl;
214  ss << endl;
215 
216  ss << "Filenames: " << endl;
217  ss << sep_subheader << endl;
218  ss << "Configuration .ini file = " << this->m_ini_fname << endl;
219  ss << "Ground truth filename = "
220  << (!this->m_gt_fname.empty() ? this->m_gt_fname : "NONE") << endl;
221  ss << endl;
222 
223  ss << "Miscellaneous: " << endl;
224  ss << sep_subheader << endl;
225  ss << "Enable MRPT visuals? = "
226  << (this->m_enable_visuals ? "TRUE" : "FALSE") << endl;
227  ss << "Logging verbosity Level = "
228  << COutputLogger::logging_levels_to_names()[m_min_logging_level] << endl;
229 
230  ss << endl;
231 
232  *str_out = ss.str();
233 }
234 
235 template <class GRAPH_T>
237 {
238  ASSERT_(str_out);
239 
240  // ros parameters
241  std::string ros_params("");
242  this->getROSParameters(&ros_params);
243  std::string mrpt_params("");
244  parent_t::getParamsAsString(&mrpt_params);
245 
246  *str_out += ros_params;
247  *str_out += "\n\n";
248  *str_out += mrpt_params;
249 
250  // various parameters
251 }
252 
253 template <class GRAPH_T>
255 {
256  std::string params;
257  this->getParamsAsString(&params);
258  return params;
259 }
260 
261 template <class GRAPH_T>
263 {
264  using namespace std;
265  parent_t::printParams();
266  cout << this->getParamsAsString() << endl;
267 }
268 
269 template <class GRAPH_T>
271 {
272  this->m_logger->logFmt(LVL_DEBUG, "Verifying user input...");
273 
274  // verify the NRD, ERD, GSO parameters
275  bool node_success, edge_success, optimizer_success;
276  bool failed = false;
277 
278  node_success = this->m_options_checker->checkRegistrationDeciderExists(
279  m_node_reg, "node");
280  edge_success = this->m_options_checker->checkRegistrationDeciderExists(
281  m_edge_reg, "edge");
282  optimizer_success =
283  this->m_options_checker->checkOptimizerExists(m_optimizer);
284 
285  if (!node_success)
286  {
287  this->m_logger->logFmt(
288  LVL_ERROR, "\nNode Registration Decider \"%s\" is not available",
289  m_node_reg.c_str());
290  this->m_options_checker->dumpRegistrarsToConsole("node");
291  failed = true;
292  }
293  if (!edge_success)
294  {
295  this->m_logger->logFmt(
296  LVL_ERROR, "\nEdge Registration Decider \"%s\" is not available.",
297  m_edge_reg.c_str());
298  this->m_options_checker->dumpRegistrarsToConsole("edge");
299  failed = true;
300  }
301  if (!optimizer_success)
302  {
303  this->m_logger->logFmt(
304  LVL_ERROR, "\ngraphSLAM Optimizser \"%s\" is not available.",
305  m_optimizer.c_str());
306  this->m_options_checker->dumpOptimizersToConsole();
307  failed = true;
308  }
309  ASSERT_(!failed);
310 
311  // verify that the path to the files is correct
312  // .ini file
313  bool ini_exists = system::fileExists(this->m_ini_fname);
314  ASSERTMSG_(
315  ini_exists, format(
316  "\n.ini configuration file \"%s\"doesn't exist. "
317  "Please specify a valid pathname.\nExiting...\n",
318  this->m_ini_fname.c_str()));
319  // ground-truth file
320  if (!this->m_gt_fname.empty())
321  {
322  bool gt_exists = system::fileExists(this->m_gt_fname);
323  ASSERTMSG_(
324  gt_exists, format(
325  "\nGround truth file \"%s\"doesn't exist."
326  "Either unset the corresponding ROS parameter or "
327  "specify a valid pathname.\n"
328  "Exiting...\n",
329  this->m_gt_fname.c_str()));
330  }
331 
332 } // end of verifyUserInput
333 
334 template <class GRAPH_T>
336 {
337  this->m_logger->logFmt(
338  LVL_INFO,
339  "Setting up ROS-related subscribers, publishers, services...");
340 
341  // setup subscribers, publishers, services...
342  this->setupSubs();
343  this->setupPubs();
344  this->setupSrvs();
345 
346  // fetch the static geometrical transformations
347  // this->readStaticTFs();
348 
349 } // end of setupComm
350 
351 template <class GRAPH_T>
353 {
354  this->m_logger->logFmt(LVL_INFO, "Setting up the subscribers...");
355 
356  // setup the names
357  std::string ns = "input/";
358 
359  m_odom_topic = ns + "odom";
360  m_laser_scan_topic = ns + "laser_scan";
361 
362  // odometry
363  m_odom_sub = m_nh->subscribe<nav_msgs::Odometry>(
365 
366  // laser_scans
367  m_laser_scan_sub = m_nh->subscribe<sensor_msgs::LaserScan>(
369 
370  // camera
371  // TODO
372 
373  // 3D point clouds
374  // TODO
375 
376 } // end of setupSubs
377 
378 template <class GRAPH_T>
380 {
381  this->m_logger->logFmt(LVL_INFO, "Setting up the publishers...");
382 
383  // setup the names
384  std::string ns = "feedback/";
385 
386  m_curr_robot_pos_topic = ns + "robot_position";
387  m_robot_trajectory_topic = ns + "robot_trajectory";
388  m_robot_tr_poses_topic = ns + "robot_tr_poses";
389  m_odom_trajectory_topic = ns + "odom_trajectory";
390  m_gridmap_topic = ns + "gridmap";
391  m_stats_topic = ns + "graphslam_stats";
392 
393  // setup the publishers
394 
395  // agent estimated position
396  m_curr_robot_pos_pub = m_nh->advertise<geometry_msgs::PoseStamped>(
398  m_robot_trajectory_pub = m_nh->advertise<nav_msgs::Path>(
400  m_robot_tr_poses_pub = m_nh->advertise<geometry_msgs::PoseArray>(
402 
403  // odometry nav_msgs::Path
404  m_odom_path.header.seq = 0;
405  m_odom_path.header.stamp = ros::Time::now();
406  m_odom_path.header.frame_id = m_anchor_frame_id;
407 
410 
411  // generated gridmap
412  m_gridmap_pub = m_nh->advertise<nav_msgs::OccupancyGrid>(
414  /*latch=*/true);
415 
416  m_stats_pub = m_nh->advertise<mrpt_msgs::GraphSlamStats>(
418  /*latch=*/true);
419 
420 } // end of setupPubs
421 
422 template <class GRAPH_T>
424 {
425  this->m_logger->logFmt(LVL_INFO, "Setting up the services...");
426 
427  // TODO Error statistics
428 
429 } // end of setupSrvs
430 
431 template <class GRAPH_T>
433 {
434  using namespace std;
435 
436  MRPT_START;
437  bool ret_val = true;
438 
439  ros::Time timestamp = ros::Time::now();
440 
441  // current MRPT robot pose
442  pose_t mrpt_pose = this->m_engine->getCurrentRobotPosEstimation();
443 
444  //
445  // convert pose_t to corresponding geometry_msg::TransformStamped
446  // anchor frame <=> base_link
447  //
448  geometry_msgs::TransformStamped anchor_base_link_transform;
449  anchor_base_link_transform.header.stamp = ros::Time::now();
450  anchor_base_link_transform.header.frame_id = m_anchor_frame_id;
451  anchor_base_link_transform.child_frame_id = m_base_link_frame_id;
452 
453  // translation
454  anchor_base_link_transform.transform.translation.x = mrpt_pose.x();
455  anchor_base_link_transform.transform.translation.y = mrpt_pose.y();
456  anchor_base_link_transform.transform.translation.z = 0;
457 
458  // rotation
459  anchor_base_link_transform.transform.rotation =
460  createQuaternionMsgFromYaw(mrpt_pose.phi());
461 
462  // TODO - potential error in the rotation, investigate this
463  m_broadcaster.sendTransform(anchor_base_link_transform);
464 
465  // anchor frame <=> odom frame
466  //
467  // make sure that we have received odometry information in the first
468  // place...
469  // the corresponding field would be initialized
470  if (!m_anchor_odom_transform.child_frame_id.empty())
471  {
473  }
474 
475  // set an arrow indicating the current orientation of the robot
476  {
477  geometry_msgs::PoseStamped geom_pose;
478  geom_pose.header.stamp = timestamp;
479  geom_pose.header.seq = m_pub_seq;
480  geom_pose.header.frame_id =
481  m_anchor_frame_id; // with regards to base_link...
482 
483  // position
484  geom_pose.pose = mrpt::ros1bridge::toROS_Pose(mrpt_pose);
485  m_curr_robot_pos_pub.publish(geom_pose);
486  }
487 
488  // robot trajectory
489  // publish the trajectory of the robot
490  {
491  this->m_logger->logFmt(
492  LVL_DEBUG, "Publishing the current robot trajectory");
493  typename GRAPH_T::global_poses_t graph_poses;
494  graph_poses = this->m_engine->getRobotEstimatedTrajectory();
495 
496  nav_msgs::Path path;
497 
498  // set the header
499  path.header.stamp = timestamp;
500  path.header.seq = m_pub_seq;
501  path.header.frame_id = m_anchor_frame_id;
502 
503  //
504  // fill in the pose as well as the nav_msgs::Path at the same time.
505  //
506 
507  geometry_msgs::PoseArray geom_poses;
508  geom_poses.header.stamp = timestamp;
509  geom_poses.header.frame_id = m_anchor_frame_id;
510 
511  for (auto n_cit = graph_poses.begin(); n_cit != graph_poses.end();
512  ++n_cit)
513  {
514  geometry_msgs::PoseStamped geom_pose_stamped;
515  geometry_msgs::Pose geom_pose;
516 
517  // grab the pose - convert to geometry_msgs::Pose format
518  const pose_t& mrpt_pose = n_cit->second;
519  geom_pose = mrpt::ros1bridge::toROS_Pose(mrpt_pose);
520  geom_poses.poses.push_back(geom_pose);
521  geom_pose_stamped.pose = geom_pose;
522 
523  // edit the header
524  geom_pose_stamped.header.stamp = timestamp;
525  geom_pose_stamped.header.seq = m_pub_seq;
526  geom_pose_stamped.header.frame_id = m_anchor_frame_id;
527 
528  path.poses.push_back(geom_pose_stamped);
529  }
530 
531  // publish only on new node addition
532  if (this->m_engine->getGraph().nodeCount() > m_graph_nodes_last_size)
533  {
534  m_robot_tr_poses_pub.publish(geom_poses);
536  }
537  }
538 
539  // Odometry trajectory - nav_msgs::Path
541 
542  // generated gridmap
543  // publish only on new node addition
544  if (this->m_engine->getGraph().nodeCount() > m_graph_nodes_last_size)
545  {
546  std_msgs::Header h;
547  mrpt::system::TTimeStamp mrpt_time;
548  auto mrpt_gridmap = mrpt::maps::COccupancyGridMap2D::Create();
549  this->m_engine->getMap(mrpt_gridmap, &mrpt_time);
550 
551  // timestamp
552  h.stamp = mrpt::ros1bridge::toROS(mrpt_time);
553  h.seq = m_pub_seq;
554  h.frame_id = m_anchor_frame_id;
555 
556  // nav gridmap
557  nav_msgs::OccupancyGrid nav_gridmap;
558  mrpt::ros1bridge::toROS(*mrpt_gridmap, nav_gridmap, h);
559  m_gridmap_pub.publish(nav_gridmap);
560  }
561 
562  // GraphSlamStats publishing
563  {
564  mrpt_msgs::GraphSlamStats stats;
565  stats.header.seq = m_stats_pub_seq++;
566 
567  map<string, int> node_stats;
568  map<string, int> edge_stats;
569  vector<double> def_energy_vec;
570  mrpt::system::TTimeStamp mrpt_time;
571 
572  this->m_engine->getGraphSlamStats(&node_stats, &edge_stats, &mrpt_time);
573 
574  // node/edge count
575  stats.nodes_total = node_stats["nodes_total"];
576  stats.edges_total = edge_stats["edges_total"];
577  if (edge_stats.find("ICP2D") != edge_stats.end())
578  {
579  stats.edges_icp_2d = edge_stats["ICP2D"];
580  }
581  if (edge_stats.find("ICP3D") != edge_stats.end())
582  {
583  stats.edges_icp_3d = edge_stats["ICP3D"];
584  }
585  if (edge_stats.find("Odometry") != edge_stats.end())
586  {
587  stats.edges_odom = edge_stats["Odometry"];
588  }
589  stats.loop_closures = edge_stats["loop_closures"];
590 
591  // SLAM evaluation metric
592  this->m_engine->getDeformationEnergyVector(
593  &stats.slam_evaluation_metric);
594 
595  stats.header.stamp = mrpt::ros1bridge::toROS(mrpt_time);
596 
597  m_stats_pub.publish(stats);
598  }
599 
600  // update the last known size
601  m_graph_nodes_last_size = this->m_engine->getGraph().nodeCount();
602  m_pub_seq++;
603 
604  if (this->m_enable_visuals)
605  {
606  ret_val = this->queryObserverForEvents();
607  }
608 
609  return ret_val;
610  MRPT_END;
611 } // end of usePublishersBroadcasters
612 
613 template <class GRAPH_T>
615  const sensor_msgs::LaserScan::ConstPtr& ros_laser_scan)
616 {
617  using namespace std;
618  using namespace mrpt::obs;
619 
620  this->m_logger->logFmt(
621  LVL_DEBUG,
622  "sniffLaserScan: Received a LaserScan msg. Converting it to MRPT "
623  "format...");
624 
625  // build the CObservation2DRangeScan
626  m_mrpt_laser_scan = CObservation2DRangeScan::Create();
627  mrpt::poses::CPose3D rel_pose; // pose is 0.
628  mrpt::ros1bridge::fromROS(*ros_laser_scan, rel_pose, *m_mrpt_laser_scan);
629 
630  m_received_laser_scan = true;
631  CObservation::Ptr tmp =
632  mrpt::ptr_cast<CObservation>::from(m_mrpt_laser_scan);
633  this->processObservation(tmp);
634 } // end of sniffLaserScan
635 
636 template <class GRAPH_T>
638  const nav_msgs::Odometry::ConstPtr& ros_odom)
639 {
640  using namespace std;
641  using namespace mrpt::obs;
642  using namespace mrpt::poses;
643 
644  this->m_logger->logFmt(
645  LVL_DEBUG,
646  "sniffOdom: Received an odometry msg. Converting it to MRPT format...");
647 
648  // update the odometry frame with regards to the anchor
649  {
650  // header
651  m_anchor_odom_transform.header.frame_id = m_anchor_frame_id;
652  m_anchor_odom_transform.header.stamp = ros_odom->header.stamp;
653  m_anchor_odom_transform.header.seq = ros_odom->header.seq;
654 
655  m_anchor_odom_transform.child_frame_id = m_odom_frame_id;
656 
657  //
658  // copy ros_odom ==> m_anchor_odom
659  //
660 
661  // translation
662  m_anchor_odom_transform.transform.translation.x =
663  ros_odom->pose.pose.position.x;
664  m_anchor_odom_transform.transform.translation.y =
665  ros_odom->pose.pose.position.y;
666  m_anchor_odom_transform.transform.translation.z =
667  ros_odom->pose.pose.position.z;
668 
669  // quaternion
670  m_anchor_odom_transform.transform.rotation =
671  ros_odom->pose.pose.orientation;
672  }
673 
674  // build and fill an MRPT CObservationOdometry instance for manipulation
675  // from the main algorithm
676  m_mrpt_odom->timestamp = mrpt::ros1bridge::fromROS(ros_odom->header.stamp);
677  m_mrpt_odom->odometry =
678  mrpt::poses::CPose2D(mrpt::ros1bridge::fromROS(ros_odom->pose.pose));
679 
680  // if this is the first call odometry should be 0. Decrement by the
681  // corresponding offset
683  {
686  }
687  // decrement by the (constant) offset
688  m_mrpt_odom->odometry = m_mrpt_odom->odometry - m_input_odometry_offset;
689 
690  // add to the overall odometry path
691  {
692  geometry_msgs::PoseStamped pose_stamped;
693  pose_stamped.header = ros_odom->header;
694 
695  // just for convenience - convert the MRPT pose back to PoseStamped
696  pose_stamped.pose = mrpt::ros1bridge::toROS_Pose(m_mrpt_odom->odometry);
697  m_odom_path.poses.push_back(pose_stamped);
698  }
699 
700  // print the odometry - for debugging reasons...
701  stringstream ss;
702  ss << "Odometry - MRPT format:\t" << m_mrpt_odom->odometry << endl;
703  this->m_logger->logFmt(LVL_DEBUG, "%s", ss.str().c_str());
704 
705  m_received_odom = true;
706  CObservation::Ptr tmp =
707  mrpt::ptr_cast<mrpt::obs::CObservation>::from(m_mrpt_odom);
708  this->processObservation(tmp);
709 } // end of sniffOdom
710 
711 template <class GRAPH_T>
713 {
714  THROW_EXCEPTION("Method is not implemented yet.");
715 }
716 template <class GRAPH_T>
718 {
719  THROW_EXCEPTION("Method is not implemented yet.");
720 }
721 template <class GRAPH_T>
723  mrpt::obs::CObservation::Ptr& observ)
724 {
725  using namespace std;
726 
727  this->_process(observ);
728  this->resetReceivedFlags();
729 }
730 
731 template <class GRAPH_T>
733  mrpt::obs::CObservation::Ptr& observ)
734 {
735  // this->m_logger->logFmt(LVL_DEBUG, "Calling execGraphSlamStep...");
736 
737  // TODO - use the exit code of execGraphSlamStep to exit??
738  if (!this->m_engine->isPaused())
739  {
740  this->m_engine->execGraphSlamStep(observ, m_measurement_cnt);
742  }
743 }
744 
745 template <class GRAPH_T>
747 {
748  m_received_odom = false;
749  m_received_laser_scan = false;
750  m_received_camera = false;
751  m_received_point_cloud = false;
752 }
753 
754 } // namespace apps
755 } // namespace graphslam
756 } // namespace mrpt
void readROSParameters()
read configuration parameters from the ROS parameter server.
void readParams()
Read the problem configuration parameters.
void verifyUserInput()
Verify that the parameters read are valid and can be used with the CGraphSlamEngine_ROS instance...
void setRPY(const tf2Scalar &roll, const tf2Scalar &pitch, const tf2Scalar &yaw)
static auto createQuaternionMsgFromYaw(double yaw)
bool usePublishersBroadcasters()
Provide feedback about the SLAM operation using ROS publilshers, update the registered frames using t...
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void initEngine_ROS()
Initialize the CGraphslamEngine_* object.
bool m_first_time_in_sniff_odom
Initial offset of the received odometry.
size_t m_measurement_cnt
Total counter of the processed measurements.
mrpt::obs::CObservation2DRangeScan::Ptr m_mrpt_laser_scan
GRAPH_T::constraint_t::type_value pose_t
type of underlying poses (2D/3D).
VerbosityLevel m_min_logging_level
Minimum logging level for the current class instance.
bool param(const std::string &param_name, T &param_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
bool getParam(const std::string &key, std::string &s) const
geometry_msgs::TransformStamped m_anchor_odom_transform
ros::NodeHandle * m_nh
Pointer to the Ros NodeHanle instance.
void sniffOdom(const nav_msgs::Odometry::ConstPtr &ros_odom)
Callback method for handling incoming odometry measurements in a ROS topic.
CGraphSlamHandler< GRAPH_T > parent_t
Handy parent type.
void _process(mrpt::obs::CObservation::Ptr &observ)
Low level wrapper for executing the CGraphSlamEngine_ROS::execGraphSlamStep method.
void sniffLaserScan(const sensor_msgs::LaserScan::ConstPtr &ros_laser_scan)
Callback method for handling incoming LaserScans objects in a ROS topic.
void setupComm()
Wrapper method around the protected setup* class methods.
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void getROSParameters(std::string *str_out)
Fill in the given string with the parameters that have been read from the ROS parameter server...
void sendTransform(const geometry_msgs::TransformStamped &transform)
B toMsg(const A &a)
nav_msgs::Path m_odom_path
Odometry path of the robot. Handy mostly for visualization reasons.
std::string m_anchor_frame_id
Frame that the robot starts from. In a single-robot SLAM setup this can be set to the world frame...
void printParams()
Print in a compact manner the overall problem configuration parameters.
int m_pub_seq
Times a messge has been published => usePublishersBroadcasters method is called.
void resetReceivedFlags()
Reset the flags indicating whether we have received new data (odometry, laser scans etc...
static Time now()
mrpt::obs::CObservationOdometry::Ptr m_mrpt_odom
Received laser scan - converted into MRPT CObservation* format.
void processObservation(mrpt::obs::CObservation::Ptr &observ)
Process an incoming measurement.
int m_queue_size
ROS topic publisher standard queue size.
mrpt::graphslam::CGraphSlamEngine derived class for executing multi-robot graphSLAM ...
CGraphSlamHandler_ROS(mrpt::system::COutputLogger *logger, TUserOptionsChecker< GRAPH_T > *options_checker, ros::NodeHandle *nh_in)


mrpt_graphslam_2d
Author(s): Nikos Koukis
autogenerated on Sun Jun 26 2022 02:12:26