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> 65 #ifdef WITH_OCTOMAP_MSGS 66 #ifdef RTABMAP_OCTOMAP 72 #define BAD_COVARIANCE 9999 75 #include "rtabmap_ros/Info.h" 76 #include "rtabmap_ros/MapData.h" 77 #include "rtabmap_ros/MapGraph.h" 78 #include "rtabmap_ros/Path.h" 86 CoreWrapper::CoreWrapper() :
90 lastPoseIntermediate_(
false),
91 latestNodeWasReached_(
false),
92 frameId_(
"base_link"),
95 groundTruthFrameId_(
""),
96 groundTruthBaseFrameId_(
""),
98 odomDefaultAngVariance_(0.001),
99 odomDefaultLinVariance_(0.001),
100 landmarkDefaultAngVariance_(0.001),
101 landmarkDefaultLinVariance_(0.001),
102 waitForTransform_(
true),
103 waitForTransformDuration_(0.2),
104 useActionForGoal_(
false),
107 genScanMaxDepth_(4.0),
108 genScanMinDepth_(0.0),
110 genDepthDecimation_(1),
111 genDepthFillHolesSize_(0),
112 genDepthFillIterations_(1),
113 genDepthFillHolesError_(0.1),
114 scanCloudMaxPoints_(0),
115 scanCloudIs2d_(
false),
118 tfThreadRunning_(
false),
119 stereoToDepth_(
false),
121 odomSensorSync_(
false),
122 rate_(
Parameters::defaultRtabmapDetectionRate()),
123 createIntermediateNodes_(
Parameters::defaultRtabmapCreateIntermediateNodes()),
124 mappingMaxNodes_(
Parameters::defaultGridGlobalMaxNodes()),
125 mappingAltitudeDelta_(
Parameters::defaultGridGlobalAltitudeDelta()),
126 alreadyRectifiedImages_(
Parameters::defaultRtabmapImagesAlreadyRectified()),
127 twoDMapping_(
Parameters::defaultRegForce3DoF()),
131 char * rosHomePath = getenv(
"ROS_HOME");
144 bool publishTf =
true;
145 std::string initialPoseStr;
146 double tfDelay = 0.05;
147 double tfTolerance = 0.1;
148 std::string odomFrameIdInit;
155 pnh.
param(
"odom_frame_id_init", odomFrameIdInit, odomFrameIdInit);
162 "anymore! It is replaced by \"rgbd_cameras\" parameter " 163 "used when \"subscribe_rgbd\" is true");
165 if(!odomFrameIdInit.empty())
169 ROS_INFO(
"rtabmap: odom_frame_id_init = %s", odomFrameIdInit.c_str());
174 ROS_WARN(
"odom_frame_id_init (%s) is ignored if odom_frame_id (%s) is set.", odomFrameIdInit.c_str(),
odomFrameId_.c_str());
179 pnh.
param(
"log_to_rosout_level", eventLevel, eventLevel);
183 pnh.
param(
"publish_tf", publishTf, publishTf);
184 pnh.
param(
"tf_delay", tfDelay, tfDelay);
187 ROS_ERROR(
"tf_prefix parameter has been removed, use directly map_frame_id, odom_frame_id and frame_id parameters.");
189 pnh.
param(
"tf_tolerance", tfTolerance, tfTolerance);
196 pnh.
param(
"initial_pose", initialPoseStr, initialPoseStr);
209 if(pnh.
hasParam(
"scan_cloud_normal_k"))
211 ROS_WARN(
"rtabmap: Parameter \"scan_cloud_normal_k\" has been removed. RTAB-Map's parameter \"%s\" should be used instead. " 212 "The value is copied. Use \"%s\" to avoid this warning.",
213 Parameters::kMemLaserScanNormalK().c_str(),
214 Parameters::kMemLaserScanNormalK().c_str());
216 pnh.
getParam(
"scan_cloud_normal_k", value);
223 NODELET_WARN(
"Parameter \"flip_scan\" doesn't exist anymore. Rtabmap now " 224 "detects automatically if the laser is upside down with /tf, then if so, it " 225 "switches scan values.");
235 NODELET_INFO(
"rtabmap: ground_truth_frame_id = %s -> ground_truth_base_frame_id = %s",
240 NODELET_INFO(
"rtabmap: log_to_rosout_level = %d", eventLevel);
241 NODELET_INFO(
"rtabmap: initial_pose = %s", initialPoseStr.c_str());
242 NODELET_INFO(
"rtabmap: use_action_for_goal = %s",
useActionForGoal_?
"true":
"false");
243 NODELET_INFO(
"rtabmap: tf_delay = %f", tfDelay);
244 NODELET_INFO(
"rtabmap: tf_tolerance = %f", tfTolerance);
245 NODELET_INFO(
"rtabmap: odom_sensor_sync = %s",
odomSensorSync_?
"true":
"false");
246 bool subscribeStereo =
false;
247 pnh.
param(
"subscribe_stereo", subscribeStereo, subscribeStereo);
250 NODELET_INFO(
"rtabmap: stereo_to_depth = %s",
stereoToDepth_?
"true":
"false");
253 NODELET_INFO(
"rtabmap: gen_scan = %s",
genScan_?
"true":
"false");
260 NODELET_INFO(
"rtabmap: gen_depth = %s",
genDepth_?
"true":
"false");
268 bool subscribeScanCloud =
false;
269 pnh.
param(
"subscribe_scan_cloud", subscribeScanCloud, subscribeScanCloud);
270 if(subscribeScanCloud)
273 NODELET_INFO(
"rtabmap: scan_cloud_is_2d = %s",
scanCloudIs2d_?
"true":
"false");
316 ParametersMap allParameters = Parameters::getDefaultParameters();
318 for(ParametersMap::iterator iter=allParameters.begin(); iter!=allParameters.end();)
320 if(iter->first.find(
"Odom") == 0)
322 allParameters.erase(iter++);
330 char * rosHomePath = getenv(
"ROS_HOME");
338 if(iter->first.find(
"Odom") == 0)
349 for(ParametersMap::iterator iter=allParameters.begin(); iter!=allParameters.end(); ++iter)
357 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(), vStr.c_str());
359 if(iter->first.compare(Parameters::kRtabmapWorkingDirectory()) == 0)
363 else if(iter->first.compare(Parameters::kKpDictionaryPath()) == 0)
369 else if(pnh.
getParam(iter->first, vBool))
371 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uBool2Str(vBool).c_str());
374 else if(pnh.
getParam(iter->first, vDouble))
376 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uNumber2Str(vDouble).c_str());
379 else if(pnh.
getParam(iter->first, vInt))
381 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uNumber2Str(vInt).c_str());
387 std::vector<std::string> argList =
getMyArgv();
388 char **
argv =
new char*[argList.size()];
389 bool deleteDbOnStart =
false;
390 for(
unsigned int i=0; i<argList.size(); ++i)
392 argv[i] = &argList[i].at(0);
393 if(strcmp(argv[i],
"--delete_db_on_start") == 0 || strcmp(argv[i],
"-d") == 0)
395 deleteDbOnStart =
true;
400 for(ParametersMap::const_iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
403 NODELET_INFO(
"Update RTAB-Map parameter \"%s\"=\"%s\" from arguments", iter->first.c_str(), iter->second.c_str());
407 for(std::map<std::string, std::pair<bool, std::string> >::const_iterator iter=Parameters::getRemovedParameters().begin();
408 iter!=Parameters::getRemovedParameters().end();
415 std::string paramValue;
420 else if(pnh.
getParam(iter->first, vBool))
424 else if(pnh.
getParam(iter->first, vDouble))
428 else if(pnh.
getParam(iter->first, vInt))
432 if(!paramValue.empty())
436 NODELET_WARN(
"Rtabmap: Parameter name changed: \"%s\" -> \"%s\". The new parameter is already used with value \"%s\", ignoring the old one with value \"%s\".",
437 iter->first.c_str(), iter->second.second.c_str(),
parameters_.find(iter->second.second)->second.c_str(), paramValue.c_str());
439 else if(iter->second.first)
443 NODELET_WARN(
"Rtabmap: Parameter name changed: \"%s\" -> \"%s\". Please update your launch file accordingly. Value \"%s\" is still set to the new parameter name.",
444 iter->first.c_str(), iter->second.second.c_str(), paramValue.c_str());
448 if(iter->second.second.empty())
450 NODELET_ERROR(
"Rtabmap: Parameter \"%s\" doesn't exist anymore!",
451 iter->first.c_str());
455 NODELET_ERROR(
"Rtabmap: Parameter \"%s\" doesn't exist anymore! You may look at this similar parameter: \"%s\"",
456 iter->first.c_str(), iter->second.second.c_str());
465 bool subscribeScan2d =
false;
466 bool subscribeScan3d =
false;
467 pnh.
param(
"subscribe_scan", subscribeScan2d, subscribeScan2d);
468 pnh.
param(
"subscribe_scan_cloud", subscribeScan3d, subscribeScan3d);
469 int gridSensor = Parameters::defaultGridSensor();
472 NODELET_WARN(
"Setting \"%s\" parameter to 0 (default 1) as \"subscribe_scan\", \"subscribe_scan_cloud\" or \"gen_scan\" is " 473 "true. The occupancy grid map will be constructed from " 474 "laser scans. To get occupancy grid map from camera's cloud projection, set \"%s\" " 475 "to 1. To suppress this warning, " 476 "add <param name=\"%s\" type=\"string\" value=\"0\"/>",
477 Parameters::kGridSensor().c_str(),
478 Parameters::kGridSensor().c_str(),
479 Parameters::kGridSensor().c_str());
482 Parameters::parse(
parameters_, Parameters::kGridSensor(), gridSensor);
485 NODELET_INFO(
"Setting \"%s\" parameter to 0 (default %f) as \"subscribe_scan\", \"subscribe_scan_cloud\" or \"gen_scan\" is true and %s is 0.",
486 Parameters::kGridRangeMax().c_str(),
487 Parameters::defaultGridRangeMax(),
488 Parameters::kGridSensor().c_str());
493 NODELET_INFO(
"Setting \"%s\" parameter to 0 (default %f) as \"subscribe_scan_cloud\" is true.",
494 Parameters::kIcpPointToPlaneRadius().c_str(),
495 Parameters::defaultIcpPointToPlaneRadius());
498 int regStrategy = Parameters::defaultRegStrategy();
499 Parameters::parse(
parameters_, Parameters::kRegStrategy(), regStrategy);
501 (regStrategy == Registration::kTypeIcp || regStrategy == Registration::kTypeVisIcp))
505 NODELET_WARN(
"Setting \"%s\" parameter to 10 (default 0) as \"%s\" is " 506 "true and \"%s\" uses ICP. Proximity detection by space will be also done by merging close " 507 "scans. To disable, set \"%s\" to 0. To suppress this warning, " 508 "add <param name=\"%s\" type=\"string\" value=\"10\"/>",
509 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
510 subscribeScan2d?
"subscribe_scan":
"scan_cloud_is_2d",
511 Parameters::kRegStrategy().c_str(),
512 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
513 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
516 else if(subscribeScan3d)
518 NODELET_WARN(
"Setting \"%s\" parameter to 1 (default 0) as \"subscribe_scan_cloud\" is " 519 "true and \"%s\" uses ICP. To disable, set \"%s\" to 0. To suppress this warning, " 520 "add <param name=\"%s\" type=\"string\" value=\"1\"/>",
521 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
522 Parameters::kRegStrategy().c_str(),
523 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
524 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
529 int estimationType = Parameters::defaultVisEstimationType();
530 Parameters::parse(
parameters_, Parameters::kVisEstimationType(), estimationType);
532 bool subscribeRGBD =
false;
533 pnh.
param(
"rgbd_cameras", cameras, cameras);
534 pnh.
param(
"subscribe_rgbd", subscribeRGBD, subscribeRGBD);
546 for(ParametersMap::iterator iter=dbParameters.begin(); iter!=dbParameters.end(); ++iter)
548 if(iter->first.compare(Parameters::kRtabmapWorkingDirectory()) == 0)
554 allParameters.find(iter->first) != allParameters.end() &&
555 allParameters.find(iter->first)->second.compare(iter->second) !=0)
557 NODELET_INFO(
"Update RTAB-Map parameter \"%s\"=\"%s\" from database", iter->first.c_str(), iter->second.c_str());
564 parameters_.insert(allParameters.begin(), allParameters.end());
569 NODELET_INFO(
"RTAB-Map detection rate = %f Hz",
rate_);
576 NODELET_INFO(
"Create intermediate nodes");
579 bool interOdomInfo =
false;
580 pnh.
getParam(
"subscribe_inter_odom_info", interOdomInfo);
583 NODELET_INFO(
"Subscribe to inter odom + info messages");
586 interOdomSyncSub_.subscribe(nh,
"inter_odom", 100);
591 NODELET_INFO(
"Subscribe to inter odom messages");
626 NODELET_WARN(
"Node paused... don't forget to call service \"resume\" to start rtabmap.");
633 NODELET_INFO(
"rtabmap: Deleted database \"%s\" (--delete_db_on_start or -d are set).",
databasePath_.c_str());
643 NODELET_INFO(
"rtabmap: database_path parameter not set, the map will not be saved.");
655 float xMin, yMin, gridCellSize;
659 NODELET_INFO(
"rtabmap: 2D occupancy grid map loaded (%dx%d).", map.cols, map.rows);
666 NODELET_INFO(
"rtabmap: Working Memory = %d, Local map = %d.",
678 NODELET_INFO(
"rtabmap: SLAM mode (%s=true)", Parameters::kMemIncrementalMemory().c_str());
682 NODELET_INFO(
"rtabmap: Localization mode (%s=false)", Parameters::kMemIncrementalMemory().c_str());
716 #ifdef WITH_OCTOMAP_MSGS 717 #ifdef RTABMAP_OCTOMAP 718 octomapBinarySrv_ = nh.
advertiseService(
"octomap_binary", &CoreWrapper::octomapBinaryCallback,
this);
719 octomapFullSrv_ = nh.
advertiseService(
"octomap_full", &CoreWrapper::octomapFullCallback,
this);
728 int optimizeIterations = 0;
729 Parameters::parse(
parameters_, Parameters::kOptimizerIterations(), optimizeIterations);
730 if(publishTf && optimizeIterations != 0)
737 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.",
738 Parameters::kOptimizerIterations().c_str(),
mapFrameId_.c_str());
747 NODELET_WARN(
"ROS param subscribe_depth, subscribe_stereo and subscribe_rgbd are false, but RTAB-Map " 748 "parameter \"%s\" is true! Please set subscribe_depth, subscribe_stereo or subscribe_rgbd " 749 "to true to use rtabmap node for RGB-D SLAM, set \"%s\" to false for loop closure " 750 "detection on images-only or set subscribe_rgb to true to localize a single RGB camera against pre-built 3D map.",
751 Parameters::kRGBDEnabled().c_str(),
752 Parameters::kRGBDEnabled().c_str());
768 NODELET_WARN(
"There is no image subscription, bag-of-words loop closure detection will be disabled...");
769 int kpMaxFeatures = Parameters::defaultKpMaxFeatures();
770 int registrationStrategy = Parameters::defaultRegStrategy();
771 Parameters::parse(
parameters_, Parameters::kKpMaxFeatures(), kpMaxFeatures);
772 Parameters::parse(
parameters_, Parameters::kRegStrategy(), registrationStrategy);
773 bool updateParams =
false;
774 if(kpMaxFeatures!= -1)
777 NODELET_WARN(
"Setting %s=-1 (bag-of-words disabled)", Parameters::kKpMaxFeatures().c_str());
783 NODELET_WARN(
"Setting %s=1 (ICP)", Parameters::kRegStrategy().c_str());
786 if(modifiedParameters.find(Parameters::kRGBDProximityPathMaxNeighbors()) == modifiedParameters.end())
790 NODELET_WARN(
"Setting \"%s\" parameter to 10 (default 0) as \"subscribe_scan\" is " 791 "true and \"%s\" uses ICP. Proximity detection by space will be also done by merging close " 792 "scans. To disable, set \"%s\" to 0. To suppress this warning, " 793 "add <param name=\"%s\" type=\"string\" value=\"10\"/>",
794 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
795 Parameters::kRegStrategy().c_str(),
796 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
797 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
802 NODELET_WARN(
"Setting \"%s\" parameter to 1 (default 0) as \"subscribe_scan_cloud\" is " 803 "true and \"%s\" uses ICP. To disable, set \"%s\" to 0. To suppress this warning, " 804 "add <param name=\"%s\" type=\"string\" value=\"1\"/>",
805 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
806 Parameters::kRegStrategy().c_str(),
807 Parameters::kRGBDProximityPathMaxNeighbors().c_str(),
808 Parameters::kRGBDProximityPathMaxNeighbors().c_str());
820 if(!initialPoseStr.empty())
822 Transform intialPose = Transform::fromString(initialPoseStr);
825 NODELET_INFO(
"Setting initial pose: \"%s\"", intialPose.
prettyPrint().c_str());
830 NODELET_ERROR(
"Invalid initial_pose: \"%s\"", initialPoseStr.c_str());
837 pnh.
setParam(iter->first, iter->second);
843 #ifdef WITH_APRILTAG_ROS 846 #ifdef WITH_FIDUCIAL_MSGS 864 printf(
"rtabmap: Saving database/long-term memory... (located at %s)\n",
databasePath_.c_str());
868 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
872 printf(
"rtabmap: 2D occupancy grid map saved.\n");
886 if(!configFile.empty())
888 NODELET_INFO(
"Loading parameters from %s", configFile.c_str());
891 NODELET_WARN(
"Config file doesn't exist! It will be generated...");
893 Parameters::readINI(configFile.c_str(), parameters);
899 if(!configFile.empty())
901 printf(
"Saving parameters to %s\n", configFile.c_str());
905 printf(
"Config file doesn't exist, a new one will be created.\n");
907 Parameters::writeINI(configFile.c_str(),
parameters_);
911 NODELET_INFO(
"Parameters are not saved! (No configuration file provided...)");
929 msg.header.stamp = tfExpiration;
943 if(stamp.
toSec() == 0.0)
945 ROS_WARN(
"A null stamp has been detected in the input topic. Make sure the stamp is set.");
963 NODELET_ERROR(
"Input type must be image=mono8,mono16,rgb8,bgr8");
984 NODELET_WARN(
"RTAB-Map could not process the data received! (ROS id = %d)", ptrImage->header.seq);
993 NODELET_WARN(
"Ignoring received image because its sequence ID=0. Please " 994 "set \"Mem/GenerateIds\"=\"true\" to ignore ros generated sequence id. " 995 "Use only \"Mem/GenerateIds\"=\"false\" for once-time run of RTAB-Map and " 996 "when you need to have IDs output of RTAB-map synchronised with the source " 997 "image sequence ID.");
999 NODELET_INFO(
"rtabmap: Update rate=%fs, Limit=%fs, Processing time = %fs (%d local nodes)",
1020 static bool shown =
false;
1023 NODELET_WARN(
"We received odometry message, but we cannot get the " 1024 "corresponding TF %s->%s at data stamp %fs (odom msg stamp is %fs). Make sure TF of odometry is " 1025 "also published to get more accurate pose estimation. This " 1026 "warning is only printed once.", odomMsg->header.frame_id.c_str(),
frameId_.c_str(), stamp.
toSec(), odomMsg->header.stamp.toSec());
1029 stamp = odomMsg->header.stamp;
1039 UWARN(
"Odometry is reset (identity pose or high variance (%f) detected). Increment map id!",
MAX(odomMsg->pose.covariance[0], odomMsg->twist.covariance[0]));
1059 double variance = odomMsg->twist.covariance[0];
1063 covariance = cv::Mat(6,6,CV_64FC1, (
void*)odomMsg->pose.covariance.data()).clone();
1068 covariance = cv::Mat(6,6,CV_64FC1, (
void*)odomMsg->twist.covariance.data()).clone();
1071 if(
uIsFinite(covariance.at<
double>(0,0)) &&
1072 covariance.at<
double>(0,0) != 1.0 &&
1073 covariance.at<
double>(0,0)>0.0)
1084 bool ignoreFrame =
false;
1085 if(stamp.
toSec() == 0.0)
1087 ROS_WARN(
"A null stamp has been detected in the input topics. Make sure the stamp in all input topics is set.");
1108 else if(!ignoreFrame)
1131 UWARN(
"Odometry is reset (identity pose detected). Increment map id!");
1141 bool ignoreFrame =
false;
1142 if(stamp.
toSec() == 0.0)
1144 ROS_WARN(
"A null stamp has been detected in the input topics. Make sure the stamp in all input topics is set.");
1165 else if(!ignoreFrame)
1176 const nav_msgs::OdometryConstPtr & odomMsg,
1177 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1178 const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
1179 const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
1180 const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
1181 const std::vector<sensor_msgs::CameraInfo> & depthCameraInfoMsgs,
1182 const sensor_msgs::LaserScan& scan2dMsg,
1183 const sensor_msgs::PointCloud2& scan3dMsg,
1184 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1185 const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
1186 const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPoints,
1187 const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3d,
1188 const std::vector<cv::Mat> & localDescriptors)
1193 odomFrameId = odomMsg->header.frame_id;
1194 if(!scan2dMsg.ranges.empty())
1196 if(!
odomUpdate(odomMsg, scan2dMsg.header.stamp))
1201 else if(!scan3dMsg.data.empty())
1203 if(!
odomUpdate(odomMsg, scan3dMsg.header.stamp))
1208 else if(cameraInfoMsgs.size() == 0 || !
odomUpdate(odomMsg, cameraInfoMsgs[0].
header.stamp))
1213 else if(!scan2dMsg.ranges.empty())
1220 else if(!scan3dMsg.data.empty())
1237 depthCameraInfoMsgs,
1241 globalDescriptorMsgs,
1248 const std::string & odomFrameId,
1249 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1250 const std::vector<cv_bridge::CvImageConstPtr> & imageMsgs,
1251 const std::vector<cv_bridge::CvImageConstPtr> & depthMsgs,
1252 const std::vector<sensor_msgs::CameraInfo> & cameraInfoMsgs,
1253 const std::vector<sensor_msgs::CameraInfo> & depthCameraInfoMsgs,
1254 const sensor_msgs::LaserScan& scan2dMsg,
1255 const sensor_msgs::PointCloud2& scan3dMsg,
1256 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1257 const std::vector<rtabmap_ros::GlobalDescriptor> & globalDescriptorMsgs,
1258 const std::vector<std::vector<rtabmap_ros::KeyPoint> > & localKeyPointsMsgs,
1259 const std::vector<std::vector<rtabmap_ros::Point3f> > & localPoints3dMsgs,
1260 const std::vector<cv::Mat> & localDescriptorsMsgs)
1265 std::vector<rtabmap::CameraModel> cameraModels;
1266 std::vector<rtabmap::StereoCameraModel> stereoCameraModels;
1267 std::vector<cv::KeyPoint> keypoints;
1268 std::vector<cv::Point3f> points;
1269 cv::Mat descriptors;
1275 depthCameraInfoMsgs,
1288 localDescriptorsMsgs,
1293 NODELET_ERROR(
"Could not convert rgb/depth msgs! Aborting rtabmap update...");
1296 UDEBUG(
"cameraModels=%ld stereoCameraModels=%ld", cameraModels.size(), stereoCameraModels.size());
1297 UDEBUG(
"rgb=%dx%d(type=%d), depth/right=%dx%d(type=%d)", rgb.rows, rgb.cols, rgb.type(), depth.rows, depth.cols, depth.type());
1301 UASSERT(depth.type() == CV_8UC1);
1303 if(rgb.channels() == 3)
1305 cv::cvtColor(rgb, leftMono, CV_BGR2GRAY);
1311 cv::Mat rightMono = depth;
1314 UASSERT(
int((leftMono.cols/stereoCameraModels.size())*stereoCameraModels.size()) == leftMono.cols);
1315 UASSERT(
int((rightMono.cols/stereoCameraModels.size())*stereoCameraModels.size()) == rightMono.cols);
1316 int subImageWidth = leftMono.cols/stereoCameraModels.size();
1317 for(
size_t i=0; i<stereoCameraModels.size(); ++i)
1319 cv::Mat left(leftMono, cv::Rect(subImageWidth*i, 0, subImageWidth, leftMono.rows));
1320 cv::Mat right(rightMono, cv::Rect(subImageWidth*i, 0, subImageWidth, rightMono.rows));
1327 if(disparity.empty())
1329 NODELET_ERROR(
"Could not compute disparity image (\"stereo_to_depth\" is true)!");
1334 stereoCameraModels[i].left().fx(),
1335 stereoCameraModels[i].baseline());
1337 if(subDepth.empty())
1339 NODELET_ERROR(
"Could not compute depth image (\"stereo_to_depth\" is true)!");
1342 UASSERT(subDepth.type() == CV_16UC1 || subDepth.type() == CV_32FC1);
1346 depth = cv::Mat(subDepth.rows, subDepth.cols*stereoCameraModels.size(), subDepth.type());
1349 if(subDepth.type() == depth.type())
1351 subDepth.copyTo(cv::Mat(depth, cv::Rect(i*subDepth.cols, 0, subDepth.cols, subDepth.rows)));
1355 ROS_ERROR(
"Some Depth images are not the same type!");
1359 cameraModels.push_back(stereoCameraModels[i].left());
1361 stereoCameraModels.clear();
1365 if(!depth.empty() && depth.type() == CV_32FC1 &&
uStr2Bool(
parameters_.at(Parameters::kMemSaveDepth16Format())))
1368 static bool shown =
false;
1371 NODELET_WARN(
"Save depth data to 16 bits format: depth type detected is " 1372 "32FC1, use 16UC1 depth format to avoid this conversion " 1373 "(or set parameter \"Mem/SaveDepth16Format=false\" to use " 1374 "32bits format). This message is only printed once...");
1380 bool genMaxScanPts = 0;
1381 if(scan2dMsg.ranges.empty() && scan3dMsg.data.empty() && !depth.empty() && stereoCameraModels.empty() &&
genScan_)
1383 pcl::PointCloud<pcl::PointXYZ>::Ptr scanCloud2d(
new pcl::PointCloud<pcl::PointXYZ>);
1384 *scanCloud2d = util3d::laserScanFromDepthImages(
1389 genMaxScanPts += depth.cols;
1392 else if(!scan2dMsg.ranges.empty())
1405 NODELET_ERROR(
"Could not convert laser scan msg! Aborting rtabmap update...");
1409 else if(!scan3dMsg.data.empty())
1423 NODELET_ERROR(
"Could not convert 3d laser scan msg! Aborting rtabmap update...");
1430 for(
size_t i=0; i<cameraModels.size(); ++i)
1441 ROS_ERROR(
"decimation (%d) not valid for image size %dx%d! Aborting depth generation from scan...",
1450 cv::Mat depthProjected = util3d::projectCloudToCamera(
1460 depthProjected = util2d::fillDepthHoles(
1477 if(userDataMsg.get())
1483 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1495 if(!stereoCameraModels.empty())
1519 if(odomInfoMsg.get())
1524 if(!globalDescriptorMsgs.empty())
1529 if(!keypoints.empty())
1531 UASSERT(points.empty() || points.size() == keypoints.size());
1532 UASSERT(descriptors.empty() || descriptors.rows == (int)keypoints.size());
1543 timerConversion.
ticks());
1548 const nav_msgs::OdometryConstPtr & odomMsg,
1549 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1550 const sensor_msgs::LaserScan& scan2dMsg,
1551 const sensor_msgs::PointCloud2& scan3dMsg,
1552 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg,
1553 const rtabmap_ros::GlobalDescriptor & globalDescriptor)
1559 odomFrameId = odomMsg->header.frame_id;
1560 if(!scan2dMsg.ranges.empty())
1562 if(!
odomUpdate(odomMsg, scan2dMsg.header.stamp))
1567 else if(!scan3dMsg.data.empty())
1569 if(!
odomUpdate(odomMsg, scan3dMsg.header.stamp))
1579 else if(!scan2dMsg.ranges.empty())
1586 else if(!scan3dMsg.data.empty())
1599 if(!scan2dMsg.ranges.empty())
1612 NODELET_ERROR(
"Could not convert laser scan msg! Aborting rtabmap update...");
1616 else if(!scan3dMsg.data.empty())
1630 NODELET_ERROR(
"Could not convert 3d laser scan msg! Aborting rtabmap update...");
1636 if(userDataMsg.get())
1642 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1663 if(odomInfoMsg.get())
1668 if(!globalDescriptor.data.empty())
1680 timerConversion.
ticks());
1686 const nav_msgs::OdometryConstPtr & odomMsg,
1687 const rtabmap_ros::UserDataConstPtr & userDataMsg,
1688 const rtabmap_ros::OdomInfoConstPtr& odomInfoMsg)
1694 odomFrameId = odomMsg->header.frame_id;
1695 if(!
odomUpdate(odomMsg, odomMsg->header.stamp))
1701 if(userDataMsg.get())
1707 NODELET_WARN(
"Synchronized and asynchronized user data topics cannot be used at the same time. Async user data dropped!");
1727 if(odomInfoMsg.get())
1739 timerConversion.
ticks());
1748 const std::vector<float> & odomVelocityIn,
1749 const std::string & odomFrameId,
1750 const cv::Mat & odomCovariance,
1752 double timeMsgConversion)
1758 for(std::list<std::pair<nav_msgs::Odometry, rtabmap_ros::OdomInfo> >::iterator iter=
interOdoms_.begin(); iter!=
interOdoms_.end();)
1771 double variance = iter->first.twist.covariance[0];
1775 covariance = cv::Mat(6,6,CV_64FC1, (
void*)iter->first.pose.covariance.data()).clone();
1780 covariance = cv::Mat(6,6,CV_64FC1, (
void*)iter->first.twist.covariance.data()).clone();
1782 if(!
uIsFinite(covariance.at<
double>(0,0)) || covariance.at<
double>(0,0)<=0.0f)
1784 covariance = cv::Mat::eye(6,6,CV_64FC1);
1801 covariance.at<
double>(2,2) =
uIsFinite(covariance.at<
double>(2,2)) && covariance.at<
double>(2,2)!=0?covariance.at<
double>(2,2):1;
1802 covariance.at<
double>(3,3) =
uIsFinite(covariance.at<
double>(3,3)) && covariance.at<
double>(3,3)!=0?covariance.at<
double>(3,3):1;
1803 covariance.at<
double>(4,4) =
uIsFinite(covariance.at<
double>(4,4)) && covariance.at<
double>(4,4)!=0?covariance.at<
double>(4,4):1;
1812 interData.setGroundTruth(gt);
1814 std::map<std::string, float> externalStats;
1815 std::vector<float> odomVelocity;
1816 if(iter->second.timeEstimation != 0.0f)
1823 odomVelocity.resize(6);
1829 odomVelocity[3] = roll/info.
interval;
1830 odomVelocity[4] = pitch/info.
interval;
1831 odomVelocity[5] = yaw/info.
interval;
1834 if(odomVelocity.empty())
1836 odomVelocity.resize(6);
1837 odomVelocity[0] = iter->first.twist.twist.linear.x;
1838 odomVelocity[1] = iter->first.twist.twist.linear.y;
1839 odomVelocity[2] = iter->first.twist.twist.linear.z;
1840 odomVelocity[3] = iter->first.twist.twist.angular.x;
1841 odomVelocity[4] = iter->first.twist.twist.angular.y;
1842 odomVelocity[5] = iter->first.twist.twist.angular.z;
1845 rtabmap_.
process(interData, interOdom, covariance, odomVelocity, externalStats);
1878 if(!sensorToBase.
isNull())
1881 globalPose *= sensorToBase;
1893 globalPose *= correction;
1897 NODELET_WARN(
"Could not adjust global pose accordingly to latest odometry pose. " 1898 "If odometry is small since it received the global pose and " 1899 "covariance is large, this should not be a problem.");
1901 cv::Mat globalPoseCovariance = cv::Mat(6,6, CV_64FC1, (
void*)
globalPose_.pose.covariance.data()).clone();
1924 if(!landmarks.empty())
1946 if(!localTransform.
isNull())
1949 data.
setIMU(
IMU(cv::Vec4d(q.x(), q.y(), q.z(), q.w()), cv::Mat::eye(3,3,CV_64FC1),
1950 cv::Vec3d(), cv::Mat(),
1951 cv::Vec3d(), cv::Mat(),
1957 ROS_WARN(
"We are receiving imu data (buffer=%d), but cannot interpolate " 1958 "imu transform at time %f. IMU won't be added to graph.",
1963 double timeRtabmap = 0.0;
1964 double timeUpdateMaps = 0.0;
1965 double timePublishMaps = 0.0;
1968 if(covariance.empty() || !
uIsFinite(covariance.at<
double>(0,0)) || covariance.at<
double>(0,0)<=0.0
f)
1970 covariance = cv::Mat::eye(6,6,CV_64FC1);
1987 covariance.at<
double>(2,2) =
uIsFinite(covariance.at<
double>(2,2)) && covariance.at<
double>(2,2)!=0?covariance.at<
double>(2,2):1;
1988 covariance.at<
double>(3,3) =
uIsFinite(covariance.at<
double>(3,3)) && covariance.at<
double>(3,3)!=0?covariance.at<
double>(3,3):1;
1989 covariance.at<
double>(4,4) =
uIsFinite(covariance.at<
double>(4,4)) && covariance.at<
double>(4,4)!=0?covariance.at<
double>(4,4):1;
1992 std::map<std::string, float> externalStats;
1993 std::vector<float> odomVelocity;
2000 odomVelocity.resize(6);
2003 odomVelocity[0] = x/odomInfo.
interval;
2004 odomVelocity[1] = y/odomInfo.
interval;
2005 odomVelocity[2] = z/odomInfo.
interval;
2006 odomVelocity[3] = roll/odomInfo.
interval;
2007 odomVelocity[4] = pitch/odomInfo.
interval;
2008 odomVelocity[5] = yaw/odomInfo.
interval;
2011 if(odomVelocity.empty())
2013 odomVelocity = odomVelocityIn;
2021 timeMsgConversion += timer.
ticks();
2022 if(
rtabmap_.
process(data, odom, covariance, odomVelocity, externalStats))
2024 timeRtabmap = timer.
ticks();
2030 ROS_ERROR(
"Odometry received doesn't have same frame_id " 2031 "than the one previously set (old=%s, new=%s). " 2032 "Are there multiple nodes publishing on same odometry topic name? " 2033 "The new frame_id is now used.",
odomFrameId_.c_str(), odomFrameId.c_str());
2050 geometry_msgs::PoseWithCovarianceStamped poseMsg;
2052 poseMsg.header.stamp =
stamp;
2054 poseMsg.pose.covariance;
2056 memcpy(poseMsg.pose.covariance.data(), cov.data, cov.total()*
sizeof(double));
2062 std::map<int, rtabmap::Signature> tmpSignature;
2064 filteredPoses.size() == 0 ||
2073 filteredPoses.insert(std::make_pair(0,
mapToOdom_*odom));
2081 std::set<int> onPath;
2085 onPath.insert(nextNodes.begin(), nextNodes.end());
2087 for(std::map<int, Transform>::iterator iter=filteredPoses.begin(); iter!=filteredPoses.end(); ++iter)
2089 if(iter->first == 0 || onPath.find(iter->first) != onPath.end())
2091 nearestPoses.insert(*iter);
2093 else if(onPath.empty())
2099 filteredPoses = nearestPoses;
2110 timeUpdateMaps = timer.
ticks();
2139 std_msgs::Bool result;
2161 Transform goalLocalTransform = Transform::getIdentity();
2185 NODELET_ERROR(
"Planning: Local map broken, current goal id=%d (the robot may have moved to far from planned nodes)",
2190 std_msgs::Bool result;
2191 result.data =
false;
2202 timePublishMaps = timer.
ticks();
2207 timeRtabmap = timer.
ticks();
2209 NODELET_INFO(
"rtabmap (%d): Rate=%.2fs, Limit=%.3fs, Conversion=%.4fs, RTAB-Map=%.4fs, Maps update=%.4fs pub=%.4fs (local map=%d, WM=%d)",
2220 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeMsgConversion/ms"), timeMsgConversion*1000.0
f));
2221 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeRtabmap/ms"), timeRtabmap*1000.0f));
2222 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeUpdatingMaps/ms"), timeUpdateMaps*1000.0f));
2223 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimePublishing/ms"), timePublishMaps*1000.0f));
2224 rtabmapROSStats_.insert(std::make_pair(std::string(
"RtabmapROS/TimeTotal/ms"), (timeMsgConversion+timeRtabmap+timeUpdateMaps+timePublishMaps)*1000.0f));
2228 NODELET_WARN(
"Ignoring received image because its sequence ID=0. Please " 2229 "set \"Mem/GenerateIds\"=\"true\" to ignore ros generated sequence id. " 2230 "Use only \"Mem/GenerateIds\"=\"false\" for once-time run of RTAB-Map and " 2231 "when you need to have IDs output of RTAB-map synchronized with the source " 2232 "image sequence ID.");
2237 const std::map<int, Transform> & nodes,
2240 std::map<int, Transform> output;
2243 std::map<int, float> nodesDist = graph::findNearestNodes(currentPose, nodes, 0, 0,
mappingMaxNodes_);
2244 for(std::map<int, float>::iterator iter=nodesDist.begin(); iter!=nodesDist.end(); ++iter)
2249 output.insert(*nodes.find(iter->first));
2255 for(std::map<int, Transform>::const_iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
2259 output.insert(*iter);
2271 static bool warningShow =
false;
2274 ROS_WARN(
"Overwriting previous user data set. When asynchronous user " 2275 "data input topic rate is higher than " 2276 "map update rate (current %s=%f), only latest data is saved " 2277 "in the next node created. This message will is shown only once.",
2278 Parameters::kRtabmapDetectionRate().c_str(),
rate_);
2297 double error = 10.0;
2298 if(gpsFixMsg->position_covariance_type != sensor_msgs::NavSatFix::COVARIANCE_TYPE_UNKNOWN)
2300 double variance =
uMax3(gpsFixMsg->position_covariance.at(0), gpsFixMsg->position_covariance.at(4), gpsFixMsg->position_covariance.at(8));
2303 error =
sqrt(variance);
2307 gpsFixMsg->header.stamp.toSec(),
2308 gpsFixMsg->longitude,
2309 gpsFixMsg->latitude,
2310 gpsFixMsg->altitude,
2316 #ifdef WITH_APRILTAG_ROS 2317 void CoreWrapper::tagDetectionsAsyncCallback(
const apriltag_ros::AprilTagDetectionArray & tagDetections)
2321 for(
unsigned int i=0; i<tagDetections.detections.size(); ++i)
2323 if(tagDetections.detections[i].id.size() >= 1)
2325 geometry_msgs::PoseWithCovarianceStamped p = tagDetections.detections[i].pose;
2326 p.header = tagDetections.header;
2327 if(!tagDetections.detections[i].pose.header.frame_id.empty())
2329 p.header.frame_id = tagDetections.detections[i].pose.header.frame_id;
2331 static bool warned =
false;
2333 !tagDetections.header.frame_id.empty() &&
2334 tagDetections.detections[i].pose.header.frame_id.compare(tagDetections.header.frame_id)!=0)
2336 NODELET_WARN(
"frame_id set for individual tag detections (%s) doesn't match the frame_id of the message (%s), " 2337 "the resulting pose of the tag may be wrong. This message is only printed once.",
2338 tagDetections.detections[i].pose.header.frame_id.c_str(), tagDetections.header.frame_id.c_str());
2342 if(!tagDetections.detections[i].pose.header.stamp.isZero())
2344 p.header.stamp = tagDetections.detections[i].pose.header.stamp;
2346 static bool warned =
false;
2348 !tagDetections.header.stamp.isZero() &&
2349 tagDetections.detections[i].pose.header.stamp != tagDetections.header.stamp)
2351 NODELET_WARN(
"stamp set for individual tag detections (%f) doesn't match the stamp of the message (%f), " 2352 "the resulting pose of the tag may be wrongly interpolated. This message is only printed once.",
2353 tagDetections.detections[i].pose.header.stamp.toSec(), tagDetections.header.stamp.toSec());
2358 std::make_pair(tagDetections.detections[i].id[0],
2359 std::make_pair(p, tagDetections.detections[i].size.size()==1?(float)tagDetections.detections[i].size[0]:0.0f)));
2366 #ifdef WITH_FIDUCIAL_MSGS 2367 void CoreWrapper::fiducialDetectionsAsyncCallback(
const fiducial_msgs::FiducialTransformArray & fiducialDetections)
2371 for(
unsigned int i=0; i<fiducialDetections.transforms.size(); ++i)
2373 geometry_msgs::PoseWithCovarianceStamped p;
2374 p.pose.pose.orientation = fiducialDetections.transforms[i].transform.rotation;
2375 p.pose.pose.position.x = fiducialDetections.transforms[i].transform.translation.x;
2376 p.pose.pose.position.y = fiducialDetections.transforms[i].transform.translation.y;
2377 p.pose.pose.position.z = fiducialDetections.transforms[i].transform.translation.z;
2378 p.header = fiducialDetections.header;
2380 std::make_pair(fiducialDetections.transforms[i].fiducial_id,
2381 std::make_pair(p, 0.0f)));
2391 if(msg->orientation.x == 0 && msg->orientation.y == 0 && msg->orientation.z == 0 && msg->orientation.w == 0)
2393 UERROR(
"IMU received doesn't have orientation set, it is ignored.");
2397 Transform orientation(0,0,0, msg->orientation.x, msg->orientation.y, msg->orientation.z, msg->orientation.w);
2399 if(
imus_.size() > 1000)
2405 ROS_ERROR(
"IMU frame_id has changed from %s to %s! Are " 2406 "multiple nodes publishing " 2407 "on same topic %s? IMU buffer is cleared!",
2409 msg->header.frame_id.c_str(),
2431 interOdoms_.push_back(std::make_pair(*msg, rtabmap_ros::OdomInfo()));
2439 interOdoms_.push_back(std::make_pair(*msg1, *msg2));
2458 const std::string & label,
2462 double * planningTime)
2486 *planningTime = 0.0;
2489 bool success =
false;
2495 *planningTime = timer.
elapsed();
2498 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
2504 if(poses.size() == 0)
2506 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
2511 std_msgs::Bool result;
2522 NODELET_INFO(
"Planning: Path successfully created (size=%d)", (
int)poses.size());
2531 Transform goalLocalTransform = Transform::getIdentity();
2532 if(!goalFrameId_.empty() && goalFrameId_.compare(
frameId_) != 0)
2549 std::stringstream stream;
2550 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
2552 if(iter != poses.begin())
2556 stream << iter->first;
2558 NODELET_INFO(
"Global path: [%s]", stream.str().c_str());
2567 else if(!label.empty())
2569 NODELET_ERROR(
"Planning: Node with label \"%s\" not found!", label.c_str());
2575 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);
2579 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);
2596 std_msgs::Bool result;
2597 result.data =
false;
2608 if(!msg->header.frame_id.empty() &&
mapFrameId_.compare(msg->header.frame_id) != 0)
2613 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
2614 msg->header.frame_id.c_str(),
mapFrameId_.c_str());
2617 std_msgs::Bool result;
2618 result.data =
false;
2623 targetPose = t * targetPose;
2632 if(msg->node_id == 0 && msg->node_label.empty())
2637 std_msgs::Bool result;
2638 result.data =
false;
2655 if(pnh.
getParam(iter->first, vStr))
2657 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(), vStr.c_str());
2658 iter->second = vStr;
2660 else if(pnh.
getParam(iter->first, vBool))
2662 NODELET_INFO(
"Setting RTAB-Map parameter \"%s\"=\"%s\"", iter->first.c_str(),
uBool2Str(vBool).c_str());
2665 else if(pnh.
getParam(iter->first, vInt))
2670 else if(pnh.
getParam(iter->first, vDouble))
2753 pnh.
setParam(
"is_rtabmap_paused",
true);
2769 pnh.
setParam(
"is_rtabmap_paused",
false);
2776 NODELET_INFO(
"LoadDatabase: Loading database (%s, clear=%s)...", req.database_path.c_str(), req.clear?
"true":
"false");
2781 ROS_ERROR(
"Directory %s doesn't exist! Cannot load database \"%s\"", newDatabasePath.c_str(), dir.c_str());
2795 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
2799 printf(
"rtabmap: 2D occupancy grid map saved.\n");
2842 for(ParametersMap::iterator iter=dbParameters.begin(); iter!=dbParameters.end(); ++iter)
2844 if(iter->first.compare(Parameters::kRtabmapWorkingDirectory()) == 0)
2850 parameters_.find(iter->first)->second.compare(iter->second) !=0)
2852 NODELET_WARN(
"RTAB-Map parameter \"%s\" from database (%s) is different " 2853 "from the current used one (%s). We still keep the " 2854 "current parameter value (%s). If you want to switch between databases " 2855 "with different configurations, restart rtabmap node instead of using this service.",
2856 iter->first.c_str(), iter->second.c_str(),
2865 NODELET_INFO(
"LoadDatabase: Loading database... done!");
2871 float xMin, yMin, gridCellSize;
2875 NODELET_INFO(
"LoadDatabase: 2D occupancy grid map loaded (%dx%d).", map.cols, map.rows);
2882 NODELET_INFO(
"LoadDatabase: Working Memory = %d, Local map = %d.",
2894 NODELET_INFO(
"LoadDatabase: SLAM mode (%s=true)", Parameters::kMemIncrementalMemory().c_str());
2898 NODELET_INFO(
"LoadDatabase: Localization mode (%s=false)", Parameters::kMemIncrementalMemory().c_str());
2920 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
2924 printf(
"rtabmap: 2D occupancy grid map saved.\n");
2951 NODELET_INFO(
"Backup: Reloading memory... done!");
2963 rtabmap_ros::MapDataPtr msg(
new rtabmap_ros::MapData);
2964 msg->header.stamp =
stamp;
2970 std::map<int, Signature>(),
2979 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
2980 msg->header.stamp =
stamp;
2995 NODELET_WARN(
"Detect more loop closures service called");
2998 float clusterRadiusMax = 1;
2999 float clusterRadiusMin = 0;
3000 float clusterAngle = 0;
3002 bool intraSession =
true;
3003 bool interSession =
true;
3004 if(req.cluster_radius_max > 0.0f)
3006 clusterRadiusMax = req.cluster_radius_max;
3008 if(req.cluster_radius_min >= 0.0f)
3010 clusterRadiusMin = req.cluster_radius_min;
3012 if(req.cluster_angle >= 0.0f)
3014 clusterAngle = req.cluster_angle;
3016 if(req.iterations >= 1.0f)
3018 iterations = (int)req.iterations;
3022 interSession =
false;
3024 else if(req.inter_only)
3026 intraSession =
false;
3028 NODELET_WARN(
"Post-Processing service called: Detecting more loop closures " 3029 "(max radius=%f, min radius=%f, angle=%f, iterations=%d, intra=%s, inter=%s)...",
3034 intraSession?
"true":
"false",
3035 interSession?
"true":
"false");
3038 clusterAngle*
M_PI/180.0,
3046 NODELET_ERROR(
"Post-Processing: Detecting more loop closures failed!");
3050 NODELET_WARN(
"Post-Processing: Detected %d loop closures! (%fs)", res.detected, timer.
ticks());
3066 bool filterScans =
false;
3067 if(req.radius > 1.0f)
3069 radius = (int)req.radius;
3071 filterScans = req.filter_scans;
3072 float xMin, yMin, gridCellSize;
3076 NODELET_ERROR(
"Post-Processing: Cleanup local grids failed! There is no optimized map.");
3080 NODELET_WARN(
"Post-Processing: Cleanup local grids... (radius=%d, filter scans=%s)",
3082 filterScans?
"true":
"false");
3086 NODELET_ERROR(
"Post-Processing: Cleanup local grids failed!");
3092 NODELET_WARN(
"Post-Processing: %d grids and scans modified! (%fs)", res.modified, timer.
ticks());
3096 NODELET_WARN(
"Post-Processing: %d grids modified! (%fs)", res.modified, timer.
ticks());
3098 if(res.modified > 0)
3113 NODELET_WARN(
"Global bundle adjustment service called");
3116 int optimizer = (int)Optimizer::kTypeG2O;
3117 int iterations = Parameters::defaultOptimizerIterations();
3118 float pixelVariance = Parameters::defaultg2oPixelVariance();
3119 bool rematchFeatures =
true;
3120 Parameters::parse(
parameters_, Parameters::kOptimizerIterations(), iterations);
3121 Parameters::parse(
parameters_, Parameters::kg2oPixelVariance(), pixelVariance);
3122 if(req.type == 1.0f)
3124 optimizer = (int)Optimizer::kTypeCVSBA;
3126 if(req.iterations >= 1.0f)
3128 iterations = req.iterations;
3130 if(req.pixel_variance > 0.0f)
3132 pixelVariance = req.pixel_variance;
3134 rematchFeatures = !req.voc_matches;
3136 NODELET_WARN(
"Post-Processing: Global Bundle Adjustment... " 3137 "(Optimizer=%s, iterations=%d, pixel variance=%f, rematch=%s)...",
3138 optimizer==Optimizer::kTypeG2O?
"g2o":
"cvsba",
3141 rematchFeatures?
"true":
"false");
3145 NODELET_ERROR(
"Post-Processing: Global Bundle Adjustment failed!");
3149 NODELET_WARN(
"Post-Processing: Global Bundle Adjustment... done! (%fs)", timer.
ticks());
3163 nh.
setParam(rtabmap::Parameters::kMemIncrementalMemory(),
"false");
3175 nh.
setParam(rtabmap::Parameters::kMemIncrementalMemory(),
"true");
3208 NODELET_INFO(
"rtabmap: Getting node data (%d node(s), images=%s scan=%s grid=%s user_data=%s)...",
3209 (
int)req.ids.size(),
3210 req.images?
"true":
"false",
3211 req.scan?
"true":
"false",
3212 req.grid?
"true":
"false",
3213 req.user_data?
"true":
"false");
3219 for(
size_t i=0; i<req.ids.size(); ++i)
3221 int id = req.ids[i];
3228 res.data.push_back(msg);
3232 return !res.data.empty();
3237 NODELET_INFO(
"rtabmap: Getting map (global=%s optimized=%s graphOnly=%s)...",
3238 req.global?
"true":
"false",
3239 req.optimized?
"true":
"false",
3240 req.graphOnly?
"true":
"false");
3241 std::map<int, Signature> signatures;
3242 std::map<int, Transform> poses;
3243 std::multimap<int, rtabmap::Link> constraints;
3271 NODELET_INFO(
"rtabmap: Getting map (global=%s optimized=%s with_images=%s with_scans=%s with_user_data=%s with_grids=%s)...",
3272 req.global?
"true":
"false",
3273 req.optimized?
"true":
"false",
3274 req.with_images?
"true":
"false",
3275 req.with_scans?
"true":
"false",
3276 req.with_user_data?
"true":
"false",
3277 req.with_grids?
"true":
"false");
3278 std::map<int, Signature> signatures;
3279 std::map<int, Transform> poses;
3280 std::multimap<int, rtabmap::Link> constraints;
3293 req.with_global_descriptors);
3313 NODELET_WARN(
"/get_proj_map service is deprecated! Call /get_grid_map service " 3314 "instead with <param name=\"%s\" type=\"string\" value=\"1\"/>. " 3315 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see " 3316 "all occupancy grid parameters.",
3317 Parameters::kGridSensor().c_str());
3321 NODELET_WARN(
"/get_proj_map service is deprecated! Call /get_grid_map service instead.");
3328 NODELET_WARN(
"/get_grid_map service is deprecated! Call /get_map service instead.");
3339 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
3345 res.map.info.resolution = gridCellSize;
3346 res.map.info.origin.position.x = 0.0;
3347 res.map.info.origin.position.y = 0.0;
3348 res.map.info.origin.position.z = 0.0;
3349 res.map.info.origin.orientation.x = 0.0;
3350 res.map.info.origin.orientation.y = 0.0;
3351 res.map.info.origin.orientation.z = 0.0;
3352 res.map.info.origin.orientation.w = 1.0;
3354 res.map.info.width = pixels.cols;
3355 res.map.info.height = pixels.rows;
3356 res.map.info.origin.position.x = xMin;
3357 res.map.info.origin.position.y = yMin;
3358 res.map.data.resize(res.map.info.width * res.map.info.height);
3360 memcpy(res.map.data.data(), pixels.data, res.map.info.width * res.map.info.height);
3380 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
3386 res.map.info.resolution = gridCellSize;
3387 res.map.info.origin.position.x = 0.0;
3388 res.map.info.origin.position.y = 0.0;
3389 res.map.info.origin.position.z = 0.0;
3390 res.map.info.origin.orientation.x = 0.0;
3391 res.map.info.origin.orientation.y = 0.0;
3392 res.map.info.origin.orientation.z = 0.0;
3393 res.map.info.origin.orientation.w = 1.0;
3395 res.map.info.width = pixels.cols;
3396 res.map.info.height = pixels.rows;
3397 res.map.info.origin.position.x = xMin;
3398 res.map.info.origin.position.y = yMin;
3399 res.map.data.resize(res.map.info.width * res.map.info.height);
3401 memcpy(res.map.data.data(), pixels.data, res.map.info.width * res.map.info.height);
3424 std::map<int, Transform> poses;
3425 std::multimap<int, rtabmap::Link> constraints;
3426 std::map<int, Signature > signatures;
3441 rtabmap_ros::MapDataPtr msg(
new rtabmap_ros::MapData);
3442 msg->header.stamp =
now;
3456 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
3457 msg->header.stamp =
now;
3472 geometry_msgs::PoseArrayPtr msg(
new geometry_msgs::PoseArray);
3473 msg->header.stamp =
now;
3475 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end() && iter->first<0; ++iter)
3477 geometry_msgs::Pose p;
3479 msg->poses.push_back(p);
3484 visualization_msgs::Marker marker;
3486 marker.header.stamp =
now;
3487 marker.ns =
"landmarks";
3488 marker.id = iter->first;
3489 marker.action = visualization_msgs::Marker::ADD;
3490 marker.pose.position.x = iter->second.x();
3491 marker.pose.position.y = iter->second.y();
3492 marker.pose.position.z = iter->second.z();
3493 marker.pose.orientation.x = 0.0;
3494 marker.pose.orientation.y = 0.0;
3495 marker.pose.orientation.z = 0.0;
3496 marker.pose.orientation.w = 1.0;
3499 marker.scale.z = 0.35;
3500 marker.color.a = 0.5;
3501 marker.color.r = 1.0;
3502 marker.color.g = 1.0;
3503 marker.color.b = 0.0;
3506 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3509 markers.markers.push_back(marker);
3520 std::map<int, Transform> filteredPoses(poses.lower_bound(1), poses.end());
3523 std::map<int, Transform> nearestPoses =
filterNodesToAssemble(filteredPoses, filteredPoses.rbegin()->second);
3525 if(signatures.size())
3548 if(pubLabels || pubPath)
3550 if(poses.size() && signatures.size())
3555 path.poses.resize(poses.size());
3558 for(std::map<int, Signature>::const_iterator iter=signatures.begin();
3559 iter!=signatures.end();
3562 std::map<int, Transform>::const_iterator poseIter= poses.find(iter->first);
3563 if(poseIter!=poses.end())
3568 if(!iter->second.getLabel().empty())
3570 visualization_msgs::Marker marker;
3572 marker.header.stamp =
now;
3573 marker.ns =
"labels";
3574 marker.id = iter->first;
3575 marker.action = visualization_msgs::Marker::ADD;
3576 marker.pose.position.x = poseIter->second.x();
3577 marker.pose.position.y = poseIter->second.y();
3578 marker.pose.position.z = poseIter->second.z();
3579 marker.pose.orientation.x = 0.0;
3580 marker.pose.orientation.y = 0.0;
3581 marker.pose.orientation.z = 0.0;
3582 marker.pose.orientation.w = 1.0;
3585 marker.scale.z = 0.5;
3586 marker.color.a = 0.7;
3587 marker.color.r = 1.0;
3588 marker.color.g = 0.0;
3589 marker.color.b = 0.0;
3591 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3592 marker.text = iter->second.getLabel();
3594 markers.markers.push_back(marker);
3597 visualization_msgs::Marker marker;
3599 marker.header.stamp =
now;
3601 marker.id = iter->first;
3602 marker.action = visualization_msgs::Marker::ADD;
3603 marker.pose.position.x = poseIter->second.x();
3604 marker.pose.position.y = poseIter->second.y();
3605 marker.pose.position.z = poseIter->second.z();
3606 marker.pose.orientation.x = 0.0;
3607 marker.pose.orientation.y = 0.0;
3608 marker.pose.orientation.z = 0.0;
3609 marker.pose.orientation.w = 1.0;
3612 marker.scale.z = 0.2;
3613 marker.color.a = 0.5;
3614 marker.color.r = 1.0;
3615 marker.color.g = 1.0;
3616 marker.color.b = 1.0;
3619 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
3622 markers.markers.push_back(marker);
3628 path.poses.at(oi).header.stamp =
ros::Time(iter->second.getStamp());
3634 if(pubLabels && markers.markers.size())
3641 path.header.stamp =
now;
3642 path.poses.resize(oi);
3650 UWARN(
"No subscribers, don't need to publish!");
3668 Transform coordinateTransform = Transform::getIdentity();
3669 if(!req.goal.header.frame_id.empty() &&
mapFrameId_.compare(req.goal.header.frame_id) != 0)
3672 if(coordinateTransform.
isNull())
3674 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
3675 req.goal.header.frame_id.c_str(),
mapFrameId_.c_str());
3678 pose = coordinateTransform * pose;
3683 coordinateTransform = coordinateTransform.
inverse();
3688 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
3689 res.plan.header.frame_id = req.goal.header.frame_id;
3690 res.plan.header.stamp = req.goal.header.stamp;
3691 if(poses.size() == 0)
3693 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
3696 res.plan.poses.resize(1);
3701 res.plan.poses.resize(poses.size());
3703 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3705 res.plan.poses[oi].header = res.plan.header;
3711 res.plan.poses.resize(res.plan.poses.size()+1);
3712 res.plan.poses[res.plan.poses.size()-1].header = res.plan.header;
3718 std::stringstream stream;
3719 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3721 if(iter != poses.begin())
3725 stream << iter->first;
3727 NODELET_INFO(
"Planned path: [%s]", stream.str().c_str());
3738 if(req.goal_node <= 0)
3743 if(req.goal_node > 0 || !pose.
isNull())
3745 Transform coordinateTransform = Transform::getIdentity();
3747 if(!pose.
isNull() && !req.goal.header.frame_id.empty() &&
mapFrameId_.compare(req.goal.header.frame_id) != 0)
3750 if(coordinateTransform.
isNull())
3752 NODELET_ERROR(
"Cannot transform goal pose from \"%s\" frame to \"%s\" frame!",
3753 req.goal.header.frame_id.c_str(),
mapFrameId_.c_str());
3758 pose = coordinateTransform * pose;
3764 coordinateTransform = coordinateTransform.
inverse();
3770 const std::vector<std::pair<int, Transform> > & poses =
rtabmap_.
getPath();
3772 res.plan.header.stamp = req.goal_node > 0?
ros::Time::now():req.goal.header.stamp;
3773 if(poses.size() == 0)
3775 NODELET_WARN(
"Planning: Goal already reached (RGBD/GoalReachedRadius=%fm).",
3780 res.plan.poses.resize(1);
3781 res.plan.nodeIds.resize(1);
3783 res.plan.nodeIds[0] = 0;
3788 res.plan.poses.resize(poses.size());
3789 res.plan.nodeIds.resize(poses.size());
3791 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3794 res.plan.nodeIds[oi] = iter->first;
3799 res.plan.poses.resize(res.plan.poses.size()+1);
3800 res.plan.nodeIds.resize(res.plan.nodeIds.size()+1);
3803 res.plan.nodeIds[res.plan.nodeIds.size()-1] = 0;
3807 std::stringstream stream;
3808 for(std::vector<std::pair<int, Transform> >::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
3810 if(iter != poses.begin())
3814 stream << iter->first;
3816 NODELET_INFO(
"Planned path: [%s]", stream.str().c_str());
3826 double planningTime = 0.0;
3828 const std::vector<std::pair<int, Transform> > & path =
rtabmap_.
getPath();
3829 res.path_ids.resize(path.size());
3830 res.path_poses.resize(path.size());
3831 res.planning_time = planningTime;
3832 for(
unsigned int i=0; i<path.size(); ++i)
3834 res.path_ids[i] = path[i].first;
3852 std_msgs::Bool result;
3853 result.data =
false;
3871 NODELET_INFO(
"Set label \"%s\" to node %d", req.node_label.c_str(), req.node_id);
3875 NODELET_INFO(
"Set label \"%s\" to last node", req.node_label.c_str());
3882 NODELET_ERROR(
"Could not set label \"%s\" to node %d", req.node_label.c_str(), req.node_id);
3886 NODELET_ERROR(
"Could not set label \"%s\" to last node", req.node_label.c_str());
3897 res.ids =
uKeys(labels);
3899 NODELET_INFO(
"List labels service: %d labels found.", (
int)res.labels.size());
3911 NODELET_WARN(
"Label \"%s\" not found in the map, cannot remove it!", req.label.c_str());
3915 NODELET_ERROR(
"Failed removing label \"%s\".", req.label.c_str());
3919 NODELET_INFO(
"Removed label \"%s\".", req.label.c_str());
3929 ROS_INFO(
"Adding external link %d -> %d", req.link.fromId, req.link.toId);
3938 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);
3939 std::map<int, Transform> poses;
3940 std::map<int, float> dists;
3941 if(req.node_id != 0 || (req.x == 0.0f && req.y == 0.0f && req.z == 0.0f))
3951 res.ids.resize(poses.size());
3952 res.poses.resize(poses.size());
3953 res.distsSqr.resize(poses.size());
3955 for(std::map<int, rtabmap::Transform>::const_iterator iter = poses.begin();
3956 iter != poses.end();
3959 res.ids[index] = iter->first;
3961 UASSERT(dists.find(iter->first) != dists.end());
3962 res.distsSqr[index] = dists.at(iter->first);
3971 UDEBUG(
"Publishing stats...");
3977 rtabmap_ros::InfoPtr msg(
new rtabmap_ros::Info);
3978 msg->header.stamp =
stamp;
3987 rtabmap_ros::MapDataPtr msg(
new rtabmap_ros::MapData);
3988 msg->header.stamp =
stamp;
4003 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
4004 msg->header.stamp =
stamp;
4018 rtabmap_ros::MapGraphPtr msg(
new rtabmap_ros::MapGraph);
4019 msg->header.stamp =
stamp;
4025 for(std::map<int, Transform>::iterator iter=poses.begin();
4031 for(std::multimap<int, rtabmap::Link>::const_iterator iter=stats.
odomCacheConstraints().begin();
4035 std::map<int, Transform>::const_iterator pter = stats.
poses().find(iter->second.to());
4036 if(pter != stats.
poses().end())
4038 poses.insert(*pter);
4053 sensor_msgs::PointCloud2 msg;
4055 msg.header.stamp =
stamp;
4062 sensor_msgs::PointCloud2 msg;
4064 msg.header.stamp =
stamp;
4071 sensor_msgs::PointCloud2 msg;
4073 msg.header.stamp =
stamp;
4082 geometry_msgs::PoseArrayPtr msg(
new geometry_msgs::PoseArray);
4083 msg->header.stamp =
stamp;
4085 for(std::map<int, Transform>::const_iterator iter=stats.
poses().begin(); iter!=stats.
poses().end() && iter->first<0; ++iter)
4087 geometry_msgs::Pose p;
4089 msg->poses.push_back(p);
4094 visualization_msgs::Marker marker;
4096 marker.header.stamp =
stamp;
4097 marker.ns =
"landmarks";
4098 marker.id = iter->first;
4099 marker.action = visualization_msgs::Marker::ADD;
4100 marker.pose.position.x = iter->second.x();
4101 marker.pose.position.y = iter->second.y();
4102 marker.pose.position.z = iter->second.z();
4103 marker.pose.orientation.x = 0.0;
4104 marker.pose.orientation.y = 0.0;
4105 marker.pose.orientation.z = 0.0;
4106 marker.pose.orientation.w = 1.0;
4109 marker.scale.z = 0.35;
4110 marker.color.a = 0.7;
4111 marker.color.r = 0.0;
4112 marker.color.g = 1.0;
4113 marker.color.b = 0.0;
4116 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
4119 markers.markers.push_back(marker);
4127 if(pubLabels || pubPath)
4129 if(stats.
poses().size())
4138 for(std::map<int, Transform>::const_iterator poseIter=stats.
poses().begin();
4139 poseIter!=stats.
poses().end();
4148 visualization_msgs::Marker marker;
4150 marker.header.stamp =
stamp;
4151 marker.ns =
"labels";
4152 marker.id = -poseIter->first;
4153 marker.action = visualization_msgs::Marker::ADD;
4154 marker.pose.position.x = poseIter->second.x();
4155 marker.pose.position.y = poseIter->second.y();
4156 marker.pose.position.z = poseIter->second.z();
4157 marker.pose.orientation.x = 0.0;
4158 marker.pose.orientation.y = 0.0;
4159 marker.pose.orientation.z = 0.0;
4160 marker.pose.orientation.w = 1.0;
4163 marker.scale.z = 0.5;
4164 marker.color.a = 0.7;
4165 marker.color.r = 1.0;
4166 marker.color.g = 0.0;
4167 marker.color.b = 0.0;
4169 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
4170 marker.text = lter->second;
4172 markers.markers.push_back(marker);
4176 visualization_msgs::Marker marker;
4178 marker.header.stamp =
stamp;
4180 marker.id = poseIter->first;
4181 marker.action = visualization_msgs::Marker::ADD;
4182 marker.pose.position.x = poseIter->second.x();
4183 marker.pose.position.y = poseIter->second.y();
4184 marker.pose.position.z = poseIter->second.z();
4185 marker.pose.orientation.x = 0.0;
4186 marker.pose.orientation.y = 0.0;
4187 marker.pose.orientation.z = 0.0;
4188 marker.pose.orientation.w = 1.0;
4191 marker.scale.z = 0.2;
4192 marker.color.a = 0.5;
4193 marker.color.r = 1.0;
4194 marker.color.g = 1.0;
4195 marker.color.b = 1.0;
4198 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
4201 markers.markers.push_back(marker);
4207 path.poses.at(oi).header.stamp =
stamp;
4212 if(pubLabels && markers.markers.size())
4219 path.header.stamp =
stamp;
4220 path.poses.resize(oi);
4234 geometry_msgs::PoseStamped poseMsg;
4236 poseMsg.header.stamp =
stamp;
4243 NODELET_INFO(
"Connecting to move_base action server...");
4252 move_base_msgs::MoveBaseGoal goal;
4253 goal.target_pose = poseMsg;
4263 NODELET_ERROR(
"Cannot connect to move_base action server (called \"%s\")!", this->
getNodeHandle().resolveName(
"move_base").c_str());
4279 const move_base_msgs::MoveBaseResultConstPtr& result)
4281 bool ignore =
false;
4290 NODELET_WARN(
"Planning: move_base reached current goal but it is not " 4291 "the last one planned by rtabmap. A new goal should be sent when " 4292 "rtabmap will be able to retrieve next locations on the path.");
4302 NODELET_ERROR(
"Planning: move_base failed for some reason. Aborting the plan...");
4307 std_msgs::Bool result;
4347 path.header.frame_id = pathNodes.header.frame_id =
mapFrameId_;
4348 path.header.stamp = pathNodes.header.stamp =
stamp;
4349 path.poses.resize(poses.size());
4350 pathNodes.nodeIds.resize(poses.size());
4351 pathNodes.poses.resize(poses.size());
4353 for(std::vector<std::pair<int, Transform> >::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
4355 path.poses[oi].header = path.header;
4357 pathNodes.poses[oi] = path.poses[oi].pose;
4358 pathNodes.nodeIds[oi] = iter->first;
4386 path.header.frame_id = pathNodes.header.frame_id =
mapFrameId_;
4387 path.header.stamp = pathNodes.header.stamp =
stamp;
4394 path.poses[oi].header = path.header;
4396 pathNodes.poses[oi] = path.poses[oi].pose;
4397 pathNodes.nodeIds[oi] = iter->first;
4400 Transform goalLocalTransform = Transform::getIdentity();
4412 path.poses.resize(path.poses.size()+1);
4413 path.poses[path.poses.size()-1].header = path.header;
4414 pathNodes.nodeIds.resize(pathNodes.nodeIds.size()+1);
4415 pathNodes.poses.resize(pathNodes.poses.size()+1);
4418 pathNodes.poses[pathNodes.poses.size()-1] = path.poses[path.poses.size()-1].pose;
4419 pathNodes.nodeIds[pathNodes.nodeIds.size()-1] = 0;
4433 #ifdef WITH_OCTOMAP_MSGS 4434 #ifdef RTABMAP_OCTOMAP 4435 bool CoreWrapper::octomapBinaryCallback(
4436 octomap_msgs::GetOctomap::Request &req,
4437 octomap_msgs::GetOctomap::Response &
res)
4439 NODELET_INFO(
"Sending binary map data on service request");
4456 bool CoreWrapper::octomapFullCallback(
4457 octomap_msgs::GetOctomap::Request &req,
4458 octomap_msgs::GetOctomap::Response &res)
4460 NODELET_INFO(
"Sending full map data on service request");
geometry_msgs::PoseWithCovarianceStamped globalPose_
ros::ServiceServer setLogErrorSrv_
bool detectMoreLoopClosuresCallback(rtabmap_ros::DetectMoreLoopClosures::Request &, rtabmap_ros::DetectMoreLoopClosures::Response &)
ros::ServiceServer getMapDataSrv_
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()
bool isSubscribedToRGBD() const
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())
bool getMapDataCallback(rtabmap_ros::GetMap::Request &req, rtabmap_ros::GetMap::Response &res)
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)
const cv::Size & imageSize() const
ros::ServiceServer getProjMapSrv_
const rtabmap::OccupancyGrid * getOccupancyGrid() const
int genDepthFillIterations_
double genDepthFillHolesError_
ros::ServiceServer pauseSrv_
bool isIDsGenerated() const
ros::Publisher localPathNodesPub_
void defaultCallback(const sensor_msgs::ImageConstPtr &imageMsg)
void setParameters(const rtabmap::ParametersMap ¶meters)
void userDataAsyncCallback(const rtabmap_ros::UserDataConstPtr &dataMsg)
std::string getTopic() const
ros::Subscriber republishNodeDataSub_
const rtabmap::OctoMap * getOctomap() const
float getTimeThreshold() const
#define NODELET_ERROR(...)
int getLastSignatureId() const
ros::ServiceServer setLogDebugSrv_
const double & stamp() const
CameraModel scaled(double scale) const
bool convertRGBDMsgs(const std::vector< cv_bridge::CvImageConstPtr > &imageMsgs, const std::vector< cv_bridge::CvImageConstPtr > &depthMsgs, const std::vector< sensor_msgs::CameraInfo > &cameraInfoMsgs, const std::vector< sensor_msgs::CameraInfo > &depthCameraInfoMsgs, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, cv::Mat &rgb, cv::Mat &depth, std::vector< rtabmap::CameraModel > &cameraModels, std::vector< rtabmap::StereoCameraModel > &stereoCameraModels, tf::TransformListener &listener, double waitForTransform, bool alreadRectifiedImages, const std::vector< std::vector< rtabmap_ros::KeyPoint > > &localKeyPointsMsgs=std::vector< std::vector< rtabmap_ros::KeyPoint > >(), const std::vector< std::vector< rtabmap_ros::Point3f > > &localPoints3dMsgs=std::vector< std::vector< rtabmap_ros::Point3f > >(), const std::vector< cv::Mat > &localDescriptorsMsgs=std::vector< cv::Mat >(), std::vector< cv::KeyPoint > *localKeyPoints=0, std::vector< cv::Point3f > *localPoints3d=0, cv::Mat *localDescriptors=0)
rtabmap::Transform lastPose_
bool cleanupLocalGridsCallback(rtabmap_ros::CleanupLocalGrids::Request &, rtabmap_ros::CleanupLocalGrids::Response &)
void clearPath(int status)
#define NODELET_WARN(...)
double mappingAltitudeDelta_
virtual void commonOdomCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg)
unsigned int getPathCurrentGoalIndex() const
bool setLogWarn(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::Publisher globalPathNodesPub_
std::string getTopic() const
ros::ServiceServer publishMapDataSrv_
void goalDoneCb(const actionlib::SimpleClientGoalState &state, const move_base_msgs::MoveBaseResultConstPtr &result)
bool isSubscribedToScan2d() const
std::vector< std::pair< int, Transform > > getPathNextPoses() const
ros::ServiceServer detectMoreLoopClosuresSrv_
virtual void commonMultiCameraCallback(const nav_msgs::OdometryConstPtr &odomMsg, const rtabmap_ros::UserDataConstPtr &userDataMsg, const std::vector< cv_bridge::CvImageConstPtr > &imageMsgs, const std::vector< cv_bridge::CvImageConstPtr > &depthMsgs, const std::vector< sensor_msgs::CameraInfo > &cameraInfoMsgs, const std::vector< sensor_msgs::CameraInfo > &depthCameraInfoMsgs, const sensor_msgs::LaserScan &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 >())
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_
int uStrNumCmp(const std::string &a, const std::string &b)
Signature getSignatureCopy(int id, bool images, bool scan, bool userData, bool occupancyGrid, bool withWords, bool withGlobalDescriptors) const
void publishCurrentGoal(const ros::Time &stamp)
std::vector< rtabmap::GlobalDescriptor > globalDescriptorsFromROS(const std::vector< rtabmap_ros::GlobalDescriptor > &msg)
const Signature * getLastWorkingSignature() const
const Statistics & getStatistics() const
static std::string getDir(const std::string &filePath)
ros::ServiceServer addLinkSrv_
void saveParameters(const std::string &configFile)
void setGlobalPose(const Transform &pose, const cv::Mat &covariance)
bool isSubscribedToOdom() const
ros::Subscriber tagDetectionsSub_
bool resetRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::Publisher localGridEmpty_
std::pair< std::string, std::string > ParametersPair
ros::ServiceServer getNodeDataSrv_
bool isIncremental() const
ros::NodeHandle & getNodeHandle() const
bool isGridFromDepth() const
ros::ServiceServer getMapSrv_
int getPathCurrentGoalId() const
bool setModeMappingCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::ServiceServer getGridMapSrv_
rtabmap::Rtabmap rtabmap_
void setInitialPose(const Transform &initialPose)
bool globalBundleAdjustmentCallback(rtabmap_ros::GlobalBundleAdjustment::Request &, rtabmap_ros::GlobalBundleAdjustment::Response &)
bool labelLocation(int id, const std::string &label)
static bool fullMapToMsg(const OctomapT &octomap, Octomap &msg)
bool isServerConnected() const
void goalFeedbackCb(const move_base_msgs::MoveBaseFeedbackConstPtr &feedback)
ros::ServiceServer removeLabelSrv_
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)
rtabmap::Landmarks landmarksFromROS(const std::map< int, std::pair< geometry_msgs::PoseWithCovarianceStamped, float > > &tags, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, tf::TransformListener &listener, double waitForTransform, double defaultLinVariance, double defaultAngVariance)
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 removeLabelCallback(rtabmap_ros::RemoveLabel::Request &req, rtabmap_ros::RemoveLabel::Response &res)
void process(const ros::Time &stamp, rtabmap::SensorData &data, const rtabmap::Transform &odom=rtabmap::Transform(), const std::vector< float > &odomVelocity=std::vector< float >(), const std::string &odomFrameId="", const cv::Mat &odomCovariance=cv::Mat::eye(6, 6, CV_64FC1), const rtabmap::OdometryInfo &odomInfo=rtabmap::OdometryInfo(), double timeMsgConversion=0.0)
std::map< int, Landmark > Landmarks
void interOdomCallback(const nav_msgs::OdometryConstPtr &msg)
ros::Publisher localizationPosePub_
ros::Subscriber fiducialTransfromsSub_
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)
const cv::Mat & data() const
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)
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_
int getLastLocationId() const
void setGPS(const GPS &gps)
bool cancelGoalCallback(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
bool globalBundleAdjustment(int optimizerType=1, bool rematchFeatures=true, int iterations=0, float pixelVariance=0.0f)
bool getPlanCallback(nav_msgs::GetPlan::Request &req, nav_msgs::GetPlan::Response &res)
int getSignatureIdByLabel(const std::string &label, bool lookInDatabase=true) const
ros::NodeHandle & getPrivateNodeHandle() const
double landmarkDefaultAngVariance_
ServiceServer advertiseService(const std::string &service, bool(T::*srv_func)(MReq &, MRes &), T *obj)
void addNodesToRepublish(const std::vector< int > &ids)
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
float getGoalReachedRadius() const
bool setLabelCallback(rtabmap_ros::SetLabel::Request &req, rtabmap_ros::SetLabel::Response &res)
ros::Publisher landmarksPub_
void republishNodeDataCallback(const std_msgs::Int32MultiArray::ConstPtr &msg)
bool lastPoseIntermediate_
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 &)
ros::ServiceServer getMapData2Srv_
ros::ServiceServer cleanupLocalGridsSrv_
const std::map< int, Transform > & poses() const
ros::Publisher nextMetricGoalPub_
float gridCellSize() const
const std::map< int, std::string > & getAllLabels() const
void initialPoseCallback(const geometry_msgs::PoseWithCovarianceStampedConstPtr &msg)
ros::Subscriber initialPoseSub_
void goalCallback(const geometry_msgs::PoseStampedConstPtr &msg)
Transform getMapCorrection() const
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_
bool waitForServer(const ros::Duration &timeout=ros::Duration(0, 0)) const
const std::string & getName() const
std::map< int, Transform > getNodesInRadius(const Transform &pose, float radius, int k=0, std::map< int, float > *distsSqr=0)
static std::string currentDir(bool trailingSeparator=false)
bool odomTFUpdate(const ros::Time &stamp)
std::map< std::string, float > odomInfoToStatistics(const rtabmap::OdometryInfo &info)
int uStr2Int(const std::string &str)
ros::ServiceServer globalBundleAdjustmentSrv_
std::string uNumber2Str(unsigned int number)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
void publish(const boost::shared_ptr< M > &message) const
T uMax3(const T &a, const T &b, const T &c)
rtabmap::OdometryInfo odomInfoFromROS(const rtabmap_ros::OdomInfo &msg, bool ignoreData=false)
void close(bool databaseSaved=true, const std::string &ouputDatabasePath="")
ros::ServiceServer setModeMappingSrv_
ros::Subscriber userDataAsyncSub_
void publishGlobalPath(const ros::Time &stamp)
bool addLinkCallback(rtabmap_ros::AddLink::Request &, rtabmap_ros::AddLink::Response &)
bool isDataSubscribed() const
void save2DMap(const cv::Mat &map, float xMin, float yMin, float cellSize) const
int detectMoreLoopClosures(float clusterRadiusMax=0.5f, float clusterAngle=M_PI/6.0f, int iterations=1, bool intraSession=true, bool interSession=true, const ProgressState *state=0, float clusterRadiusMin=0.0f)
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 >())
std::vector< int > getPathNextNodes() const
double odomDefaultAngVariance_
ros::ServiceServer updateSrv_
bool latestNodeWasReached_
rtabmap::Link linkFromROS(const rtabmap_ros::Link &msg)
bool pauseRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
const Transform & getPathTransformToGoal() const
ros::ServiceServer backupDatabase_
void setupCallbacks(ros::NodeHandle &nh, ros::NodeHandle &pnh, const std::string &name)
ros::ServiceServer setLogInfoSrv_
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_
bool setGoalCallback(rtabmap_ros::SetGoal::Request &req, rtabmap_ros::SetGoal::Response &res)
const Memory * getMemory() const
bool getParam(const std::string &key, std::string &s) const
void commonMultiCameraCallbackImpl(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 std::vector< sensor_msgs::CameraInfo > &depthCameraInfoMsgs, const sensor_msgs::LaserScan &scan2dMsg, const sensor_msgs::PointCloud2 &scan3dMsg, const rtabmap_ros::OdomInfoConstPtr &odomInfoMsg, const std::vector< rtabmap_ros::GlobalDescriptor > &globalDescriptorMsgs, 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 getGridMapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
bool updateRtabmapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
const Transform & mapCorrection() const
void loadParameters(const std::string &configFile, rtabmap::ParametersMap ¶meters)
void interOdomInfoCallback(const nav_msgs::OdometryConstPtr &msg1, const rtabmap_ros::OdomInfoConstPtr &msg2)
static void setEventLevel(ULogger::Level eventSentLevel)
ros::Subscriber interOdomSub_
bool addLink(const Link &link)
bool process(const SensorData &data, Transform odomPose, const cv::Mat &odomCovariance=cv::Mat::eye(6, 6, CV_64FC1), const std::vector< float > &odomVelocity=std::vector< float >(), const std::map< std::string, float > &externalStats=std::map< std::string, float >())
ros::ServiceServer setLabelSrv_
int getPathStatus() const
bool isSubscribedToRGB() const
const Transform & localTransform() const
tf2_ros::TransformBroadcaster tfBroadcaster_
bool triggerNewMapCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
ros::Publisher localGridObstacle_
const std::vector< std::pair< int, Transform > > & getPath() const
const std::multimap< int, Link > & odomCacheConstraints() const
const RtabmapColorOcTree * octree() const
QMap< QString, QVariant > ParametersMap
const std::map< int, Signature > & getSignaturesData() const
const std::multimap< int, Link > & getLocalConstraints() const
message_filters::Subscriber< nav_msgs::Odometry > interOdomSyncSub_
MoveBaseClient * mbClient_
boost::mutex mapToOdomMutex_
float getLocalRadius() const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool uStr2Bool(const char *str)
ros::ServiceServer cancelGoalSrv_
const std::map< int, Transform > & getLocalOptimizedPoses() const
tf::TransformListener tfListener_
bool setModeLocalizationCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
std::list< V > uValues(const std::multimap< K, V > &mm)
void goalNodeCallback(const rtabmap_ros::GoalConstPtr &msg)
bool getProjMapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
bool uContains(const std::list< V > &list, const V &value)
static DBDriver * create(const ParametersMap ¶meters=ParametersMap())
double landmarkDefaultLinVariance_
void parseParameters(const ParametersMap ¶meters)
cv::Mat userDataFromROS(const rtabmap_ros::UserData &dataMsg)
bool hasParam(const std::string &key) const
rtabmap::Transform mapToOdom_
std::vector< float > lastPoseVelocity_
void transformToPoseMsg(const rtabmap::Transform &transform, geometry_msgs::Pose &msg)
const V_string & getMyArgv() const
const std::multimap< int, Link > & constraints() const
void publishMaps(const std::map< int, rtabmap::Transform > &poses, const ros::Time &stamp, const std::string &mapFrameId)
bool convertScanMsg(const sensor_msgs::LaserScan &scan2dMsg, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, rtabmap::LaserScan &scan, tf::TransformListener &listener, double waitForTransform, bool outputInFrameId=false)
const std::map< int, double > & getWorkingMem() const
void sendGoal(const Goal &goal, SimpleDoneCallback done_cb=SimpleDoneCallback(), SimpleActiveCallback active_cb=SimpleActiveCallback(), SimpleFeedbackCallback feedback_cb=SimpleFeedbackCallback())
#define NODELET_INFO(...)
rtabmap::GlobalDescriptor globalDescriptorFromROS(const rtabmap_ros::GlobalDescriptor &msg)
void gpsFixAsyncCallback(const sensor_msgs::NavSatFixConstPtr &gpsFixMsg)
actionlib::SimpleActionClient< move_base_msgs::MoveBaseAction > MoveBaseClient
std::map< int, rtabmap::Transform > filterNodesToAssemble(const std::map< int, rtabmap::Transform > &nodes, const rtabmap::Transform ¤tPose)
const LaserScan & laserScanRaw() const
bool getMapCallback(nav_msgs::GetMap::Request &req, nav_msgs::GetMap::Response &res)
void setGlobalDescriptors(const std::vector< GlobalDescriptor > &descriptors)
int cleanupLocalGrids(const std::map< int, Transform > &mapPoses, const cv::Mat &map, float xMin, float yMin, float cellSize, int cropRadius=1, bool filterScans=false)
SensorData & sensorData()
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
ros::Publisher odomCachePub_
void setParam(const std::string &key, const XmlRpc::XmlRpcValue &v) const
std::list< K > uKeys(const std::multimap< K, V > &mm)
std::string getDatabaseVersion() const
const cv::Mat & gridEmptyCellsRaw() const
boost::thread * transformThread_
rtabmap::Transform currentMetricGoal_
bool setLogError(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
const cv::Mat & gridGroundCellsRaw() const
ros::Subscriber goalNodeSub_
void backwardCompatibilityParameters(ros::NodeHandle &pnh, rtabmap::ParametersMap ¶meters) const
const Transform & getLastLocalizationPose() const
const Signature & getLastSignatureData() const
ros::ServiceServer listLabelsSrv_
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
ParametersMap getLastParameters() const
static std::string getDefaultDatabaseName()
double timestampFromROS(const ros::Time &stamp)
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
float uStr2Float(const std::string &str)
ros::Publisher labelsPub_
static bool exists(const std::string &dirPath)
bool setLogInfo(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
void setLandmarks(const Landmarks &landmarks)
ros::Publisher mapPathPub_
PLUGINLIB_EXPORT_CLASS(rtabmap_ros::CoreWrapper, nodelet::Nodelet)
void setIMU(const IMU &imu)
cv::Mat load2DMap(float &xMin, float &yMin, float &cellSize) const
void setGroundTruth(const Transform &pose)
cv::Mat RTABMAP_EXP cvtDepthFromFloat(const cv::Mat &depth32F)
const cv::Mat & gridObstacleCellsRaw() const
cv::Mat getGridMap(float &xMin, float &yMin, float &gridCellSize)
Transform getPose(int locationId) const
bool isSubscribedToScan3d() const
ros::ServiceServer getPlanNodesSrv_
const cv::Mat & localizationCovariance() const
ros::Publisher localPathPub_
bool getPlanNodesCallback(rtabmap_ros::GetPlan::Request &req, rtabmap_ros::GetPlan::Response &res)
void moveFromPCL(pcl::PCLImage &pcl_image, sensor_msgs::Image &image)
std::map< int, std::pair< geometry_msgs::PoseWithCovarianceStamped, float > > tags_
double waitForTransformDuration_
void goalCommonCallback(int id, const std::string &label, const std::string &frameId, const rtabmap::Transform &pose, const ros::Time &stamp, double *planningTime=0)
std::string groundTruthFrameId_
bool loadDatabaseCallback(rtabmap_ros::LoadDatabase::Request &, rtabmap_ros::LoadDatabase::Response &)
uint32_t getNumSubscribers() const
std::map< double, rtabmap::Transform > imus_
ros::ServiceServer loadDatabaseSrv_
bool backupDatabaseCallback(std_srvs::Empty::Request &, std_srvs::Empty::Response &)
bool hasSubscribers() const
ros::ServiceServer getPlanSrv_
std::list< std::pair< nav_msgs::Odometry, rtabmap_ros::OdomInfo > > interOdoms_
void publishStats(const ros::Time &stamp)
ros::ServiceServer setGoalSrv_
void publishLoop(double tfDelay, double tfTolerance)
ros::Publisher globalPathPub_
bool getMapData2Callback(rtabmap_ros::GetMap2::Request &req, rtabmap_ros::GetMap2::Response &res)
void nodeDataToROS(const rtabmap::Signature &signature, rtabmap_ros::NodeData &msg)
std::string groundTruthBaseFrameId_
ros::ServiceServer setModeLocalizationSrv_
Transform localTransform() const
bool convertScan3dMsg(const sensor_msgs::PointCloud2 &scan3dMsg, const std::string &frameId, const std::string &odomFrameId, const ros::Time &odomStamp, rtabmap::LaserScan &scan, tf::TransformListener &listener, double waitForTransform, int maxPoints=0, float maxRange=0.0f, bool is2D=false)
ros::Publisher goalReachedPub_
bool isSubscribedToStereo() const
LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud< pcl::PointXYZ > &cloud, const Transform &transform=Transform(), bool filterNaNs=true)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
void setFeatures(const std::vector< cv::KeyPoint > &keypoints, const std::vector< cv::Point3f > &keypoints3D, const cv::Mat &descriptors)
const std::map< int, Transform > & odomCachePoses() const
bool isSubscribedToDepth() const
void infoToROS(const rtabmap::Statistics &stats, rtabmap_ros::Info &info)
bool getNodesInRadiusCallback(rtabmap_ros::GetNodesInRadius::Request &, rtabmap_ros::GetNodesInRadius::Response &)
ros::ServiceServer triggerNewMapSrv_
GLM_FUNC_DECL detail::tmat4x4< T, P > orientation(detail::tvec3< T, P > const &Normal, detail::tvec3< T, P > const &Up)
ros::Publisher mapGraphPub_
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
ros::Publisher localGridGround_
ros::ServiceServer resumeSrv_