39 #include <rtabmap/core/Version.h>    42 #include <pcl/search/kdtree.h>    44 #include <nav_msgs/OccupancyGrid.h>    49 #ifdef WITH_OCTOMAP_MSGS    50 #ifdef RTABMAP_OCTOMAP    60                 cloudOutputVoxelized_(
true),
    61                 cloudSubtractFiltering_(
false),
    62                 cloudSubtractFilteringMinNeighbors_(2),
    63                 mapFilterRadius_(0.0),
    64                 mapFilterAngle_(30.0), 
    65                 mapCacheCleanup_(
true),
    66                 alwaysUpdateMap_(
false),
    67                 scanEmptyRayTracing_(
true),
    72 #ifdef WITH_OCTOMAP_MSGS
    73 #ifdef RTABMAP_OCTOMAP
    77                 octomapTreeDepth_(16),
    78                 octomapUpdated_(
true),
    90         if(pnh.
hasParam(
"map_negative_poses_ignored"))
    92                 ROS_WARN(
"Parameter \"map_negative_poses_ignored\" has been "    93                                 "removed. Use \"map_always_update\" instead.");
    94                 if(!pnh.
hasParam(
"map_always_update"))
    97                         pnh.
getParam(
"map_negative_poses_ignored", negPosesIgnored);
   103         if(pnh.
hasParam(
"map_negative_scan_empty_ray_tracing"))
   105                 ROS_WARN(
"Parameter \"map_negative_scan_empty_ray_tracing\" has been "   106                                 "removed. Use \"map_empty_ray_tracing\" instead.");
   107                 if(!pnh.
hasParam(
"map_empty_ray_tracing"))
   114         if(pnh.
hasParam(
"scan_output_voxelized"))
   116                 ROS_WARN(
"Parameter \"scan_output_voxelized\" has been "   117                                 "removed. Use \"cloud_output_voxelized\" instead.");
   118                 if(!pnh.
hasParam(
"cloud_output_voxelized"))
   136 #ifdef WITH_OCTOMAP_MSGS   137 #ifdef RTABMAP_OCTOMAP   141                 ROS_WARN(
