34 #include <nav_msgs/Path.h> 35 #include <std_msgs/Int32MultiArray.h> 36 #include <std_msgs/Bool.h> 37 #include <geometry_msgs/PoseArray.h> 41 #include <pcl/io/io.h> 43 #include <visualization_msgs/MarkerArray.h> 58 #include <rtabmap/core/Version.h> 64 #ifdef WITH_OCTOMAP_MSGS 65 #ifdef RTABMAP_OCTOMAP 71 #define BAD_COVARIANCE 9999 74 #include "rtabmap_ros/Info.h" 75 #include "rtabmap_ros/MapData.h" 76 #include "rtabmap_ros/MapGraph.h" 77 #include "rtabmap_ros/Path.h" 85 CoreWrapper::CoreWrapper() :
89 lastPoseIntermediate_(
false),
90 latestNodeWasReached_(
false),
91 frameId_(
"base_link"),
94 groundTruthFrameId_(
""),
95 groundTruthBaseFrameId_(
""),
97 odomDefaultAngVariance_(0.001),
98 odomDefaultLinVariance_(0.001),
99 landmarkDefaultAngVariance_(0.001),
100 landmarkDefaultLinVariance_(0.001),
101 waitForTransform_(
true),
102 waitForTransformDuration_(0.2),
103 useActionForGoal_(
false),
106 genScanMaxDepth_(4.0),
107 genScanMinDepth_(0.0),
109 genDepthDecimation_(1),
110 genDepthFillHolesSize_(0),
111 genDepthFillIterations_(1),
112 genDepthFillHolesError_(0.1),
113 scanCloudMaxPoints_(0),
116 tfThreadRunning_(
false),
117 stereoToDepth_(
false),
119 odomSensorSync_(
false),
120 rate_(
Parameters::defaultRtabmapDetectionRate()),
121 createIntermediateNodes_(
Parameters::defaultRtabmapCreateIntermediateNodes()),
122 maxMappingNodes_(
Parameters::defaultGridGlobalMaxNodes()),
123 alreadyRectifiedImages_(
Parameters::defaultRtabmapImagesAlreadyRectified()),
127 char * rosHomePath = getenv(
"ROS_HOME");
140 bool publishTf =
true;
141 double tfDelay = 0.05;
142 double tfTolerance = 0.1;
155 "anymore! It is replaced by \"rgbd_cameras\" parameter " 156 "used when \"subscribe_rgbd\" is true");
159 pnh.
param(
"publish_tf", publishTf, publishTf);
160 pnh.
param(
"tf_delay", tfDelay, tfDelay);
163 ROS_ERROR(
"tf_prefix parameter has been removed, use directly map_frame_id, odom_frame_id and frame_id parameters.");
165 pnh.
param(
"tf_tolerance", tfTolerance, tfTolerance);
183 if(pnh.
hasParam(
"scan_cloud_normal_k"))
185 ROS_WARN(
"rtabmap: Parameter \"scan_cloud_normal_k\" has been removed. RTAB-Map's parameter \"%s\" should be used instead. " 186 "The value is copied. Use \"%s\" to avoid this warning.",
187 Parameters::kMemLaserScanNormalK().c_str(),
188 Parameters::kMemLaserScanNormalK().c_str());
190 pnh.
getParam(
"scan_cloud_normal_k", value);
197 NODELET_WARN(
"Parameter \"flip_scan\" doesn't exist anymore. Rtabmap now " 198 "detects automatically if the laser is upside down with /tf, then if so, it " 199 "switches scan values.");
209 NODELET_INFO(
"rtabmap: ground_truth_frame_id = %s -> ground_truth_base_frame_id = %s",
215 NODELET_INFO(
"rtabmap: tf_delay = %f", tfDelay);
216 NODELET_INFO(
"rtabmap: tf_tolerance = %f", tfTolerance);
217 NODELET_INFO(
"rtabmap: odom_sensor_sync = %s",
odomSensorSync_?
"true":
"false");
218 bool subscribeStereo =
false;
219 pnh.
param(
"subscribe_stereo", subscribeStereo, subscribeStereo);
222 NODELET_INFO(
"rtabmap: stereo_to_depth = %s",
stereoToDepth_?
"true":
"false");
264 ParametersMap allParameters = Parameters::getDefaultParameters();
266 for(ParametersMap::iterator iter=allParameters.begin(); iter!=allParameters.end();)
268 if(iter->first.find(
"Odom") == 0)
270 allParameters.erase(iter++);
278 char * rosHomePath = getenv(
"ROS_HOME");
286 if(iter->first.find(
"Odom") == 0)
297 for(ParametersMap::iterator iter=allParameters.begin(); iter!=allParameters.end(); ++iter)
305 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(), vStr.c_str());
307 if(iter->first.compare(Parameters::kRtabmapWorkingDirectory()) == 0)
311 else if(iter->first.compare(Parameters::kKpDictionaryPath()) == 0)
317 else if(pnh.
getParam(iter->first, vBool))
319 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uBool2Str(vBool).c_str());
322 else if(pnh.
getParam(iter->first, vDouble))
324 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uNumber2Str(vDouble).c_str());
327 else if(pnh.
getParam(iter->first, vInt))
329 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uNumber2Str(vInt).c_str());
335 std::vector<std::string> argList =
getMyArgv();
336 char **
argv =
new char*[argList.size()];
337 bool deleteDbOnStart =
false;
338 for(
unsigned int i=0; i<argList.size(); ++i)
340 argv[i] = &argList[i].at(0);
341 if(strcmp(argv[i],
"--delete_db_on_start") == 0 || strcmp(argv[i],
"-d") == 0)
343 deleteDbOnStart =
true;
348 for(ParametersMap::const_iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
351 NODELET_INFO(
"Update RTAB-Map parameter \"%s\"=\"%s\" from arguments", iter->first.c_str(), iter->second.c_str());
355 for(std::map<std::string, std::pair<bool, std::string> >::const_iterator iter=Parameters::getRemovedParameters().begin();
356 iter!=Parameters::getRemovedParameters().end();
363 std::string paramValue;
368 else if(pnh.
getParam(iter->first, vBool))
372 else if(pnh.
getParam(iter->first, vDouble))
376 else if(pnh.
getParam(iter->first, vInt))
380 if(!paramValue.empty())
382 if(iter->second.first)
386 NODELET_WARN(
"Rtabmap: Parameter name changed: \"%s\" -> \"%s\". Please update your launch file accordingly. Value \"%s\" is still set to the new parameter name.",
387 iter->first.c_str(), iter->second.second.c_str(), paramValue.c_str());
391 if(iter->second.second.empty())
393 NODELET_ERROR(
"Rtabmap: Parameter \"%s\" doesn't exist anymore!",
394 iter->first.c_str());
398 NODELET_ERROR(
"Rtabmap: Parameter \"%s\" doesn't exist anymore! You may look at this similar parameter: \"%s\"",
399 iter->first.c_str(), iter->second.second.c_str());
408 bool subscribeScan2d =
false;
409 bool subscribeScan3d =
false;
410 pnh.
param(
"subscribe_scan", subscribeScan2d, subscribeScan2d);
411 pnh.
param(
"subscribe_scan_cloud", subscribeScan3d, subscribeScan3d);
412 bool gridFromDepth = Parameters::defaultGridFromDepth();
413 if((subscribeScan2d || subscribeScan3d) &&
parameters_.find(Parameters::kGridFromDepth()) ==
parameters_.end())
415 NODELET_WARN(
"Setting \"%s\" parameter to false (default true) as \"subscribe_scan\" or \"subscribe_scan_cloud\" is " 416 "true. The occupancy grid map will be constructed from " 417 "laser scans. To get occupancy grid map from cloud projection, set \"%s\" " 418 "to true. To suppress this warning, " 419 "add <param name=\"%s\" type=\"string\" value=\"false\"/>",
420 Parameters::kGridFromDepth().c_str(),
421 Parameters::kGridFromDepth().c_str(),
422 Parameters::kGridFromDepth().c_str());
425 Parameters::parse(
parameters_, Parameters::kGridFromDepth(), gridFromDepth);
426 if((subscribeScan2d || subscribeScan3d) &&
parameters_.find(Parameters::kGridRangeMax()) ==
parameters_.end() && !gridFromDepth)
428 NODELET_INFO(
"Setting \"%s\" parameter to 0 (default %f) as \"subscribe_scan\" or \"subscribe_scan_cloud\" is true and %s is false.",
429 Parameters::kGridRangeMax().c_str(),
430 Parameters::defaultGridRangeMax(),
431 Parameters::kGridFromDepth().c_str());
436 NODELET_INFO(
"Setting \"%s\" parameter to 0 (default %f) as \"subscribe_scan_cloud\" is true.",
437 Parameters::kIcpPointToPlaneRadius().c_str(),
438 Parameters::defaultIcpPointToPlaneRadius());
441 int regStrategy = Parameters::defaultRegStrategy();
442 Parameters::parse(
parameters_, Parameters::kRegStrategy(), regStrategy);
444 (regStrategy == Registration::kTypeIcp || regStrategy == Registration::kTypeVisIcp))
448 NODELET_WARN(
"Setting \"%s\" parameter to 10 (default 0) as \"subscribe_scan\" is " 449 "true and \"%s\" uses ICP. Proximity detection by space will be also done by merging close " 450 "scans. To disable, set \"%s\" to 0. To suppress this warning, " 451 "add <param name=\"%s\" type=\"string\" value=\"10\"/>",
452 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
453 Parameters::kRegStrategy().c_str(),
454 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
455 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
458 else if(subscribeScan3d)
460 NODELET_WARN(
"Setting \"%s\" parameter to 1 (default 0) as \"subscribe_scan_cloud\" is " 461 "true and \"%s\" uses ICP. To disable, set \"%s\" to 0. To suppress this warning, " 462 "add <param name=\"%s\" type=\"string\" value=\"1\"/>",
463 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
464 Parameters::kRegStrategy().c_str(),
465 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
466 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
471 int estimationType = Parameters::defaultVisEstimationType();
472 Parameters::parse(
parameters_, Parameters::kVisEstimationType(), estimationType);
474 bool subscribeRGBD =
false;
475 pnh.
param(
"rgbd_cameras", cameras, cameras);
476 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
477 if(subscribeRGBD && cameras> 1 && estimationType>0)
479 NODELET_WARN(
"Setting \"%s\" parameter to 0 (%d is not supported " 480 "for multi-cameras) as \"subscribe_rgbd\" is " 481 "true and \"rgbd_cameras\">1. Set \"%s\" to 0 to suppress this warning.",
482 Parameters::kVisEstimationType().c_str(),
484 Parameters::kVisEstimationType().c_str());
498 for(ParametersMap::iterator iter=dbParameters.begin(); iter!=dbParameters.end(); ++iter)
500 if(iter->first.compare(Parameters::kRtabmapWorkingDirectory()) == 0)
506 allParameters.find(iter->first) != allParameters.end() &&
507 allParameters.find(iter->first)->second.compare(iter->second) !=0)
509 NODELET_INFO(
"Update RTAB-Map parameter \"%s\"=\"%s\" from database", iter->first.c_str(), iter->second.c_str());
516 parameters_.insert(allParameters.begin(), allParameters.end());
521 NODELET_INFO(
"RTAB-Map detection rate = %f Hz",
rate_);
528 NODELET_INFO(
"Create intermediate nodes");
531 bool interOdomInfo =
false;
532 pnh.
getParam(
"subscribe_inter_odom_info", interOdomInfo);
535 NODELET_INFO(
"Subscribe to inter odom + info messages");
538 interOdomSyncSub_.subscribe(nh,
"inter_odom", 1);
543 NODELET_INFO(
"Subscribe to inter odom messages");
565 NODELET_WARN(
"Node paused... don't forget to call service \"resume\" to start rtabmap.");
572 NODELET_INFO(
"rtabmap: Deleted database \"%s\" (--delete_db_on_start or -d are set).",
databasePath_.c_str());
582 NODELET_INFO(
"rtabmap: database_path parameter not set, the map will not be saved.");
592 float xMin, yMin, gridCellSize;
596 NODELET_INFO(
"rtabmap: 2D occupancy grid map loaded (%dx%d).", map.cols, map.rows);
631 #ifdef WITH_OCTOMAP_MSGS 632 #ifdef RTABMAP_OCTOMAP 633 octomapBinarySrv_ = nh.
advertiseService(
"octomap_binary", &CoreWrapper::octomapBinaryCallback,
this);
634 octomapFullSrv_ = nh.
advertiseService(
"octomap_full", &CoreWrapper::octomapFullCallback,
this);
643 int optimizeIterations = 0;
644 Parameters::parse(
parameters_, Parameters::kOptimizerIterations(), optimizeIterations);
645 if(publishTf && optimizeIterations != 0)
652 NODELET_WARN(
"Graph optimization is disabled (%s=0), the tf between frame \"%s\" and odometry frame will not be published. You can safely ignore this warning if you are using map_optimizer node.",
653 Parameters::kOptimizerIterations().c_str(),
mapFrameId_.c_str());
662 NODELET_WARN(
"ROS param subscribe_depth, subscribe_stereo and subscribe_rgbd are false, but RTAB-Map " 663 "parameter \"%s\" is true! Please set subscribe_depth, subscribe_stereo or subscribe_rgbd " 664 "to true to use rtabmap node for RGB-D SLAM, set \"%s\" to false for loop closure " 665 "detection on images-only or set subscribe_rgb to true to localize a single RGB camera against pre-built 3D map.",
666 Parameters::kRGBDEnabled().c_str(),
667 Parameters::kRGBDEnabled().c_str());
683 NODELET_WARN(
"There is no image subscription, bag-of-words loop closure detection will be disabled...");
684 int kpMaxFeatures = Parameters::defaultKpMaxFeatures();
685 int registrationStrategy = Parameters::defaultRegStrategy();
686 Parameters::parse(
parameters_, Parameters::kKpMaxFeatures(), kpMaxFeatures);
687 Parameters::parse(
parameters_, Parameters::kRegStrategy(), registrationStrategy);
688 bool updateParams =
false;
689 if(kpMaxFeatures!= -1)
692 NODELET_WARN(
"Setting %s=-1 (bag-of-words disabled)", Parameters::kKpMaxFeatures().c_str());
698 NODELET_WARN(
"Setting %s=1 (ICP)", Parameters::kRegStrategy().c_str());
701 if(modifiedParameters.find(Parameters::kRGBDProximityPathMaxNeighbors()) == modifiedParameters.end())
705 NODELET_WARN(
"Setting \"%s\" parameter to 10 (default 0) as \"subscribe_scan\" is " 706 "true and \"%s\" uses ICP. Proximity detection by space will be also done by merging close " 707 "scans. To disable, set \"%s\" to 0. To suppress this warning, " 708 "add <param name=\"%s\" type=\"string\" value=\"10\"/>",
709 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
710 Parameters::kRegStrategy().c_str(),
711 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
712 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
717 NODELET_WARN(
"Setting \"%s\" parameter to 1 (default 0) as \"subscribe_scan_cloud\" is " 718 "true and \"%s\" uses ICP. To disable, set \"%s\" to 0. To suppress this warning, " 719 "add <param name=\"%s\" type=\"string\" value=\"1\"/>",
720 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
721 Parameters::kRegStrategy().c_str(),
722 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
723 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
738 nh.
setParam(iter->first, iter->second);
744 #ifdef WITH_APRILTAG_ROS 768 printf(
"rtabmap: Saving database/long-term memory... (located at %s)\n",
databasePath_.c_str());
772 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
776 printf(
"rtabmap: 2D occupancy grid map saved.\n");
790 if(!configFile.empty())
792 NODELET_INFO(
"Loading parameters from %s", configFile.c_str());
795 NODELET_WARN(
"Config file doesn't exist! It will be generated...");
797 Parameters::readINI(configFile.c_str(), parameters);
803 if(!configFile.empty())
805 printf(
"Saving parameters to %s\n", configFile.c_str());
809 printf(
"Config file doesn't exist, a new one will be created.\n");
811 Parameters::writeINI(configFile.c_str(),
parameters_);
815 NODELET_INFO(
"Parameters are not saved! (No configuration file provided...)");
833 msg.header.stamp = tfExpiration;
847 if(stamp.
toSec() == 0.0)
849 ROS_WARN(
"A null stamp has been detected in the input topic. Make sure the stamp is set.");
867 NODELET_ERROR(
"Input type must be image=mono8,mono16,rgb8,bgr8");
888 NODELET_WARN(
"RTAB-Map could not process the data received! (ROS id = %d)", ptrImage->header.seq);
897 NODELET_WARN(
"Ignoring received image because its sequence ID=0. Please " 898 "set \"Mem/GenerateIds\"=\"true\" to ignore ros generated sequence id. " 899 "Use only \"Mem/GenerateIds\"=\"false\" for once-time run of RTAB-Map and " 900 "when you need to have IDs output of RTAB-map synchronised with the source " 901 "image sequence ID.");
903 NODELET_INFO(
"rtabmap: Update rate=%fs, Limit=%fs, Processing time = %fs (%d local nodes)",
921 static bool shown =
false;
924 NODELET_WARN(
"We received odometry message, but we cannot get the " 925 "corresponding TF %s->%s at data stamp %fs (odom msg stamp is %fs). Make sure TF of odometry is " 926 "also published to get more accurate pose estimation. This " 927 "warning is only printed once.", odomMsg->header.frame_id.c_str(),
frameId_.c_str(), stamp.
toSec(), odomMsg->header.stamp.toSec());
930 stamp = odomMsg->header.stamp;
940 UWARN(
"Odometry is reset (identity pose or high variance (%f) detected). Increment map id!",
MAX(odomMsg->pose.covariance[0], odomMsg->twist.covariance[0]));
953 double variance = odomMsg->twist.covariance[0];
957 covariance = cv::Mat(6,6,CV_64FC1, (
void*)odomMsg->pose.covariance.data()).clone();
962 covariance = cv::Mat(6,6,CV_64FC1, (
void*)odomMsg->twist.covariance.data()).clone();
965 if(
uIsFinite(covariance.at<
double>(0,0)) &&
966 covariance.at<
double>(0,0) != 1.0 &&
967 covariance.at<
double>(0,0)>0.0)
978 bool ignoreFrame =
false;
979 if(stamp.
toSec() == 0.0)
981 ROS_WARN(
"A null stamp has been detected in the input topics. Make sure the stamp in all input topics is set.");
1002 else if(!ignoreFrame)
1025 UWARN(
"Odometry is reset (identity pose detected). Increment map id!");
1034 bool ignoreFrame =
false;
1035 if(stamp.
toSec() == 0.0)
1037 ROS_WARN(
"A null stamp has been detected in the input topics. Make sure the stamp in all input topics is set.");
1058 else if(!ignoreFrame)
1069 const nav_msgs::OdometryConstPtr & odomMsg,
1070 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1071 const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
1072 const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
1073 const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
1074 const sensor_msgs::LaserScan& scan2dMsg,
1075 const sensor_msgs::PointCloud2& scan3dMsg,
1076 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1077 const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
1078 const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPoints,
1079 const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3d,
1080 const std::vector<cv::Mat> & localDescriptors)
1085 odomFrameId = odomMsg->header.frame_id;
1086 if(!scan2dMsg.ranges.empty())
1088 if(!
odomUpdate(odomMsg, scan2dMsg.header.stamp))
1093 else if(!scan3dMsg.data.empty())
1095 if(!
odomUpdate(odomMsg, scan3dMsg.header.stamp))
1100 else if(imageMsgs.size() == 0 || imageMsgs[0].get() == 0 || !
odomUpdate(odomMsg, imageMsgs[0]->header.stamp))
1105 else if(!scan2dMsg.ranges.empty())
1112 else if(!scan3dMsg.data.empty())
1119 else if(imageMsgs.size() == 0 || imageMsgs[0].get() == 0 || !
odomTFUpdate(imageMsgs[0]->header.stamp))
1132 globalDescriptorMsgs,
1139 const std::string & odomFrameId,
1140 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1141 const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
1142 const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
1143 const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
1144 const sensor_msgs::LaserScan& scan2dMsg,
1145 const sensor_msgs::PointCloud2& scan3dMsg,
1146 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1147 const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
1148 const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPointsMsgs,
1149 const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3dMsgs,
1150 const std::vector<cv::Mat> & localDescriptorsMsgs)
1154 std::vector<rtabmap::CameraModel> cameraModels;
1155 std::vector<cv::KeyPoint> keypoints;
1156 std::vector<cv::Point3f> points;
1157 cv::Mat descriptors;
1172 localDescriptorsMsgs,
1177 NODELET_ERROR(
"Could not convert rgb/depth msgs! Aborting rtabmap update...");
1182 if(!depth.empty() && depth.type() == CV_32FC1 &&
uStr2Bool(
parameters_.at(Parameters::kMemSaveDepth16Format())))
1185 static bool shown =
false;
1188 NODELET_WARN(
"Save depth data to 16 bits format: depth type detected is " 1189 "32FC1, use 16UC1 depth format to avoid this conversion " 1190 "(or set parameter \"Mem/SaveDepth16Format=false\" to use " 1191 "32bits format). This message is only printed once...");
1197 bool genMaxScanPts = 0;
1198 if(!scan2dMsg.ranges.empty() && !scan3dMsg.data.empty() && !depth.empty() &&
genScan_)
1200 pcl::PointCloud<pcl::PointXYZ>::Ptr scanCloud2d(
new pcl::PointCloud<pcl::PointXYZ>);
1201 *scanCloud2d = util3d::laserScanFromDepthImages(
1206 genMaxScanPts += depth.cols;
1209 else if(!scan2dMsg.ranges.empty())
1222 NODELET_ERROR(
"Could not convert laser scan msg! Aborting rtabmap update...");
1226 else if(!scan3dMsg.data.empty())
1238 NODELET_ERROR(
"Could not convert 3d laser scan msg! Aborting rtabmap update...");
1245 for(
size_t i=0; i<cameraModels.size(); ++i)
1256 ROS_ERROR(
"decimation (%d) not valid for image size %dx%d! Aborting depth generation from scan...",
1285 if(userDataMsg.get())
1291 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1312 if(odomInfoMsg.get())
1317 if(!globalDescriptorMsgs.empty())
1322 if(!keypoints.empty())
1324 UASSERT(points.empty() || points.size() == keypoints.size());
1325 UASSERT(descriptors.empty() || descriptors.rows == (int)keypoints.size());
1339 const nav_msgs::OdometryConstPtr & odomMsg,
1340 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1343 const sensor_msgs::CameraInfo& leftCamInfoMsg,
1344 const sensor_msgs::CameraInfo& rightCamInfoMsg,
1345 const sensor_msgs::LaserScan& scan2dMsg,
1346 const sensor_msgs::PointCloud2& scan3dMsg,
1347 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1348 const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
1349 const std::vector<rtabmap_ros::KeyPoint> & localKeyPointsMsg,
1350 const std::vector<rtabmap_ros::Point3f> & localPoints3dMsg,
1351 const cv::Mat & localDescriptorsMsg)
1356 odomFrameId = odomMsg->header.frame_id;
1357 if(!scan2dMsg.ranges.empty())
1359 if(!
odomUpdate(odomMsg, scan2dMsg.header.stamp))
1364 else if(!scan3dMsg.data.empty())
1366 if(!
odomUpdate(odomMsg, scan3dMsg.header.stamp))
1371 else if(leftImageMsg.get() == 0 || !
odomUpdate(odomMsg, leftImageMsg->header.stamp))
1376 else if(!scan2dMsg.ranges.empty())
1383 else if(!scan3dMsg.data.empty())
1390 else if(leftImageMsg.get() == 0 || !
odomTFUpdate(leftImageMsg->header.stamp))
1413 NODELET_ERROR(
"Could not convert stereo msgs! Aborting rtabmap update...");
1424 if(disparity.empty())
1426 NODELET_ERROR(
"Could not compute disparity image (\"stereo_to_depth\" is true)!");
1436 NODELET_ERROR(
"Could not compute depth image (\"stereo_to_depth\" is true)!");
1439 UASSERT(depth.type() == CV_16UC1 || depth.type() == CV_32FC1);
1443 if(depth.type() == CV_16UC1)
1451 imgDepth->image = depth;
1452 imgDepth->header = leftImageMsg->header;
1453 std::vector<cv_bridge::CvImageConstPtr> rgbImages(1);
1454 std::vector<cv_bridge::CvImageConstPtr> depthImages(1);
1455 std::vector<sensor_msgs::CameraInfo> cameraInfos(1);
1456 rgbImages[0] = leftImageMsg;
1457 depthImages[0] = imgDepth;
1458 cameraInfos[0] = leftCamInfoMsg;
1460 std::vector<std::vector<rtabmap_ros::KeyPoint> > localKeyPointsMsgs;
1461 std::vector<std::vector<rtabmap_ros::Point3f> > localPoints3dMsgs;
1462 std::vector<cv::Mat> localDescriptorsMsgs;
1463 if(!localKeyPointsMsg.empty())
1465 localKeyPointsMsgs.push_back(localKeyPointsMsg);
1467 if(!localPoints3dMsg.empty())
1469 localPoints3dMsgs.push_back(localPoints3dMsg);
1471 if(!localDescriptorsMsg.empty())
1473 localDescriptorsMsgs.push_back(localDescriptorsMsg);
1476 rtabmap_ros::UserDataConstPtr(),
1477 rgbImages, depthImages, cameraInfos,
1478 scan2dMsg, scan3dMsg,
1480 globalDescriptorMsgs, localKeyPointsMsgs, localPoints3dMsgs, localDescriptorsMsgs);
1485 if(!scan2dMsg.ranges.empty())
1498 NODELET_ERROR(
"Could not convert laser scan msg! Aborting rtabmap update...");
1502 else if(!scan3dMsg.data.empty())
1514 NODELET_ERROR(
"Could not convert 3d laser scan msg! Aborting rtabmap update...");
1520 if(userDataMsg.get())
1526 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1547 if(odomInfoMsg.get())
1552 if(!globalDescriptorMsgs.empty())
1557 std::vector<cv::KeyPoint> keypoints;
1558 std::vector<cv::Point3f> points;
1559 if(!localKeyPointsMsg.empty())
1563 if(!localPoints3dMsg.empty())
1568 if(!keypoints.empty())
1570 UASSERT(points.empty() || points.size() == keypoints.size());
1571 UASSERT(localDescriptorsMsg.empty() || localDescriptorsMsg.rows == (int)keypoints.size());
1572 data.
setFeatures(keypoints, points, localDescriptorsMsg);
1586 const nav_msgs::OdometryConstPtr & odomMsg,
1587 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1588 const sensor_msgs::LaserScan& scan2dMsg,
1589 const sensor_msgs::PointCloud2& scan3dMsg,
1590 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1591 const rtabmap_ros::GlobalDescriptor & globalDescriptor)
1596 odomFrameId = odomMsg->header.frame_id;
1597 if(!scan2dMsg.ranges.empty())
1599 if(!
odomUpdate(odomMsg, scan2dMsg.header.stamp))
1604 else if(!scan3dMsg.data.empty())
1606 if(!
odomUpdate(odomMsg, scan3dMsg.header.stamp))
1616 else if(!scan2dMsg.ranges.empty())
1623 else if(!scan3dMsg.data.empty())
1636 if(!scan2dMsg.ranges.empty())
1649 NODELET_ERROR(
"Could not convert laser scan msg! Aborting rtabmap update...");
1653 else if(!scan3dMsg.data.empty())
1665 NODELET_ERROR(
"Could not convert 3d laser scan msg! Aborting rtabmap update...");
1671 if(userDataMsg.get())
1677 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1688 cv::Mat rgb = cv::Mat::zeros(3,4,CV_8UC1);
1689 cv::Mat depth = cv::Mat::zeros(3,4,CV_16UC1);
1695 scan.
localTransform()*
Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0),
1709 if(odomInfoMsg.get())
1714 if(!globalDescriptor.data.empty())
1730 const nav_msgs::OdometryConstPtr & odomMsg,
1731 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1732 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg)
1737 odomFrameId = odomMsg->header.frame_id;
1738 if(!
odomUpdate(odomMsg, odomMsg->header.stamp))
1744 if(userDataMsg.get())
1750 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1761 cv::Mat rgb = cv::Mat::zeros(3,4,CV_8UC1);
1762 cv::Mat depth = cv::Mat::zeros(3,4,CV_16UC1);
1768 Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0),
1781 if(odomInfoMsg.get())
1800 const std::string & odomFrameId,
1801 const cv::Mat & odomCovariance,
1808 for(std::list<std::pair<nav_msgs::Odometry, rtabmap_ros::OdomInfo> >::iterator iter=
interOdoms_.begin(); iter!=
interOdoms_.end();)
1816 double variance = iter->first.twist.covariance[0];
1820 covariance = cv::Mat(6,6,CV_64FC1, (
void*)iter->first.pose.covariance.data()).clone();
1825 covariance = cv::Mat(6,6,CV_64FC1, (
void*)iter->first.twist.covariance.data()).clone();
1827 if(!
uIsFinite(covariance.at<
double>(0,0)) || covariance.at<
double>(0,0)<=0.0f)
1829 covariance = cv::Mat::eye(6,6,CV_64FC1);
1844 cv::Mat rgb = cv::Mat::zeros(3,4,CV_8UC1);
1845 cv::Mat depth = cv::Mat::zeros(3,4,CV_16UC1);
1851 Transform(0,0,1,0, -1,0,0,0, 0,-1,0,0),
1862 std::map<std::string, float> externalStats;
1863 std::vector<float> odomVelocity;
1864 if(iter->second.timeEstimation != 0.0f)
1871 odomVelocity.resize(6);
1877 odomVelocity[3] = roll/info.
interval;
1878 odomVelocity[4] = pitch/info.
interval;
1879 odomVelocity[5] = yaw/info.
interval;
1883 rtabmap_.
process(interData, interOdom, covariance, odomVelocity, externalStats);
1916 if(!sensorToBase.
isNull())
1919 globalPose *= sensorToBase;
1931 globalPose *= correction;
1935 NODELET_WARN(
"Could not adjust global pose accordingly to latest odometry pose. " 1936 "If odometry is small since it received the global pose and " 1937 "covariance is large, this should not be a problem.");
1939 cv::Mat globalPoseCovariance = cv::Mat(6,6, CV_64FC1, (
void*)
globalPose_.pose.covariance.data()).clone();
1962 if(!landmarks.empty())
1984 if(!localTransform.
isNull())
1987 data.
setIMU(
IMU(cv::Vec4d(q.x(), q.y(), q.z(), q.w()), cv::Mat::eye(3,3,CV_64FC1),
1988 cv::Vec3d(), cv::Mat(),
1989 cv::Vec3d(), cv::Mat(),
1995 ROS_WARN(
"We are receiving imu data (buffer=%d), but cannot interpolate " 1996 "imu transform at time %f. IMU won't be added to graph.",
2001 double timeRtabmap = 0.0;
2002 double timeUpdateMaps = 0.0;
2003 double timePublishMaps = 0.0;
2006 if(covariance.empty() || !
uIsFinite(covariance.at<
double>(0,0)) || covariance.at<
double>(0,0)<=0.0
f)
2008 covariance = cv::Mat::eye(6,6,CV_64FC1);
2023 std::map<std::string, float> externalStats;
2024 std::vector<float> odomVelocity;
2031 odomVelocity.resize(6);
2034 odomVelocity[0] = x/odomInfo.
interval;
2035 odomVelocity[1] = y/odomInfo.
interval;
2036 odomVelocity[2] = z/odomInfo.
interval;
2037 odomVelocity[3] = roll/odomInfo.
interval;
2038 odomVelocity[4] = pitch/odomInfo.
interval;
2039 odomVelocity[5] = yaw/odomInfo.
interval;
2048 if(
rtabmap_.
process(data, odom, covariance, odomVelocity, externalStats))
2050 timeRtabmap = timer.
ticks();
2067 geometry_msgs::PoseWithCovarianceStamped poseMsg;
2069 poseMsg.header.stamp =
stamp;
2071 poseMsg.pose.covariance;
2073 memcpy(poseMsg.pose.covariance.data(), cov.data, cov.total()*
sizeof(double));
2079 std::map<int, rtabmap::Signature> tmpSignature;
2081 filteredPoses.size() == 0 ||
2090 filteredPoses.insert(std::make_pair(0,
mapToOdom_*odom));
2095 std::map<int, Transform> nearestPoses;
2097 for(std::map<int, float>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
2099 std::map<int, Transform>::iterator pter = filteredPoses.find(iter->first);
2100 if(pter != filteredPoses.end())
2102 nearestPoses.insert(*pter);
2106 std::set<int> onPath;
2110 onPath.insert(nextNodes.begin(), nextNodes.end());
2112 for(std::map<int, Transform>::iterator iter=filteredPoses.begin(); iter!=filteredPoses.end(); ++iter)
2114 if(iter->first == 0 || onPath.find(iter->first) != onPath.end())
2116 nearestPoses.insert(*iter);
2118 else if(onPath.empty())
2124 filteredPoses = nearestPoses;
2135 timeUpdateMaps = timer.
ticks();
2164 std_msgs::Bool result;
2186 Transform goalLocalTransform = Transform::getIdentity();
2210 NODELET_ERROR(
"Planning: Local map broken, current goal id=%d (the robot may have moved to far from planned nodes)",
2215 std_msgs::Bool result;
2216 result.data =
false;
2227 timePublishMaps = timer.
ticks();
2232 timeRtabmap = timer.
ticks();
2234 NODELET_INFO(
"rtabmap (%d): Rate=%.2fs, Limit=%.3fs, RTAB-Map=%.4fs, Maps update=%.4fs pub=%.4fs (local map=%d, WM=%d)",
2244 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeRtabmap/ms"), timeRtabmap*1000.0
f));
2245 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeUpdatingMaps/ms"), timeUpdateMaps*1000.0f));
2246 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimePublishing/ms"), timePublishMaps*1000.0f));
2247 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeTotal/ms"), (timeRtabmap+timeUpdateMaps+timePublishMaps)*1000.0f));
2251 NODELET_WARN(
"Ignoring received image because its sequence ID=0. Please " 2252 "set \"Mem/GenerateIds\"=\"true\" to ignore ros generated sequence id. " 2253 "Use only \"Mem/GenerateIds\"=\"false\" for once-time run of RTAB-Map and " 2254 "when you need to have IDs output of RTAB-map synchronized with the source " 2255 "image sequence ID.");
2264 static bool warningShow =
false;
2267 ROS_WARN(
"Overwriting previous user data set. When asynchronous user " 2268 "data input topic rate is higher than " 2269 "map update rate (current %s=%f), only latest data is saved " 2270 "in the next node created. This message will is shown only once.",
2271 Parameters::kRtabmapDetectionRate().c_str(),
rate_);
2290 double error = 10.0;
2291 if(gpsFixMsg->position_covariance_type != sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN)
2293 double variance =
uMax3(gpsFixMsg->position_covariance.at(0), gpsFixMsg->position_covariance.at(4), gpsFixMsg->position_covariance.at(8));
2296 error =
sqrt(variance);
2300 gpsFixMsg->header.stamp.toSec(),
2301 gpsFixMsg->longitude,
2302 gpsFixMsg->latitude,
2303 gpsFixMsg->altitude,
2309 #ifdef WITH_APRILTAG_ROS 2310 void CoreWrapper::tagDetectionsAsyncCallback(
const apriltag_ros::AprilTagDetectionArray & tagDetections)
2314 for(
unsigned int i=0; i<tagDetections.detections.size(); ++i)
2316 if(tagDetections.detections[i].id.size() >= 1)
2318 geometry_msgs::PoseWithCovarianceStamped p = tagDetections.detections[i].pose;
2319 p.header = tagDetections.header;
2320 if(!tagDetections.detections[i].pose.header.frame_id.empty())
2322 p.header.frame_id = tagDetections.detections[i].pose.header.frame_id;
2324 static bool warned =
false;
2326 !tagDetections.header.frame_id.empty() &&
2327 tagDetections.detections[i].pose.header.frame_id.compare(tagDetections.header.frame_id)!=0)
2329 NODELET_WARN(
"frame_id set for individual tag detections (%s) doesn't match the frame_id of the message (%s), " 2330 "the resulting pose of the tag may be wrong. This message is only printed once.",
2331 tagDetections.detections[i].pose.header.frame_id.c_str(), tagDetections.header.frame_id.c_str());
2335 if(!tagDetections.detections[i].pose.header.stamp.isZero())
2337 p.header.stamp = tagDetections.detections[i].pose.header.stamp;
2339 static bool warned =
false;
2341 !tagDetections.header.stamp.isZero() &&
2342 tagDetections.detections[i].pose.header.stamp != tagDetections.header.stamp)
2344 NODELET_WARN(
"stamp set for individual tag detections (%f) doesn't match the stamp of the message (%f), " 2345 "the resulting pose of the tag may be wrongly interpolated. This message is only printed once.",
2346 tagDetections.detections[i].pose.header.stamp.toSec(), tagDetections.header.stamp.toSec());
2350 uInsert(
tags_, std::make_pair(tagDetections.detections[i].id[0], p));
2361 if(msg->orientation.x == 0 && msg->orientation.y == 0 && msg->orientation.z == 0 && msg->orientation.w == 0)
2363 UERROR(
"IMU received doesn't have orientation set, it is ignored.");
2367 Transform orientation(0,0,0, msg->orientation.x, msg->orientation.y, msg->orientation.z, msg->orientation.w);
2369 if(
imus_.size() > 1000)
2375 ROS_ERROR(
"IMU frame_id has changed from %s to %s! Are " 2376 "multiple nodes publishing " 2377 "on same topic %s? IMU buffer is cleared!",
2379 msg->header.frame_id.c_str(),
2396 interOdoms_.push_back(std::make_pair(*msg, rtabmap_ros::OdomInfo()));
2404 interOdoms_.push_back(std::make_pair(*msg1, *msg2));
2423 const std::string & label,
2427 double * planningTime)
2451 *planningTime = 0.0;
2454 bool success =
false;
2460 *planningTime = timer.
elapsed();
2463 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
2469 if(poses.size() == 0)
2471 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
2476 std_msgs::Bool result;
2487 NODELET_INFO(
"Planning: Path successfully created (size=%d)", (
int)poses.size());
2496 Transform goalLocalTransform = Transform::getIdentity();
2497 if(!goalFrameId_.empty() && goalFrameId_.compare(
frameId_) != 0)
2514 std::stringstream stream;
2515 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
2517 if(iter != poses.begin())
2521 stream << iter->first;
2523 NODELET_INFO(
"Global path: [%s]", stream.str().c_str());
2532 else if(!label.empty())
2534 NODELET_ERROR(
"Planning: Node with label \"%s\" not found!", label.c_str());
2540 NODELET_ERROR(
"Planning: Could not plan to node %d! The node is not in map's graph (look for warnings before this message for more details).",
id);
2544 NODELET_ERROR(
"Planning: Could not plan to landmark %d! The landmark is not in map's graph (look for warnings before this message for more details).",
id);
2561 std_msgs::Bool result;
2562 result.data =
false;
2573 if(!msg->header.frame_id.empty() &&
mapFrameId_.compare(msg->header.frame_id) != 0)
2578 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
2579 msg->header.frame_id.c_str(),
mapFrameId_.c_str());
2582 std_msgs::Bool result;
2583 result.data =
false;
2588 targetPose = t * targetPose;
2597 if(msg->node_id == 0 && msg->node_label.empty())
2602 std_msgs::Bool result;
2603 result.data =
false;
2622 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(), vStr.c_str());
2623 iter->second = vStr;
2625 else if(nh.
getParam(iter->first, vBool))
2627 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uBool2Str(vBool).c_str());
2630 else if(nh.
getParam(iter->first, vInt))
2635 else if(nh.
getParam(iter->first, vDouble))
2688 nh.
setParam(
"is_rtabmap_paused",
true);
2704 nh.
setParam(
"is_rtabmap_paused",
false);
2722 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
2726 printf(
"rtabmap: 2D occupancy grid map saved.\n");
2752 NODELET_INFO(
"Backup: Reloading memory... done!");
2763 nh.
setParam(rtabmap::Parameters::kMemIncrementalMemory(),
"false");
2775 nh.
setParam(rtabmap::Parameters::kMemIncrementalMemory(),
"true");
2808 NODELET_INFO(
"rtabmap: Getting node data (%d node(s), images=%s scan=%s grid=%s user_data=%s)...",
2809 (
int)req.ids.size(),
2810 req.images?
"true":
"false",
2811 req.scan?
"true":
"false",
2812 req.grid?
"true":
"false",
2813 req.user_data?
"true":
"false");
2819 for(
size_t i=0; i<req.ids.size(); ++i)
2821 int id = req.ids[i];
2828 res.data.push_back(msg);
2832 return !res.data.empty();
2837 NODELET_INFO(
"rtabmap: Getting map (global=%s optimized=%s graphOnly=%s)...",
2838 req.global?
"true":
"false",
2839 req.optimized?
"true":
"false",
2840 req.graphOnly?
"true":
"false");
2841 std::map<int, Signature> signatures;
2842 std::map<int, Transform> poses;
2843 std::multimap<int, rtabmap::Link> constraints;
2871 NODELET_INFO(
"rtabmap: Getting map (global=%s optimized=%s with_images=%s with_scans=%s with_user_data=%s with_grids=%s)...",
2872 req.global?
"true":
"false",
2873 req.optimized?
"true":
"false",
2874 req.with_images?
"true":
"false",
2875 req.with_scans?
"true":
"false",
2876 req.with_user_data?
"true":
"false",
2877 req.with_grids?
"true":
"false");
2878 std::map<int, Signature> signatures;
2879 std::map<int, Transform> poses;
2880 std::multimap<int, rtabmap::Link> constraints;
2893 req.with_global_descriptors);
2913 NODELET_WARN(
"/get_proj_map service is deprecated! Call /get_grid_map service " 2914 "instead with <param name=\"%s\" type=\"string\" value=\"true\"/>. " 2915 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see " 2916 "all occupancy grid parameters.",
2917 Parameters::kGridFromDepth().c_str());
2921 NODELET_WARN(
"/get_proj_map service is deprecated! Call /get_grid_map service instead.");
2928 NODELET_WARN(
"/get_grid_map service is deprecated! Call /get_map service instead.");
2939 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
2945 res.map.info.resolution = gridCellSize;
2946 res.map.info.origin.position.x = 0.0;
2947 res.map.info.origin.position.y = 0.0;
2948 res.map.info.origin.position.z = 0.0;
2949 res.map.info.origin.orientation.x = 0.0;
2950 res.map.info.origin.orientation.y = 0.0;
2951 res.map.info.origin.orientation.z = 0.0;
2952 res.map.info.origin.orientation.w = 1.0;
2954 res.map.info.width = pixels.cols;
2955 res.map.info.height = pixels.rows;
2956 res.map.info.origin.position.x = xMin;
2957 res.map.info.origin.position.y = yMin;
2958 res.map.data.resize(res.map.info.width * res.map.info.height);
2960 memcpy(res.map.data.data(), pixels.data, res.map.info.width * res.map.info.height);
2980 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
2986 res.map.info.resolution = gridCellSize;
2987 res.map.info.origin.position.x = 0.0;
2988 res.map.info.origin.position.y = 0.0;
2989 res.map.info.origin.position.z = 0.0;
2990 res.map.info.origin.orientation.x = 0.0;
2991 res.map.info.origin.orientation.y = 0.0;
2992 res.map.info.origin.orientation.z = 0.0;
2993 res.map.info.origin.orientation.w = 1.0;
2995 res.map.info.width = pixels.cols;
2996 res.map.info.height = pixels.rows;
2997 res.map.info.origin.position.x = xMin;
2998 res.map.info.origin.position.y = yMin;
2999 res.map.data.resize(res.map.info.width * res.map.info.height);
3001 memcpy(res.map.data.data(), pixels.data, res.map.info.width * res.map.info.height);
3024 std::map<int, Transform> poses;
3025 std::multimap<int, rtabmap::Link> constraints;
3026 std::map<int, Signature > signatures;
3041 rtabmap_ros::MapDataPtr msg(
new rtabmap_ros::MapData);
3042 msg->header.stamp = now;
3056 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
3057 msg->header.stamp = now;
3072 geometry_msgs::PoseArrayPtr msg(
new geometry_msgs::PoseArray);
3073 msg->header.stamp = now;
3075 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end() && iter->first<0; ++iter)
3077 geometry_msgs::Pose p;
3079 msg->poses.push_back(p);
3084 visualization_msgs::Marker marker;
3086 marker.header.stamp = now;
3087 marker.ns =
"landmarks";
3088 marker.id = iter->first;
3089 marker.action = visualization_msgs::Marker::ADD;
3090 marker.pose.position.x = iter->second.x();
3091 marker.pose.position.y = iter->second.y();
3092 marker.pose.position.z = iter->second.z();
3093 marker.pose.orientation.x = 0.0;
3094 marker.pose.orientation.y = 0.0;
3095 marker.pose.orientation.z = 0.0;
3096 marker.pose.orientation.w = 1.0;
3099 marker.scale.z = 0.35;
3100 marker.color.a = 0.5;
3101 marker.color.r = 1.0;
3102 marker.color.g = 1.0;
3103 marker.color.b = 0.0;
3106 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3109 markers.markers.push_back(marker);
3120 std::map<int, Transform> filteredPoses(poses.lower_bound(1), poses.end());
3123 std::map<int, Transform> nearestPoses;
3124 std::map<int, float> nodes = graph::findNearestNodes(filteredPoses, filteredPoses.rbegin()->second,
maxMappingNodes_);
3125 for(std::map<int, float>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
3127 std::map<int, Transform>::iterator pter = filteredPoses.find(iter->first);
3128 if(pter != filteredPoses.end())
3130 nearestPoses.insert(*pter);
3134 if(signatures.size())
3157 if(pubLabels || pubPath)
3159 if(poses.size() && signatures.size())
3164 path.poses.resize(poses.size());
3167 for(std::map<int, Signature>::const_iterator iter=signatures.begin();
3168 iter!=signatures.end();
3171 std::map<int, Transform>::const_iterator poseIter= poses.find(iter->first);
3172 if(poseIter!=poses.end())
3177 if(!iter->second.getLabel().empty())
3179 visualization_msgs::Marker marker;
3181 marker.header.stamp = now;
3182 marker.ns =
"labels";
3183 marker.id = iter->first;
3184 marker.action = visualization_msgs::Marker::ADD;
3185 marker.pose.position.x = poseIter->second.x();
3186 marker.pose.position.y = poseIter->second.y();
3187 marker.pose.position.z = poseIter->second.z();
3188 marker.pose.orientation.x = 0.0;
3189 marker.pose.orientation.y = 0.0;
3190 marker.pose.orientation.z = 0.0;
3191 marker.pose.orientation.w = 1.0;
3194 marker.scale.z = 0.5;
3195 marker.color.a = 0.7;
3196 marker.color.r = 1.0;
3197 marker.color.g = 0.0;
3198 marker.color.b = 0.0;
3200 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3201 marker.text = iter->second.getLabel();
3203 markers.markers.push_back(marker);
3206 visualization_msgs::Marker marker;
3208 marker.header.stamp = now;
3210 marker.id = iter->first;
3211 marker.action = visualization_msgs::Marker::ADD;
3212 marker.pose.position.x = poseIter->second.x();
3213 marker.pose.position.y = poseIter->second.y();
3214 marker.pose.position.z = poseIter->second.z();
3215 marker.pose.orientation.x = 0.0;
3216 marker.pose.orientation.y = 0.0;
3217 marker.pose.orientation.z = 0.0;
3218 marker.pose.orientation.w = 1.0;
3221 marker.scale.z = 0.2;
3222 marker.color.a = 0.5;
3223 marker.color.r = 1.0;
3224 marker.color.g = 1.0;
3225 marker.color.b = 1.0;
3228 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3231 markers.markers.push_back(marker);
3237 path.poses.at(oi).header.stamp =
ros::Time(iter->second.getStamp());
3243 if(pubLabels && markers.markers.size())
3250 path.header.stamp = now;
3251 path.poses.resize(oi);
3259 UWARN(
"No subscribers, don't need to publish!");
3277 Transform coordinateTransform = Transform::getIdentity();
3278 if(!req.goal.header.frame_id.empty() &&
mapFrameId_.compare(req.goal.header.frame_id) != 0)
3281 if(coordinateTransform.
isNull())
3283 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
3284 req.goal.header.frame_id.c_str(),
mapFrameId_.c_str());
3287 pose = coordinateTransform * pose;
3292 coordinateTransform = coordinateTransform.
inverse();
3297 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
3298 res.plan.header.frame_id = req.goal.header.frame_id;
3299 res.plan.header.stamp = req.goal.header.stamp;
3300 if(poses.size() == 0)
3302 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
3305 res.plan.poses.resize(1);
3310 res.plan.poses.resize(poses.size());
3312 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3314 res.plan.poses[oi].header = res.plan.header;
3320 res.plan.poses.resize(res.plan.poses.size()+1);
3321 res.plan.poses[res.plan.poses.size()-1].header = res.plan.header;
3327 std::stringstream stream;
3328 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3330 if(iter != poses.begin())
3334 stream << iter->first;
3336 NODELET_INFO(
"Planned path: [%s]", stream.str().c_str());
3347 if(req.goal_node <= 0)
3352 if(req.goal_node > 0 || !pose.
isNull())
3354 Transform coordinateTransform = Transform::getIdentity();
3356 if(!pose.
isNull() && !req.goal.header.frame_id.empty() &&
mapFrameId_.compare(req.goal.header.frame_id) != 0)
3359 if(coordinateTransform.
isNull())
3361 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
3362 req.goal.header.frame_id.c_str(),
mapFrameId_.c_str());
3367 pose = coordinateTransform * pose;
3373 coordinateTransform = coordinateTransform.
inverse();
3379 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
3381 res.plan.header.stamp = req.goal_node > 0?
ros::Time::now():req.goal.header.stamp;
3382 if(poses.size() == 0)
3384 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
3389 res.plan.poses.resize(1);
3390 res.plan.nodeIds.resize(1);
3392 res.plan.nodeIds[0] = 0;
3397 res.plan.poses.resize(poses.size());
3398 res.plan.nodeIds.resize(poses.size());
3400 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3403 res.plan.nodeIds[oi] = iter->first;
3408 res.plan.poses.resize(res.plan.poses.size()+1);
3409 res.plan.nodeIds.resize(res.plan.nodeIds.size()+1);
3412 res.plan.nodeIds[res.plan.nodeIds.size()-1] = 0;
3416 std::stringstream stream;
3417 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3419 if(iter != poses.begin())
3423 stream << iter->first;
3425 NODELET_INFO(
"Planned path: [%s]", stream.str().c_str());
3435 double planningTime = 0.0;
3437 const std::vector<std::pair<int, Transform> > & path =
rtabmap_.
getPath();
3438 res.path_ids.resize(path.size());
3439 res.path_poses.resize(path.size());
3440 res.planning_time = planningTime;
3441 for(
unsigned int i=0; i<path.size(); ++i)
3443 res.path_ids[i] = path[i].first;
3461 std_msgs::Bool result;
3462 result.data =
false;
3480 NODELET_INFO(
"Set label \"%s\" to node %d", req.node_label.c_str(), req.node_id);
3484 NODELET_INFO(
"Set label \"%s\" to last node", req.node_label.c_str());
3491 NODELET_ERROR(
"Could not set label \"%s\" to node %d", req.node_label.c_str(), req.node_id);
3495 NODELET_ERROR(
"Could not set label \"%s\" to last node", req.node_label.c_str());
3506 res.ids =
uKeys(labels);
3508 NODELET_INFO(
"List labels service: %d labels found.", (
int)res.labels.size());
3517 ROS_INFO(
"Adding external link %d -> %d", req.link.fromId, req.link.toId);
3526 ROS_INFO(
"Get nodes in radius (%f): node_id=%d pose=(%f,%f,%f)", req.radius, req.node_id, req.x, req.y, req.z);
3527 std::map<int, Transform> poses;
3528 if(req.node_id != 0 || (req.x == 0.0f && req.y == 0.0f && req.z == 0.0f))
3538 res.ids.resize(poses.size());
3539 res.poses.resize(poses.size());
3541 for(std::map<int, rtabmap::Transform>::const_iterator iter = poses.begin();
3542 iter != poses.end();
3545 res.ids[index] = iter->first;
3555 UDEBUG(
"Publishing stats...");
3561 rtabmap_ros::InfoPtr msg(
new rtabmap_ros::Info);
3562 msg->header.stamp =
stamp;
3571 rtabmap_ros::MapDataPtr msg(
new rtabmap_ros::MapData);
3572 msg->header.stamp =
stamp;
3575 std::map<int, Signature> signatures;
3592 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
3593 msg->header.stamp =
stamp;
3608 sensor_msgs::PointCloud2 msg;
3610 msg.header.stamp =
stamp;
3617 sensor_msgs::PointCloud2 msg;
3619 msg.header.stamp =
stamp;
3626 sensor_msgs::PointCloud2 msg;
3628 msg.header.stamp =
stamp;
3637 geometry_msgs::PoseArrayPtr msg(
new geometry_msgs::PoseArray);
3638 msg->header.stamp =
stamp;
3640 for(std::map<int, Transform>::const_iterator iter=stats.
poses().begin(); iter!=stats.
poses().end() && iter->first<0; ++iter)
3642 geometry_msgs::Pose p;
3644 msg->poses.push_back(p);
3649 visualization_msgs::Marker marker;
3651 marker.header.stamp =
stamp;
3652 marker.ns =
"landmarks";
3653 marker.id = iter->first;
3654 marker.action = visualization_msgs::Marker::ADD;
3655 marker.pose.position.x = iter->second.x();
3656 marker.pose.position.y = iter->second.y();
3657 marker.pose.position.z = iter->second.z();
3658 marker.pose.orientation.x = 0.0;
3659 marker.pose.orientation.y = 0.0;
3660 marker.pose.orientation.z = 0.0;
3661 marker.pose.orientation.w = 1.0;
3664 marker.scale.z = 0.35;
3665 marker.color.a = 0.7;
3666 marker.color.r = 0.0;
3667 marker.color.g = 1.0;
3668 marker.color.b = 0.0;
3671 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3674 markers.markers.push_back(marker);
3682 if(pubLabels || pubPath)
3684 if(stats.
poses().size())
3689 path.poses.resize(stats.
poses().size());
3692 for(std::map<int, Transform>::const_iterator poseIter=stats.
poses().begin();
3693 poseIter!=stats.
poses().end();
3702 visualization_msgs::Marker marker;
3704 marker.header.stamp =
stamp;
3705 marker.ns =
"labels";
3706 marker.id = -poseIter->first;
3707 marker.action = visualization_msgs::Marker::ADD;
3708 marker.pose.position.x = poseIter->second.x();
3709 marker.pose.position.y = poseIter->second.y();
3710 marker.pose.position.z = poseIter->second.z();
3711 marker.pose.orientation.x = 0.0;
3712 marker.pose.orientation.y = 0.0;
3713 marker.pose.orientation.z = 0.0;
3714 marker.pose.orientation.w = 1.0;
3717 marker.scale.z = 0.5;
3718 marker.color.a = 0.7;
3719 marker.color.r = 1.0;
3720 marker.color.g = 0.0;
3721 marker.color.b = 0.0;
3723 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3724 marker.text = lter->second;
3726 markers.markers.push_back(marker);
3730 visualization_msgs::Marker marker;
3732 marker.header.stamp =
stamp;
3734 marker.id = poseIter->first;
3735 marker.action = visualization_msgs::Marker::ADD;
3736 marker.pose.position.x = poseIter->second.x();
3737 marker.pose.position.y = poseIter->second.y();
3738 marker.pose.position.z = poseIter->second.z();
3739 marker.pose.orientation.x = 0.0;
3740 marker.pose.orientation.y = 0.0;
3741 marker.pose.orientation.z = 0.0;
3742 marker.pose.orientation.w = 1.0;
3745 marker.scale.z = 0.2;
3746 marker.color.a = 0.5;
3747 marker.color.r = 1.0;
3748 marker.color.g = 1.0;
3749 marker.color.b = 1.0;
3752 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3755 markers.markers.push_back(marker);
3761 path.poses.at(oi).header.stamp =
stamp;
3766 if(pubLabels && markers.markers.size())
3773 path.header.stamp =
stamp;
3774 path.poses.resize(oi);
3788 geometry_msgs::PoseStamped poseMsg;
3790 poseMsg.header.stamp =
stamp;
3797 NODELET_INFO(
"Connecting to move_base action server...");
3806 move_base_msgs::MoveBaseGoal goal;
3807 goal.target_pose = poseMsg;
3817 NODELET_ERROR(
"Cannot connect to move_base action server (called \"%s\")!", this->
getNodeHandle().resolveName(
"move_base").c_str());
3833 const move_base_msgs::MoveBaseResultConstPtr& result)
3835 bool ignore =
false;
3844 NODELET_WARN(
"Planning: move_base reached current goal but it is not " 3845 "the last one planned by rtabmap. A new goal should be sent when " 3846 "rtabmap will be able to retrieve next locations on the path.");
3856 NODELET_ERROR(
"Planning: move_base failed for some reason. Aborting the plan...");
3861 std_msgs::Bool result;
3901 path.header.frame_id = pathNodes.header.frame_id =
mapFrameId_;
3902 path.header.stamp = pathNodes.header.stamp =
stamp;
3903 path.poses.resize(poses.size());
3904 pathNodes.nodeIds.resize(poses.size());
3905 pathNodes.poses.resize(poses.size());
3907 for(std::vector<std::pair<int, Transform> >::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3909 path.poses[oi].header = path.header;
3911 pathNodes.poses[oi] = path.poses[oi].pose;
3912 pathNodes.nodeIds[oi] = iter->first;
3940 path.header.frame_id = pathNodes.header.frame_id =
mapFrameId_;
3941 path.header.stamp = pathNodes.header.stamp =
stamp;
3948 path.poses[oi].header = path.header;
3950 pathNodes.poses[oi] = path.poses[oi].pose;
3951 pathNodes.nodeIds[oi] = iter->first;
3954 Transform goalLocalTransform = Transform::getIdentity();
3966 path.poses.resize(path.poses.size()+1);
3967 path.poses[path.poses.size()-1].header = path.header;
3968 pathNodes.nodeIds.resize(pathNodes.nodeIds.size()+1);
3969 pathNodes.poses.resize(pathNodes.poses.size()+1);
3972 pathNodes.poses[pathNodes.poses.size()-1] = path.poses[path.poses.size()-1].pose;
3973 pathNodes.nodeIds[pathNodes.nodeIds.size()-1] = 0;
3987 #ifdef WITH_OCTOMAP_MSGS 3988 #ifdef RTABMAP_OCTOMAP 3989 bool CoreWrapper::octomapBinaryCallback(
3990 octomap_msgs::GetOctomap::Request &req,
3991 octomap_msgs::GetOctomap::Response &res)
3993 NODELET_INFO(
"Sending binary map data on service request");
4000 std::map<int, Transform> nearestPoses;
4001 std::map<int, float> nodes = graph::findNearestNodes(poses, poses.rbegin()->second,
maxMappingNodes_);
4002 for(std::map<int, float>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
4004 std::map<int, Transform>::iterator pter = poses.find(iter->first);
4005 if(pter != poses.end())
4007 nearestPoses.insert(*pter);
4010 poses = nearestPoses;
4020 bool CoreWrapper::octomapFullCallback(
4021 octomap_msgs::GetOctomap::Request &req,
4022 octomap_msgs::GetOctomap::Response &res)
4024 NODELET_INFO(
"Sending full map data on service request");
4031 std::map<int, Transform> nearestPoses;
4032 std::map<int, float> nodes = graph::findNearestNodes(poses, poses.rbegin()->second,
maxMappingNodes_);
4033 for(std::map<int, float>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
4035 std::map<int, Transform>::iterator pter = poses.find(iter->first);
4036 if(pter != poses.end())
4038 nearestPoses.insert(*pter);
4041 poses = nearestPoses;
geometry_msgs::PoseWithCovarianceStamped globalPose_
ros::ServiceServer setLogErrorSrv_
ros::ServiceServer getMapDataSrv_
Transform getMapCorrection() const
cv::Mat RTABMAP_EXP disparityFromStereoImages(const cv::Mat &leftImage, const cv::Mat &rightImage, const ParametersMap ¶meters=ParametersMap())
ros::Subscriber gpsFixAsyncSub_
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
static std::string homeDir()
std::map< int, geometry_msgs::PoseWithCovarianceStamped > tags_
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
Subscriber subscribe(const std::string &base_topic, uint32_t queue_size, const boost::function< void(const sensor_msgs::ImageConstPtr &)> &callback, const ros::VoidPtr &tracked_object=ros::VoidPtr(), const TransportHints &transport_hints=TransportHints())
const Transform & getPathTransformToGoal() const
void commonDepthCallbackImpl(const std::string &odomFrameId, 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 sensor_msgs::LaserScan &scan2dMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const std::vector< rtabmap_ros::GlobalDescriptor > &globalDescriptorMsgs, const std::vector< std::vector< rtabmap_ros::KeyPoint > > &localKeyPoints, const std::vector< std::vector< rtabmap_ros::Point3f > > &localPoints3d, const std::vector< cv::Mat > &localDescriptors)
bool getMapDataCallback(rtabmap_ros::GetMap::Request &req, rtabmap_ros::GetMap::Response &res)
Signature getSignatureCopy(int id, bool images, bool scan, bool userData, bool occupancyGrid, bool withWords, bool withGlobalDescriptors) const
ros::ServiceServer getNodesInRadiusSrv_
void set2DMap(const cv::Mat &map, float xMin, float yMin, float cellSize, const std::map< int, rtabmap::Transform > &poses, const rtabmap::Memory *memory=0)
std::map< int, rtabmap::Transform > getFilteredPoses(const std::map< int, rtabmap::Transform > &poses)
bool getNodeDataCallback(rtabmap_ros::GetNodeData::Request &req, rtabmap_ros::GetNodeData::Response &res)
ros::ServiceServer getProjMapSrv_
rtabmap::Landmarks landmarksFromROS(const std::map< int, geometry_msgs::PoseWithCovarianceStamped > &tags, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, tf::TransformListener &listener, double waitForTransform, double defaultLinVariance, double defaultAngVariance)
int genDepthFillIterations_
double genDepthFillHolesError_
ros::ServiceServer pauseSrv_
const V_string & getMyArgv() const
ros::Publisher localPathNodesPub_
void defaultCallback(const sensor_msgs::ImageConstPtr &imageMsg)
void setParameters(const rtabmap::ParametersMap ¶meters)
void userDataAsyncCallback(const rtabmap_ros::UserDataConstPtr &dataMsg)
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0)) const
#define NODELET_ERROR(...)
ros::ServiceServer setLogDebugSrv_
const cv::Size & imageSize() 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)
virtual void commonDepthCallback(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 sensor_msgs::LaserScan &scanMsg, 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 >())
const cv::Mat & data() const
const cv::Mat & localizationCovariance() const
rtabmap::Transform lastPose_
void clearPath(int status)
#define NODELET_WARN(...)
void publish(const boost::shared_ptr< M > &message) const
virtual void commonOdomCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg)
bool setLogWarn(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
Transform getPose(int locationId) const
ros::Publisher globalPathNodesPub_
ros::ServiceServer publishMapDataSrv_
void goalDoneCb(const actionlib::SimpleClientGoalState &state, const move_base_msgs::MoveBaseResultConstPtr &result)
double odomDefaultLinVariance_
ros::ServiceServer setLogWarnSrv_
std::string uReplaceChar(const std::string &str, char before, char after)
image_transport::Subscriber defaultSub_
ros::ServiceServer resetSrv_
void mapGraphToROS(const std::map< int, rtabmap::Transform > &poses, const std::multimap< int, rtabmap::Link > &links, const rtabmap::Transform &mapToOdom, rtabmap_ros::MapGraph &msg)
bool computePath(int targetNode, bool global)
bool getProbMapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
virtual void commonLaserScanCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const sensor_msgs::LaserScan &scanMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const rtabmap_ros::GlobalDescriptor &globalDescriptor=rtabmap_ros::GlobalDescriptor())
rtabmap::ParametersMap parameters_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
bool createIntermediateNodes_
rtabmap::OdometryInfo odomInfoFromROS(const rtabmap_ros::OdomInfo &msg)
int uStrNumCmp(const std::string &a, const std::string &b)
void publishCurrentGoal(const ros::Time &stamp)
std::vector< rtabmap::GlobalDescriptor > globalDescriptorsFromROS(const std::vector< rtabmap_ros::GlobalDescriptor > &msg)
ros::ServiceServer addLinkSrv_
void saveParameters(const std::string &configFile)
void setGlobalPose(const Transform &pose, const cv::Mat &covariance)
ros::Subscriber tagDetectionsSub_
bool resetRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
bool isSubscribedToRGB() const
ros::Publisher localGridEmpty_
bool deleteParam(const std::string &key) const
std::pair< std::string, std::string > ParametersPair
ros::ServiceServer getNodeDataSrv_
const Signature & getLastSignatureData() const
ros::ServiceServer getMapSrv_
bool setModeMappingCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::ServiceServer getGridMapSrv_
rtabmap::Rtabmap rtabmap_
void setInitialPose(const Transform &initialPose)
bool labelLocation(int id, const std::string &label)
static bool fullMapToMsg(const OctomapT &octomap, Octomap &msg)
void goalFeedbackCb(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback)
const rtabmap::OctoMap * getOctomap() const
void transformToGeometryMsg(const rtabmap::Transform &transform, geometry_msgs::Transform &msg)
pcl::PCLPointCloud2::Ptr RTABMAP_EXP laserScanToPointCloud2(const LaserScan &laserScan, const Transform &transform=Transform())
static ParametersMap parseArguments(int argc, char *argv[], bool onlyParameters=false)
cv::Mat RTABMAP_EXP depthFromDisparity(const cv::Mat &disparity, float fx, float baseline, int type=CV_32FC1)
void publishLocalPath(const ros::Time &stamp)
static int erase(const std::string &filePath)
bool isSubscribedToScan2d() const
const std::string & getName() const
std::map< int, Landmark > Landmarks
void interOdomCallback(const nav_msgs::OdometryConstPtr &msg)
ros::Publisher localizationPosePub_
bool publishMapCallback(rtabmap_ros::PublishMap::Request &, rtabmap_ros::PublishMap::Response &)
void copy(const std::string &to)
rtabmap::Transform lastPublishedMetricGoal_
bool listLabelsCallback(rtabmap_ros::ListLabels::Request &req, rtabmap_ros::ListLabels::Response &res)
message_filters::Synchronizer< MyExactInterOdomSyncPolicy > * interOdomSync_
rtabmap::Transform transformFromPoseMsg(const geometry_msgs::Pose &msg, bool ignoreRotationIfNotSet=false)
std::map< std::string, std::string > ParametersMap
cv::Mat getGridProbMap(float &xMin, float &yMin, float &gridCellSize)
float gridCellSize() const
void init(const ParametersMap ¶meters, const std::string &databasePath="", bool loadDatabaseParameters=false)
message_filters::sync_policies::ExactTime< nav_msgs::Odometry, rtabmap_ros::OdomInfo > MyExactInterOdomSyncPolicy
ros::ServiceServer getProbMapSrv_
void setGPS(const GPS &gps)
bool cancelGoalCallback(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
const cv::Mat & gridGroundCellsRaw() const
bool getPlanCallback(nav_msgs::GetPlan::Request &req, nav_msgs::GetPlan::Response &res)
double landmarkDefaultAngVariance_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
float getGoalReachedRadius() const
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
std::string getDatabaseVersion() const
bool setLabelCallback(rtabmap_ros::SetLabel::Request &req, rtabmap_ros::SetLabel::Response &res)
ros::Publisher landmarksPub_
bool lastPoseIntermediate_
std::vector< std::pair< int, Transform > > getPathNextPoses() const
message_filters::Subscriber< rtabmap_ros::OdomInfo > interOdomInfoSyncSub_
int genDepthFillHolesSize_
static void setLevel(ULogger::Level level)
void imuAsyncCallback(const sensor_msgs::ImuConstPtr &tagDetections)
std::string databasePath_
geometry_msgs::TransformStamped t
rtabmap::Transform getTransform(const std::string &fromFrameId, const std::string &toFrameId, const ros::Time &stamp, tf::TransformListener &listener, double waitForTransform)
bool resumeRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
static bool binaryMapToMsg(const OctomapT &octomap, Octomap &msg)
bool odomUpdate(const nav_msgs::OdometryConstPtr &odomMsg, ros::Time stamp)
std::string uBool2Str(bool boolean)
bool setLogDebug(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
const std::map< int, Transform > & getLocalOptimizedPoses() const
ros::ServiceServer getMapData2Srv_
void getGraph(std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global, std::map< int, Signature > *signatures=0, bool withImages=false, bool withScan=false, bool withUserData=false, bool withGrid=false, bool withWords=true, bool withGlobalDescriptors=true) const
ros::Publisher nextMetricGoalPub_
bool isIDsGenerated() const
void initialPoseCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr &msg)
bool isSubscribedToDepth() const
ros::NodeHandle & getPrivateNodeHandle() const
ros::Subscriber initialPoseSub_
bool isServerConnected() const
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud< pcl::PointXYZ > &cloud, const Transform &transform=Transform(), bool filterNaNs=true)
void goalCallback(const geometry_msgs::PoseStampedConstPtr &msg)
bool uIsFinite(const T &value)
bool openConnection(const std::string &url, bool overwritten=false)
#define UASSERT(condition)
ros::Publisher mapDataPub_
bool alreadyRectifiedImages_
void init(ros::NodeHandle &nh, ros::NodeHandle &pnh, const std::string &name, bool usePublicNamespace)
void globalPoseAsyncCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr &globalPoseMsg)
ros::Subscriber globalPoseAsyncSub_
static std::string currentDir(bool trailingSeparator=false)
bool odomTFUpdate(const ros::Time &stamp)
const CameraModel & left() const
std::map< std::string, float > odomInfoToStatistics(const rtabmap::OdometryInfo &info)
std::string uNumber2Str(unsigned int number)
T uMax3(const T &a, const T &b, const T &c)
void close(bool databaseSaved=true, const std::string &ouputDatabasePath="")
bool isSubscribedToRGBD() const
std::string getTopic() const
ros::ServiceServer setModeMappingSrv_
ros::Subscriber userDataAsyncSub_
void publishGlobalPath(const ros::Time &stamp)
bool addLinkCallback(rtabmap_ros::AddLink::Request &, rtabmap_ros::AddLink::Response &)
std::map< int, rtabmap::Transform > updateMapCaches(const std::map< int, rtabmap::Transform > &poses, const rtabmap::Memory *memory, bool updateGrid, bool updateOctomap, const std::map< int, rtabmap::Signature > &signatures=std::map< int, rtabmap::Signature >())
double odomDefaultAngVariance_
ros::ServiceServer updateSrv_
unsigned int getPathCurrentGoalIndex() const
bool latestNodeWasReached_
rtabmap::Link linkFromROS(const rtabmap_ros::Link &msg)
bool pauseRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::ServiceServer backupDatabase_
void setupCallbacks(ros::NodeHandle &nh, ros::NodeHandle &pnh, const std::string &name)
ros::ServiceServer setLogInfoSrv_
bool isSubscribedToStereo() const
void mapDataToROS(const std::map< int, rtabmap::Transform > &poses, const std::multimap< int, rtabmap::Link > &links, const std::map< int, rtabmap::Signature > &signatures, const rtabmap::Transform &mapToOdom, rtabmap_ros::MapData &msg)
std::map< std::string, float > rtabmapROSStats_