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 negativePosesIgnored_(
true),
67 negativeScanEmptyRayTracing_(
true),
85 if(pnh.
hasParam(
"scan_output_voxelized"))
87 ROS_WARN(
"Parameter \"scan_output_voxelized\" has been " 88 "removed. Use \"cloud_output_voxelized\" instead.");
89 if(!pnh.
hasParam(
"cloud_output_voxelized"))
107 #ifdef WITH_OCTOMAP_MSGS 108 #ifdef RTABMAP_OCTOMAP 113 ROS_WARN(
"octomap_tree_depth maximum is 16");
118 ROS_WARN(
"octomap_tree_depth cannot be negative, set to 16 instead");
129 pnh.
param(
"latch", latch, latch);
133 if(usePublicNamespace)
151 #ifdef WITH_OCTOMAP_MSGS 152 #ifdef RTABMAP_OCTOMAP 169 #ifdef WITH_OCTOMAP_MSGS 170 #ifdef RTABMAP_OCTOMAP 182 const std::string & rosName,
183 const std::string & parameterName,
188 ParametersMap::const_iterator iter = Parameters::getDefaultParameters().find(parameterName);
189 if(iter != Parameters::getDefaultParameters().end())
191 ROS_WARN(
"Parameter \"%s\" has moved from " 192 "rtabmap_ros to rtabmap library. Use " 193 "parameter \"%s\" instead. The value is still " 194 "copied to new parameter name.",
196 parameterName.c_str());
197 std::string type = Parameters::getType(parameterName);
198 if(type.compare(
"float") || type.compare(
"double"))
204 else if(type.compare(
"int") || type.compare(
"unsigned int"))
210 else if(type.compare(
"bool"))
214 if(rosName.compare(
"grid_incremental") == 0)
223 ROS_ERROR(
"Not handled type \"%s\" for parameter \"%s\"", type.c_str(), parameterName.c_str());
228 ROS_ERROR(
"Parameter \"%s\" not found in default parameters.", parameterName.c_str());
236 if(pnh.
hasParam(
"cloud_frustum_culling"))
238 ROS_WARN(
"Parameter \"cloud_frustum_culling\" has been removed. OctoMap topics " 239 "already do it. You can remove it from your launch file.");
243 parameterMoved(pnh,
"cloud_decimation", Parameters::kGridDepthDecimation(), parameters);
244 parameterMoved(pnh,
"cloud_max_depth", Parameters::kGridRangeMax(), parameters);
245 parameterMoved(pnh,
"cloud_min_depth", Parameters::kGridRangeMin(), parameters);
246 parameterMoved(pnh,
"cloud_voxel_size", Parameters::kGridCellSize(), parameters);
247 parameterMoved(pnh,
"cloud_floor_culling_height", Parameters::kGridMaxGroundHeight(), parameters);
248 parameterMoved(pnh,
"cloud_ceiling_culling_height", Parameters::kGridMaxObstacleHeight(), parameters);
249 parameterMoved(pnh,
"cloud_noise_filtering_radius", Parameters::kGridNoiseFilteringRadius(), parameters);
250 parameterMoved(pnh,
"cloud_noise_filtering_min_neighbors", Parameters::kGridNoiseFilteringMinNeighbors(), parameters);
251 parameterMoved(pnh,
"scan_decimation", Parameters::kGridScanDecimation(), parameters);
252 parameterMoved(pnh,
"scan_voxel_size", Parameters::kGridCellSize(), parameters);
253 parameterMoved(pnh,
"proj_max_ground_angle", Parameters::kGridMaxGroundAngle(), parameters);
254 parameterMoved(pnh,
"proj_min_cluster_size", Parameters::kGridMinClusterSize(), parameters);
255 parameterMoved(pnh,
"proj_max_height", Parameters::kGridMaxObstacleHeight(), parameters);
256 parameterMoved(pnh,
"proj_max_obstacles_height", Parameters::kGridMaxObstacleHeight(), parameters);
257 parameterMoved(pnh,
"proj_max_ground_height", Parameters::kGridMaxGroundHeight(), parameters);
259 parameterMoved(pnh,
"proj_detect_flat_obstacles", Parameters::kGridFlatObstacleDetected(), parameters);
260 parameterMoved(pnh,
"proj_map_frame", Parameters::kGridMapFrameProjection(), parameters);
261 parameterMoved(pnh,
"grid_unknown_space_filled", Parameters::kGridScan2dUnknownSpaceFilled(), parameters);
262 parameterMoved(pnh,
"grid_cell_size", Parameters::kGridCellSize(), parameters);
263 parameterMoved(pnh,
"grid_incremental", Parameters::kGridGlobalFullUpdate(), parameters);
264 parameterMoved(pnh,
"grid_size", Parameters::kGridGlobalMinSize(), parameters);
265 parameterMoved(pnh,
"grid_eroded", Parameters::kGridGlobalEroded(), parameters);
266 parameterMoved(pnh,
"grid_footprint_radius", Parameters::kGridGlobalFootprintRadius(), parameters);
268 #ifdef WITH_OCTOMAP_MSGS 269 #ifdef RTABMAP_OCTOMAP 270 parameterMoved(pnh,
"octomap_ground_is_obstacle", Parameters::kGridGroundIsObstacle(), parameters);
271 parameterMoved(pnh,
"octomap_occupancy_thr", Parameters::kGridGlobalOccupancyThr(), parameters);
281 #ifdef WITH_OCTOMAP_MSGS 282 #ifdef RTABMAP_OCTOMAP 298 const std::map<int, rtabmap::Transform> & poses,
305 for(std::map<int, rtabmap::Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
307 std::map<int, std::pair< std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator jter =
gridMaps_.find(iter->first);
314 ROS_WARN(
"Local occupancy grid doesn't exist for node %d", iter->first);
318 cv::Mat ground, obstacles, emptyCells;
328 uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
354 #ifdef WITH_OCTOMAP_MSGS 355 #ifdef RTABMAP_OCTOMAP 387 return std::map<int, Transform>();
391 const std::map<int, rtabmap::Transform> & poses,
395 const std::map<int, rtabmap::Signature> & signatures)
397 bool updateGridCache = updateGrid || updateOctomap;
398 if(!updateGrid && !updateOctomap)
414 updateGridCache = updateOctomap || updateGrid ||
421 #ifndef WITH_OCTOMAP_MSGS 422 updateOctomap =
false;
424 #ifndef RTABMAP_OCTOMAP 425 updateOctomap =
false;
429 UDEBUG(
"Updating map caches...");
431 if(!memory && signatures.size() == 0)
433 ROS_ERROR(
"Memory and signatures should not be both null!?");
434 return std::map<int, rtabmap::Transform>();
437 std::map<int, rtabmap::Transform> filteredPoses;
445 UDEBUG(
"Filter nodes...");
448 for(std::map<int, rtabmap::Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
453 filteredPoses.insert(*iter);
463 filteredPoses = poses;
468 for(std::map<int, rtabmap::Transform>::iterator iter=filteredPoses.begin(); iter!=filteredPoses.end();)
472 filteredPoses.erase(iter++);
481 bool longUpdate =
false;
483 if(filteredPoses.size() > 20)
485 if(updateGridCache &&
gridMaps_.size() < 5)
487 ROS_WARN(
"Many occupancy grids should be loaded (~%d), this may take a while to update the map(s)...",
int(filteredPoses.size()-
gridMaps_.size()));
490 #ifdef WITH_OCTOMAP_MSGS 491 #ifdef RTABMAP_OCTOMAP 494 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()));
503 for(std::map<int, rtabmap::Transform>::iterator iter=filteredPoses.begin(); iter!=filteredPoses.end(); ++iter)
505 if(!iter->second.isNull())
510 UDEBUG(
"Data required for %d", iter->first);
511 std::map<int, rtabmap::Signature>::const_iterator findIter = signatures.find(iter->first);
512 if(findIter != signatures.end())
514 data = findIter->second.sensorData();
523 UDEBUG(
"Adding grid map %d to cache...", iter->first);
524 cv::Point3f viewPoint;
525 cv::Mat ground, obstacles, emptyCells;
531 static bool warningShown =
false;
532 if(occupancySavedInDB && generateGrid && !warningShown)
535 UWARN(
"Occupancy grid for location %d should be added to global map (e..g, a ROS node is subscribed to " 536 "any occupancy grid output) but it cannot be found " 537 "in memory. For convenience, the occupancy " 538 "grid is regenerated. Make sure parameter \"%s\" is true to " 539 "avoid this warning for the next locations added to map. For older " 540 "locations already in database without an occupancy grid map, you can use the " 541 "\"rtabmap-databaseViewer\" to regenerate the missing occupancy grid maps and " 542 "save them back in the database for next sessions. This warning is only shown once.",
543 data.
id(), Parameters::kRGBDCreateOccupancyGrid().c_str());
545 if(memory && occupancySavedInDB && generateGrid)
556 generateGrid?0:&ground,
557 generateGrid?0:&obstacles,
558 generateGrid?0:&emptyCells);
565 uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
571 uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
579 bool unknownSpaceFilled = Parameters::defaultGridScan2dUnknownSpaceFilled();
580 Parameters::parse(
parameters_, Parameters::kGridScan2dUnknownSpaceFilled(), unknownSpaceFilled);
597 generateGrid?0:&ground,
598 generateGrid?0:&obstacles,
599 generateGrid?0:&emptyCells);
606 uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
612 uInsert(
gridMaps_, std::make_pair(iter->first, std::make_pair(std::make_pair(ground, obstacles), emptyCells)));
627 ROS_ERROR(
"Data missing for node %d to update the maps", iter->first);
635 std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator mter =
gridMaps_.find(iter->first);
638 if(!mter->second.first.first.empty() || !mter->second.first.second.empty())
645 #ifdef WITH_OCTOMAP_MSGS 646 #ifdef RTABMAP_OCTOMAP 651 std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator mter =
gridMaps_.find(iter->first);
655 if((mter->second.first.first.empty() || mter->second.first.first.channels() > 2) &&
656 (mter->second.first.second.empty() || mter->second.first.second.channels() > 2))
658 octomap_->
addToCache(iter->first, mter->second.first.first, mter->second.first.second, mter->second.second, pter->second);
660 else if(!mter->second.first.first.empty() && !mter->second.first.second.empty())
662 ROS_WARN(
"Node %d: Cannot update octomap with 2D occupancy grids. " 663 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see " 664 "all occupancy grid parameters.",
674 ROS_ERROR(
"Pose null for node %d", iter->first);
683 #ifdef WITH_OCTOMAP_MSGS 684 #ifdef RTABMAP_OCTOMAP 693 for(std::map<
int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator iter=
gridMaps_.begin();
707 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator iter=
groundClouds_.begin();
720 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator iter=
obstacleClouds_.begin();
739 return filteredPoses;
743 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
746 int minNeighborsInRadius)
748 UASSERT(minNeighborsInRadius > 0);
751 pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(
new pcl::PointCloud<pcl::PointXYZRGB>);
752 output->resize(cloud->size());
754 for(
unsigned int i=0; i<cloud->size(); ++i)
756 std::vector<std::vector<size_t> > kIndices;
757 std::vector<std::vector<float> > kDistances;
758 cv::Mat pt = (cv::Mat_<float>(1, 3) << cloud->at(i).x, cloud->at(i).y, cloud->at(i).z);
759 substractCloudIndex.
radiusSearch(pt, kIndices, kDistances, radiusSearch, minNeighborsInRadius, 32, 0,
false);
760 if(kIndices.size() == 1 && kIndices[0].size() < minNeighborsInRadius)
762 output->at(oi++) = cloud->at(i);
770 const std::map<int, rtabmap::Transform> & poses,
772 const std::string & mapFrameId)
774 UDEBUG(
"Publishing maps...");
790 ROS_WARN(
"/scan_map topic is deprecated! Subscribe to /cloud_map topic " 791 "instead with <param name=\"%s\" type=\"string\" value=\"false\"/>. " 792 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see " 793 "all occupancy grid parameters.",
794 Parameters::kGridFromDepth().c_str());
798 ROS_WARN(
"/scan_map topic is deprecated! Subscribe to /cloud_map topic instead.");
803 bool graphGroundOptimized =
false;
804 bool graphObstacleOptimized =
false;
811 bool graphGroundChanged = updateGround;
812 bool graphObstacleChanged = updateObstacles;
813 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
815 std::map<int, Transform>::const_iterator jter;
821 graphGroundChanged =
false;
822 UASSERT(!iter->second.isNull() && !jter->second.isNull());
823 if(iter->second.getDistanceSquared(jter->second) > 0.0001)
825 graphGroundOptimized =
true;
834 graphObstacleChanged =
false;
835 UASSERT(!iter->second.isNull() && !jter->second.isNull());
836 if(iter->second.getDistanceSquared(jter->second) > 0.0001)
838 graphObstacleOptimized =
true;
843 int countObstacles = 0;
844 int countGrounds = 0;
847 if(graphGroundOptimized || graphGroundChanged)
855 if(graphObstacleOptimized || graphObstacleChanged )
864 if(graphGroundOptimized || graphObstacleOptimized)
866 ROS_INFO(
"Graph has changed, updating clouds...");
868 cv::Mat tmpGroundPts;
869 cv::Mat tmpObstaclePts;
870 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
878 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator kter=
groundClouds_.find(iter->first);
881 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::transformPointCloud(kter->second, iter->second);
885 for(
unsigned int i=0; i<transformed->size(); ++i)
887 if(tmpGroundPts.empty())
889 tmpGroundPts = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
890 tmpGroundPts.reserve(previousIndexedGroundSize>0?previousIndexedGroundSize:100);
894 cv::Mat pt = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
895 tmpGroundPts.push_back(pt);
902 if(updateObstacles &&
906 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr >::iterator kter=
obstacleClouds_.find(iter->first);
909 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::transformPointCloud(kter->second, iter->second);
913 for(
unsigned int i=0; i<transformed->size(); ++i)
915 if(tmpObstaclePts.empty())
917 tmpObstaclePts = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
918 tmpObstaclePts.reserve(previousIndexedObstacleSize>0?previousIndexedObstacleSize:100);
922 cv::Mat pt = (cv::Mat_<float>(1, 3) << transformed->at(i).x, transformed->at(i).y, transformed->at(i).z);
923 tmpObstaclePts.push_back(pt);
932 double addingPointsTime = t.
ticks();
934 if(graphGroundOptimized && !tmpGroundPts.empty())
938 if(graphObstacleOptimized && !tmpObstaclePts.empty())
942 double indexingTime = t.
ticks();
943 UINFO(
"Graph optimized! Time recreating clouds (%d ground, %d obstacles) = %f s (indexing %fs)", countGrounds, countObstacles, addingPointsTime+indexingTime, indexingTime);
945 else if(graphGroundChanged || graphObstacleChanged)
947 UWARN(
"Graph has changed! The whole cloud is regenerated.");
950 for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
952 std::map<int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator jter =
gridMaps_.find(iter->first);
959 if(jter!=
gridMaps_.end() && jter->second.first.first.cols)
961 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(jter->second.first.first), iter->second, 0, 255, 0);
962 pcl::PointCloud<pcl::PointXYZRGB>::Ptr subtractedCloud = transformed;
969 if(subtractedCloud->size())
972 cv::Mat pts(subtractedCloud->size(), 3, CV_32FC1);
973 for(
unsigned int i=0; i<subtractedCloud->size(); ++i)
975 pts.at<
float>(i, 0) = subtractedCloud->at(i).x;
976 pts.at<
float>(i, 1) = subtractedCloud->at(i).y;
977 pts.at<
float>(i, 2) = subtractedCloud->at(i).z;
991 groundClouds_.insert(std::make_pair(iter->first, util3d::transformPointCloud(subtractedCloud, iter->second.inverse())));
993 if(subtractedCloud->size())
1006 if(jter!=
gridMaps_.end() && jter->second.first.second.cols)
1008 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformed = util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(jter->second.first.second), iter->second, 255, 0, 0);
1009 pcl::PointCloud<pcl::PointXYZRGB>::Ptr subtractedCloud = transformed;
1016 if(subtractedCloud->size())
1019 cv::Mat pts(subtractedCloud->size(), 3, CV_32FC1);
1020 for(
unsigned int i=0; i<subtractedCloud->size(); ++i)
1022 pts.at<
float>(i, 0) = subtractedCloud->at(i).x;
1023 pts.at<
float>(i, 1) = subtractedCloud->at(i).y;
1024 pts.at<
float>(i, 2) = subtractedCloud->at(i).z;
1038 obstacleClouds_.insert(std::make_pair(iter->first, util3d::transformPointCloud(subtractedCloud, iter->second.inverse())));
1040 if(subtractedCloud->size())
1062 ROS_INFO(
"Assembled %d obstacle and %d ground clouds (%d points, %fs)",
1067 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
1069 cloudMsg->header.stamp = stamp;
1070 cloudMsg->header.frame_id = mapFrameId;
1075 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
1077 cloudMsg->header.stamp = stamp;
1078 cloudMsg->header.frame_id = mapFrameId;
1084 sensor_msgs::PointCloud2::Ptr cloudMsg(
new sensor_msgs::PointCloud2);
1086 cloudMsg->header.stamp = stamp;
1087 cloudMsg->header.frame_id = mapFrameId;
1111 #ifdef WITH_OCTOMAP_MSGS 1112 #ifdef RTABMAP_OCTOMAP 1123 octomap_msgs::Octomap msg;
1125 msg.header.frame_id = mapFrameId;
1126 msg.header.stamp = stamp;
1131 octomap_msgs::Octomap msg;
1133 msg.header.frame_id = mapFrameId;
1134 msg.header.stamp = stamp;
1142 sensor_msgs::PointCloud2 msg;
1143 pcl::IndicesPtr obstacleIndices(
new std::vector<int>);
1144 pcl::IndicesPtr emptyIndices(
new std::vector<int>);
1145 pcl::IndicesPtr groundIndices(
new std::vector<int>);
1150 pcl::PointCloud<pcl::PointXYZRGB> cloudOccupiedSpace;
1151 pcl::IndicesPtr indices = util3d::concatenate(obstacleIndices, groundIndices);
1152 pcl::copyPointCloud(*cloud, *indices, cloudOccupiedSpace);
1154 msg.header.frame_id = mapFrameId;
1155 msg.header.stamp = stamp;
1160 pcl::PointCloud<pcl::PointXYZRGB> cloudObstacles;
1161 pcl::copyPointCloud(*cloud, *obstacleIndices, cloudObstacles);
1163 msg.header.frame_id = mapFrameId;
1164 msg.header.stamp = stamp;
1169 pcl::PointCloud<pcl::PointXYZRGB> cloudGround;
1170 pcl::copyPointCloud(*cloud, *groundIndices, cloudGround);
1172 msg.header.frame_id = mapFrameId;
1173 msg.header.stamp = stamp;
1178 pcl::PointCloud<pcl::PointXYZRGB> cloudEmptySpace;
1179 pcl::copyPointCloud(*cloud, *emptyIndices, cloudEmptySpace);
1181 msg.header.frame_id = mapFrameId;
1182 msg.header.stamp = stamp;
1189 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
1195 nav_msgs::OccupancyGrid map;
1196 map.info.resolution = gridCellSize;
1197 map.info.origin.position.x = 0.0;
1198 map.info.origin.position.y = 0.0;
1199 map.info.origin.position.z = 0.0;
1200 map.info.origin.orientation.x = 0.0;
1201 map.info.origin.orientation.y = 0.0;
1202 map.info.origin.orientation.z = 0.0;
1203 map.info.origin.orientation.w = 1.0;
1205 map.info.width = pixels.cols;
1206 map.info.height = pixels.rows;
1207 map.info.origin.position.x = xMin;
1208 map.info.origin.position.y = yMin;
1209 map.data.resize(map.info.width * map.info.height);
1211 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
1213 map.header.frame_id = mapFrameId;
1214 map.header.stamp = stamp;
1218 else if(poses.size())
1220 ROS_WARN(
"Octomap projection map is empty! (poses=%d octomap nodes=%d). " 1221 "Make sure you activated \"%s\" and \"%s\" to true. " 1222 "See \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" for more info.",
1224 Parameters::kGrid3D().c_str(), Parameters::kGridFromDepth().c_str());
1242 ROS_WARN(
"/proj_map topic is deprecated! Subscribe to /grid_map topic " 1243 "instead with <param name=\"%s\" type=\"string\" value=\"true\"/>. " 1244 "Do \"$ rosrun rtabmap_ros rtabmap --params | grep Grid\" to see " 1245 "all occupancy grid parameters.",
1246 Parameters::kGridFromDepth().c_str());
1250 ROS_WARN(
"/proj_map topic is deprecated! Subscribe to /grid_map topic instead.");
1257 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
1262 nav_msgs::OccupancyGrid map;
1263 map.info.resolution = gridCellSize;
1264 map.info.origin.position.x = 0.0;
1265 map.info.origin.position.y = 0.0;
1266 map.info.origin.position.z = 0.0;
1267 map.info.origin.orientation.x = 0.0;
1268 map.info.origin.orientation.y = 0.0;
1269 map.info.origin.orientation.z = 0.0;
1270 map.info.origin.orientation.w = 1.0;
1272 map.info.width = pixels.cols;
1273 map.info.height = pixels.rows;
1274 map.info.origin.position.x = xMin;
1275 map.info.origin.position.y = yMin;
1276 map.data.resize(map.info.width * map.info.height);
1278 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
1280 map.header.frame_id = mapFrameId;
1281 map.header.stamp = stamp;
1288 else if(poses.size())
1296 float xMin=0.0f, yMin=0.0f, gridCellSize = 0.05f;
1297 cv::Mat pixels = this->
getGridMap(xMin, yMin, gridCellSize);
1302 nav_msgs::OccupancyGrid map;
1303 map.info.resolution = gridCellSize;
1304 map.info.origin.position.x = 0.0;
1305 map.info.origin.position.y = 0.0;
1306 map.info.origin.position.z = 0.0;
1307 map.info.origin.orientation.x = 0.0;
1308 map.info.origin.orientation.y = 0.0;
1309 map.info.origin.orientation.z = 0.0;
1310 map.info.origin.orientation.w = 1.0;
1312 map.info.width = pixels.cols;
1313 map.info.height = pixels.rows;
1314 map.info.origin.position.x = xMin;
1315 map.info.origin.position.y = yMin;
1316 map.data.resize(map.info.width * map.info.height);
1318 memcpy(map.data.data(), pixels.data, map.info.width * map.info.height);
1320 map.header.frame_id = mapFrameId;
1321 map.header.stamp = stamp;
1332 else if(poses.size())
1349 float & gridCellSize)
1358 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)
float getMinMapSize() const
std::map< int, rtabmap::Transform > getFilteredPoses(const std::map< int, rtabmap::Transform > &poses)
int cloudSubtractFilteringMinNeighbors_
ros::Publisher octoMapObstacleCloud_
bool negativeScanEmptyRayTracing_
void setParameters(const rtabmap::ParametersMap ¶meters)
ros::Publisher cloudGroundPub_
float getCellSize() const
std::map< int, Transform > RTABMAP_EXP radiusPosesFiltering(const std::map< int, Transform > &poses, float radius, float angle, bool keepLatest=true)
void publish(const boost::shared_ptr< M > &message) const
double uStr2Double(const std::string &str)
void update(const std::map< int, Transform > &poses)
ros::Publisher gridMapPub_
rtabmap::OccupancyGrid * occupancyGrid_
int uStrNumCmp(const std::string &a, const std::string &b)
std::pair< std::string, std::string > ParametersPair
ros::Publisher scanMapPub_
static bool fullMapToMsg(const OctomapT &octomap, Octomap &msg)
bool cloudOutputVoxelized_
ros::Publisher octoMapCloud_
std::map< std::string, std::string > ParametersMap
cv::Mat getGridProbMap(float &xMin, float &yMin, float &gridCellSize)
float gridCellSize() const
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
void update(const std::map< int, Transform > &poses)
sensor_msgs::PointCloud2 PointCloud
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
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledObstacles_
std::map< int, pcl::PointCloud< pcl::PointXYZRGB >::Ptr > groundClouds_
rtabmap::OctoMap * octomap_
std::string getDatabaseVersion() const
unsigned int addPoints(const cv::Mat &features)
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_
ros::Publisher octoMapPubFull_
#define UASSERT(condition)
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)
const std::map< int, Transform > & addedNodes() const
int uStr2Int(const std::string &str)
std::string uNumber2Str(unsigned int number)
void createLocalMap(const Signature &node, cv::Mat &groundCells, cv::Mat &obstacleCells, cv::Mat &emptyCells, cv::Point3f &viewPoint) const
ros::Publisher cloudMapPub_
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)
unsigned int indexedFeatures() const
std::map< int, std::pair< std::pair< cv::Mat, cv::Mat >, cv::Mat > > gridMaps_
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
rtabmap::FlannIndex assembledGroundIndex_
void buildKDTreeSingleIndex(const cv::Mat &features, int leafMaxSize=10, bool reorder=true, bool useDistanceL1=false, float rebalancingFactor=2.0f)
ros::Publisher projMapPub_
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) const
const RtabmapColorOcTree * octree() const
cv::Mat getProbMap(float &xMin, float &yMin) const
QMap< QString, QVariant > ParametersMap
SensorData getSignatureDataConst(int locationId, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
bool uStr2Bool(const char *str)
bool isFullUpdate() const
bool uContains(const std::list< V > &list, const V &value)
void setPose(const Transform &pose)
bool negativePosesIgnored_
rtabmap::FlannIndex assembledObstacleIndex_
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)
uint32_t getNumSubscribers() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr subtractFiltering(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const rtabmap::FlannIndex &substractCloudIndex, float radiusSearch, int minNeighborsInRadius)
bool hasSubscribers() const
bool getParam(const std::string &key, std::string &s) const
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
ros::Publisher octoMapEmptySpace_
ros::Publisher octoMapGroundCloud_
std::map< int, pcl::PointCloud< pcl::PointXYZRGB >::Ptr > obstacleClouds_
void parseParameters(const ParametersMap ¶meters)
float getUpdateError() const
cv::Mat getGridMap(float &xMin, float &yMin, float &gridCellSize)
ros::Publisher octoMapProj_
bool hasParam(const std::string &key) const
cv::Mat createProjectionMap(float &xMin, float &yMin, float &gridCellSize, float minGridSize=0.0f, unsigned int treeDepth=0)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledGround_
bool isGridFromDepth() const
ros::Publisher cloudObstaclesPub_
cv::Mat getMap(float &xMin, float &yMin) const
ros::Publisher gridProbMapPub_
const std::map< int, Transform > & addedNodes() const
const cv::Point3f & gridViewPoint() const
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_
void backwardCompatibilityParameters(ros::NodeHandle &pnh, rtabmap::ParametersMap ¶meters) const