"octomap_tree_depth maximum is 16");
   146                 ROS_WARN(
"octomap_tree_depth cannot be negative, set to 16 instead");
   160         if(usePublicNamespace)
   186 #ifdef WITH_OCTOMAP_MSGS   187 #ifdef RTABMAP_OCTOMAP   213 #ifdef WITH_OCTOMAP_MSGS   214 #ifdef RTABMAP_OCTOMAP   226                 const std::string & rosName,
   227                 const std::string & parameterName,
   232                 ParametersMap::const_iterator iter = Parameters::getDefaultParameters().find(parameterName);
   233                 if(iter != Parameters::getDefaultParameters().
end())
   235                         ROS_WARN(
"Parameter \"%s\" has moved from "   236                                          "rtabmap_ros to rtabmap library. Use "   237                                          "parameter \"%s\" instead. The value is still "   238                                          "copied to new parameter name.",
   240                                          parameterName.c_str());
   241                         std::string type = Parameters::getType(parameterName);
   242                         if(type.compare(
"float") || type.compare(
"double"))
   248                         else if(type.compare(
"int") || type.compare(
"unsigned int"))
   254                         else if(type.compare(
"bool"))
   258                                 if(rosName.compare(
"grid_incremental") == 0)
   267                                 ROS_ERROR(
"Not handled type \"%s\" for parameter \"%s\"", type.c_str(), parameterName.c_str());
   272                         ROS_ERROR(
"Parameter \"%s\" not found in default parameters.", parameterName.c_str());
   280         if(pnh.
hasParam(
"cloud_frustum_culling"))
   282                 ROS_WARN(
"Parameter \"cloud_frustum_culling\" has been removed. OctoMap topics "   283                                 "already do it. You can remove it from your launch file.");
   287         parameterMoved(pnh, 
"cloud_decimation", Parameters::kGridDepthDecimation(), parameters);
   288         parameterMoved(pnh, 
"cloud_max_depth", Parameters::kGridRangeMax(), parameters);
   289         parameterMoved(pnh, 
"cloud_min_depth", Parameters::kGridRangeMin(), parameters);
   290         parameterMoved(pnh, 
"cloud_voxel_size", Parameters::kGridCellSize(), parameters);
   291         parameterMoved(pnh, 
"cloud_floor_culling_height", Parameters::kGridMaxGroundHeight(), parameters);
   292         parameterMoved(pnh, 
"cloud_ceiling_culling_height", Parameters::kGridMaxObstacleHeight(), parameters);
   293         parameterMoved(pnh, 
"cloud_noise_filtering_radius", Parameters::kGridNoiseFilteringRadius(), parameters);
   294         parameterMoved(pnh, 
"cloud_noise_filtering_min_neighbors", Parameters::kGridNoiseFilteringMinNeighbors(), parameters);
   295         parameterMoved(pnh, 
"scan_decimation", Parameters::kGridScanDecimation(), parameters);
   296         parameterMoved(pnh, 
"scan_voxel_size", Parameters::kGridCellSize(), parameters);
   297         parameterMoved(pnh, 
"proj_max_ground_angle", Parameters::kGridMaxGroundAngle(), parameters);
   298         parameterMoved(pnh, 
"proj_min_cluster_size", Parameters::kGridMinClusterSize(), parameters);
   299         parameterMoved(pnh, 
"proj_max_height", Parameters::kGridMaxObstacleHeight(), parameters);
   300         parameterMoved(pnh, 
"proj_max_obstacles_height", Parameters::kGridMaxObstacleHeight(), parameters);
   301         parameterMoved(pnh, 
"proj_max_ground_height", Parameters::kGridMaxGroundHeight(), parameters);
   303         parameterMoved(pnh, 
"proj_detect_flat_obstacles", Parameters::kGridFlatObstacleDetected(), parameters);
   304         parameterMoved(pnh, 
"proj_map_frame", Parameters::kGridMapFrameProjection(), parameters);
   305         parameterMoved(pnh, 
"grid_unknown_space_filled", Parameters::kGridScan2dUnknownSpaceFilled(), parameters);
   306         parameterMoved(pnh, 
"grid_cell_size", Parameters::kGridCellSize(), parameters);
   307         parameterMoved(pnh, 
"grid_incremental", Parameters::kGridGlobalFullUpdate(), parameters);
   308         parameterMoved(pnh, 
"grid_size", Parameters::kGridGlobalMinSize(), parameters);
   309         parameterMoved(pnh, 
"grid_eroded", Parameters::kGridGlobalEroded(), parameters);
   310         parameterMoved(pnh, 
"grid_footprint_radius", Parameters::kGridGlobalFootprintRadius(), parameters);
   312 #ifdef WITH_OCTOMAP_MSGS   313 #ifdef RTABMAP_OCTOMAP   314         parameterMoved(pnh, 
"octomap_ground_is_obstacle", Parameters::kGridGroundIsObstacle(), parameters);
   315         parameterMoved(pnh, 
"octomap_occupancy_thr", Parameters::kGridGlobalOccupancyThr(), parameters);
   325 #ifdef WITH_OCTOMAP_MSGS   326 #ifdef RTABMAP_OCTOMAP   342                 const std::map<int, rtabmap::Transform> & poses,
   349                 for(std::map<int, rtabmap::Transform>::const_iterator iter=poses.lower_bound(1); iter!=poses.end(); ++iter)
   351                         std::map<int, std::pair< std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator jter = 
gridMaps_.find(iter->first);
   355                                 data = memory->
getNodeData(iter->first, 
false, 
false, 
false, 
true);
   358                                         ROS_WARN(
"Local occupancy grid doesn't exist for node %d", iter->first);
   362                                         cv::Mat ground, obstacles, emptyCells;
   372                                         uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
   398 #ifdef WITH_OCTOMAP_MSGS   399 #ifdef RTABMAP_OCTOMAP   403         for(std::map<void*, bool>::iterator iter=
latched_.begin(); iter!=
latched_.end(); ++iter)
   405                 iter->second = 
false;
   436         return std::map<int, Transform>();
   440                 const std::map<int, rtabmap::Transform> & posesIn,
   444                 const std::map<int, rtabmap::Signature> & signatures)
   446         bool updateGridCache = updateGrid || updateOctomap;
   447         if(!updateGrid && !updateOctomap)
   464                 updateGridCache = updateOctomap || updateGrid ||
   471 #ifndef WITH_OCTOMAP_MSGS   472         updateOctomap = 
false;
   474 #ifndef RTABMAP_OCTOMAP   475         updateOctomap = 
