DbPlayerNode.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 <ros/ros.h>
29 #include <sensor_msgs/Image.h>
31 #include <sensor_msgs/PointCloud2.h>
32 #include <sensor_msgs/LaserScan.h>
33 #include <sensor_msgs/CameraInfo.h>
34 #include <sensor_msgs/NavSatFix.h>
35 #include <geometry_msgs/PoseWithCovarianceStamped.h>
36 #include <rosgraph_msgs/Clock.h>
38 #include <nav_msgs/Odometry.h>
39 #include <cv_bridge/cv_bridge.h>
42 #include <std_srvs/Empty.h>
44 #include <rtabmap_ros/SetGoal.h>
46 #include <rtabmap/utilite/UStl.h>
50 #include <rtabmap/core/util3d.h>
51 #include <rtabmap/core/DBReader.h>
53 #include <cmath>
54 
55 #ifndef _WIN32
56 #include <sys/ioctl.h>
57 #include <termios.h>
58 bool spacehit()
59 {
60  bool charAvailable = true;
61  bool hit = false;
62  while(charAvailable)
63  {
64  termios term;
65  tcgetattr(0, &term);
66 
67  termios term2 = term;
68  term2.c_lflag &= ~ICANON;
69  term2.c_lflag &= ~ECHO;
70  term2.c_lflag &= ~ISIG;
71  term2.c_cc[VMIN] = 0;
72  term2.c_cc[VTIME] = 0;
73  tcsetattr(0, TCSANOW, &term2);
74 
75  int c = getchar();
76  if(c != EOF)
77  {
78  if(c == ' ')
79  {
80  hit = true;
81  }
82  }
83  else
84  {
85  charAvailable = false;
86  }
87 
88  tcsetattr(0, TCSANOW, &term);
89  }
90 
91  return hit;
92 }
93 #endif
94 
95 bool paused = false;
96 bool pauseCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
97 {
98  if(paused)
99  {
100  ROS_WARN("Already paused!");
101  }
102  else
103  {
104  paused = true;
105  ROS_INFO("paused!");
106  }
107  return true;
108 }
109 
110 bool resumeCallback(std_srvs::Empty::Request&, std_srvs::Empty::Response&)
111 {
112  if(!paused)
113  {
114  ROS_WARN("Already running!");
115  }
116  else
117  {
118  paused = false;
119  ROS_INFO("resumed!");
120  }
121  return true;
122 }
123 
124 int main(int argc, char** argv)
125 {
126  ros::init(argc, argv, "data_player");
127 
128  //ULogger::setType(ULogger::kTypeConsole);
129  //ULogger::setLevel(ULogger::kDebug);
130  //ULogger::setEventLevel(ULogger::kWarning);
131 
132  bool publishClock = false;
133  for(int i=1;i<argc;++i)
134  {
135  if(strcmp(argv[i], "--clock") == 0)
136  {
137  publishClock = true;
138  }
139  }
140 
141  ros::NodeHandle nh;
142  ros::NodeHandle pnh("~");
143 
144  std::string frameId = "base_link";
145  std::string odomFrameId = "odom";
146  std::string cameraFrameId = "camera_optical_link";
147  std::string scanFrameId = "base_laser_link";
148  double rate = 1.0f;
149  std::string databasePath = "";
150  bool publishTf = true;
151  int startId = 0;
152  bool useDbStamps = true;
153 
154  pnh.param("frame_id", frameId, frameId);
155  pnh.param("odom_frame_id", odomFrameId, odomFrameId);
156  pnh.param("camera_frame_id", cameraFrameId, cameraFrameId);
157  pnh.param("scan_frame_id", scanFrameId, scanFrameId);
158  pnh.param("rate", rate, rate); // Ratio of the database stamps
159  pnh.param("database", databasePath, databasePath);
160  pnh.param("publish_tf", publishTf, publishTf);
161  pnh.param("start_id", startId, startId);
162 
163  // A general 360 lidar with 0.5 deg increment
164  double scanAngleMin, scanAngleMax, scanAngleIncrement, scanRangeMin, scanRangeMax;
165  pnh.param<double>("scan_angle_min", scanAngleMin, -M_PI);
166  pnh.param<double>("scan_angle_max", scanAngleMax, M_PI);
167  pnh.param<double>("scan_angle_increment", scanAngleIncrement, M_PI / 720.0);
168  pnh.param<double>("scan_range_min", scanRangeMin, 0.0);
169  pnh.param<double>("scan_range_max", scanRangeMax, 60);
170 
171  ROS_INFO("frame_id = %s", frameId.c_str());
172  ROS_INFO("odom_frame_id = %s", odomFrameId.c_str());
173  ROS_INFO("camera_frame_id = %s", cameraFrameId.c_str());
174  ROS_INFO("scan_frame_id = %s", scanFrameId.c_str());
175  ROS_INFO("rate = %f", rate);
176  ROS_INFO("publish_tf = %s", publishTf?"true":"false");
177  ROS_INFO("start_id = %d", startId);
178  ROS_INFO("Publish clock (--clock): %s", publishClock?"true":"false");
179 
180  if(databasePath.empty())
181  {
182  ROS_ERROR("Parameter \"database\" must be set (path to a RTAB-Map database).");
183  return -1;
184  }
185  databasePath = uReplaceChar(databasePath, '~', UDirectory::homeDir());
186  if(databasePath.size() && databasePath.at(0) != '/')
187  {
188  databasePath = UDirectory::currentDir(true) + databasePath;
189  }
190  ROS_INFO("database = %s", databasePath.c_str());
191 
192  rtabmap::DBReader reader(databasePath, -rate, false, false, false, startId);
193  if(!reader.init())
194  {
195  ROS_ERROR("Cannot open database \"%s\".", databasePath.c_str());
196  return -1;
197  }
198 
199  ros::ServiceServer pauseSrv = pnh.advertiseService("pause", pauseCallback);
200  ros::ServiceServer resumeSrv = pnh.advertiseService("resume", resumeCallback);
201 
208  ros::Publisher rgbCamInfoPub;
209  ros::Publisher depthCamInfoPub;
210  ros::Publisher leftCamInfoPub;
211  ros::Publisher rightCamInfoPub;
212  ros::Publisher odometryPub;
213  ros::Publisher scanPub;
214  ros::Publisher scanCloudPub;
215  ros::Publisher globalPosePub;
216  ros::Publisher gpsFixPub;
217  ros::Publisher clockPub;
218  tf2_ros::TransformBroadcaster tfBroadcaster;
219 
220  if(publishClock)
221  {
222  clockPub = nh.advertise<rosgraph_msgs::Clock>("/clock", 1);
223  }
224 
225  UTimer timer;
226  rtabmap::CameraInfo cameraInfo;
227  rtabmap::SensorData data = reader.takeImage(&cameraInfo);
228  rtabmap::OdometryInfo odomInfo;
229  odomInfo.reg.covariance = cameraInfo.odomCovariance;
230  rtabmap::OdometryEvent odom(data, cameraInfo.odomPose, odomInfo);
231  double acquisitionTime = timer.ticks();
232  while(ros::ok() && odom.data().id())
233  {
234  ROS_INFO("Reading sensor data %d...", odom.data().id());
235 
236  ros::Time time(odom.data().stamp());
237 
238  if(publishClock)
239  {
240  rosgraph_msgs::Clock msg;
241  msg.clock = time;
242  clockPub.publish(msg);
243  }
244 
245  sensor_msgs::CameraInfo camInfoA; //rgb or left
246  sensor_msgs::CameraInfo camInfoB; //depth or right
247 
248  camInfoA.K.assign(0);
249  camInfoA.K[0] = camInfoA.K[4] = camInfoA.K[8] = 1;
250  camInfoA.R.assign(0);
251  camInfoA.R[0] = camInfoA.R[4] = camInfoA.R[8] = 1;
252  camInfoA.P.assign(0);
253  camInfoA.P[10] = 1;
254 
255  camInfoA.header.frame_id = cameraFrameId;
256  camInfoA.header.stamp = time;
257 
258  camInfoB = camInfoA;
259 
260  int type = -1;
261  if(!odom.data().depthRaw().empty() && (odom.data().depthRaw().type() == CV_32FC1 || odom.data().depthRaw().type() == CV_16UC1))
262  {
263  if(odom.data().cameraModels().size() > 1)
264  {
265  ROS_WARN("Multi-cameras detected in database but this node cannot send multi-images yet...");
266  }
267  else
268  {
269  //depth
270  if(odom.data().cameraModels().size())
271  {
272  camInfoA.D.resize(5,0);
273 
274  camInfoA.P[0] = odom.data().cameraModels()[0].fx();
275  camInfoA.K[0] = odom.data().cameraModels()[0].fx();
276  camInfoA.P[5] = odom.data().cameraModels()[0].fy();
277  camInfoA.K[4] = odom.data().cameraModels()[0].fy();
278  camInfoA.P[2] = odom.data().cameraModels()[0].cx();
279  camInfoA.K[2] = odom.data().cameraModels()[0].cx();
280  camInfoA.P[6] = odom.data().cameraModels()[0].cy();
281  camInfoA.K[5] = odom.data().cameraModels()[0].cy();
282 
283  camInfoB = camInfoA;
284  }
285 
286  type=0;
287 
288  if(rgbPub.getTopic().empty()) rgbPub = it.advertise("rgb/image", 1);
289  if(depthPub.getTopic().empty()) depthPub = it.advertise("depth_registered/image", 1);
290  if(rgbCamInfoPub.getTopic().empty()) rgbCamInfoPub = nh.advertise<sensor_msgs::CameraInfo>("rgb/camera_info", 1);
291  if(depthCamInfoPub.getTopic().empty()) depthCamInfoPub = nh.advertise<sensor_msgs::CameraInfo>("depth_registered/camera_info", 1);
292  }
293  }
294  else if(!odom.data().rightRaw().empty() && odom.data().rightRaw().type() == CV_8U)
295  {
296  if(odom.data().stereoCameraModels().size() > 1)
297  {
298  ROS_WARN("Multi-cameras detected in database but this node cannot send multi-images yet...");
299  }
300  else
301  {
302  //stereo
303  if(odom.data().stereoCameraModels()[0].isValidForProjection())
304  {
305  camInfoA.D.resize(8,0);
306 
307  camInfoA.P[0] = odom.data().stereoCameraModels()[0].left().fx();
308  camInfoA.K[0] = odom.data().stereoCameraModels()[0].left().fx();
309  camInfoA.P[5] = odom.data().stereoCameraModels()[0].left().fy();
310  camInfoA.K[4] = odom.data().stereoCameraModels()[0].left().fy();
311  camInfoA.P[2] = odom.data().stereoCameraModels()[0].left().cx();
312  camInfoA.K[2] = odom.data().stereoCameraModels()[0].left().cx();
313  camInfoA.P[6] = odom.data().stereoCameraModels()[0].left().cy();
314  camInfoA.K[5] = odom.data().stereoCameraModels()[0].left().cy();
315 
316  camInfoB = camInfoA;
317  camInfoB.P[3] = odom.data().stereoCameraModels()[0].right().Tx(); // Right_Tx = -baseline*fx
318  }
319 
320  type=1;
321 
322  if(leftPub.getTopic().empty()) leftPub = it.advertise("left/image", 1);
323  if(rightPub.getTopic().empty()) rightPub = it.advertise("right/image", 1);
324  if(leftCamInfoPub.getTopic().empty()) leftCamInfoPub = nh.advertise<sensor_msgs::CameraInfo>("left/camera_info", 1);
325  if(rightCamInfoPub.getTopic().empty()) rightCamInfoPub = nh.advertise<sensor_msgs::CameraInfo>("right/camera_info", 1);
326  }
327 
328  }
329  else
330  {
331  if(imagePub.getTopic().empty()) imagePub = it.advertise("image", 1);
332  }
333 
334  camInfoA.height = odom.data().imageRaw().rows;
335  camInfoA.width = odom.data().imageRaw().cols;
336  camInfoB.height = odom.data().depthOrRightRaw().rows;
337  camInfoB.width = odom.data().depthOrRightRaw().cols;
338 
339  if(!odom.data().laserScanRaw().isEmpty())
340  {
341  if(scanPub.getTopic().empty() && odom.data().laserScanRaw().is2d())
342  {
343  scanPub = nh.advertise<sensor_msgs::LaserScan>("scan", 1);
344  if(odom.data().laserScanRaw().angleIncrement() > 0.0f)
345  {
346  ROS_INFO("Scan will be published.");
347  }
348  else
349  {
350  ROS_INFO("Scan will be published with those parameters:");
351  ROS_INFO(" scan_angle_min=%f", scanAngleMin);
352  ROS_INFO(" scan_angle_max=%f", scanAngleMax);
353  ROS_INFO(" scan_angle_increment=%f", scanAngleIncrement);
354  ROS_INFO(" scan_range_min=%f", scanRangeMin);
355  ROS_INFO(" scan_range_max=%f", scanRangeMax);
356  }
357  }
358  else if(scanCloudPub.getTopic().empty())
359  {
360  scanCloudPub = nh.advertise<sensor_msgs::PointCloud2>("scan_cloud", 1);
361  ROS_INFO("Scan cloud will be published.");
362  }
363  }
364 
365  if(!odom.data().globalPose().isNull() &&
366  odom.data().globalPoseCovariance().cols==6 &&
367  odom.data().globalPoseCovariance().rows==6)
368  {
369  if(globalPosePub.getTopic().empty())
370  {
371  globalPosePub = nh.advertise<geometry_msgs::PoseWithCovarianceStamped>("global_pose", 1);
372  ROS_INFO("Global pose will be published.");
373  }
374  }
375 
376  if(odom.data().gps().stamp() > 0.0)
377  {
378  if(gpsFixPub.getTopic().empty())
379  {
380  gpsFixPub = nh.advertise<sensor_msgs::NavSatFix>("gps/fix", 1);
381  ROS_INFO("GPS will be published.");
382  }
383  }
384 
385  // publish transforms first
386  if(publishTf)
387  {
388  rtabmap::Transform localTransform;
389  if(odom.data().cameraModels().size() == 1)
390  {
391  localTransform = odom.data().cameraModels()[0].localTransform();
392  }
393  else if(odom.data().stereoCameraModels().size() == 1)
394  {
395  localTransform = odom.data().stereoCameraModels()[0].left().localTransform();
396  }
397  if(!localTransform.isNull())
398  {
399  geometry_msgs::TransformStamped baseToCamera;
400  baseToCamera.child_frame_id = cameraFrameId;
401  baseToCamera.header.frame_id = frameId;
402  baseToCamera.header.stamp = time;
403  rtabmap_ros::transformToGeometryMsg(localTransform, baseToCamera.transform);
404  tfBroadcaster.sendTransform(baseToCamera);
405  }
406 
407  if(!odom.pose().isNull())
408  {
410  odomToBase.child_frame_id = frameId;
411  odomToBase.header.frame_id = odomFrameId;
412  odomToBase.header.stamp = time;
413  rtabmap_ros::transformToGeometryMsg(odom.pose(), odomToBase.transform);
414  tfBroadcaster.sendTransform(odomToBase);
415  }
416 
417  if(!scanPub.getTopic().empty() || !scanCloudPub.getTopic().empty())
418  {
419  geometry_msgs::TransformStamped baseToLaserScan;
420  baseToLaserScan.child_frame_id = scanFrameId;
421  baseToLaserScan.header.frame_id = frameId;
422  baseToLaserScan.header.stamp = time;
423  rtabmap_ros::transformToGeometryMsg(odom.data().laserScanCompressed().localTransform(), baseToLaserScan.transform);
424  tfBroadcaster.sendTransform(baseToLaserScan);
425  }
426  }
427  if(!odom.pose().isNull())
428  {
429  if(odometryPub.getTopic().empty()) odometryPub = nh.advertise<nav_msgs::Odometry>("odom", 1);
430 
431  if(odometryPub.getNumSubscribers())
432  {
433  nav_msgs::Odometry odomMsg;
434  odomMsg.child_frame_id = frameId;
435  odomMsg.header.frame_id = odomFrameId;
436  odomMsg.header.stamp = time;
437  rtabmap_ros::transformToPoseMsg(odom.pose(), odomMsg.pose.pose);
438  UASSERT(odomMsg.pose.covariance.size() == 36 &&
439  odom.covariance().total() == 36 &&
440  odom.covariance().type() == CV_64FC1);
441  memcpy(odomMsg.pose.covariance.begin(), odom.covariance().data, 36*sizeof(double));
442  odometryPub.publish(odomMsg);
443  }
444  }
445 
446  // Publish async topics first (so that they can catched by rtabmap before the image topics)
447  if(globalPosePub.getNumSubscribers() > 0 &&
448  !odom.data().globalPose().isNull() &&
449  odom.data().globalPoseCovariance().cols==6 &&
450  odom.data().globalPoseCovariance().rows==6)
451  {
452  geometry_msgs::PoseWithCovarianceStamped msg;
453  rtabmap_ros::transformToPoseMsg(odom.data().globalPose(), msg.pose.pose);
454  memcpy(msg.pose.covariance.data(), odom.data().globalPoseCovariance().data, 36*sizeof(double));
455  msg.header.frame_id = frameId;
456  msg.header.stamp = time;
457  globalPosePub.publish(msg);
458  }
459 
460  if(odom.data().gps().stamp() > 0.0)
461  {
462  sensor_msgs::NavSatFix msg;
463  msg.longitude = odom.data().gps().longitude();
464  msg.latitude = odom.data().gps().latitude();
465  msg.altitude = odom.data().gps().altitude();
466  msg.position_covariance_type = sensor_msgs::NavSatFix::COVARIANCE_TYPE_DIAGONAL_KNOWN;
467  msg.position_covariance.at(0) = msg.position_covariance.at(4) = msg.position_covariance.at(8)= odom.data().gps().error()* odom.data().gps().error();
468  msg.header.frame_id = frameId;
469  msg.header.stamp.fromSec(odom.data().gps().stamp());
470  gpsFixPub.publish(msg);
471  }
472 
473  if(type >= 0)
474  {
475  if(rgbCamInfoPub.getNumSubscribers() && type == 0)
476  {
477  rgbCamInfoPub.publish(camInfoA);
478  }
479  if(leftCamInfoPub.getNumSubscribers() && type == 1)
480  {
481  leftCamInfoPub.publish(camInfoA);
482  }
483  if(depthCamInfoPub.getNumSubscribers() && type == 0)
484  {
485  depthCamInfoPub.publish(camInfoB);
486  }
487  if(rightCamInfoPub.getNumSubscribers() && type == 1)
488  {
489  rightCamInfoPub.publish(camInfoB);
490  }
491  }
492 
493  if(imagePub.getNumSubscribers() || rgbPub.getNumSubscribers() || leftPub.getNumSubscribers())
494  {
495  cv_bridge::CvImage img;
496  if(odom.data().imageRaw().channels() == 1)
497  {
499  }
500  else
501  {
503  }
504  img.image = odom.data().imageRaw();
505  sensor_msgs::ImagePtr imageRosMsg = img.toImageMsg();
506  imageRosMsg->header.frame_id = cameraFrameId;
507  imageRosMsg->header.stamp = time;
508 
509  if(imagePub.getNumSubscribers())
510  {
511  imagePub.publish(imageRosMsg);
512  }
513  if(rgbPub.getNumSubscribers() && type == 0)
514  {
515  rgbPub.publish(imageRosMsg);
516  }
517  if(leftPub.getNumSubscribers() && type == 1)
518  {
519  leftPub.publish(imageRosMsg);
520  leftCamInfoPub.publish(camInfoA);
521  }
522  }
523 
524  if(depthPub.getNumSubscribers() && !odom.data().depthRaw().empty() && type==0)
525  {
526  cv_bridge::CvImage img;
527  if(odom.data().depthRaw().type() == CV_32FC1)
528  {
530  }
531  else
532  {
534  }
535  img.image = odom.data().depthRaw();
536  sensor_msgs::ImagePtr imageRosMsg = img.toImageMsg();
537  imageRosMsg->header.frame_id = cameraFrameId;
538  imageRosMsg->header.stamp = time;
539 
540  depthPub.publish(imageRosMsg);
541  depthCamInfoPub.publish(camInfoB);
542  }
543 
544  if(rightPub.getNumSubscribers() && !odom.data().rightRaw().empty() && type==1)
545  {
546  cv_bridge::CvImage img;
548  img.image = odom.data().rightRaw();
549  sensor_msgs::ImagePtr imageRosMsg = img.toImageMsg();
550  imageRosMsg->header.frame_id = cameraFrameId;
551  imageRosMsg->header.stamp = time;
552 
553  rightPub.publish(imageRosMsg);
554  rightCamInfoPub.publish(camInfoB);
555  }
556 
557  if(!odom.data().laserScanRaw().isEmpty())
558  {
559  if(scanPub.getNumSubscribers() && odom.data().laserScanRaw().is2d())
560  {
561  //inspired from pointcloud_to_laserscan package
562  sensor_msgs::LaserScan msg;
563  msg.header.frame_id = scanFrameId;
564  msg.header.stamp = time;
565 
566  msg.angle_min = scanAngleMin;
567  msg.angle_max = scanAngleMax;
568  msg.angle_increment = scanAngleIncrement;
569  msg.time_increment = 0.0;
570  msg.scan_time = 0;
571  msg.range_min = scanRangeMin;
572  msg.range_max = scanRangeMax;
573  if(odom.data().laserScanRaw().angleIncrement() > 0.0f)
574  {
575  msg.angle_min = odom.data().laserScanRaw().angleMin();
576  msg.angle_max = odom.data().laserScanRaw().angleMax();
577  msg.angle_increment = odom.data().laserScanRaw().angleIncrement();
578  msg.range_min = odom.data().laserScanRaw().rangeMin();
579  msg.range_max = odom.data().laserScanRaw().rangeMax();
580  }
581 
582  uint32_t rangesSize = std::ceil((msg.angle_max - msg.angle_min) / msg.angle_increment);
583  msg.ranges.assign(rangesSize, 0.0);
584 
585  const cv::Mat & scan = odom.data().laserScanRaw().data();
586  for (int i=0; i<scan.cols; ++i)
587  {
588  const float * ptr = scan.ptr<float>(0,i);
589  double range = hypot(ptr[0], ptr[1]);
590  if (range >= msg.range_min && range <=msg.range_max)
591  {
592  double angle = atan2(ptr[1], ptr[0]);
593  if (angle >= msg.angle_min && angle <= msg.angle_max)
594  {
595  int index = (angle - msg.angle_min) / msg.angle_increment;
596  if (index>=0 && index<rangesSize && (range < msg.ranges[index] || msg.ranges[index]==0))
597  {
598  msg.ranges[index] = range;
599  }
600  }
601  }
602  }
603 
604  scanPub.publish(msg);
605  }
606  else if(scanCloudPub.getNumSubscribers())
607  {
608  sensor_msgs::PointCloud2 msg;
610  msg.header.frame_id = scanFrameId;
611  msg.header.stamp = time;
612  scanCloudPub.publish(msg);
613  }
614  }
615 
616  if(odom.data().userDataRaw().type() == CV_8SC1 &&
617  odom.data().userDataRaw().cols >= 7 && // including null str ending
618  odom.data().userDataRaw().rows == 1 &&
619  memcmp(odom.data().userDataRaw().data, "GOAL:", 5) == 0)
620  {
621  //GOAL format detected, remove it from the user data and send it as goal event
622  std::string goalStr = (const char *)odom.data().userDataRaw().data;
623  if(!goalStr.empty())
624  {
625  std::list<std::string> strs = uSplit(goalStr, ':');
626  if(strs.size() == 2)
627  {
628  int goalId = atoi(strs.rbegin()->c_str());
629 
630  if(goalId > 0)
631  {
632  ROS_WARN("Goal %d detected, calling rtabmap's set_goal service!", goalId);
633  rtabmap_ros::SetGoal setGoalSrv;
634  setGoalSrv.request.node_id = goalId;
635  setGoalSrv.request.node_label = "";
636  if(!ros::service::call("set_goal", setGoalSrv))
637  {
638  ROS_ERROR("Can't call \"set_goal\" service");
639  }
640  }
641  }
642  }
643  }
644 
645  ros::spinOnce();
646 
647  while(ros::ok())
648  {
649 #ifndef _WIN32
650  if (spacehit()) {
651  paused = !paused;
652  if(paused)
653  {
654  ROS_INFO("paused!");
655  }
656  else
657  {
658  ROS_INFO("resumed!");
659  }
660  }
661 #endif
662 
663  if(!paused)
664  {
665  break;
666  }
667 
668  uSleep(100);
669  ros::spinOnce();
670  }
671 
672  timer.restart();
673  cameraInfo = rtabmap::CameraInfo();
674  data = reader.takeImage(&cameraInfo);
675  odomInfo.reg.covariance = cameraInfo.odomCovariance;
676  odom = rtabmap::OdometryEvent(data, cameraInfo.odomPose, odomInfo);
677  acquisitionTime = timer.ticks();
678  }
679 
680 
681  return 0;
682 }
static std::string homeDir()
SensorData & data()
const double & error() const
const double & stamp() const
const Transform & globalPose() const
const cv::Mat & covariance() const
const LaserScan & laserScanCompressed() const
float angleMin() const
std::string uReplaceChar(const std::string &str, char before, char after)
uint32_t getNumSubscribers() const
int main(int argc, char **argv)
bool call(const std::string &service_name, MReq &req, MRes &res)
const cv::Mat & depthOrRightRaw() const
data
void transformToGeometryMsg(const rtabmap::Transform &transform, geometry_msgs::Transform &msg)
pcl::PCLPointCloud2::Ptr RTABMAP_EXP laserScanToPointCloud2(const LaserScan &laserScan, const Transform &transform=Transform())
bool resumeCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
std::string encoding
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
const std::vector< StereoCameraModel > & stereoCameraModels() const
const cv::Mat & data() const
INLINE Rall1d< T, V, S > hypot(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
bool isEmpty() const
bool is2d() const
#define ROS_WARN(...)
const cv::Mat & globalPoseCovariance() const
float rangeMax() const
cv::Mat rightRaw() const
#define UASSERT(condition)
std::list< std::string > uSplit(const std::string &str, char separator=' ')
const double & altitude() const
bool pauseCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
static std::string currentDir(bool trailingSeparator=false)
sensor_msgs::ImagePtr toImageMsg() const
const std::vector< CameraModel > & cameraModels() const
bool param(const std::string &param_name, T &param_val, const T &default_val) const
bool paused
void publish(const boost::shared_ptr< M > &message) const
const GPS & gps() const
cv::Mat depthRaw() const
const cv::Mat & imageRaw() const
#define ROS_INFO(...)
const std::string TYPE_32FC1
ROSCPP_DECL bool ok()
const std::string TYPE_16UC1
float rangeMin() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
GLM_FUNC_QUALIFIER T atan2(T x, T y)
void sendTransform(const geometry_msgs::TransformStamped &transform)
bool spacehit()
void publish(const sensor_msgs::Image &message) const
bool isNull() const
void transformToPoseMsg(const rtabmap::Transform &transform, geometry_msgs::Pose &msg)
string frameId
Definition: patrol.py:11
detail::uint32 uint32_t
float angleMax() const
void uSleep(unsigned int ms)
std::string getTopic() const
const LaserScan & laserScanRaw() const
const cv::Mat & userDataRaw() const
const double & longitude() const
double stamp() const
RegistrationInfo reg
const double & latitude() const
image_transport::Publisher imagePub
float angleIncrement() const
void moveFromPCL(pcl::PCLImage &pcl_image, sensor_msgs::Image &image)
uint32_t getNumSubscribers() const
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
const Transform & pose() const
#define M_PI
GLM_FUNC_DECL genType ceil(genType const &x)
Transform localTransform() const
std::string getTopic() const


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