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_