false;
   482         UDEBUG(
"Updating map caches...");
   484         if(!memory && signatures.size() == 0)
   486                 ROS_ERROR(
"Memory and signatures should not be both null!?");
   487                 return std::map<int, rtabmap::Transform>();
   491         std::map<int, rtabmap::Transform> poses;
   492         if(posesIn.begin()->first < 0)
   494                 poses.insert(posesIn.lower_bound(0), posesIn.end());
   500         std::map<int, rtabmap::Transform> filteredPoses;
   508                         UDEBUG(
"Filter nodes...");
   511                         if(poses.find(0) != poses.end())
   514                                 filteredPoses.insert(*poses.find(0));
   519                         filteredPoses = poses;
   524                         filteredPoses.erase(0);
   527                 bool longUpdate = 
false;
   529                 if(filteredPoses.size() > 20)
   531                         if(updateGridCache && 
gridMaps_.size() < 5)
   533                                 ROS_WARN(
"Many occupancy grids should be loaded (~%d), this may take a while to update the map(s)...", 
int(filteredPoses.size()-
gridMaps_.size()));
   536 #ifdef WITH_OCTOMAP_MSGS   537 #ifdef RTABMAP_OCTOMAP   540                                 ROS_WARN(
"Many clouds should be added to octomap (~%d), this may take a while to update the map(s)...", 
int(filteredPoses.size()-
octomap_->
addedNodes().size()));
   549                 for(std::map<int, rtabmap::Transform>::iterator iter=filteredPoses.begin(); iter!=filteredPoses.end(); ++iter)
   551                         if(!iter->second.isNull())
   556                                         ROS_DEBUG(
"Data required for %d", iter->first);
   557                                         std::map<int, rtabmap::Signature>::const_iterator findIter = signatures.find(iter->first);
   558                                         if(findIter != signatures.end())
   560                                                 data = findIter->second.sensorData();
   567                                         ROS_DEBUG(
"Adding grid map %d to cache...", iter->first);
   568                                         cv::Point3f viewPoint;
   569                                         cv::Mat ground, obstacles, emptyCells;
   575                                                 static bool warningShown = 
