36 #include <pcl/common/transforms.h>
49 UFATAL(
"This function should not be used with octomap >= 1.8");
57 UFATAL(
"This function should not be used with octomap >= 1.8");
66 if (!this->collapsible())
return false;
68 setLogOdds(
getChild(0)->getLogOdds());
70 if (isColorSet()) color = getAverageChildColor();
72 for (
unsigned int i=0;
i<8;
i++) {
79 UFATAL(
"This function should not be used with octomap >= 1.8");
86 assert(!hasChildren());
87 for (
unsigned int k=0; k<8; k++) {
89 children[k]->setValue(
value);
93 UFATAL(
"This function should not be used with octomap >= 1.8");
100 if (children ==
NULL) allocChildren();
104 UFATAL(
"This function should not be used with octomap >= 1.8");
111 if (children !=
NULL){
137 n->setColor(r,
g,
b);
143 #ifndef OCTOMAP_PRE_18
148 node->copyData(*(getNodeChild(node, 0)));
150 if (node->isColorSet())
151 node->setColor(node->getAverageChildColor());
154 for (
unsigned int i=0;
i<8;
i++) {
155 deleteNodeChild(node,
i);
157 delete[] node->children;
158 node->children =
NULL;
162 UFATAL(
"This function should not be used with octomap < 1.8");
168 #ifndef OCTOMAP_PRE_18
171 if (!nodeChildExists(node, 0))
175 if (nodeHasChildren(firstChild))
178 for (
unsigned int i = 1;
i<8;
i++) {
180 if (!nodeChildExists(node,
i) || nodeHasChildren(getNodeChild(node,
i)) || !(getNodeChild(node,
i)->getValue() == firstChild->getValue()))
186 UFATAL(
"This function should not be used with octomap < 1.8");
197 if (
n->isColorSet()) {
198 RtabmapColorOcTreeNode::Color prev_color =
n->getColor();
199 n->setColor((prev_color.r + r)/2, (prev_color.g +
g)/2, (prev_color.b +
b)/2);
202 n->setColor(r,
g,
b);
214 if (
n->isColorSet()) {
215 RtabmapColorOcTreeNode::Color prev_color =
n->getColor();
216 double node_prob =
n->getOccupancy();
218 + (double) r * (0.99-node_prob));
220 + (double)
g * (0.99-node_prob));
222 + (double)
b * (0.99-node_prob));
223 n->setColor(new_r, new_g, new_b);
226 n->setColor(r,
g,
b);
238 #ifndef OCTOMAP_PRE_18
240 if (nodeHasChildren(node)){
242 if (depth < this->tree_depth){
243 for (
unsigned int i=0;
i<8;
i++) {
244 if (nodeChildExists(node,
i)) {
249 node->updateOccupancyChildren();
250 node->updateColorChildren();
255 if (node->hasChildren()){
257 if (depth < this->tree_depth){
258 for (
unsigned int i=0;
i<8;
i++) {
259 if (node->childExists(
i)) {
264 node->updateOccupancyChildren();
265 node->updateColorChildren();
274 #ifndef OCTOMAP_PRE_18
275 tree->clearKeyRays();
278 AbstractOcTree::registerTreeType(
tree);
295 rayTracing_(
Parameters::defaultGridRayTracing()),
296 emptyFloodFillDepth_(
Parameters::defaultGridGlobalFloodFillDepth())
301 UWARN(
"Cannot set %s to null for OctoMap, using default value %f instead.",
302 Parameters::kGridGlobalOccupancyThr().
c_str(),
303 Parameters::defaultGridGlobalOccupancyThr());
354 auto nodePtr =
octree_->search(startPosition.x(), startPosition.y(), startPosition.z(), treeDepth);
357 if(!
octree_->isNodeOccupied(*nodePtr))
372 return startPosition;
376 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x()+
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z())))
378 return octomap::point3d(startPosition.x()+
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z());
382 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x()-
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z())))
384 return octomap::point3d(startPosition.x()-
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z());
388 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x(), startPosition.y()+
octree_->getNodeSize(treeDepth), startPosition.z())))
390 return octomap::point3d(startPosition.x(), startPosition.y()+
octree_->getNodeSize(treeDepth), startPosition.z());
395 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x()-
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z())))
397 return octomap::point3d(startPosition.x(), startPosition.y()-
octree_->getNodeSize(treeDepth), startPosition.z());
401 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()+
octree_->getNodeSize(treeDepth))))
403 return octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()+
octree_->getNodeSize(treeDepth));
407 if(
isValidEmpty(
octree_,treeDepth,octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()-
octree_->getNodeSize(treeDepth))))
409 return octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()-
octree_->getNodeSize(treeDepth));
413 return startPosition;
416 bool OctoMap::isNodeVisited(std::unordered_set<octomap::OcTreeKey,octomap::OcTreeKey::KeyHash>
const & EmptyNodes,octomap::OcTreeKey
const key)
418 for(
auto it = EmptyNodes.find(
key);it != EmptyNodes.end();it++)
429 void OctoMap::floodFill(
RtabmapColorOcTree* octree_,
unsigned int treeDepth,octomap::point3d startPosition, std::unordered_set<octomap::OcTreeKey, octomap::OcTreeKey::KeyHash> & EmptyNodes,std::queue<octomap::point3d>& positionToExplore)
432 auto key =
octree_->coordToKey(startPosition,treeDepth);
437 EmptyNodes.insert(
key);
438 positionToExplore.push(octomap::point3d(startPosition.x()+
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z()));
439 positionToExplore.push(octomap::point3d(startPosition.x()-
octree_->getNodeSize(treeDepth), startPosition.y(), startPosition.z()));
440 positionToExplore.push(octomap::point3d(startPosition.x(), startPosition.y()+
octree_->getNodeSize(treeDepth), startPosition.z()));
441 positionToExplore.push(octomap::point3d(startPosition.x(), startPosition.y()-
octree_->getNodeSize(treeDepth), startPosition.z()));
442 positionToExplore.push(octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()+
octree_->getNodeSize(treeDepth)));
443 positionToExplore.push(octomap::point3d(startPosition.x(), startPosition.y(), startPosition.z()-
octree_->getNodeSize(treeDepth)));
451 std::unordered_set<octomap::OcTreeKey, octomap::OcTreeKey::KeyHash> exploreNode;
452 std::queue<octomap::point3d> positionToExplore;
456 floodFill(
octree_, treeDepth, startPosition, exploreNode, positionToExplore);
457 while(!positionToExplore.empty())
459 floodFill(
octree_, treeDepth, positionToExplore.front(), exploreNode, positionToExplore);
460 positionToExplore.pop();
474 UDEBUG(
"Last id = %d", lastId);
476 UDEBUG(
"newPoses = %d", (
int)newPoses.size());
478 if(!newPoses.empty())
481 float cellSize =
octree_->getResolution();
482 for(std::list<std::pair<int, Transform> >::const_iterator
iter=newPoses.begin();
iter!=newPoses.end(); ++
iter)
484 std::map<int, LocalGrid>::const_iterator localGridIter;
485 localGridIter =
cache().find(
iter->first);
488 cv::Mat ground = localGridIter->second.groundCells;
489 cv::Mat obstacles = localGridIter->second.obstacleCells;
490 cv::Mat emptyCells = localGridIter->second.emptyCells;
492 if(!localGridIter->second.is3D())
494 UWARN(
"It seems the local occupancy grids are not 3d, cannot update OctoMap! (ground type=%d, obstacles type=%d, empty type=%d)",
495 ground.type(), obstacles.type(), emptyCells.type());
499 UDEBUG(
"Adding %d to octomap (resolution=%f)",
iter->first,
octree_->getResolution());
501 octomap::point3d sensorOrigin(
iter->second.x(),
iter->second.y(),
iter->second.z());
502 sensorOrigin += octomap::point3d(localGridIter->second.viewPoint.x, localGridIter->second.viewPoint.y, localGridIter->second.viewPoint.z);
506 octomap::OcTreeKey tmpKey;
507 if (!
octree_->coordToKeyChecked(sensorOrigin, tmpKey))
509 UERROR(
"Could not generate Key for origin ", sensorOrigin.x(), sensorOrigin.y(), sensorOrigin.z());
512 bool computeRays =
rayTracing_ && emptyCells.empty();
515 octomap::KeySet free_cells;
517 unsigned int maxGroundPts = ground.cols;
518 UDEBUG(
"%d: compute free cells (from %d ground points)",
iter->first, (
int)maxGroundPts);
522 for (
unsigned int i=0;
i<maxGroundPts; ++
i)
528 octomap::point3d
point(pt.x, pt.y, pt.z);
529 bool ignoreOccupiedCell =
false;
530 if(rangeMaxSqrd > 0.0
f)
532 octomap::point3d
v(pt.x - cellSize - sensorOrigin.x(), pt.y - cellSize - sensorOrigin.y(), pt.z - cellSize - sensorOrigin.z());
533 if(
v.norm_sq() > rangeMaxSqrd)
539 ignoreOccupiedCell=
true;
543 if(!ignoreOccupiedCell)
546 octomap::OcTreeKey
key;
549 if(
iter->first >0 &&
iter->first<lastId)
552 if(
n &&
n->getNodeRefId() > 0 &&
n->getNodeRefId() >
iter->first)
564 if(!
hasColor_ && !(pt.r ==0 && pt.g == 0 && pt.b == 0) && !(pt.r ==255 && pt.g == 255 && pt.b == 255))
571 n->setNodeRefId(
iter->first);
580 octomap::KeyRay keyRay;
582 (
iter->first < 0 ||
iter->first>lastId) &&
585 free_cells.insert(keyRay.begin(), keyRay.end());
588 UDEBUG(
"%d: ground cells=%d free cells=%d",
iter->first, (
int)maxGroundPts, (
int)free_cells.size());
591 unsigned int maxObstaclePts = obstacles.cols;
592 UDEBUG(
"%d: compute occupied cells (from %d obstacle points)",
iter->first, (
int)maxObstaclePts);
594 UASSERT(tmpObstacle.
size() == (
int)maxObstaclePts);
595 for (
unsigned int i=0;
i<maxObstaclePts; ++
i)
601 octomap::point3d
point(pt.x, pt.y, pt.z);
603 bool ignoreOccupiedCell =
false;
604 if(rangeMaxSqrd > 0.0
f)
606 octomap::point3d
v(pt.x - cellSize - sensorOrigin.x(), pt.y - cellSize - sensorOrigin.y(), pt.z - cellSize - sensorOrigin.z());
607 if(
v.norm_sq() > rangeMaxSqrd)
613 ignoreOccupiedCell=
true;
617 if(!ignoreOccupiedCell)
620 octomap::OcTreeKey
key;
623 if(
iter->first >0 &&
iter->first<lastId)
626 if(
n &&
n->getNodeRefId() > 0 &&
n->getNodeRefId() >
iter->first)
638 if(!
hasColor_ && !(pt.r ==0 && pt.g == 0 && pt.b == 0) && !(pt.r ==255 && pt.g == 255 && pt.b == 255))
645 n->setNodeRefId(
iter->first);
654 octomap::KeyRay keyRay;
656 (
iter->first < 0 ||
iter->first>lastId) &&
659 free_cells.insert(keyRay.begin(), keyRay.end());
662 UDEBUG(
"%d: occupied cells=%d free cells=%d",
iter->first, (
int)maxObstaclePts, (
int)free_cells.size());
666 for(octomap::KeySet::iterator it = free_cells.begin(),
end=free_cells.end(); it!=
end; ++it)
671 if(
n &&
n->getNodeRefId() > 0 &&
n->getNodeRefId() >=
iter->first)
684 n->setNodeRefId(
iter->first);
692 unsigned int maxEmptyPts = emptyCells.cols;
693 UDEBUG(
"%d: compute free cells (from %d empty points)",
iter->first, (
int)maxEmptyPts);
696 for (
unsigned int i=0;
i<maxEmptyPts; ++
i)
702 octomap::point3d
point(pt.x, pt.y, pt.z);
704 bool ignoreCell =
false;
705 if(rangeMaxSqrd > 0.0
f)
707 octomap::point3d
v(pt.x - sensorOrigin.x(), pt.y - sensorOrigin.y(), pt.z - sensorOrigin.z());
708 if(
v.norm_sq() > rangeMaxSqrd)
716 octomap::OcTreeKey
key;
723 if(
n &&
n->getNodeRefId() > 0 &&
n->getNodeRefId() >=
iter->first)
738 n->setNodeRefId(
iter->first);
746 if(emptyCells.cols || !free_cells.empty())
762 UDEBUG(
"Did not find %d in cache",
iter->first);
775 std::vector<octomap::OcTreeKey> nodeToDelete;
779 if(!
octree_->isNodeOccupied(*it))
783 nodeToDelete.push_back(it.getKey());
788 for(
unsigned int y=0;
y < nodeToDelete.size();
y++)
792 UDEBUG(
"Flood Fill: deleted %d empty cells (%fs)", (
int)nodeToDelete.size(),
t.ticks());
826 unsigned int treeDepth,
827 std::vector<int> * obstacleIndices,
828 std::vector<int> * emptyIndices,
829 std::vector<int> * groundIndices,
830 bool originalRefPoints,
831 std::vector<int> * frontierIndices,
832 std::vector<double> * cloudProb)
const
834 UASSERT(treeDepth <= octree_->getTreeDepth());
835 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
838 cloudProb->resize(
octree_->size());
840 UDEBUG(
"depth=%d (maxDepth=%d) octree = %d",
841 (
int)treeDepth, (
int)
octree_->getTreeDepth(), (
int)
octree_->size());
842 cloud->resize(
octree_->size());
845 obstacleIndices->resize(
octree_->size());
849 emptyIndices->resize(
octree_->size());
853 frontierIndices->resize(
octree_->size());
857 groundIndices->resize(
octree_->size());
862 treeDepth =
octree_->getTreeDepth();
868 bool addAllPoints = obstacleIndices == 0 && groundIndices == 0 && emptyIndices == 0;
874 float halfCellSize =
octree_->getNodeSize(treeDepth)/2.0f;
876 for (RtabmapColorOcTree::iterator it =
octree_->begin(treeDepth); it !=
octree_->end(); ++it)
878 if(
octree_->isNodeOccupied(*it) && (obstacleIndices != 0 || groundIndices != 0 || addAllPoints))
880 octomap::point3d pt =
octree_->keyToCoord(it.getKey());
883 (*cloudProb)[oi] = it->getOccupancy();
887 (*cloud)[oi] = pcl::PointXYZRGB(it->getColor().r, it->getColor().g, it->getColor().b);
892 float H = (maxZ - pt.z())*299.0
f/(maxZ-minZ);
895 (*cloud)[oi].r = r*255.0f;
896 (*cloud)[oi].g =
g*255.0f;
897 (*cloud)[oi].b =
b*255.0f;
900 if(originalRefPoints && it->getOccupancyType() > 0)
902 const octomap::point3d &
p = it->getPointRef();
903 (*cloud)[oi].x =
p.x();
904 (*cloud)[oi].y =
p.y();
905 (*cloud)[oi].z =
p.z();
909 (*cloud)[oi].x = pt.x()-halfCellSize;
910 (*cloud)[oi].y = pt.y()-halfCellSize;
911 (*cloud)[oi].z = pt.z();
918 groundIndices->at(gi++) = oi;
921 else if(obstacleIndices)
923 obstacleIndices->at(si++) = oi;
928 else if(!
octree_->isNodeOccupied(*it) && (emptyIndices != 0 || addAllPoints || frontierIndices !=0))
930 octomap::point3d pt =
octree_->keyToCoord(it.getKey());
933 (*cloudProb)[oi] = it->getOccupancy();
935 if(frontierIndices !=0 &&
936 (!
octree_->search( pt.x()+
octree_->getNodeSize(treeDepth), pt.y(), pt.z(), treeDepth) || !
octree_->search( pt.x()-
octree_->getNodeSize(treeDepth), pt.y(), pt.z(), treeDepth) ||
937 !
octree_->search( pt.x(), pt.y()+
octree_->getNodeSize(treeDepth), pt.z(), treeDepth) || !
octree_->search( pt.x(), pt.y()-
octree_->getNodeSize(treeDepth), pt.z(), treeDepth) ||
938 !
octree_->search( pt.x(), pt.y(), pt.z()+
octree_->getNodeSize(treeDepth), treeDepth) || !
octree_->search( pt.x(), pt.y(), pt.z()-
octree_->getNodeSize(treeDepth), treeDepth) ))
941 frontierIndices->at(fi++) = oi;
945 (*cloud)[oi] = pcl::PointXYZRGB(it->getColor().r, it->getColor().g, it->getColor().b);
946 (*cloud)[oi].x = pt.x()-halfCellSize;
947 (*cloud)[oi].y = pt.y()-halfCellSize;
948 (*cloud)[oi].z = pt.z();
952 emptyIndices->at(ei++) = oi;
962 cloudProb->resize(oi);
966 obstacleIndices->resize(si);
967 UDEBUG(
"obstacle=%d", si);
971 emptyIndices->resize(ei);
976 frontierIndices->resize(fi);
977 UDEBUG(
"frontier=%d", fi);
981 groundIndices->resize(gi);
991 UDEBUG(
"minGridSize=%f, treeDepth=%d", minGridSize, (
int)treeDepth);
992 UASSERT(treeDepth <= octree_->getTreeDepth());
995 treeDepth =
octree_->getTreeDepth();
998 gridCellSize =
octree_->getNodeSize(treeDepth);
1000 cv::Mat obstaclesMat = cv::Mat(1, (
int)
octree_->size(), CV_32FC2);
1001 cv::Mat groundMat = cv::Mat(1, (
int)
octree_->size(), CV_32FC2);
1004 cv::Vec2f * oPtr = obstaclesMat.ptr<cv::Vec2f>(0,0);
1005 cv::Vec2f * gPtr = groundMat.ptr<cv::Vec2f>(0,0);
1006 float halfCellSize =
octree_->getNodeSize(treeDepth)/2.0f;
1007 for (RtabmapColorOcTree::iterator it =
octree_->begin(treeDepth); it !=
octree_->end(); ++it)
1009 octomap::point3d pt =
octree_->keyToCoord(it.getKey());
1010 if(
octree_->isNodeOccupied(*it) &&
1014 oPtr[oi][0] = pt.x()-halfCellSize;
1015 oPtr[oi][1] = pt.y()-halfCellSize;
1021 gPtr[gi][0] = pt.x()-halfCellSize;
1022 gPtr[gi][1] = pt.y()-halfCellSize;
1029 std::map<int, Transform> poses;
1031 std::map<int, std::pair<cv::Mat, cv::Mat> > maps;
1032 maps.insert(std::make_pair(1, std::make_pair(groundMat, obstaclesMat)));