GuiWrapper.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "rtabmap_ros/GuiWrapper.h"
29 #include <QApplication>
30 #include <QDir>
31 
32 #include <std_srvs/Empty.h>
33 #include <std_msgs/Empty.h>
34 #include <std_msgs/Int32MultiArray.h>
35 
39 
40 #include <opencv2/highgui/highgui.hpp>
41 
42 #include <rtabmap/gui/MainWindow.h>
47 #include <rtabmap/core/util2d.h>
48 #include <rtabmap/core/util3d.h>
50 #include <rtabmap/utilite/UTimer.h>
51 
53 #include "rtabmap_ros/GetMap.h"
54 #include "rtabmap_ros/SetGoal.h"
55 #include "rtabmap_ros/SetLabel.h"
56 #include "rtabmap_ros/RemoveLabel.h"
58 
59 float max3( const float& a, const float& b, const float& c)
60 {
61  float m=a>b?a:b;
62  return m>c?m:c;
63 }
64 
65 namespace rtabmap_ros {
66 
67 GuiWrapper::GuiWrapper(int & argc, char** argv) :
69  mainWindow_(0),
70  frameId_("base_link"),
71  odomFrameId_(""),
72  waitForTransform_(true),
73  waitForTransformDuration_(0.2), // 200 ms
74  odomSensorSync_(false),
75  maxOdomUpdateRate_(10),
76  cameraNodeName_(""),
77  lastOdomInfoUpdateTime_(0),
78  rtabmapNodeName_("rtabmap")
79 {
80  ros::NodeHandle nh;
81  ros::NodeHandle pnh("~");
82 
83  QString configFile = QDir::homePath()+"/.ros/rtabmapGUI.ini";
84  for(int i=1; i<argc; ++i)
85  {
86  if(strcmp(argv[i], "-d") == 0)
87  {
88  ++i;
89  if(i < argc)
90  {
91  configFile = argv[i];
92  }
93  break;
94  }
95  }
96 
97  configFile.replace('~', QDir::homePath());
98 
99  pnh.param("rtabmap", rtabmapNodeName_, rtabmapNodeName_);
100 
101  ROS_INFO("rtabmapviz: Using configuration from \"%s\"", configFile.toStdString().c_str());
102  uSleep(500);
105  mainWindow_->setWindowTitle(mainWindow_->windowTitle()+" [ROS]");
106  mainWindow_->show();
107 
108  bool paused = false;
110  rnh.param("is_rtabmap_paused", paused, paused);
112 
113  // To receive odometry events
114  std::string initCachePath;
115  pnh.param("frame_id", frameId_, frameId_);
116  pnh.param("odom_frame_id", odomFrameId_, odomFrameId_); // set to use odom from TF
117  pnh.param("wait_for_transform", waitForTransform_, waitForTransform_);
118  pnh.param("wait_for_transform_duration", waitForTransformDuration_, waitForTransformDuration_);
119  pnh.param("odom_sensor_sync", odomSensorSync_, odomSensorSync_);
120  pnh.param("max_odom_update_rate", maxOdomUpdateRate_, maxOdomUpdateRate_);
121  pnh.param("camera_node_name", cameraNodeName_, cameraNodeName_); // used to pause the rtabmap_ros/camera when pausing the process
122  pnh.param("init_cache_path", initCachePath, initCachePath);
123  if(initCachePath.size())
124  {
125  initCachePath = uReplaceChar(initCachePath, '~', UDirectory::homeDir());
126  if(initCachePath.at(0) != '/')
127  {
128  initCachePath = UDirectory::currentDir(true) + initCachePath;
129  }
130  ROS_INFO("rtabmapviz: Initializing cache with local database \"%s\"", initCachePath.c_str());
131  uSleep(2000); // make sure rtabmap node is created if launched at the same time
132  rtabmap_ros::GetMap getMapSrv;
133  getMapSrv.request.global = false;
134  getMapSrv.request.optimized = true;
135  getMapSrv.request.graphOnly = true;
136  if(!ros::service::call("get_map", getMapSrv))
137  {
138  ROS_WARN("Can't call \"get_map\" service. The cache will still be loaded "
139  "but the clouds won't be created until next time rtabmapviz "
140  "receives the optimized graph.");
141  }
142  else
143  {
144  // this will update the poses and constraints of the MainWindow
145  processRequestedMap(getMapSrv.response.data);
146  }
147  QMetaObject::invokeMethod(mainWindow_, "updateCacheFromDatabase", Q_ARG(QString, QString(initCachePath.c_str())));
148  }
149 
150  if(pnh.hasParam("tf_prefix"))
151  {
152  ROS_ERROR("tf_prefix parameter has been removed, use directly odom_frame_id and frame_id parameters.");
153  }
154 
157 
158  republishNodeDataPub_ = nh.advertise<std_msgs::Int32MultiArray>("republish_node_data", 1);
159 
160  infoTopic_.subscribe(nh, "info", 1);
161  mapDataTopic_.subscribe(nh, "mapData", 1);
164  infoTopic_,
165  mapDataTopic_);
166  infoMapSync_->registerCallback(boost::bind(&GuiWrapper::infoMapCallback, this, boost::placeholders::_1, boost::placeholders::_2));
167 
168  goalTopic_.subscribe(nh, "goal_node", 1);
169  pathTopic_.subscribe(nh, "global_path", 1);
172  goalTopic_,
173  pathTopic_);
174  goalPathSync_->registerCallback(boost::bind(&GuiWrapper::goalPathCallback, this, boost::placeholders::_1, boost::placeholders::_2));
175  goalReachedTopic_ = nh.subscribe("goal_reached", 1, &GuiWrapper::goalReachedCallback, this);
176 
177  setupCallbacks(nh, pnh, ros::this_node::getName()); // do it at the end
178 }
179 
181 {
182  UDEBUG("");
183 
184  delete infoMapSync_;
185  delete mainWindow_;
186 }
187 
189  const rtabmap_ros::InfoConstPtr & infoMsg,
190  const rtabmap_ros::MapDataConstPtr & mapMsg)
191 {
192  //ROS_INFO("rtabmapviz: RTAB-Map info ex received!");
193 
194  // Map from ROS struct to rtabmap struct
195  rtabmap::Statistics stat;
196 
197  // Info
198  rtabmap_ros::infoFromROS(*infoMsg, stat);
199 
200  // MapData
201  rtabmap::Transform mapToOdom;
202  std::map<int, rtabmap::Transform> poses;
203  std::map<int, Signature> signatures;
204  std::multimap<int, rtabmap::Link> links;
205 
206  rtabmap_ros::mapDataFromROS(*mapMsg, poses, links, signatures, mapToOdom);
207 
208  stat.setMapCorrection(mapToOdom);
209  stat.setPoses(poses);
210  stat.setSignaturesData(signatures);
211  stat.setConstraints(links);
212 
213  this->post(new RtabmapEvent(stat));
214 }
215 
217  const rtabmap_ros::GoalConstPtr & goalMsg,
218  const nav_msgs::PathConstPtr & pathMsg)
219 {
220  // we don't have the node ids, just generate fake ones.
221  std::vector<std::pair<int, Transform> > poses(pathMsg->poses.size());
222  for(unsigned int i=0; i<pathMsg->poses.size(); ++i)
223  {
224  poses[i].first = -int(i)-1;
225  poses[i].second = rtabmap_ros::transformFromPoseMsg(pathMsg->poses[i].pose);
226  }
227  this->post(new RtabmapGlobalPathEvent(goalMsg->node_id, goalMsg->node_label, poses, 0.0));
228 }
229 
231  const std_msgs::BoolConstPtr & value)
232 {
233  this->post(new RtabmapGoalStatusEvent(value->data?1:-1));
234 }
235 
236 void GuiWrapper::processRequestedMap(const rtabmap_ros::MapData & map)
237 {
238  // Make sure parameters are loaded
239  if(((PreferencesDialogROS*)prefDialog_)->hasAllParameters())
240  {
241  QMetaObject::invokeMethod(((PreferencesDialogROS*)prefDialog_), "readRtabmapNodeParameters");
242  }
243 
244  std::map<int, Signature> signatures;
245  std::map<int, Transform> poses;
246  std::multimap<int, rtabmap::Link> constraints;
247  Transform mapToOdom;
248 
249  rtabmap_ros::mapDataFromROS(map, poses, constraints, signatures, mapToOdom);
250 
251  RtabmapEvent3DMap e(signatures,
252  poses,
253  constraints);
254  QMetaObject::invokeMethod(mainWindow_, "processRtabmapEvent3DMap", Q_ARG(rtabmap::RtabmapEvent3DMap, e));
255 }
256 
258 {
259  if(anEvent->getClassName().compare("ParamEvent") == 0)
260  {
262  rtabmap::ParametersMap parameters = ((rtabmap::ParamEvent *)anEvent)->getParameters();
263  bool modified = false;
265  for(rtabmap::ParametersMap::iterator i=parameters.begin(); i!=parameters.end(); ++i)
266  {
267  //save only parameters with valid names
268  if(defaultParameters.find((*i).first) != defaultParameters.end())
269  {
270  rnh.setParam((*i).first, (*i).second);
271  modified = true;
272  }
273  else if((*i).first.find('/') != (*i).first.npos)
274  {
275  ROS_WARN("Parameter %s is not used by the rtabmap node.", (*i).first.c_str());
276  }
277  }
278  if(modified)
279  {
280  ROS_INFO("Parameters updated");
281  std_srvs::Empty srv;
282  if(!ros::service::call("update_parameters", srv))
283  {
284  ROS_ERROR("Can't call \"update_parameters\" service");
285  }
286  }
287  }
288  else if(anEvent->getClassName().compare("RtabmapEventCmd") == 0)
289  {
290  std_srvs::Empty emptySrv;
291  rtabmap::RtabmapEventCmd * cmdEvent = (rtabmap::RtabmapEventCmd *)anEvent;
294  {
295  if(!ros::service::call("reset", emptySrv))
296  {
297  ROS_ERROR("Can't call \"reset\" service");
298  }
299  }
301  {
302  // Pause the camera if the rtabmap/camera node is used
303  if(!cameraNodeName_.empty())
304  {
305  std::string str = uFormat("rosrun dynamic_reconfigure dynparam set %s pause true", cameraNodeName_.c_str());
306  if(system(str.c_str()) !=0)
307  {
308  ROS_ERROR("Command \"%s\" returned non zero value.", str.c_str());
309  }
310  }
311 
312  // Pause visual_odometry
313  ros::service::call("pause_odom", emptySrv);
314 
315  // Pause rtabmap
316  if(!ros::service::call("pause", emptySrv))
317  {
318  ROS_ERROR("Can't call \"pause\" service");
319  }
320  }
322  {
323  // Resume rtabmap
324  if(!ros::service::call("resume", emptySrv))
325  {
326  ROS_ERROR("Can't call \"resume\" service");
327  }
328 
329  // Pause visual_odometry
330  ros::service::call("resume_odom", emptySrv);
331 
332  // Resume the camera if the rtabmap/camera node is used
333  if(!cameraNodeName_.empty())
334  {
335  std::string str = uFormat("rosrun dynamic_reconfigure dynparam set %s pause false", cameraNodeName_.c_str());
336  if(system(str.c_str()) !=0)
337  {
338  ROS_ERROR("Command \"%s\" returned non zero value.", str.c_str());
339  }
340  }
341  }
343  {
344  if(!ros::service::call("trigger_new_map", emptySrv))
345  {
346  ROS_ERROR("Can't call \"trigger_new_map\" service");
347  }
348  }
350  {
351  UASSERT(cmdEvent->value1().isBool());
352  UASSERT(cmdEvent->value2().isBool());
353  UASSERT(cmdEvent->value3().isBool());
354 
355  rtabmap_ros::GetMap getMapSrv;
356  getMapSrv.request.global = cmdEvent->value1().toBool();
357  getMapSrv.request.optimized = cmdEvent->value2().toBool();
358  getMapSrv.request.graphOnly = cmdEvent->value3().toBool();
359  if(!ros::service::call("get_map_data", getMapSrv))
360  {
361  ROS_WARN("Can't call \"get_map_data\" service");
362  this->post(new RtabmapEvent3DMap(1)); // service error
363  }
364  else
365  {
366  processRequestedMap(getMapSrv.response.data);
367  }
368  }
369  else if(cmd == rtabmap::RtabmapEventCmd::kCmdGoal)
370  {
371  UASSERT(cmdEvent->value1().isStr() || cmdEvent->value1().isInt() || cmdEvent->value1().isUInt());
372  rtabmap_ros::SetGoal setGoalSrv;
373  setGoalSrv.request.node_id = !cmdEvent->value1().isStr()?cmdEvent->value1().toInt():0;
374  setGoalSrv.request.node_label = cmdEvent->value1().isStr()?cmdEvent->value1().toStr():"";
375  if(!ros::service::call("set_goal", setGoalSrv))
376  {
377  ROS_ERROR("Can't call \"set_goal\" service");
378  }
379  else
380  {
381  UASSERT(setGoalSrv.response.path_ids.size() == setGoalSrv.response.path_poses.size());
382  std::vector<std::pair<int, Transform> > poses(setGoalSrv.response.path_poses.size());
383  for(unsigned int i=0; i<setGoalSrv.response.path_poses.size(); ++i)
384  {
385  poses[i].first = setGoalSrv.response.path_ids[i];
386  poses[i].second = rtabmap_ros::transformFromPoseMsg(setGoalSrv.response.path_poses[i]);
387  }
388  this->post(new RtabmapGlobalPathEvent(setGoalSrv.request.node_id, setGoalSrv.request.node_label, poses, setGoalSrv.response.planning_time));
389  }
390  }
392  {
393  if(!ros::service::call("cancel_goal", emptySrv))
394  {
395  ROS_ERROR("Can't call \"cancel_goal\" service");
396  }
397  }
399  {
400  UASSERT(cmdEvent->value1().isStr());
401  UASSERT(cmdEvent->value2().isUndef() || cmdEvent->value2().isInt() || cmdEvent->value2().isUInt());
402  rtabmap_ros::SetLabel setLabelSrv;
403  setLabelSrv.request.node_label = cmdEvent->value1().toStr();
404  setLabelSrv.request.node_id = cmdEvent->value2().isUndef()?0:cmdEvent->value2().toInt();
405  if(!ros::service::call("set_label", setLabelSrv))
406  {
407  ROS_ERROR("Can't call \"set_label\" service");
408  }
409  }
411  {
412  UASSERT(cmdEvent->value1().isStr());
413  rtabmap_ros::RemoveLabel removeLabelSrv;
414  removeLabelSrv.request.label = cmdEvent->value1().toStr();
415  if(!ros::service::call("remove_label", removeLabelSrv))
416  {
417  ROS_ERROR("Can't call \"remove_label\" service");
418  }
419  }
421  {
422  UASSERT(cmdEvent->value1().isIntArray());
423  std_msgs::Int32MultiArray msg;
424  msg.data = cmdEvent->value1().toIntArray();
426  }
427  else
428  {
429  ROS_WARN("Not handled command (%d)...", cmd);
430  }
431  }
432  else if(anEvent->getClassName().compare("OdometryResetEvent") == 0)
433  {
434  std_srvs::Empty srv;
435  if(!ros::service::call("reset_odom", srv))
436  {
437  ROS_ERROR("Can't call \"reset_odom\" service, (will only work with rtabmap/visual_odometry node.)");
438  }
439  }
440  return false;
441 }
442 
444  const nav_msgs::OdometryConstPtr & odomMsg,
445  const rtabmap_ros::UserDataConstPtr & userDataMsg,
446  const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
447  const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
448  const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
449  const std::vector<sensor_msgs::CameraInfo> & depthCameraInfoMsgs,
450  const sensor_msgs::LaserScan& scan2dMsg,
451  const sensor_msgs::PointCloud2& scan3dMsg,
452  const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
453  const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
454  const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPoints,
455  const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3d,
456  const std::vector<cv::Mat> & localDescriptors)
457 {
458  UASSERT(imageMsgs.size() == 0 || (imageMsgs.size() == cameraInfoMsgs.size()));
459 
460  std_msgs::Header odomHeader;
461  std::string frameId = frameId_;
462  if(odomMsg.get())
463  {
464  odomHeader = odomMsg->header;
465  if(!odomMsg->child_frame_id.empty())
466  {
467  frameId = odomMsg->child_frame_id;
468  }
469  else
470  {
471  ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
472  }
473  }
474  else
475  {
476  if(!scan2dMsg.ranges.empty())
477  {
478  odomHeader = scan2dMsg.header;
479  }
480  else if(!scan3dMsg.data.empty())
481  {
482  odomHeader = scan3dMsg.header;
483  }
484  else if(cameraInfoMsgs.size())
485  {
486  odomHeader = cameraInfoMsgs[0].header;
487  }
488  else if(depthMsgs.size() && depthMsgs[0].get())
489  {
490  odomHeader = depthMsgs[0]->header;
491  }
492  else if(imageMsgs.size() && imageMsgs[0].get())
493  {
494  odomHeader = imageMsgs[0]->header;
495  }
496  odomHeader.frame_id = odomFrameId_;
497  }
498 
499  Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
500  cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
501  if(odomMsg.get())
502  {
503  UASSERT(odomMsg->twist.covariance.size() == 36);
504  if(odomMsg->twist.covariance[0] != 0 &&
505  odomMsg->twist.covariance[7] != 0 &&
506  odomMsg->twist.covariance[14] != 0 &&
507  odomMsg->twist.covariance[21] != 0 &&
508  odomMsg->twist.covariance[28] != 0 &&
509  odomMsg->twist.covariance[35] != 0)
510  {
511  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
512  }
513  }
514  else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
515  {
516  if(odomInfoMsg->covariance[0] != 0 &&
517  odomInfoMsg->covariance[7] != 0 &&
518  odomInfoMsg->covariance[14] != 0 &&
519  odomInfoMsg->covariance[21] != 0 &&
520  odomInfoMsg->covariance[28] != 0 &&
521  odomInfoMsg->covariance[35] != 0)
522  {
523  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
524  }
525  }
526  if(odomHeader.frame_id.empty())
527  {
528  ROS_ERROR("Odometry frame not set!?");
529  return;
530  }
531 
532  cv::Mat rgb;
533  cv::Mat depth;
534  std::vector<rtabmap::CameraModel> cameraModels;
535  std::vector<rtabmap::StereoCameraModel> stereoCameraModels;
536  LaserScan scan;
538  bool ignoreData = false;
539 
540  // limit update rate
541  if(maxOdomUpdateRate_<=0.0 ||
545  {
547 
548  if(imageMsgs.size() && imageMsgs[0].get() && depthMsgs.size() && depthMsgs[0].get())
549  {
550  ParametersMap allParameters = prefDialog_->getAllParameters();
551  bool imagesAlreadyRectified = Parameters::defaultRtabmapImagesAlreadyRectified();
552  Parameters::parse(allParameters, Parameters::kRtabmapImagesAlreadyRectified(), imagesAlreadyRectified);
553 
555  imageMsgs,
556  depthMsgs,
557  cameraInfoMsgs,
558  depthCameraInfoMsgs,
559  frameId,
560  odomSensorSync_?odomHeader.frame_id:"",
561  odomHeader.stamp,
562  rgb,
563  depth,
564  cameraModels,
565  stereoCameraModels,
566  tfListener_,
567  waitForTransform_?waitForTransformDuration_:0.0,
568  imagesAlreadyRectified))
569  {
570  ROS_ERROR("Could not convert rgb/depth msgs! Aborting rtabmapviz update...");
571  return;
572  }
573  }
574 
575  if(!scan2dMsg.ranges.empty())
576  {
578  scan2dMsg,
579  frameId,
580  odomSensorSync_?odomHeader.frame_id:"",
581  odomHeader.stamp,
582  scan,
583  tfListener_,
584  waitForTransform_?waitForTransformDuration_:0))
585  {
586  ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
587  return;
588  }
589  }
590  else if(!scan3dMsg.data.empty())
591  {
593  scan3dMsg,
594  frameId,
595  odomSensorSync_?odomHeader.frame_id:"",
596  odomHeader.stamp,
597  scan,
598  tfListener_,
599  waitForTransform_?waitForTransformDuration_:0))
600  {
601  ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
602  return;
603  }
604  }
605 
606  if(odomInfoMsg.get())
607  {
608  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
609  }
610  ignoreData = false;
611  }
612  else if(odomInfoMsg.get())
613  {
614  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
615  ignoreData = true;
616  }
617  else
618  {
619  // don't update GUI odom stuff if we don't use visual odometry
620  return;
621  }
622 
623  info.reg.covariance = covariance;
624  rtabmap::OdometryEvent odomEvent(
625  !stereoCameraModels.empty()?
627  scan,
628  rgb,
629  depth,
630  stereoCameraModels,
631  odomHeader.seq,
632  rtabmap_ros::timestampFromROS(odomHeader.stamp)):
634  scan,
635  rgb,
636  depth,
637  cameraModels,
638  odomHeader.seq,
639  rtabmap_ros::timestampFromROS(odomHeader.stamp)),
640  odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
641  info);
642 
643  QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
644 }
645 
647  const nav_msgs::OdometryConstPtr & odomMsg,
648  const rtabmap_ros::UserDataConstPtr & userDataMsg,
649  const cv_bridge::CvImageConstPtr& leftImageMsg,
650  const cv_bridge::CvImageConstPtr& rightImageMsg,
651  const sensor_msgs::CameraInfo& leftCamInfoMsg,
652  const sensor_msgs::CameraInfo& rightCamInfoMsg,
653  const sensor_msgs::LaserScan& scan2dMsg,
654  const sensor_msgs::PointCloud2& scan3dMsg,
655  const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
656  const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
657  const std::vector<rtabmap_ros::KeyPoint> & localKeyPoints,
658  const std::vector<rtabmap_ros::Point3f> & localPoints3d,
659  const cv::Mat & localDescriptors)
660 {
661  std_msgs::Header odomHeader;
662  std::string frameId = frameId_;
663  if(odomMsg.get())
664  {
665  odomHeader = odomMsg->header;
666  if(!odomMsg->child_frame_id.empty())
667  {
668  frameId = odomMsg->child_frame_id;
669  }
670  else
671  {
672  ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
673  }
674  }
675  else
676  {
677  if(!scan2dMsg.ranges.empty())
678  {
679  odomHeader = scan2dMsg.header;
680  }
681  else if(!scan3dMsg.data.empty())
682  {
683  odomHeader = scan3dMsg.header;
684  }
685  else
686  {
687  odomHeader = leftCamInfoMsg.header;
688  }
689  odomHeader.frame_id = odomFrameId_;
690  }
691 
692  Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
693  cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
694  if(odomMsg.get())
695  {
696  UASSERT(odomMsg->twist.covariance.size() == 36);
697  if(odomMsg->twist.covariance[0] != 0 &&
698  odomMsg->twist.covariance[7] != 0 &&
699  odomMsg->twist.covariance[14] != 0 &&
700  odomMsg->twist.covariance[21] != 0 &&
701  odomMsg->twist.covariance[28] != 0 &&
702  odomMsg->twist.covariance[35] != 0)
703  {
704  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
705  }
706  }
707  else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
708  {
709  if(odomInfoMsg->covariance[0] != 0 &&
710  odomInfoMsg->covariance[7] != 0 &&
711  odomInfoMsg->covariance[14] != 0 &&
712  odomInfoMsg->covariance[21] != 0 &&
713  odomInfoMsg->covariance[28] != 0 &&
714  odomInfoMsg->covariance[35] != 0)
715  {
716  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
717  }
718  }
719  if(odomHeader.frame_id.empty())
720  {
721  ROS_ERROR("Odometry frame not set!?");
722  return;
723  }
724 
725  cv::Mat left;
726  cv::Mat right;
727  LaserScan scan;
728  rtabmap::StereoCameraModel stereoModel;
730  bool ignoreData = false;
731 
732  // limit update rate
733  if(maxOdomUpdateRate_<=0.0 ||
737  {
739 
740  ParametersMap allParameters = prefDialog_->getAllParameters();
741  bool imagesAlreadyRectified = Parameters::defaultRtabmapImagesAlreadyRectified();
742  Parameters::parse(allParameters, Parameters::kRtabmapImagesAlreadyRectified(), imagesAlreadyRectified);
743 
745  leftImageMsg,
746  rightImageMsg,
747  leftCamInfoMsg,
748  rightCamInfoMsg,
749  frameId,
750  odomSensorSync_?odomHeader.frame_id:"",
751  odomHeader.stamp,
752  left,
753  right,
754  stereoModel,
755  tfListener_,
756  waitForTransform_?waitForTransformDuration_:0.0,
757  imagesAlreadyRectified))
758  {
759  ROS_ERROR("Could not convert stereo msgs! Aborting rtabmapviz update...");
760  return;
761  }
762 
763  if(!scan2dMsg.ranges.empty())
764  {
766  scan2dMsg,
767  frameId,
768  odomSensorSync_?odomHeader.frame_id:"",
769  odomHeader.stamp,
770  scan,
771  tfListener_,
772  waitForTransform_?waitForTransformDuration_:0))
773  {
774  ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
775  return;
776  }
777  }
778  else if(!scan3dMsg.data.empty())
779  {
781  scan3dMsg,
782  frameId,
783  odomSensorSync_?odomHeader.frame_id:"",
784  odomHeader.stamp,
785  scan,
786  tfListener_,
787  waitForTransform_?waitForTransformDuration_:0))
788  {
789  ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
790  return;
791  }
792  }
793 
794  if(odomInfoMsg.get())
795  {
796  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
797  }
798  ignoreData = false;
799  }
800  else if(odomInfoMsg.get())
801  {
802  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
803  ignoreData = true;
804  }
805  else
806  {
807  // don't update GUI odom stuff if we don't use visual odometry
808  return;
809  }
810 
811  info.reg.covariance = covariance;
812  rtabmap::OdometryEvent odomEvent(
814  scan,
815  left,
816  right,
817  stereoModel,
818  odomHeader.seq,
819  rtabmap_ros::timestampFromROS(odomHeader.stamp)),
820  odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
821  info);
822 
823  QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
824 }
825 
827  const nav_msgs::OdometryConstPtr & odomMsg,
828  const rtabmap_ros::UserDataConstPtr & userDataMsg,
829  const sensor_msgs::LaserScan& scan2dMsg,
830  const sensor_msgs::PointCloud2& scan3dMsg,
831  const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
832  const rtabmap_ros::GlobalDescriptor & globalDescriptor)
833 {
834  std_msgs::Header odomHeader;
835  std::string frameId = frameId_;
836  if(odomMsg.get())
837  {
838  odomHeader = odomMsg->header;
839  if(!odomMsg->child_frame_id.empty())
840  {
841  frameId = odomMsg->child_frame_id;
842  }
843  else
844  {
845  ROS_WARN("Received odom topic with child_frame_id not set! Using \"%s\" as base frame.", frameId_.c_str());
846  }
847  }
848  else
849  {
850  if(!scan2dMsg.ranges.empty())
851  {
852  odomHeader = scan2dMsg.header;
853  }
854  else if(!scan3dMsg.data.empty())
855  {
856  odomHeader = scan3dMsg.header;
857  }
858  else
859  {
860  return;
861  }
862  odomHeader.frame_id = odomFrameId_;
863  }
864 
865  Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, frameId, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
866  cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
867  if(odomMsg.get())
868  {
869  UASSERT(odomMsg->twist.covariance.size() == 36);
870  if(odomMsg->twist.covariance[0] != 0 &&
871  odomMsg->twist.covariance[7] != 0 &&
872  odomMsg->twist.covariance[14] != 0 &&
873  odomMsg->twist.covariance[21] != 0 &&
874  odomMsg->twist.covariance[28] != 0 &&
875  odomMsg->twist.covariance[35] != 0)
876  {
877  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
878  }
879  }
880  else if(odomInfoMsg.get() && odomInfoMsg->covariance.size() == 36)
881  {
882  if(odomInfoMsg->covariance[0] != 0 &&
883  odomInfoMsg->covariance[7] != 0 &&
884  odomInfoMsg->covariance[14] != 0 &&
885  odomInfoMsg->covariance[21] != 0 &&
886  odomInfoMsg->covariance[28] != 0 &&
887  odomInfoMsg->covariance[35] != 0)
888  {
889  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomInfoMsg->covariance.data()).clone();
890  }
891  }
892  if(odomHeader.frame_id.empty())
893  {
894  ROS_ERROR("Odometry frame not set!?");
895  return;
896  }
897 
898  LaserScan scan;
900  bool ignoreData = false;
901 
902  // limit update rate
903  if(maxOdomUpdateRate_<=0.0 ||
907  {
909 
910  if(!scan2dMsg.ranges.empty())
911  {
913  scan2dMsg,
914  frameId,
915  odomSensorSync_?odomHeader.frame_id:"",
916  odomHeader.stamp,
917  scan,
918  tfListener_,
919  waitForTransform_?waitForTransformDuration_:0))
920  {
921  ROS_ERROR("Could not convert laser scan msg! Aborting rtabmapviz update...");
922  return;
923  }
924  }
925  else if(!scan3dMsg.data.empty())
926  {
928  scan3dMsg,
929  frameId,
930  odomSensorSync_?odomHeader.frame_id:"",
931  odomHeader.stamp,
932  scan,
933  tfListener_,
934  waitForTransform_?waitForTransformDuration_:0))
935  {
936  ROS_ERROR("Could not convert 3d laser scan msg! Aborting rtabmapviz update...");
937  return;
938  }
939  }
940 
941  if(odomInfoMsg.get())
942  {
943  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
944  }
945  ignoreData = false;
946  }
947  else if(odomInfoMsg.get())
948  {
949  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
950  ignoreData = true;
951  }
952  else
953  {
954  // don't update GUI odom stuff if we don't use visual odometry
955  return;
956  }
957 
958  info.reg.covariance = covariance;
959  rtabmap::OdometryEvent odomEvent(
961  scan,
962  cv::Mat(),
963  cv::Mat(),
965  odomHeader.seq,
966  rtabmap_ros::timestampFromROS(odomHeader.stamp)),
967  odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
968  info);
969 
970  QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
971 }
972 
974  const nav_msgs::OdometryConstPtr & odomMsg,
975  const rtabmap_ros::UserDataConstPtr & userDataMsg,
976  const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg)
977 {
978  UASSERT(odomMsg.get());
979 
980  std_msgs::Header odomHeader = odomMsg->header;
981 
982  Transform odomT = rtabmap_ros::getTransform(odomHeader.frame_id, odomMsg->child_frame_id, odomHeader.stamp, tfListener_, waitForTransform_?waitForTransformDuration_:0);
983  cv::Mat covariance = cv::Mat::eye(6,6,CV_64FC1);
984  if(odomMsg.get())
985  {
986  UASSERT(odomMsg->twist.covariance.size() == 36);
987  if(odomMsg->twist.covariance[0] != 0 &&
988  odomMsg->twist.covariance[7] != 0 &&
989  odomMsg->twist.covariance[14] != 0 &&
990  odomMsg->twist.covariance[21] != 0 &&
991  odomMsg->twist.covariance[28] != 0 &&
992  odomMsg->twist.covariance[35] != 0)
993  {
994  covariance = cv::Mat(6,6,CV_64FC1,(void*)odomMsg->twist.covariance.data()).clone();
995  }
996  }
997  if(odomHeader.frame_id.empty())
998  {
999  ROS_ERROR("Odometry frame not set!?");
1000  return;
1001  }
1002 
1003  rtabmap::OdometryInfo info;
1004  bool ignoreData = false;
1005 
1006  // limit update rate
1007  if(maxOdomUpdateRate_<=0.0 ||
1011  {
1013 
1014  if(odomInfoMsg.get())
1015  {
1016  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg);
1017  }
1018  ignoreData = false;
1019  }
1020  else if(odomInfoMsg.get())
1021  {
1022  info = rtabmap_ros::odomInfoFromROS(*odomInfoMsg).copyWithoutData();
1023  ignoreData = true;
1024  }
1025  else
1026  {
1027  // don't update GUI odom stuff if we don't use visual odometry
1028  return;
1029  }
1030 
1031  info.reg.covariance = covariance;
1032  rtabmap::OdometryEvent odomEvent(
1034  cv::Mat(),
1035  cv::Mat(),
1037  odomHeader.seq,
1038  rtabmap_ros::timestampFromROS(odomHeader.stamp)),
1039  odomMsg.get()?rtabmap_ros::transformFromPoseMsg(odomMsg->pose.pose):odomT,
1040  info);
1041 
1042  QMetaObject::invokeMethod(mainWindow_, "processOdometry", Q_ARG(rtabmap::OdometryEvent, odomEvent), Q_ARG(bool, ignoreData));
1043 }
1044 
1045 }
ros::ServiceClient getMapSrv
bool isInt() const
static std::string homeDir()
std::string uFormat(const char *fmt,...)
virtual void commonOdomCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg)
Definition: GuiWrapper.cpp:973
message_filters::Synchronizer< MyGoalPathSyncPolicy > * goalPathSync_
Definition: GuiWrapper.h:149
bool convertRGBDMsgs(const std::vector< cv_bridge::CvImageConstPtr > &imageMsgs, const std::vector< cv_bridge::CvImageConstPtr > &depthMsgs, const std::vector< sensor_msgs::CameraInfo > &cameraInfoMsgs, const std::vector< sensor_msgs::CameraInfo > &depthCameraInfoMsgs, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, cv::Mat &rgb, cv::Mat &depth, std::vector< rtabmap::CameraModel > &cameraModels, std::vector< rtabmap::StereoCameraModel > &stereoCameraModels, tf::TransformListener &listener, double waitForTransform, bool alreadRectifiedImages, const std::vector< std::vector< rtabmap_ros::KeyPoint > > &localKeyPointsMsgs=std::vector< std::vector< rtabmap_ros::KeyPoint > >(), const std::vector< std::vector< rtabmap_ros::Point3f > > &localPoints3dMsgs=std::vector< std::vector< rtabmap_ros::Point3f > >(), const std::vector< cv::Mat > &localDescriptorsMsgs=std::vector< cv::Mat >(), std::vector< cv::KeyPoint > *localKeyPoints=0, std::vector< cv::Point3f > *localPoints3d=0, cv::Mat *localDescriptors=0)
message_filters::Subscriber< rtabmap_ros::Info > infoTopic_
Definition: GuiWrapper.h:134
message_filters::Subscriber< rtabmap_ros::Goal > goalTopic_
Definition: GuiWrapper.h:137
bool isUInt() const
rtabmap::ParametersMap getAllParameters() const
std::string uReplaceChar(const std::string &str, char before, char after)
bool toBool() const
virtual bool handleEvent(UEvent *anEvent)
Definition: GuiWrapper.cpp:257
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
virtual void commonStereoCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const cv_bridge::CvImageConstPtr &leftImageMsg, const cv_bridge::CvImageConstPtr &rightImageMsg, const sensor_msgs::CameraInfo &leftCamInfoMsg, const sensor_msgs::CameraInfo &rightCamInfoMsg, const sensor_msgs::LaserScan &scan2dMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const std::vector< rtabmap_ros::GlobalDescriptor > &globalDescriptorMsgs=std::vector< rtabmap_ros::GlobalDescriptor >(), const std::vector< rtabmap_ros::KeyPoint > &localKeyPoints=std::vector< rtabmap_ros::KeyPoint >(), const std::vector< rtabmap_ros::Point3f > &localPoints3d=std::vector< rtabmap_ros::Point3f >(), const cv::Mat &localDescriptors=cv::Mat())
Definition: GuiWrapper.cpp:646
string cmd
bool call(const std::string &service_name, MReq &req, MRes &res)
GLM_FUNC_DECL genType e()
bool isUndef() const
rtabmap::Transform transformFromPoseMsg(const geometry_msgs::Pose &msg, bool ignoreRotationIfNotSet=false)
std::map< std::string, std::string > ParametersMap
void infoMapCallback(const rtabmap_ros::InfoConstPtr &infoMsg, const rtabmap_ros::MapDataConstPtr &mapMsg)
Definition: GuiWrapper.cpp:188
ROSCPP_DECL const std::string & getName()
std::vector< int > toIntArray(bool *ok=0) const
void setConstraints(const std::multimap< int, Link > &constraints)
void post(UEvent *event, bool async=true) const
void processRequestedMap(const rtabmap_ros::MapData &map)
Definition: GuiWrapper.cpp:236
#define ROS_WARN(...)
rtabmap::MainWindow * mainWindow_
Definition: GuiWrapper.h:118
bool isBool() const
bool isStr() const
rtabmap::PreferencesDialog * prefDialog_
Definition: GuiWrapper.h:117
rtabmap::Transform getTransform(const std::string &fromFrameId, const std::string &toFrameId, const ros::Time &stamp, tf::TransformListener &listener, double waitForTransform)
int toInt(bool *ok=0) const
#define UASSERT(condition)
void goalReachedCallback(const std_msgs::BoolConstPtr &value)
Definition: GuiWrapper.cpp:230
message_filters::Subscriber< rtabmap_ros::MapData > mapDataTopic_
Definition: GuiWrapper.h:135
static std::string currentDir(bool trailingSeparator=false)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
#define true
bool paused
void publish(const boost::shared_ptr< M > &message) const
void mapDataFromROS(const rtabmap_ros::MapData &msg, std::map< int, rtabmap::Transform > &poses, std::multimap< int, rtabmap::Link > &links, std::map< int, rtabmap::Signature > &signatures, rtabmap::Transform &mapToOdom)
rtabmap::OdometryInfo odomInfoFromROS(const rtabmap_ros::OdomInfo &msg, bool ignoreData=false)
std::string rtabmapNodeName_
Definition: GuiWrapper.h:121
double waitForTransformDuration_
Definition: GuiWrapper.h:127
const UVariant & value3() const
void setPoses(const std::map< int, Transform > &poses)
ros::Subscriber goalReachedTopic_
Definition: GuiWrapper.h:139
message_filters::Synchronizer< MyInfoMapSyncPolicy > * infoMapSync_
Definition: GuiWrapper.h:144
virtual std::string getClassName() const=0
void setupCallbacks(ros::NodeHandle &nh, ros::NodeHandle &pnh, const std::string &name)
virtual void commonMultiCameraCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const std::vector< cv_bridge::CvImageConstPtr > &imageMsgs, const std::vector< cv_bridge::CvImageConstPtr > &depthMsgs, const std::vector< sensor_msgs::CameraInfo > &cameraInfoMsgs, const std::vector< sensor_msgs::CameraInfo > &depthCameraInfoMsgs, const sensor_msgs::LaserScan &scan2dMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const std::vector< rtabmap_ros::GlobalDescriptor > &globalDescriptorMsgs=std::vector< rtabmap_ros::GlobalDescriptor >(), const std::vector< std::vector< rtabmap_ros::KeyPoint > > &localKeyPoints=std::vector< std::vector< rtabmap_ros::KeyPoint > >(), const std::vector< std::vector< rtabmap_ros::Point3f > > &localPoints3d=std::vector< std::vector< rtabmap_ros::Point3f > >(), const std::vector< cv::Mat > &localDescriptors=std::vector< cv::Mat >())
Definition: GuiWrapper.cpp:443
void setSignaturesData(const std::map< int, Signature > &data)
#define ROS_INFO(...)
void infoFromROS(const rtabmap_ros::Info &info, rtabmap::Statistics &stat)
bool isProcessingOdometry() const
QMap< QString, QVariant > ParametersMap
bool isIntArray() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
OdometryInfo copyWithoutData() const
void goalPathCallback(const rtabmap_ros::GoalConstPtr &goalMsg, const nav_msgs::PathConstPtr &pathMsg)
Definition: GuiWrapper.cpp:216
void setMonitoringState(bool pauseChecked=false)
float max3(const float &a, const float &b, const float &c)
Definition: GuiWrapper.cpp:59
bool convertStereoMsg(const cv_bridge::CvImageConstPtr &leftImageMsg, const cv_bridge::CvImageConstPtr &rightImageMsg, const sensor_msgs::CameraInfo &leftCamInfoMsg, const sensor_msgs::CameraInfo &rightCamInfoMsg, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, cv::Mat &left, cv::Mat &right, rtabmap::StereoCameraModel &stereoModel, tf::TransformListener &listener, double waitForTransform, bool alreadyRectified)
bool hasParam(const std::string &key) const
void setMapCorrection(const Transform &mapCorrection)
string frameId
Definition: patrol.py:11
#define false
void uSleep(unsigned int ms)
virtual void commonLaserScanCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const sensor_msgs::LaserScan &scan2dMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const rtabmap_ros::GlobalDescriptor &globalDescriptor=rtabmap_ros::GlobalDescriptor())
Definition: GuiWrapper.cpp:826
static const ParametersMap & getDefaultParameters()
bool convertScanMsg(const sensor_msgs::LaserScan &scan2dMsg, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, rtabmap::LaserScan &scan, tf::TransformListener &listener, double waitForTransform, bool outputInFrameId=false)
tf::TransformListener tfListener_
Definition: GuiWrapper.h:130
#define UDEBUG(...)
std::string toStr(bool *ok=0) const
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
const UVariant & value2() const
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
static void addHandler(UEventsHandler *handler)
message_filters::sync_policies::ExactTime< rtabmap_ros::Goal, nav_msgs::Path > MyGoalPathSyncPolicy
Definition: GuiWrapper.h:148
std::string cameraNodeName_
Definition: GuiWrapper.h:119
static double now()
double timestampFromROS(const ros::Time &stamp)
RegistrationInfo reg
message_filters::Subscriber< nav_msgs::Path > pathTopic_
Definition: GuiWrapper.h:138
ros::Publisher republishNodeDataPub_
Definition: GuiWrapper.h:132
bool isProcessingStatistics() const
GuiWrapper(int &argc, char **argv)
Definition: GuiWrapper.cpp:67
message_filters::sync_policies::ExactTime< rtabmap_ros::Info, rtabmap_ros::MapData > MyInfoMapSyncPolicy
Definition: GuiWrapper.h:143
std::string odomFrameId_
Definition: GuiWrapper.h:125
#define ROS_ERROR(...)
const UVariant & value1() const
bool convertScan3dMsg(const sensor_msgs::PointCloud2 &scan3dMsg, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, rtabmap::LaserScan &scan, tf::TransformListener &listener, double waitForTransform, int maxPoints=0, float maxRange=0.0f, bool is2D=false)


rtabmap_ros
Author(s): Mathieu Labbe
autogenerated on Tue Jan 24 2023 04:04:40