false;
   576                                                 if(occupancySavedInDB && generateGrid && !warningShown)
   579                                                         UWARN(
"Occupancy grid for location %d should be added to global map (e..g, a ROS node is subscribed to "   580                                                                         "any occupancy grid output) but it cannot be found "   581                                                                         "in memory. For convenience, the occupancy "   582                                                                         "grid is regenerated. Make sure parameter \"%s\" is true to "   583                                                                         "avoid this warning for the next locations added to map. For older "   584                                                                         "locations already in database without an occupancy grid map, you can use the "   585                                                                         "\"rtabmap-databaseViewer\" to regenerate the missing occupancy grid maps and "   586                                                                         "save them back in the database for next sessions. This warning is only shown once.",
   587                                                                         data.
id(), Parameters::kRGBDCreateOccupancyGrid().c_str());
   589                                                 if(memory && occupancySavedInDB && generateGrid)
   600                                                                 generateGrid?0:&ground,
   601                                                                 generateGrid?0:&obstacles,
   602                                                                 generateGrid?0:&emptyCells);
   609                                                         uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
   615                                                         uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
   623                                                 bool unknownSpaceFilled = Parameters::defaultGridScan2dUnknownSpaceFilled();
   624                                                 Parameters::parse(
parameters_, Parameters::kGridScan2dUnknownSpaceFilled(), unknownSpaceFilled);
   641                                                         generateGrid?0:&ground,
   642                                                         generateGrid?0:&obstacles,
   643                                                         generateGrid?0:&emptyCells);
   650                                                         uInsert(
gridMaps_,  std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
   656                                                         uInsert(
gridMaps_,  std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
   674                                         std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator mter = 
gridMaps_.find(iter->first);
   677                                                 if(!mter->second.first.first.empty() || !mter->second.first.second.empty() || !mter->second.second.empty())
   684 #ifdef WITH_OCTOMAP_MSGS   685 #ifdef RTABMAP_OCTOMAP   690                                         std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator mter = 
gridMaps_.find(iter->first);
   694                                                 if((mter->second.first.first.empty() || mter->second.first.first.channels() > 2) &&
   695                                                    (mter->second.first.second.empty() || mter->second.first.second.channels() > 2) &&
   696                                                    (mter->second.second.empty() || mter->second.second.channels() > 2))
   698                                                         octomap_->
addToCache(iter->first, mter->second.first.first, mter->second.first.second, mter->second.second, pter->second);
   700                                                 else if(!mter->second.first.first.empty() && !mter->second.first.second.empty() && !mter->second.second.empty())
   702                                                         ROS_WARN(
"Node %d: Cannot update octomap with 2D occupancy grids. "   703                                                                         "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see "   704                                                                         "all occupancy grid parameters.",
   714                                 ROS_ERROR(
"Pose null for node %d", iter->first);
   723 #ifdef WITH_OCTOMAP_MSGS   724 #ifdef RTABMAP_OCTOMAP   733                 for(std::map<
int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator iter=
gridMaps_.begin();
   747                 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator iter=
groundClouds_.begin();
   760                 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator iter=
obstacleClouds_.begin();
   779         return filteredPoses;
   783                 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
   786                 int minNeighborsInRadius)
   788         UASSERT(minNeighborsInRadius > 0);
   791         pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(
new pcl::PointCloud<pcl::PointXYZRGB>);
   792         output->resize(cloud->size());
   794         for(
unsigned int i=0; i<cloud->size(); ++i)
   796                 std::vector<std::vector<size_t> > kIndices;
   797                 std::vector<std::vector<float> > kDistances;
   798                 cv::Mat 
pt = (cv::Mat_<float>(1, 3) << cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
   799                 substractCloudIndex.
radiusSearch(pt, kIndices, kDistances, radiusSearch, minNeighborsInRadius, 32, 0, 
false);
   800                 if(kIndices.size() == 1 && kIndices[0].size() < minNeighborsInRadius)
   802                         output->at(oi++) = cloud->at(i);
   810                 const std::map<int, rtabmap::Transform> & poses,
   812                 const std::string & mapFrameId)
   814         ROS_DEBUG(
"Publishing maps... poses=%d", (
int)poses.size());
   830                                 ROS_WARN(
"/scan_map topic is deprecated! Subscribe to /cloud_map topic "   831                                                 "instead with <param name=\"%s\" type=\"string\" value=\"0\"/>. "   832                                                 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see "   833                                                 "all occupancy grid parameters.",
   834                                                 Parameters::kGridSensor().c_str());
   838                                 ROS_WARN(
"/scan_map topic is deprecated! Subscribe to /cloud_map topic instead.");
   843                 bool graphGroundOptimized = 
false;
   844                 bool graphObstacleOptimized = 
false;
   851                 bool graphGroundChanged = updateGround;
   852                 bool graphObstacleChanged = updateObstacles;
   854                 for(std::map<int, Transform>::const_iterator iter=poses.lower_bound(1); iter!=poses.end(); ++iter)
   856                         std::map<int, Transform>::const_iterator jter;
   862                                         graphGroundChanged = 
false;
   863                                         UASSERT(!iter->second.isNull() && !jter->second.isNull());
   864                                         if(iter->second.getDistanceSquared(jter->second) > updateErrorSqr)
   866                                                 graphGroundOptimized = 
true;
   875                                         graphObstacleChanged = 
false;
   876                                         UASSERT(!iter->second.isNull() && !jter->second.isNull());
   877                                         if(iter->second.getDistanceSquared(jter->second) > updateErrorSqr)
   879                                                 graphObstacleOptimized = 
true;
   884                 int countObstacles = 0;
   885                 int countGrounds = 0;
   888                 if(graphGroundOptimized || graphGroundChanged)
   896                 if(graphObstacleOptimized || graphObstacleChanged )
   905                 if(graphGroundOptimized || graphObstacleOptimized)
   907                         ROS_INFO(
"Graph has changed, updating clouds...");
   909                         cv::Mat tmpGroundPts;
   910                         cv::Mat tmpObstaclePts;
   911                         for(std::map<int, Transform>::const_iterator iter = poses.lower_bound(1); iter!=poses.end(); ++iter)
   916                                         std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator kter=
groundClouds_.find(iter->first);
   920                                                 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::transformPointCloud(kter->second, iter->second);
   924                                                         for(
unsigned int i=0; i<transformed->size(); ++i)
   926                                                                 if(tmpGroundPts.empty())
   928                                                                         tmpGroundPts = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
   929                                                                         tmpGroundPts.reserve(previousIndexedGroundSize>0?previousIndexedGroundSize:100);
   933                                                                         cv::Mat 
pt = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
   934                                                                         tmpGroundPts.push_back(pt);
   941                                 if(updateObstacles  &&
   944                                         std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator kter=
obstacleClouds_.find(iter->first);
   948                                                 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::transformPointCloud(kter->second, iter->second);
   952                                                         for(
unsigned int i=0; i<transformed->size(); ++i)
   954                                                                 if(tmpObstaclePts.empty())
   956                                                                         tmpObstaclePts = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
   957                                                                         tmpObstaclePts.reserve(previousIndexedObstacleSize>0?previousIndexedObstacleSize:100);
   961                                                                         cv::Mat 
pt = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
   962                                                                         tmpObstaclePts.push_back(pt);
   970                                                 std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator jter = 
gridMaps_.find(iter->first);
   974                         double addingPointsTime = t.
ticks();
   976                         if(graphGroundOptimized && !tmpGroundPts.empty())
   980                         if(graphObstacleOptimized && !tmpObstaclePts.empty())
   984                         double indexingTime = t.
ticks();
   985                         ROS_INFO(
"Graph optimized! Time recreating clouds (%d ground, %d obstacles) = %f s (indexing %fs)", countGrounds, countObstacles, addingPointsTime+indexingTime, indexingTime);
   987                 else if(graphGroundChanged || graphObstacleChanged)
   989                         ROS_WARN(
"Graph has changed! The whole cloud is regenerated.");
   992                 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
   994                         std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator jter = 
gridMaps_.find(iter->first);
  1001                                 if(jter!=
gridMaps_.end() && jter->second.first.first.cols)
  1003                                         pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(jter->second.first.first), iter->second, 0, 255, 0);
  1004                                         pcl::PointCloud<pcl::PointXYZRGB>::Ptr subtractedCloud = transformed;
  1011                                                 if(subtractedCloud->size())
  1014                                                         cv::Mat pts(subtractedCloud->size(), 3, CV_32FC1);
  1015                                                         for(
unsigned int i=0; i<subtractedCloud->size(); ++i)
  1017                                                                 pts.at<
float>(i, 0) = subtractedCloud->at(i).x;
  1018                                                                 pts.at<
float>(i, 1) = subtractedCloud->at(i).y;
  1019                                                                 pts.at<
float>(i, 2) = subtractedCloud->at(i).z;
  1033                                                 groundClouds_.insert(std::make_pair(iter->first, util3d::transformPointCloud(subtractedCloud, iter->second.inverse())));
  1035                                         if(subtractedCloud->size())
  1048                                 if(jter!=
gridMaps_.end() && jter->second.first.second.cols)
  1050                                         pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(jter->second.first.second), iter->second, 255, 0, 0);
  1051                                         pcl::PointCloud<pcl::PointXYZRGB>::Ptr subtractedCloud = transformed;
  1058                                                 if(subtractedCloud->size())
  1061                                                         cv::Mat pts(subtractedCloud->size(), 3, CV_32FC1);
  1062                                                         for(
unsigned int i=0; i<subtractedCloud->size(); ++i)
  1064                                                                 pts.at<
float>(i, 0) = subtractedCloud->at(i).x;
  1065                                                                 pts.at<
float>(i, 1) = subtractedCloud->at(i).y;
  1066                                                                 pts.at<
float>(i, 2) = subtractedCloud->at(i).z;
  1080                                                 obstacleClouds_.insert(std::make_pair(iter->first, util3d::transformPointCloud(subtractedCloud, iter->second.inverse())));
  1082                                         if(subtractedCloud->size())
  1104                 ROS_INFO(
"Assembled %d obstacle and %d ground clouds (%d points, %fs)",
  1107                 if( countGrounds > 0 ||
  1108                         countObstacles > 0 ||
  1118                                 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
  1120                                 cloudMsg->header.stamp = 
stamp;
  1121                                 cloudMsg->header.frame_id = mapFrameId;
  1127                                 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
  1129                                 cloudMsg->header.stamp = 
stamp;
  1130                                 cloudMsg->header.frame_id = mapFrameId;
  1137                                 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
  1139                                 cloudMsg->header.stamp = 
stamp;
  1140                                 cloudMsg->header.frame_id = mapFrameId;
  1159                         size_t totalBytes = 0;
  1160                         for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator iter=
groundClouds_.begin();iter!=
groundClouds_.end();++iter)
  1162                                 totalBytes += 
sizeof(int) + iter->second->points.size()*
sizeof(pcl::PointXYZRGB);
  1166                                 totalBytes += 
sizeof(int) + iter->second->points.size()*
sizeof(pcl::PointXYZRGB);
  1172                         ROS_INFO(
"MapsManager: cleanup point clouds (%ld points, %ld cached clouds, ~%ld MB)...",
  1175                                         totalBytes/1048576);
  1203 #ifdef WITH_OCTOMAP_MSGS  1204 #ifdef RTABMAP_OCTOMAP  1218                         octomap_msgs::Octomap msg;
  1220                         msg.header.frame_id = mapFrameId;
  1221                         msg.header.stamp = 
stamp;
  1227                         octomap_msgs::Octomap msg;
  1229                         msg.header.frame_id = mapFrameId;
  1230                         msg.header.stamp = 
stamp;
  1240                         sensor_msgs::PointCloud2 msg;
  1241                         pcl::IndicesPtr obstacleIndices(
new std::vector<int>);
  1242                         pcl::IndicesPtr frontierIndices(
new std::vector<int>);
  1243                         pcl::IndicesPtr emptyIndices(
new std::vector<int>);
  1244                         pcl::IndicesPtr groundIndices(
new std::vector<int>);
  1245                         pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = 
octomap_->
createCloud(
octomapTreeDepth_, obstacleIndices.get(), emptyIndices.get(), groundIndices.get(), 
true, frontierIndices.get(),0);
  1249                                 pcl::PointCloud<pcl::PointXYZRGB> cloudOccupiedSpace;
  1250                                 pcl::IndicesPtr indices = util3d::concatenate(obstacleIndices, groundIndices);
  1251                                 pcl::copyPointCloud(*cloud, *indices, cloudOccupiedSpace);
  1253                                 msg.header.frame_id = mapFrameId;
  1254                                 msg.header.stamp = 
stamp;
  1260                                 pcl::PointCloud<pcl::PointXYZRGB> cloudFrontier;
  1261                                 pcl::copyPointCloud(*cloud, *frontierIndices, cloudFrontier);
  1263                                 msg.header.frame_id = mapFrameId;
  1264                                 msg.header.stamp = 
stamp;
  1270                                 pcl::PointCloud<pcl::PointXYZRGB> cloudObstacles;
  1271                                 pcl::copyPointCloud(*cloud, *obstacleIndices, cloudObstacles);
  1273                                 msg.header.frame_id = mapFrameId;
  1274                                 msg.header.stamp = 
stamp;
  1280                                 pcl::PointCloud<pcl::PointXYZRGB> cloudGround;
  1281                                 pcl::copyPointCloud(*cloud, *groundIndices, cloudGround);
  1283                                 msg.header.frame_id = mapFrameId;
  1284                                 msg.header.stamp = 
stamp;
  1290                                 pcl::PointCloud<pcl::PointXYZRGB> cloudEmptySpace;
  1291                                 pcl::copyPointCloud(*cloud, *emptyIndices, cloudEmptySpace);
  1293                                 msg.header.frame_id = mapFrameId;
  1294                                 msg.header.stamp = 
stamp;
  1302                         float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
  1308                                 nav_msgs::OccupancyGrid map;
  1309                                 map.info.resolution = gridCellSize;
  1310                                 map.info.origin.position.x = 0.0;
  1311                                 map.info.origin.position.y = 0.0;
  1312                                 map.info.origin.position.z = 0.0;
  1313                                 map.info.origin.orientation.x = 0.0;
  1314                                 map.info.origin.orientation.y = 0.0;
  1315                                 map.info.origin.orientation.z = 0.0;
  1316                                 map.info.origin.orientation.w = 1.0;
  1318                                 map.info.width = pixels.cols;
  1319                                 map.info.height = pixels.rows;
  1320                                 map.info.origin.position.x = xMin;
  1321                                 map.info.origin.position.y = yMin;
  1322                                 map.data.resize(map.info.width * map.info.height);
  1324                                 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
  1326                                 map.header.frame_id = mapFrameId;
  1327                                 map.header.stamp = 
stamp;
  1332                         else if(poses.size())
  1334                                 ROS_WARN(
"Octomap projection map is empty! (poses=%d octomap nodes=%d). "  1335                                                 "Make sure you enabled \"%s\" and set \"%s\"=1. "  1336                                                 "See \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" for more info.",
  1338                                                 Parameters::kGrid3D().c_str(), Parameters::kGridSensor().c_str());
  1355                         ROS_INFO(
"MapsManager: cleanup octomap (%ld leaf nodes, ~%ld MB)...",
  1409                                 ROS_WARN(
"/proj_map topic is deprecated! Subscribe to /grid_map topic "  1410                                                 "instead with <param name=\"%s\" type=\"string\" value=\"1\"/>. "  1411                                                 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see "  1412                                                 "all occupancy grid parameters.",
  1413                                                 Parameters::kGridSensor().c_str());
  1417                                 ROS_WARN(
"/proj_map topic is deprecated! Subscribe to /grid_map topic instead.");
  1424                         float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
  1429                                 nav_msgs::OccupancyGrid map;
  1430                                 map.info.resolution = gridCellSize;
  1431                                 map.info.origin.position.x = 0.0;
  1432                                 map.info.origin.position.y = 0.0;
  1433                                 map.info.origin.position.z = 0.0;
  1434                                 map.info.origin.orientation.x = 0.0;
  1435                                 map.info.origin.orientation.y = 0.0;
  1436                                 map.info.origin.orientation.z = 0.0;
  1437                                 map.info.origin.orientation.w = 1.0;
  1439                                 map.info.width = pixels.cols;
  1440                                 map.info.height = pixels.rows;
  1441                                 map.info.origin.position.x = xMin;
  1442                                 map.info.origin.position.y = yMin;
  1443                                 map.data.resize(map.info.width * map.info.height);
  1445                                 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
  1447                                 map.header.frame_id = mapFrameId;
  1448                                 map.header.stamp = 
stamp;
  1456                         else if(poses.size())
  1464                         float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
  1465                         cv::Mat pixels = this->
getGridMap(xMin, yMin, gridCellSize);
  1470                                 nav_msgs::OccupancyGrid map;
  1471                                 map.info.resolution = gridCellSize;
  1472                                 map.info.origin.position.x = 0.0;
  1473                                 map.info.origin.position.y = 0.0;
  1474                                 map.info.origin.position.z = 0.0;
  1475                                 map.info.origin.orientation.x = 0.0;
  1476                                 map.info.origin.orientation.y = 0.0;
  1477                                 map.info.origin.orientation.z = 0.0;
  1478                                 map.info.origin.orientation.w = 1.0;
  1480                                 map.info.width = pixels.cols;
  1481                                 map.info.height = pixels.rows;
  1482                                 map.info.origin.position.x = xMin;
  1483                                 map.info.origin.position.y = yMin;
  1484                                 map.data.resize(map.info.width * map.info.height);
  1486                                 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
  1488                                 map.header.frame_id = mapFrameId;
  1489                                 map.header.stamp = 
stamp;
  1502                         else if(poses.size())
  1526                         size_t totalBytes = 0;
  1527                         for(std::map<
int, std::pair< std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator iter=
gridMaps_.begin(); iter!=
gridMaps_.end(); ++iter)
  1529                                 totalBytes+= 
sizeof(int)+
  1530                                                 iter->second.first.first.total()*iter->second.first.first.elemSize() +
  1531                                                 iter->second.first.second.total()*iter->second.first.second.elemSize() +
  1532                                                 iter->second.second.total()*iter->second.second.elemSize();
  1535                         ROS_INFO(
"MapsManager: cleanup %ld grid maps (~%ld MB)...", 
gridMaps_.size(), totalBytes/1048576);
  1545                 float & gridCellSize)
  1554                 float & gridCellSize)
 std::map< int, cv::Point3f > gridMapsViewpoints_
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)
int cloudSubtractFilteringMinNeighbors_
bool update(const std::map< int, Transform > &poses)
ros::Publisher octoMapObstacleCloud_
void setParameters(const rtabmap::ParametersMap ¶meters)
ros::Publisher cloudGroundPub_
pcl::PointCloud< pcl::PointXYZRGB >::Ptr createCloud(unsigned int treeDepth=0, std::vector< int > *obstacleIndices=0, std::vector< int > *emptyIndices=0, std::vector< int > *groundIndices=0, bool originalRefPoints=true, std::vector< int > *frontierIndices=0, std::vector< double > *cloudProb=0) const
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
float getCellSize() const
cv::Mat getProbMap(float &xMin, float &yMin) const
double uStr2Double(const std::string &str)
ros::Publisher gridMapPub_
rtabmap::OccupancyGrid * occupancyGrid_
int uStrNumCmp(const std::string &a, const std::string &b)
float getUpdateError() const
std::pair< std::string, std::string > ParametersPair
ros::Publisher scanMapPub_
bool isGridFromDepth() const
static bool fullMapToMsg(const OctomapT &octomap, Octomap &msg)
void radiusSearch(const cv::Mat &query, std::vector< std::vector< size_t > > &indices, std::vector< std::vector< float > > &dists, float radius, int maxNeighbors=0, int checks=32, float eps=0.0, bool sorted=true) const
bool cloudOutputVoxelized_
std::map< void *, bool > latched_
ros::Publisher octoMapCloud_
std::map< std::string, std::string > ParametersMap
cv::Mat getGridProbMap(float &xMin, float &yMin, float &gridCellSize)
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
sensor_msgs::PointCloud2 PointCloud
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledObstacles_
std::map< int, pcl::PointCloud< pcl::PointXYZRGB >::Ptr > groundClouds_
rtabmap::OctoMap * octomap_
geometry_msgs::TransformStamped t
bool cloudSubtractFiltering_
static bool binaryMapToMsg(const OctomapT &octomap, Octomap &msg)
std::string uBool2Str(bool boolean)
void setMap(const cv::Mat &map, float xMin, float yMin, float cellSize, const std::map< int, Transform > &poses)
rtabmap::ParametersMap parameters_
float gridCellSize() const
ros::Publisher octoMapPubFull_
#define UASSERT(condition)
bool update(const std::map< int, Transform > &poses)
void init(ros::NodeHandle &nh, ros::NodeHandle &pnh, const std::string &name, bool usePublicNamespace)
void addToCache(int nodeId, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &ground, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &obstacles, const pcl::PointXYZ &viewPoint)
int uStr2Int(const std::string &str)
std::string uNumber2Str(unsigned int number)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
ros::Publisher cloudMapPub_
void publish(const boost::shared_ptr< M > &message) const
const std::map< int, Transform > & addedNodes() const
ros::Publisher octoMapPubBin_
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 >())
void addToCache(int nodeId, const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty)
bool getParam(const std::string &key, std::string &s) const
std::map< int, std::pair< std::pair< cv::Mat, cv::Mat >, cv::Mat > > gridMaps_
rtabmap::FlannIndex assembledGroundIndex_
float getMinMapSize() const
void buildKDTreeSingleIndex(const cv::Mat &features, int leafMaxSize=10, bool reorder=true, bool useDistanceL1=false, float rebalancingFactor=2.0f)
ros::Publisher projMapPub_
unsigned int indexedFeatures() const
cv::Mat getMap(float &xMin, float &yMin) const
const RtabmapColorOcTree * octree() const
QMap< QString, QVariant > ParametersMap
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool uStr2Bool(const char *str)
bool uContains(const std::list< V > &list, const V &value)
SensorData getNodeData(int locationId, bool images, bool scan, bool userData, bool occupancyGrid) const
void setPose(const Transform &pose)
bool hasParam(const std::string &key) const
rtabmap::FlannIndex assembledObstacleIndex_
const std::map< int, Transform > & addedNodes() const
void publishMaps(const std::map< int, rtabmap::Transform > &poses, const ros::Time &stamp, const std::string &mapFrameId)
void parameterMoved(ros::NodeHandle &nh, const std::string &rosName, const std::string ¶meterName, ParametersMap ¶meters)
const cv::Point3f & gridViewPoint() const
bool scanEmptyRayTracing_
pcl::PointCloud< pcl::PointXYZRGB >::Ptr subtractFiltering(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const rtabmap::FlannIndex &substractCloudIndex, float radiusSearch, int minNeighborsInRadius)
std::string getDatabaseVersion() const
void createLocalMap(const Signature &node, cv::Mat &groundCells, cv::Mat &obstacleCells, cv::Mat &emptyCells, cv::Point3f &viewPoint)
void backwardCompatibilityParameters(ros::NodeHandle &pnh, rtabmap::ParametersMap ¶meters) const
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
ros::Publisher octoMapEmptySpace_
ros::Publisher octoMapFrontierCloud_
std::vector< unsigned int > addPoints(const cv::Mat &features)
ros::Publisher octoMapGroundCloud_
std::map< int, pcl::PointCloud< pcl::PointXYZRGB >::Ptr > obstacleClouds_
void parseParameters(const ParametersMap ¶meters)
cv::Mat getGridMap(float &xMin, float &yMin, float &gridCellSize)
ros::Publisher octoMapProj_
cv::Mat createProjectionMap(float &xMin, float &yMin, float &gridCellSize, float minGridSize=0.0f, unsigned int treeDepth=0)
uint32_t getNumSubscribers() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledGround_
bool hasSubscribers() const
ros::Publisher cloudObstaclesPub_
ros::Publisher gridProbMapPub_
std::map< int, rtabmap::Transform > assembledGroundPoses_
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
std::map< int, rtabmap::Transform > assembledObstaclePoses_