mrpt_icp_slam_2d_wrapper.cpp
Go to the documentation of this file.
1 /*
2  * File: mrpt_icp_slam_2d_wrapper.cpp
3  * Author: Vladislav Tananaev
4  *
5  */
6 
8 #include <mrpt/version.h>
9 #if MRPT_VERSION >= 0x150
10 #include <mrpt_bridge/utils.h>
11 #endif
12 
13 #if MRPT_VERSION >= 0x199
14 #include <mrpt/serialization/CArchive.h>
15 #endif
16 
17 #include <mrpt/maps/COccupancyGridMap2D.h>
18 #include <mrpt/maps/CSimplePointsMap.h>
19 using mrpt::maps::COccupancyGridMap2D;
20 using mrpt::maps::CSimplePointsMap;
21 
23  rawlog_play_ = false;
24  stamp = ros::Time(0);
25  // Default parameters for 3D window
27  SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS = 0; // this parameter is not used
28  SHOW_LASER_SCANS_3D = true;
30  isObsBasedRawlog = true;
31 }
33  try {
34  std::string sOutMap = "mrpt_icpslam_";
35  mrpt::system::TTimeParts parts;
36  mrpt::system::timestampToParts(now(), parts, true);
37  sOutMap += format("%04u-%02u-%02u_%02uh%02um%02us",
38  (unsigned int)parts.year, (unsigned int)parts.month,
39  (unsigned int)parts.day, (unsigned int)parts.hour,
40  (unsigned int)parts.minute, (unsigned int)parts.second);
41  sOutMap += ".simplemap";
42 
43  sOutMap = mrpt::system::fileNameStripInvalidChars(sOutMap);
44  ROS_INFO("Saving built map to `%s`", sOutMap.c_str());
45  mapBuilder.saveCurrentMapToFile(sOutMap);
46  } catch (std::exception &e) {
47  ROS_ERROR("Exception: %s", e.what());
48  }
49 }
50 bool ICPslamWrapper::is_file_exists(const std::string &name) {
51  std::ifstream f(name.c_str());
52  return f.good();
53 }
54 
56  CConfigFile iniFile(ini_filename);
57 
58  mapBuilder.ICP_options.loadFromConfigFile(iniFile, "MappingApplication");
59  mapBuilder.ICP_params.loadFromConfigFile(iniFile, "ICP");
60  mapBuilder.initialize();
61 
62 #if MRPT_VERSION < 0x150
63  mapBuilder.options.verbose = true;
64 #else
65  log4cxx::LoggerPtr ros_logger =
66  log4cxx::Logger::getLogger(ROSCONSOLE_DEFAULT_NAME);
67  mapBuilder.setVerbosityLevel(
68  mrpt_bridge::rosLoggerLvlToMRPTLoggerLvl(ros_logger->getLevel()));
69  mapBuilder.logging_enable_console_output = false;
70 #if MRPT_VERSION < 0x199
71  mapBuilder.logRegisterCallback(static_cast<output_logger_callback_t>(
72  &mrpt_bridge::mrptToROSLoggerCallback_mrpt_15));
73 #else
74  mapBuilder.logRegisterCallback(static_cast<output_logger_callback_t>(
75  &mrpt_bridge::mrptToROSLoggerCallback));
76 #endif
77 #endif
78  mapBuilder.options.alwaysInsertByClass.fromString(
79  iniFile.read_string("MappingApplication", "alwaysInsertByClass", ""));
80 
81  mapBuilder.ICP_params.dumpToConsole();
82  mapBuilder.ICP_options.dumpToConsole();
83 
84  // parameters for mrpt3D window
86  iniFile.read_bool("MappingApplication", "CAMERA_3DSCENE_FOLLOWS_ROBOT",
87  true, /*Force existence:*/ true);
88  MRPT_LOAD_CONFIG_VAR(SHOW_PROGRESS_3D_REAL_TIME, bool, iniFile,
89  "MappingApplication");
90  MRPT_LOAD_CONFIG_VAR(SHOW_LASER_SCANS_3D, bool, iniFile,
91  "MappingApplication");
92  MRPT_LOAD_CONFIG_VAR(SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS, int, iniFile,
93  "MappingApplication");
94 }
95 
97  ROS_INFO("READ PARAM FROM LAUNCH FILE");
98  n_.param<double>("rawlog_play_delay", rawlog_play_delay, 0.1);
99  ROS_INFO("rawlog_play_delay: %f", rawlog_play_delay);
100 
101  n_.getParam("rawlog_filename", rawlog_filename);
102  ROS_INFO("rawlog_filename: %s", rawlog_filename.c_str());
103 
104  n_.getParam("ini_filename", ini_filename);
105  ROS_INFO("ini_filename: %s", ini_filename.c_str());
106 
107  n_.param<std::string>("global_frame_id", global_frame_id, "map");
108  ROS_INFO("global_frame_id: %s", global_frame_id.c_str());
109 
110  n_.param<std::string>("odom_frame_id", odom_frame_id, "odom");
111  ROS_INFO("odom_frame_id: %s", odom_frame_id.c_str());
112 
113  n_.param<std::string>("base_frame_id", base_frame_id, "base_link");
114  ROS_INFO("base_frame_id: %s", base_frame_id.c_str());
115 
116  n_.param<std::string>("sensor_source", sensor_source, "scan");
117  ROS_INFO("sensor_source: %s", sensor_source.c_str());
118 
119  n_.param("trajectory_update_rate", trajectory_update_rate, 10.0);
120  ROS_INFO("trajectory_update_rate: %f", trajectory_update_rate);
121 
122  n_.param("trajectory_publish_rate", trajectory_publish_rate, 5.0);
123  ROS_INFO("trajectory_publish_rate: %f", trajectory_publish_rate);
124 }
126 #if MRPT_HAS_WXWIDGETS
128  win3D_ = mrpt::gui::CDisplayWindow3D::Create(
129  "pf-localization - The MRPT project", 1000, 600);
130  win3D_->setCameraZoom(20);
131  win3D_->setCameraAzimuthDeg(-45);
132  }
133 
134 #endif
135 }
136 
138  // Create 3D window if requested (the code is copied from
139  // ../mrpt/apps/icp-slam/icp-slam_main.cpp):
141  // get currently builded map
142  metric_map_ = mapBuilder.getCurrentlyBuiltMetricMap();
143 
144  lst_current_laser_scans.clear();
145 
146  CPose3D robotPose;
147  mapBuilder.getCurrentPoseEstimation()->getMean(robotPose);
148  COpenGLScene::Ptr scene = COpenGLScene::Create();
149 
150  COpenGLViewport::Ptr view = scene->getViewport("main");
151 
152  COpenGLViewport::Ptr view_map = scene->createViewport("mini-map");
153  view_map->setBorderSize(2);
154  view_map->setViewportPosition(0.01, 0.01, 0.35, 0.35);
155  view_map->setTransparent(false);
156 
157  {
158  mrpt::opengl::CCamera &cam = view_map->getCamera();
159  cam.setAzimuthDegrees(-90);
160  cam.setElevationDegrees(90);
161  cam.setPointingAt(robotPose);
162  cam.setZoomDistance(20);
163  cam.setOrthogonal();
164  }
165 
166  // The ground:
167  mrpt::opengl::CGridPlaneXY::Ptr groundPlane =
168  mrpt::opengl::CGridPlaneXY::Create(-200, 200, -200, 200, 0, 5);
169  groundPlane->setColor(0.4, 0.4, 0.4);
170  view->insert(groundPlane);
171  view_map->insert(CRenderizable::Ptr(groundPlane)); // A copy
172 
173  // The camera pointing to the current robot pose:
175  scene->enableFollowCamera(true);
176 
177  mrpt::opengl::CCamera &cam = view_map->getCamera();
178  cam.setAzimuthDegrees(-45);
179  cam.setElevationDegrees(45);
180  cam.setPointingAt(robotPose);
181  }
182 
183  // The maps:
184  {
185  opengl::CSetOfObjects::Ptr obj = opengl::CSetOfObjects::Create();
186  metric_map_->getAs3DObject(obj);
187  view->insert(obj);
188 
189  // now, only the point map in another OpenGL view:
190 
191  // publish map
192  CSimplePointsMap *pm = nullptr;
193 #if MRPT_VERSION >= 0x199
194  if (metric_map_->countMapsByClass<CSimplePointsMap>())
195  pm = metric_map_->mapByClass<CSimplePointsMap>().get();
196 #else
197  if (metric_map_->m_pointsMaps.size())
198  pm = metric_map_->m_pointsMaps[0].get();
199 #endif
200 
201  opengl::CSetOfObjects::Ptr ptsMap = opengl::CSetOfObjects::Create();
202  if (pm) {
203  pm->getAs3DObject(ptsMap);
204  view_map->insert(ptsMap);
205  }
206  }
207 
208  // Draw the robot path:
209  CPose3DPDF::Ptr posePDF = mapBuilder.getCurrentPoseEstimation();
210  CPose3D curRobotPose;
211  posePDF->getMean(curRobotPose);
212  {
213  opengl::CSetOfObjects::Ptr obj = opengl::stock_objects::RobotPioneer();
214  obj->setPose(curRobotPose);
215  view->insert(obj);
216  }
217  {
218  opengl::CSetOfObjects::Ptr obj = opengl::stock_objects::RobotPioneer();
219  obj->setPose(curRobotPose);
220  view_map->insert(obj);
221  }
222 
223  opengl::COpenGLScene::Ptr &ptrScene = win3D_->get3DSceneAndLock();
224  ptrScene = scene;
225 
226  win3D_->unlockAccess3DScene();
227 
228  // Move camera:
229  win3D_->setCameraPointingToPoint(curRobotPose.x(), curRobotPose.y(),
230  curRobotPose.z());
231 
232  // Update:
233  win3D_->forceRepaint();
234 
235  // Build list of scans:
236  if (SHOW_LASER_SCANS_3D) {
237  // Rawlog in "Observation-only" format:
238  if (isObsBasedRawlog) {
239  if (IS_CLASS(observation, CObservation2DRangeScan)) {
240  lst_current_laser_scans.push_back(
241  mrpt::ptr_cast<CObservation2DRangeScan>::from(observation));
242  }
243  } else {
244  // Rawlog in the Actions-SF format:
245  for (size_t i = 0;; i++) {
246  CObservation2DRangeScan::Ptr new_obs =
247  observations->getObservationByClass<CObservation2DRangeScan>(i);
248  if (!new_obs)
249  break; // There're no more scans
250  else
251  lst_current_laser_scans.push_back(new_obs);
252  }
253  }
254  }
255 
256  // Draw laser scanners in 3D:
257  if (SHOW_LASER_SCANS_3D) {
258  for (size_t i = 0; i < lst_current_laser_scans.size(); i++) {
259  // Create opengl object and load scan data from the scan observation:
260  opengl::CPlanarLaserScan::Ptr obj = opengl::CPlanarLaserScan::Create();
261  obj->setScan(*lst_current_laser_scans[i]);
262  obj->setPose(curRobotPose);
263  obj->setSurfaceColor(1.0f, 0.0f, 0.0f, 0.5f);
264  // inser into the scene:
265  view->insert(obj);
266  }
267  }
268  }
269 }
271  // get parameters from ini file
273  ROS_ERROR_STREAM("CAN'T READ INI FILE");
274  return;
275  }
277  // read rawlog file if it exists
279  ROS_WARN_STREAM("PLAY FROM RAWLOG FILE: " << rawlog_filename.c_str());
280  rawlog_play_ = true;
281  }
282 
284  // publish grid map
285  pub_map_ = n_.advertise<nav_msgs::OccupancyGrid>("map", 1, true);
286  pub_metadata_ = n_.advertise<nav_msgs::MapMetaData>("map_metadata", 1, true);
287  // publish point map
289  n_.advertise<sensor_msgs::PointCloud>("PointCloudMap", 1, true);
290 
291  trajectory_pub_ = n_.advertise<nav_msgs::Path>("trajectory", 1, true);
292 
293  // robot pose
294  pub_pose_ = n_.advertise<geometry_msgs::PoseStamped>("robot_pose", 1);
295 
299 
303 
304  // read sensor topics
305  std::vector<std::string> lstSources;
306  mrpt::system::tokenize(sensor_source, " ,\t\n", lstSources);
307  ROS_ASSERT_MSG(!lstSources.empty(),
308  "*Fatal*: At least one sensor source must be provided in "
309  "~sensor_sources (e.g. "
310  "\"scan\" or \"beacon\")");
311 
313  sensorSub_.resize(lstSources.size());
314  for (size_t i = 0; i < lstSources.size(); i++) {
315  if (lstSources[i].find("scan") != std::string::npos) {
316  sensorSub_[i] =
317  n_.subscribe(lstSources[i], 1, &ICPslamWrapper::laserCallback, this);
318  } else {
319  std::cout << "Sensor topics should be 2d laser scans which inlude in the "
320  "name the word scan "
321  << "\n";
322  }
323  }
324 
325  init3Dwindow();
326 }
327 
328 void ICPslamWrapper::laserCallback(const sensor_msgs::LaserScan &_msg) {
329 #if MRPT_VERSION >= 0x130
330  using namespace mrpt::maps;
331  using namespace mrpt::obs;
332 #else
333  using namespace mrpt::slam;
334 #endif
335  CObservation2DRangeScan::Ptr laser = CObservation2DRangeScan::Create();
336  if (laser_poses_.find(_msg.header.frame_id) == laser_poses_.end()) {
337  updateSensorPose(_msg.header.frame_id);
338  } else {
339  mrpt::poses::CPose3D pose = laser_poses_[_msg.header.frame_id];
340  mrpt_bridge::convert(_msg, laser_poses_[_msg.header.frame_id], *laser);
341  // CObservation::Ptr obs = CObservation::Ptr(laser);
342  observation = CObservation::Ptr(laser);
343  stamp = ros::Time(0);
344  tictac.Tic();
345  mapBuilder.processObservation(observation);
346  t_exec = tictac.Tac();
347  ROS_INFO("Map building executed in %.03fms", 1000.0f * t_exec);
348 
349  run3Dwindow();
350  publishTF();
351  publishMapPose();
352  }
353 }
355  // get currently builded map
356  metric_map_ = mapBuilder.getCurrentlyBuiltMetricMap();
357 
358  // publish map
359  COccupancyGridMap2D *grid = nullptr;
360  CSimplePointsMap *pm = nullptr;
361 #if MRPT_VERSION >= 0x199
362  if (metric_map_->countMapsByClass<COccupancyGridMap2D>())
363  grid = metric_map_->mapByClass<COccupancyGridMap2D>().get();
364  if (metric_map_->countMapsByClass<CSimplePointsMap>())
365  pm = metric_map_->mapByClass<CSimplePointsMap>().get();
366 #else
367  if (metric_map_->m_gridMaps.size())
368  grid = metric_map_->m_gridMaps[0].get();
369  if (metric_map_->m_pointsMaps.size())
370  pm = metric_map_->m_pointsMaps[0].get();
371 #endif
372 
373  if (grid) {
374  nav_msgs::OccupancyGrid _msg;
375  // if we have new map for current sensor update it
376  mrpt_bridge::convert(*grid, _msg);
377  pub_map_.publish(_msg);
378  pub_metadata_.publish(_msg.info);
379  }
380  if (pm) {
381  sensor_msgs::PointCloud _msg;
382  std_msgs::Header header;
383  header.stamp = ros::Time(0);
384  header.frame_id = global_frame_id;
385  // if we have new map for current sensor update it
386  mrpt_bridge::point_cloud::mrpt2ros(*pm, header, _msg);
388  }
389 
390  CPose3D robotPose;
391  mapBuilder.getCurrentPoseEstimation()->getMean(robotPose);
392 
393  // publish pose
394  // geometry_msgs::PoseStamped pose;
395  pose.header.frame_id = global_frame_id;
396 
397  // the pose
398  pose.pose.position.x = robotPose.x();
399  pose.pose.position.y = robotPose.y();
400  pose.pose.position.z = 0.0;
401  pose.pose.orientation = tf::createQuaternionMsgFromYaw(robotPose.yaw());
402 
404 }
405 void ICPslamWrapper::updateSensorPose(std::string _frame_id) {
406  CPose3D pose;
407  tf::StampedTransform transform;
408  try {
410  transform);
411 
412  tf::Vector3 translation = transform.getOrigin();
413  tf::Quaternion quat = transform.getRotation();
414  pose.x() = translation.x();
415  pose.y() = translation.y();
416  pose.z() = translation.z();
417  tf::Matrix3x3 Rsrc(quat);
418  CMatrixDouble33 Rdes;
419  for (int c = 0; c < 3; c++)
420  for (int r = 0; r < 3; r++)
421  Rdes(r, c) = Rsrc.getRow(r)[c];
422  pose.setRotationMatrix(Rdes);
423  laser_poses_[_frame_id] = pose;
424  } catch (tf::TransformException ex) {
425  ROS_ERROR("%s", ex.what());
426  ros::Duration(1.0).sleep();
427  }
428 }
430  if (rawlog_play_ == false) {
431  return false;
432  } else {
433  size_t rawlogEntry = 0;
434 #if MRPT_VERSION >= 0x199
435  CFileGZInputStream rawlog_stream(rawlog_filename);
436  auto rawlogFile = mrpt::serialization::archiveFrom(rawlog_stream);
437 #else
438  CFileGZInputStream rawlogFile(rawlog_filename);
439 #endif
440  CActionCollection::Ptr action;
441 
442  for (;;) {
443  if (ros::ok()) {
444  if (!CRawlog::getActionObservationPairOrObservation(
445  rawlogFile, action, observations, observation, rawlogEntry)) {
446  break; // file EOF
447  }
449  // Execute:
450  // ----------------------------------------
451  tictac.Tic();
452  if (isObsBasedRawlog)
453  mapBuilder.processObservation(observation);
454  else
455  mapBuilder.processActionObservation(*action, *observations);
456  t_exec = tictac.Tac();
457  ROS_INFO("Map building executed in %.03fms", 1000.0f * t_exec);
458 
460 
461  metric_map_ = mapBuilder.getCurrentlyBuiltMetricMap();
462 
463  CPose3D robotPose;
464  mapBuilder.getCurrentPoseEstimation()->getMean(robotPose);
465 
466  // publish map
467  COccupancyGridMap2D *grid = nullptr;
468  CSimplePointsMap *pm = nullptr;
469 #if MRPT_VERSION >= 0x199
470  if (metric_map_->countMapsByClass<COccupancyGridMap2D>())
471  grid = metric_map_->mapByClass<COccupancyGridMap2D>().get();
472  if (metric_map_->countMapsByClass<CSimplePointsMap>())
473  pm = metric_map_->mapByClass<CSimplePointsMap>().get();
474 #else
475  if (metric_map_->m_gridMaps.size())
476  grid = metric_map_->m_gridMaps[0].get();
477  if (metric_map_->m_pointsMaps.size())
478  pm = metric_map_->m_pointsMaps[0].get();
479 #endif
480 
481  if (grid) {
482  nav_msgs::OccupancyGrid _msg;
483 
484  // if we have new map for current sensor update it
485  mrpt_bridge::convert(*grid, _msg);
486  pub_map_.publish(_msg);
487  pub_metadata_.publish(_msg.info);
488  }
489 
490  if (pm) {
491  sensor_msgs::PointCloud _msg;
492  std_msgs::Header header;
493  header.stamp = ros::Time(0);
494  header.frame_id = global_frame_id;
495  // if we have new map for current sensor update it
496  mrpt_bridge::point_cloud::mrpt2ros(*pm, header, _msg);
498  // pub_metadata_.publish(_msg.info)
499  }
500 
501  // publish pose
502  // geometry_msgs::PoseStamped pose;
503  pose.header.frame_id = global_frame_id;
504 
505  // the pose
506  pose.pose.position.x = robotPose.x();
507  pose.pose.position.y = robotPose.y();
508  pose.pose.position.z = 0.0;
509  pose.pose.orientation = tf::createQuaternionMsgFromYaw(robotPose.yaw());
510 
512  }
513 
514  run3Dwindow();
515  ros::spinOnce();
516  }
517 
518  // if there is mrpt_gui it will wait until push any key in order to close
519  // the window
520  if (win3D_)
521  win3D_->waitForKey();
522 
523  return true;
524  }
525 }
526 
528  // Most of this code was copy and pase from ros::amcl
529  mrpt::poses::CPose3D robotPoseTF;
530  mapBuilder.getCurrentPoseEstimation()->getMean(robotPoseTF);
531 
532  stamp = ros::Time(0);
533  tf::Stamped<tf::Pose> odom_to_map;
534  tf::Transform tmp_tf;
535  mrpt_bridge::convert(robotPoseTF, tmp_tf);
536 
537  try {
538  tf::Stamped<tf::Pose> tmp_tf_stamped(tmp_tf.inverse(), stamp,
539  base_frame_id);
540  listenerTF_.transformPose(odom_frame_id, tmp_tf_stamped, odom_to_map);
541  } catch (tf::TransformException) {
542  ROS_INFO("Failed to subtract global_frame (%s) from odom_frame (%s)",
543  global_frame_id.c_str(), odom_frame_id.c_str());
544  return;
545  }
546 
547  tf::Transform latest_tf_ =
548  tf::Transform(tf::Quaternion(odom_to_map.getRotation()),
549  tf::Point(odom_to_map.getOrigin()));
550 
551  tf::StampedTransform tmp_tf_stamped(latest_tf_.inverse(), stamp,
553 
554  tf_broadcaster_.sendTransform(tmp_tf_stamped);
555 }
556 
558  const ros::TimerEvent &event) {
559  ROS_DEBUG("update trajectory");
560  path.header.frame_id = global_frame_id;
561  path.header.stamp = ros::Time(0);
562  path.poses.push_back(pose);
563 }
564 
566  const ros::TimerEvent &event) {
567  ROS_DEBUG("publish trajectory");
569 }
void publishTrajectoryTimerCallback(const ros::TimerEvent &event)
the callback for publish trajectory
mrpt::gui::CDisplayWindow3D::Ptr win3D_
MRPT window.
double now()
void updateTrajectoryTimerCallback(const ros::TimerEvent &event)
the callback for update trajectory
void publish(const boost::shared_ptr< M > &message) const
const CMultiMetricMap * metric_map_
receive map after iteration of SLAM to metric map
void get_param()
read the parameters from launch file
f
nav_msgs::Path path
trajectory path
std::string odom_frame_id
/odom frame
CSensoryFrame::Ptr observations
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
bool sleep() const
void init()
initialize publishers subscribers and icp slam
bool is_file_exists(const std::string &name)
check the existance of the file
void laserCallback(const sensor_msgs::LaserScan &_msg)
callback function for the laser scans
bool rawlog_play_
true if rawlog file exists
float t_exec
the time which take one SLAM update execution
geometry_msgs::PoseStamped pose
the robot pose
void publishMapPose()
publish point and/or grid map and robot pose
double rawlog_play_delay
delay of replay from rawlog file
std::vector< ros::Subscriber > sensorSub_
list of sensors topics
void updateSensorPose(std::string _frame_id)
update the pose of the sensor with respect to the robot
ros::Publisher pub_point_cloud_
publishers for map and pose particles
TFSIMD_FORCE_INLINE const Vector3 & getRow(int i) const
tf::TransformBroadcaster tf_broadcaster_
transform broadcaster
TFSIMD_FORCE_INLINE const tfScalar & x() const
tf::TransformListener listenerTF_
transform listener
CMetricMapBuilderICP mapBuilder
icp slam class
TFSIMD_FORCE_INLINE const tfScalar & z() const
#define ROS_INFO(...)
CTicTac tictac
timer for SLAM performance evaluation
bool param(const std::string &param_name, T &param_val, const T &default_val) const
#define ROS_ASSERT_MSG(cond,...)
ROSCPP_DECL bool ok()
TFSIMD_FORCE_INLINE const tfScalar & y() const
void sendTransform(const StampedTransform &transform)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
std::string ini_filename
name of ini file
Transform inverse() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
ros::NodeHandle n_
Node Handle.
#define ROS_WARN_STREAM(args)
bool rawlogPlay()
play rawlog file
CObservation::Ptr observation
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
void lookupTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
std::string global_frame_id
/map frame
action
ros::Time stamp
timestamp for observations
ros::Timer publish_trajectory_timer
timer for publish trajectory
void run3Dwindow()
run 3D window update from mrpt lib
static geometry_msgs::Quaternion createQuaternionMsgFromYaw(double yaw)
void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const
Quaternion getRotation() const
bool getParam(const std::string &key, std::string &s) const
ros::Publisher trajectory_pub_
trajectory publisher
const std::string header
void read_iniFile(std::string ini_filename)
read ini file
double trajectory_update_rate
trajectory update rate(Hz)
#define ROS_ERROR_STREAM(args)
std::string rawlog_filename
name of rawlog file
std::string base_frame_id
robot frame
void init3Dwindow()
init 3D window from mrpt lib
ROSCPP_DECL void spinOnce()
r
std::map< std::string, mrpt::poses::CPose3D > laser_poses_
laser scan poses with respect to the map
double trajectory_publish_rate
trajectory publish rate(Hz)
#define ROS_ERROR(...)
#define ROSCONSOLE_DEFAULT_NAME
ros::Timer update_trajector_timer
timer for update trajectory
void publishTF()
publis tf tree
std::string sensor_source
2D laser scans
std::vector< CObservation2DRangeScan::Ptr > lst_current_laser_scans
ros::Publisher pub_metadata_
#define ROS_DEBUG(...)


mrpt_icp_slam_2d
Author(s): Jose Luis Blanco Claraco, Vladislav Tananaev
autogenerated on Thu Jun 6 2019 19:37:54