35 #ifdef RTABMAP_OCTOMAP 39 #include <pcl/io/pcd_io.h> 44 parameters_(parameters),
45 cloudDecimation_(
Parameters::defaultGridDepthDecimation()),
46 cloudMaxDepth_(
Parameters::defaultGridRangeMax()),
47 cloudMinDepth_(
Parameters::defaultGridRangeMin()),
49 footprintLength_(
Parameters::defaultGridFootprintLength()),
50 footprintWidth_(
Parameters::defaultGridFootprintWidth()),
51 footprintHeight_(
Parameters::defaultGridFootprintHeight()),
52 scanDecimation_(
Parameters::defaultGridScanDecimation()),
54 preVoxelFiltering_(
Parameters::defaultGridPreVoxelFiltering()),
55 occupancyFromDepth_(
Parameters::defaultGridFromDepth()),
56 projMapFrame_(
Parameters::defaultGridMapFrameProjection()),
57 maxObstacleHeight_(
Parameters::defaultGridMaxObstacleHeight()),
58 normalKSearch_(
Parameters::defaultGridNormalK()),
60 clusterRadius_(
Parameters::defaultGridClusterRadius()),
61 minClusterSize_(
Parameters::defaultGridMinClusterSize()),
62 flatObstaclesDetected_(
Parameters::defaultGridFlatObstacleDetected()),
63 minGroundHeight_(
Parameters::defaultGridMinGroundHeight()),
64 maxGroundHeight_(
Parameters::defaultGridMaxGroundHeight()),
65 normalsSegmentation_(
Parameters::defaultGridNormalsSegmentation()),
67 groundIsObstacle_(
Parameters::defaultGridGroundIsObstacle()),
68 noiseFilteringRadius_(
Parameters::defaultGridNoiseFilteringRadius()),
69 noiseFilteringMinNeighbors_(
Parameters::defaultGridNoiseFilteringMinNeighbors()),
70 scan2dUnknownSpaceFilled_(
Parameters::defaultGridScan2dUnknownSpaceFilled()),
71 rayTracing_(
Parameters::defaultGridRayTracing()),
72 fullUpdate_(
Parameters::defaultGridGlobalFullUpdate()),
73 minMapSize_(
Parameters::defaultGridGlobalMinSize()),
75 footprintRadius_(
Parameters::defaultGridGlobalFootprintRadius()),
76 updateError_(
Parameters::defaultGridGlobalUpdateError()),
77 occupancyThr_(
Parameters::defaultGridGlobalOccupancyThr()),
84 cloudAssembling_(
false),
85 assembledGround_(new
pcl::PointCloud<
pcl::PointXYZRGB>),
86 assembledObstacles_(new
pcl::PointCloud<
pcl::PointXYZRGB>),
87 assembledEmptyCells_(new
pcl::PointCloud<
pcl::PointXYZRGB>)
163 ParametersMap::const_iterator iter;
164 if((iter=parameters.find(Parameters::kGridDepthRoiRatios())) != parameters.end())
166 std::list<std::string> strValues =
uSplit(iter->second,
' ');
167 if(strValues.size() != 4)
169 ULOGGER_ERROR(
"The number of values must be 4 (%s=\"%s\")", iter->first.c_str(), iter->second.c_str());
173 std::vector<float> tmpValues(4);
175 for(std::list<std::string>::iterator jter = strValues.begin(); jter!=strValues.end(); ++jter)
181 if(tmpValues[0] >= 0 && tmpValues[0] < 1 && tmpValues[0] < 1.0
f-tmpValues[1] &&
182 tmpValues[1] >= 0 && tmpValues[1] < 1 && tmpValues[1] < 1.0
f-tmpValues[0] &&
183 tmpValues[2] >= 0 && tmpValues[2] < 1 && tmpValues[2] < 1.0
f-tmpValues[3] &&
184 tmpValues[3] >= 0 && tmpValues[3] < 1 && tmpValues[3] < 1.0
f-tmpValues[2])
190 ULOGGER_ERROR(
"The roi ratios are not valid (%s=\"%s\")", iter->first.c_str(), iter->second.c_str());
197 UWARN(
"\"%s\" should be not equal to 0 if not using normals " 198 "segmentation approach. Setting it to cell size (%f).",
199 Parameters::kGridMaxGroundHeight().c_str(),
cellSize_);
206 UWARN(
"\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
207 Parameters::kGridMaxGroundHeight().c_str(),
208 Parameters::kGridMaxObstacleHeight().c_str(),
209 Parameters::kGridMaxObstacleHeight().c_str());
216 UWARN(
"\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
217 Parameters::kGridMinGroundHeight().c_str(),
218 Parameters::kGridMaxGroundHeight().c_str(),
219 Parameters::kGridMinGroundHeight().c_str());
224 void OccupancyGrid::setMap(
const cv::Mat & map,
float xMin,
float yMin,
float cellSize,
const std::map<int, Transform> & poses)
226 UDEBUG(
"map=%d/%d xMin=%f yMin=%f cellSize=%f poses=%d",
227 map.cols, map.rows, xMin, yMin, cellSize, (
int)poses.size());
229 if(!poses.empty() && !map.empty())
232 UASSERT(map.type() == CV_8SC1);
234 mapInfo_ = cv::Mat::zeros(map.size(), CV_32FC4);
235 for(
int i=0; i<map_.rows; ++i)
237 for(
int j=0; j<map_.cols; ++j)
239 const char value = map_.at<
char>(i,j);
240 float * info =
mapInfo_.ptr<
float>(i,j);
245 else if(value == 100)
260 UASSERT_MSG(cellSize > 0.0
f,
uFormat(
"Param name is \"%s\"", Parameters::kGridCellSize().c_str()).c_str());
265 UWARN(
"Grid cell size has changed, the map is cleared!");
284 cv::Mat & groundCells,
285 cv::Mat & obstacleCells,
286 cv::Mat & emptyCells,
287 cv::Point3f & viewPoint)
const 289 UDEBUG(
"scan format=%d, occupancyFromDepth_=%d normalsSegmentation_=%d grid3D_=%d",
296 viewPoint = cv::Point3f(
326 UDEBUG(
"ground=%d obstacles=%d channels=%d", emptyCells.cols, obstacleCells.cols, obstacleCells.cols?obstacleCells.channels():emptyCells.channels());
338 #ifdef RTABMAP_OCTOMAP 350 viewPoint = cv::Point3f(t.
x(), t.
y(), t.
z());
357 UWARN(
"Cannot create local map, scan is empty (node=%d).", node.
id());
362 pcl::IndicesPtr indices(
new std::vector<int>);
363 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
364 UDEBUG(
"Depth image : decimation=%d max=%f min=%f",
371 #ifdef RTABMAP_OCTOMAP 392 viewPoint.x += t.
x();
393 viewPoint.y += t.
y();
394 viewPoint.z += t.
z();
408 viewPoint = cv::Point3f(t.
x(), t.
y(), t.
z());
418 cv::Mat & groundCells,
419 cv::Mat & obstacleCells,
420 cv::Mat & emptyCells,
421 cv::Point3f & viewPointInOut)
const 428 Transform viewpointRotated =
Transform(0,0,0,roll,pitch,0) *
Transform(viewPointInOut.x, viewPointInOut.y, viewPointInOut.z, 0,0,0);
429 viewPointInOut.x = viewpointRotated.
x();
430 viewPointInOut.y = viewpointRotated.
y();
431 viewPointInOut.z = viewpointRotated.
z();
436 pcl::IndicesPtr groundIndices(
new std::vector<int>);
437 pcl::IndicesPtr obstaclesIndices(
new std::vector<int>);
439 cv::Mat obstaclesCloud;
444 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudSegmented = segmentCloud<pcl::PointXYZRGBNormal>(cloud, pcl::IndicesPtr(
new std::vector<int>), pose, viewPointInOut, groundIndices, obstaclesIndices);
445 UDEBUG(
"groundIndices=%d, obstaclesIndices=%d", (
int)groundIndices->size(), (int)obstaclesIndices->size());
453 util3d::occupancy2DFromGroundObstacles<pcl::PointXYZRGBNormal>(cloudSegmented, groundIndices, obstaclesIndices, groundCells, obstacleCells,
cellSize_);
459 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudSegmented = segmentCloud<pcl::PointXYZRGB>(cloud, pcl::IndicesPtr(
new std::vector<int>), pose, viewPointInOut, groundIndices, obstaclesIndices);
460 UDEBUG(
"groundIndices=%d, obstaclesIndices=%d", (
int)groundIndices->size(), (int)obstaclesIndices->size());
468 util3d::occupancy2DFromGroundObstacles<pcl::PointXYZRGB>(cloudSegmented, groundIndices, obstaclesIndices, groundCells, obstacleCells,
cellSize_);
474 pcl::PointCloud<pcl::PointNormal>::Ptr cloudSegmented = segmentCloud<pcl::PointNormal>(cloud, pcl::IndicesPtr(
new std::vector<int>), pose, viewPointInOut, groundIndices, obstaclesIndices);
475 UDEBUG(
"groundIndices=%d, obstaclesIndices=%d", (
int)groundIndices->size(), (int)obstaclesIndices->size());
483 util3d::occupancy2DFromGroundObstacles<pcl::PointNormal>(cloudSegmented, groundIndices, obstaclesIndices, groundCells, obstacleCells,
cellSize_);
489 pcl::PointCloud<pcl::PointXYZ>::Ptr cloudSegmented = segmentCloud<pcl::PointXYZ>(cloud, pcl::IndicesPtr(
new std::vector<int>), pose, viewPointInOut, groundIndices, obstaclesIndices);
490 UDEBUG(
"groundIndices=%d, obstaclesIndices=%d", (
int)groundIndices->size(), (int)obstaclesIndices->size());
498 util3d::occupancy2DFromGroundObstacles<pcl::PointXYZ>(cloudSegmented, groundIndices, obstaclesIndices, groundCells, obstacleCells,
cellSize_);
502 if(
grid3D_ && (!obstaclesCloud.empty() || !groundCloud.empty()))
504 UDEBUG(
"ground=%d obstacles=%d", groundCloud.cols, obstaclesCloud.cols);
507 if(obstaclesCloud.empty())
509 obstaclesCloud = groundCloud;
510 groundCloud = cv::Mat();
514 UASSERT(obstaclesCloud.type() == groundCloud.type());
515 cv::Mat merged(1,obstaclesCloud.cols+groundCloud.cols, obstaclesCloud.type());
516 obstaclesCloud.copyTo(merged(
cv::Range::all(), cv::Range(0, obstaclesCloud.cols)));
517 groundCloud.copyTo(merged(
cv::Range::all(), cv::Range(obstaclesCloud.cols, obstaclesCloud.cols+groundCloud.cols)));
528 #ifdef RTABMAP_OCTOMAP 529 if(!groundCloud.empty() || !obstaclesCloud.empty())
534 octomap.
addToCache(1, groundCloud, obstaclesCloud, cv::Mat(), cv::Point3f(viewPointInOut.x, viewPointInOut.y, viewPointInOut.z));
535 std::map<int, Transform> poses;
539 pcl::IndicesPtr groundIndices(
new std::vector<int>);
540 pcl::IndicesPtr obstaclesIndices(
new std::vector<int>);
541 pcl::IndicesPtr emptyIndices(
new std::vector<int>);
542 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithRayTracing = octomap.
createCloud(0, obstaclesIndices.get(), emptyIndices.get(), groundIndices.get());
543 UDEBUG(
"ground=%d obstacles=%d empty=%d", (
int)groundIndices->size(), (int)obstaclesIndices->size(), (int)emptyIndices->size());
552 pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithRayTracing2(
new pcl::PointCloud<pcl::PointXYZ>);
553 pcl::copyPointCloud(*cloudWithRayTracing, *cloudWithRayTracing2);
562 UWARN(
"RTAB-Map is not built with OctoMap dependency, 3D ray tracing is ignored. Set \"%s\" to false to avoid this warning.", Parameters::kGridRayTracing().c_str());
573 cv::Mat laserScan = obstacleCells;
574 cv::Mat laserScanNoHit = groundCells;
575 obstacleCells = cv::Mat();
576 groundCells = cv::Mat();
588 UDEBUG(
"ground=%d obstacles=%d empty=%d, channels=%d", groundCells.cols, obstacleCells.cols, emptyCells.cols, obstacleCells.cols?obstacleCells.channels():groundCells.channels());
615 map = cv::Mat(map.size(), map.type());
617 for(
int i=0; i<map.rows; ++i)
619 for(
int j=0; j<map.cols; ++j)
621 const float * info =
mapInfo_.ptr<
float>(i, j);
624 map.at<
char>(i, j) = -1;
626 else if(info[3] >= occThr)
628 map.at<
char>(i, j) = 100;
632 map.at<
char>(i, j) = 0;
639 if(
erode_ && !map.empty())
656 for(
int i=0; i<map.rows; ++i)
658 for(
int j=0; j<map.cols; ++j)
660 const float * info =
mapInfo_.ptr<
float>(i, j);
663 map.at<
char>(i, j) = -1;
667 map.at<
char>(i, j) =
char(
probability(info[3])*100.0f);
677 const cv::Mat & ground,
678 const cv::Mat & obstacles,
679 const cv::Mat & empty)
681 UDEBUG(
"nodeId=%d", nodeId);
682 uInsert(
cache_, std::make_pair(nodeId, std::make_pair(std::make_pair(ground, obstacles), empty)));
688 UDEBUG(
"Update (poses=%d addedNodes_=%d)", (
int)posesIn.size(), (int)
addedNodes_.size());
697 std::map<int, cv::Mat> emptyLocalMaps;
698 std::map<int, cv::Mat> occupiedLocalMaps;
701 bool graphOptimized =
false;
703 std::map<int, Transform> transforms;
707 std::map<int, Transform>::const_iterator jter = posesIn.find(iter->first);
708 if(jter != posesIn.end())
710 graphChanged =
false;
712 UASSERT(!iter->second.isNull() && !jter->second.isNull());
714 if(iter->second.getDistanceSquared(jter->second) > updateErrorSqrd)
716 t = jter->second * iter->second.inverse();
717 graphOptimized =
true;
719 transforms.insert(std::make_pair(jter->first, t));
721 float x = jter->second.x();
722 float y =jter->second.y();
727 undefinedSize =
false;
744 UDEBUG(
"Updated pose for node %d is not found, some points may not be copied if graph has changed.", iter->first);
748 bool assembledGroundUpdated =
false;
749 bool assembledObstaclesUpdated =
false;
750 bool assembledEmptyCellsUpdated =
false;
752 if(graphOptimized || graphChanged)
756 UWARN(
"Graph has changed! The whole map should be rebuilt.");
760 UINFO(
"Graph optimized!");
774 std::map<int, std::pair<int, int> > tmpIndices;
775 for(std::map<
int, std::pair<int, int> >::iterator iter=
cellCount_.begin(); iter!=
cellCount_.end(); ++iter)
777 if(!
uContains(
cache_, iter->first) && transforms.find(iter->first) != transforms.end())
779 if(iter->second.first)
781 emptyLocalMaps.insert(std::make_pair( iter->first, cv::Mat(1, iter->second.first, CV_32FC2)));
783 if(iter->second.second)
785 occupiedLocalMaps.insert(std::make_pair( iter->first, cv::Mat(1, iter->second.second, CV_32FC2)));
787 tmpIndices.insert(std::make_pair(iter->first, std::make_pair(0,0)));
790 for(
int y=0; y<
map_.rows; ++y)
792 for(
int x=0; x<
map_.cols; ++x)
794 float * info =
mapInfo_.ptr<
float>(y,x);
795 int nodeId = (int)info[0];
796 if(nodeId > 0 &&
map_.at<
char>(y,x) >= 0)
798 if(tmpIndices.find(nodeId)!=tmpIndices.end())
800 std::map<int, Transform>::iterator tter = transforms.find(nodeId);
801 UASSERT(tter != transforms.end());
803 cv::Point3f pt(info[1], info[2], 0.0
f);
816 std::map<int, std::pair<int, int> >::iterator jter = tmpIndices.find(nodeId);
817 if(
map_.at<
char>(y, x) == 0)
820 std::map<int, cv::Mat>::iterator iter = emptyLocalMaps.find(nodeId);
821 UASSERT(iter != emptyLocalMaps.end());
822 UASSERT(jter->second.first < iter->second.cols);
823 float * ptf = iter->second.ptr<
float>(0,jter->second.first++);
830 std::map<int, cv::Mat>::iterator iter = occupiedLocalMaps.find(nodeId);
831 UASSERT(iter != occupiedLocalMaps.end());
832 UASSERT(iter!=occupiedLocalMaps.end());
833 UASSERT(jter->second.second < iter->second.cols);
834 float * ptf = iter->second.ptr<
float>(0,jter->second.second++);
842 UERROR(
"Cell referred b node %d is unknown!?", nodeId);
848 for(std::map<
int, std::pair<int, int> >::iterator iter=tmpIndices.begin(); iter!=tmpIndices.end(); ++iter)
850 std::map<int, cv::Mat>::iterator jter = emptyLocalMaps.find(iter->first);
851 UASSERT_MSG((iter->second.first == 0 && (jter==emptyLocalMaps.end() || jter->second.empty())) ||
852 (iter->second.first != 0 && jter!=emptyLocalMaps.end() && jter->second.cols == iter->second.first),
853 uFormat(
"iter->second.first=%d jter->second.cols=%d", iter->second.first, jter!=emptyLocalMaps.end()?jter->second.cols:-1).c_str());
854 jter = occupiedLocalMaps.find(iter->first);
855 UASSERT_MSG((iter->second.second == 0 && (jter==occupiedLocalMaps.end() || jter->second.empty())) ||
856 (iter->second.second != 0 && jter!=occupiedLocalMaps.end() && jter->second.cols == iter->second.second),
857 uFormat(
"iter->second.first=%d jter->second.cols=%d", iter->second.first, jter!=emptyLocalMaps.end()?jter->second.cols:-1).c_str());
860 UDEBUG(
"min (%f,%f) max(%f,%f)", minX, minY, maxX, maxY);
870 else if(!
map_.empty())
877 undefinedSize =
false;
880 bool incrementalGraphUpdate = graphOptimized && !
fullUpdate_ && !graphChanged;
882 std::list<std::pair<int, Transform> > poses;
884 UDEBUG(
"Last id = %d", lastId);
887 for(std::map<int, Transform>::const_iterator iter=posesIn.upper_bound(0); iter!=posesIn.end(); ++iter)
891 UDEBUG(
"Pose %d not found in current added poses, it will be added to map", iter->first);
892 poses.push_back(*iter);
897 for(std::map<int, Transform>::const_iterator iter=posesIn.begin(); iter!=posesIn.end(); ++iter)
901 poses.push_back(*iter);
909 for(std::list<std::pair<int, Transform> >::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
911 UASSERT(!iter->second.isNull());
913 float x = iter->second.x();
914 float y =iter->second.y();
919 undefinedSize =
false;
937 for(std::list<std::pair<int, Transform> >::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
941 const std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> & pair =
cache_.at(iter->first);
943 UDEBUG(
"Adding grid %d: ground=%d obstacles=%d empty=%d", iter->first, pair.first.first.cols, pair.first.second.cols, pair.second.cols);
946 if(pair.first.first.cols)
948 if(pair.first.first.rows > 1 && pair.first.first.cols == 1)
950 UFATAL(
"Occupancy local maps should be 1 row and X cols! (rows=%d cols=%d)", pair.first.first.rows, pair.first.first.cols);
952 cv::Mat ground(1, pair.first.first.cols, CV_32FC2);
953 for(
int i=0; i<ground.cols; ++i)
955 const float * vi = pair.first.first.ptr<
float>(0,i);
956 float * vo = ground.ptr<
float>(0,i);
958 if(pair.first.first.channels() != 2 && pair.first.first.channels() != 5)
970 else if(maxX < vo[0])
975 else if(maxY < vo[1])
978 uInsert(emptyLocalMaps, std::make_pair(iter->first, ground));
983 assembledGroundUpdated =
true;
990 if(pair.second.rows > 1 && pair.second.cols == 1)
992 UFATAL(
"Occupancy local maps should be 1 row and X cols! (rows=%d cols=%d)", pair.second.rows, pair.second.cols);
994 cv::Mat ground(1, pair.second.cols, CV_32FC2);
995 for(
int i=0; i<ground.cols; ++i)
997 const float * vi = pair.second.ptr<
float>(0,i);
998 float * vo = ground.ptr<
float>(0,i);
1000 if(pair.second.channels() != 2 && pair.second.channels() != 5)
1012 else if(maxX < vo[0])
1017 else if(maxY < vo[1])
1020 uInsert(emptyLocalMaps, std::make_pair(iter->first, ground));
1025 assembledEmptyCellsUpdated =
true;
1030 if(pair.first.second.cols)
1032 if(pair.first.second.rows > 1 && pair.first.second.cols == 1)
1034 UFATAL(
"Occupancy local maps should be 1 row and X cols! (rows=%d cols=%d)", pair.first.second.rows, pair.first.second.cols);
1036 cv::Mat obstacles(1, pair.first.second.cols, CV_32FC2);
1037 for(
int i=0; i<obstacles.cols; ++i)
1039 const float * vi = pair.first.second.ptr<
float>(0,i);
1040 float * vo = obstacles.ptr<
float>(0,i);
1042 if(pair.first.second.channels() != 2 && pair.first.second.channels() != 5)
1054 else if(maxX < vo[0])
1059 else if(maxY < vo[1])
1062 uInsert(occupiedLocalMaps, std::make_pair(iter->first, obstacles));
1067 assembledObstaclesUpdated =
true;
1076 if(minX != maxX && minY != maxY)
1079 float xMin = minX-margin;
1081 float yMin = minY-margin;
1083 float xMax = maxX+margin;
1084 float yMax = maxY+margin;
1086 if(fabs((yMax - yMin) /
cellSize_) > 99999 ||
1087 fabs((xMax - xMin) /
cellSize_) > 99999)
1089 UERROR(
"Large map size!! map min=(%f, %f) max=(%f,%f). " 1090 "There's maybe an error with the poses provided! The map will not be created!",
1091 xMin, yMin, xMax, yMax);
1095 UDEBUG(
"map min=(%f, %f) odlMin(%f,%f) max=(%f,%f)", xMin, yMin,
xMin_,
yMin_, xMax, yMax);
1100 map = cv::Mat::ones(newMapSize, CV_8S)*-1;
1101 mapInfo = cv::Mat::zeros(newMapSize, CV_32FC4);
1106 newMapSize.width ==
map_.cols &&
1107 newMapSize.height ==
map_.rows)
1110 UDEBUG(
"Map same size!");
1136 UDEBUG(
"deltaX=%d, deltaY=%d", deltaX, deltaY);
1137 newMapSize.width = (xMax - xMin) /
cellSize_+0.5
f;
1138 newMapSize.height = (yMax - yMin) /
cellSize_+0.5
f;
1139 UDEBUG(
"%d/%d -> %d/%d",
map_.cols,
map_.rows, newMapSize.width, newMapSize.height);
1140 UASSERT(newMapSize.width >=
map_.cols && newMapSize.height >=
map_.rows);
1141 UASSERT(newMapSize.width >=
map_.cols+deltaX && newMapSize.height >=
map_.rows+deltaY);
1142 UASSERT(deltaX>=0 && deltaY>=0);
1143 map = cv::Mat::ones(newMapSize, CV_8S)*-1;
1144 mapInfo = cv::Mat::zeros(newMapSize,
mapInfo_.type());
1145 map_.copyTo(map(cv::Rect(deltaX, deltaY,
map_.cols,
map_.rows)));
1149 UASSERT(map.cols == mapInfo.cols && map.rows == mapInfo.rows);
1150 UDEBUG(
"map %d %d", map.cols, map.rows);
1153 UDEBUG(
"first pose= %d last pose=%d", poses.begin()->first, poses.rbegin()->first);
1155 for(std::list<std::pair<int, Transform> >::const_iterator kter = poses.begin(); kter!=poses.end(); ++kter)
1161 std::map<int, cv::Mat >::iterator iter = emptyLocalMaps.find(kter->first);
1162 std::map<int, cv::Mat >::iterator jter = occupiedLocalMaps.find(kter->first);
1163 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(kter->first);
1164 if(cter ==
cellCount_.end() && kter->first > 0)
1166 cter =
cellCount_.insert(std::make_pair(kter->first, std::pair<int,int>(0,0))).first;
1168 if(iter!=emptyLocalMaps.end())
1170 for(
int i=0; i<iter->second.cols; ++i)
1172 float * ptf = iter->second.ptr<
float>(0,i);
1174 UASSERT_MSG(pt.y >=0 && pt.y < map.rows && pt.x >= 0 && pt.x < map.cols,
1175 uFormat(
"%d: pt=(%d,%d) map=%dx%d rawPt=(%f,%f) xMin=%f yMin=%f channels=%dvs%d (graph modified=%d)",
1176 kter->first, pt.x, pt.y, map.cols, map.rows, ptf[0], ptf[1], xMin, yMin, iter->second.channels(), mapInfo.channels()-1, (graphOptimized || graphChanged)?1:0).c_str());
1177 char & value = map.at<
char>(pt.y, pt.x);
1178 if(value != -2 && (!incrementalGraphUpdate || value==-1))
1180 float * info = mapInfo.ptr<
float>(pt.y, pt.x);
1181 int nodeId = (int)info[0];
1184 if(kter->first > 0 && (kter->first < nodeId || nodeId < 0))
1191 std::map<int, std::pair<int, int> >::iterator eter =
cellCount_.find(nodeId);
1195 eter->second.first -= 1;
1197 else if(value == 100)
1199 eter->second.second -= 1;
1203 eter->second.first += 1;
1209 info[0] = (float)kter->first;
1212 cter->second.first+=1;
1217 if(nodeId != kter->first)
1240 if(ptEnd.x >= map.cols)
1241 ptEnd.x = map.cols-1;
1245 if(ptEnd.y >= map.rows)
1246 ptEnd.y = map.rows-1;
1247 for(
int i=ptBegin.x; i<ptEnd.x; ++i)
1249 for(
int j=ptBegin.y; j<ptEnd.y; ++j)
1251 UASSERT(j < map.rows && i < map.cols);
1252 char & value = map.at<
char>(j, i);
1253 float * info = mapInfo.ptr<
float>(j, i);
1254 int nodeId = (int)info[0];
1257 if(kter->first > 0 && (kter->first < nodeId || nodeId < 0))
1264 std::map<int, std::pair<int, int> >::iterator eter =
cellCount_.find(nodeId);
1268 eter->second.first -= 1;
1270 else if(value == 100)
1272 eter->second.second -= 1;
1276 eter->second.first += 1;
1282 info[0] = (float)kter->first;
1285 cter->second.first+=1;
1292 if(jter!=occupiedLocalMaps.end())
1294 for(
int i=0; i<jter->second.cols; ++i)
1296 float * ptf = jter->second.ptr<
float>(0,i);
1298 UASSERT_MSG(pt.y>=0 && pt.y < map.rows && pt.x>=0 && pt.x < map.cols,
1299 uFormat(
"%d: pt=(%d,%d) map=%dx%d rawPt=(%f,%f) xMin=%f yMin=%f channels=%dvs%d (graph modified=%d)",
1300 kter->first, pt.x, pt.y, map.cols, map.rows, ptf[0], ptf[1], xMin, yMin, jter->second.channels(), mapInfo.channels()-1, (graphOptimized || graphChanged)?1:0).c_str());
1301 char & value = map.at<
char>(pt.y, pt.x);
1304 float * info = mapInfo.ptr<
float>(pt.y, pt.x);
1305 int nodeId = (int)info[0];
1308 if(kter->first > 0 && (kter->first < nodeId || nodeId < 0))
1315 std::map<int, std::pair<int, int> >::iterator eter =
cellCount_.find(nodeId);
1319 eter->second.first -= 1;
1321 else if(value == 100)
1323 eter->second.second -= 1;
1327 eter->second.second += 1;
1333 info[0] = (float)kter->first;
1336 cter->second.second+=1;
1341 if(nodeId != kter->first)
1360 for(
int i=1; i<map.rows-1; ++i)
1362 for(
int j=1; j<map.cols-1; ++j)
1364 char & value = map.at<
char>(i, j);
1370 if(incrementalGraphUpdate && value == -1)
1372 float * info = mapInfo.ptr<
float>(i, j);
1375 if(map.at<
char>(i+1, j) == 100 && map.at<
char>(i-1, j) == 100)
1379 if(mapInfo.ptr<
float>(i+1, j)[0]>0.0f)
1381 info[0] = mapInfo.ptr<
float>(i+1, j)[0];
1384 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1386 cter->second.second+=1;
1388 else if(mapInfo.ptr<
float>(i-1, j)[0]>0.0f)
1390 info[0] = mapInfo.ptr<
float>(i-1, j)[0];
1393 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1395 cter->second.second+=1;
1398 else if(map.at<
char>(i, j+1) == 100 && map.at<
char>(i, j-1) == 100)
1402 if(mapInfo.ptr<
float>(i, j+1)[0]>0.0f)
1404 info[0] = mapInfo.ptr<
float>(i, j+1)[0];
1407 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1409 cter->second.second+=1;
1411 else if(mapInfo.ptr<
float>(i, j-1)[0]>0.0f)
1413 info[0] = mapInfo.ptr<
float>(i, j-1)[0];
1416 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1418 cter->second.second+=1;
1424 char sum = (map.at<
char>(i+1, j) == 0?1:0) +
1425 (map.at<
char>(i-1, j) == 0?1:0) +
1426 (map.at<
char>(i, j+1) == 0?1:0) +
1427 (map.at<
char>(i, j-1) == 0?1:0);
1432 if(map.at<
char>(i+1, j) != -1 && mapInfo.ptr<
float>(i+1, j)[0]>0.0
f)
1434 info[0] = mapInfo.ptr<
float>(i+1, j)[0];
1437 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1439 cter->second.first+=1;
1441 else if(map.at<
char>(i-1, j) != -1 && mapInfo.ptr<
float>(i-1, j)[0]>0.0
f)
1443 info[0] = mapInfo.ptr<
float>(i-1, j)[0];
1446 std::map<int, std::pair<int, int> >::iterator cter =
cellCount_.find(
int(info[0]));
1448 cter->second.first+=1;
1477 for(std::map<
int, std::pair<int, int> >::iterator iter=
cellCount_.begin(); iter!=
cellCount_.end();)
1479 UASSERT(iter->second.first >= 0 && iter->second.second >= 0);
1480 if(iter->second.first == 0 && iter->second.second == 0)
1515 for(std::map<
int, std::pair<std::pair<cv::Mat, cv::Mat>, cv::Mat> >::iterator iter=
cache_.begin(); iter!=
cache_.end();)
1528 UDEBUG(
"Occupancy Grid update time = %f s", timer.
ticks());
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 &cloud, bool filterNaNs=true)
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
cv::Mat RTABMAP_EXP erodeMap(const cv::Mat &map)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
const cv::Mat & data() const
std::vector< float > roiRatios_
static double probability(double logodds)
void update(const std::map< int, Transform > &poses)
pcl::PointCloud< pcl::PointXYZRGBNormal >::Ptr RTABMAP_EXP laserScanToPointCloudRGBNormal(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=255, unsigned char g=255, unsigned char b=255)
float UTILITE_EXP uStr2Float(const std::string &str)
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
std::map< std::string, std::string > ParametersMap
void RTABMAP_EXP occupancy2DFromLaserScan(const cv::Mat &scanHit, const cv::Mat &scanNoHit, const cv::Point3f &viewpoint, cv::Mat &empty, cv::Mat &occupied, float cellSize, bool unknownSpaceFilled=false, float scanMaxRange=0.0f)
void setCellSize(float cellSize)
std::map< int, Transform > addedNodes_
void update(const std::map< int, Transform > &poses)
Some conversion functions.
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP laserScanToPointCloud(const LaserScan &laserScan, const Transform &transform=Transform())
void setMap(const cv::Mat &map, float xMin, float yMin, float cellSize, const std::map< int, Transform > &poses)
std::list< std::string > uSplit(const std::string &str, char separator= ' ')
LaserScan RTABMAP_EXP downsample(const LaserScan &cloud, int step)
#define UASSERT(condition)
Wrappers of STL for convenient functions.
void addToCache(int nodeId, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &ground, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &obstacles, const pcl::PointXYZ &viewPoint)
void createLocalMap(const Signature &node, cv::Mat &groundCells, cv::Mat &obstacleCells, cv::Mat &emptyCells, cv::Point3f &viewPoint) const
#define UASSERT_MSG(condition, msg_str)
OccupancyGrid(const ParametersMap ¶meters=ParametersMap())
LaserScan RTABMAP_EXP transformLaserScan(const LaserScan &laserScan, const Transform &transform)
void addToCache(int nodeId, const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty)
static float logodds(double probability)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP cloudRGBFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >())
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledGround_
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
std::map< int, std::pair< int, int > > cellCount_
Transform localTransform() const
cv::Mat getProbMap(float &xMin, float &yMin) const
std::map< int, std::pair< std::pair< cv::Mat, cv::Mat >, cv::Mat > > cache_
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledEmptyCells_
bool uContains(const std::list< V > &list, const V &value)
void setMaxRange(float value)
bool flatObstaclesDetected_
const std::vector< CameraModel > & cameraModels() const
const Transform & getPose() const
pcl::PointCloud< pcl::PointXYZRGB >::Ptr assembledObstacles_
SensorData & sensorData()
pcl::PointCloud< pcl::PointNormal >::Ptr RTABMAP_EXP laserScanToPointCloudNormal(const LaserScan &laserScan, const Transform &transform=Transform())
bool normalsSegmentation_
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
ParametersMap parameters_
LaserScan RTABMAP_EXP rangeFiltering(const LaserScan &scan, float rangeMin, float rangeMax)
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
float noiseFilteringRadius_
void parseParameters(const ParametersMap ¶meters)
float logodds(double probability)
#define ULOGGER_ERROR(...)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
const Transform & localTransform() const
std::string UTILITE_EXP uFormat(const char *fmt,...)
cv::Mat getMap(float &xMin, float &yMin) const
static LaserScan backwardCompatibility(const cv::Mat &oldScanFormat, int maxPoints=0, int maxRange=0, const Transform &localTransform=Transform::getIdentity())
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP laserScanToPointCloudRGB(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=255, unsigned char g=255, unsigned char b=255)
void setCloudAssembling(bool enabled)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
bool scan2dUnknownSpaceFilled_
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)
int noiseFilteringMinNeighbors_