GridMapOctomapConverter.cpp
Go to the documentation of this file.
00001 /*
00002  * GridMapOctomapConverter.cpp
00003  *
00004  *  Created on: May 1, 2017
00005  *      Author: Jeff Delmerico, Peter Fankhauser
00006  *   Institute: University of Zürich, Robotics and Perception Group
00007  */
00008 
00009 #include "grid_map_octomap/GridMapOctomapConverter.hpp"
00010 
00011 namespace grid_map {
00012 
00013 GridMapOctomapConverter::GridMapOctomapConverter()
00014 {
00015 }
00016 
00017 GridMapOctomapConverter::~GridMapOctomapConverter()
00018 {
00019 }
00020 
00021 bool GridMapOctomapConverter::fromOctomap(const octomap::OcTree& octomap,
00022                                           const std::string& layer,
00023                                           grid_map::GridMap& gridMap,
00024                                           const grid_map::Position3* minPoint,
00025                                           const grid_map::Position3* maxPoint)
00026 {
00027   if (octomap.getTreeType() != "OcTree") {
00028     std::cerr << "Octomap conversion only implemented for standard OcTree type." << std::endl;
00029     return false;
00030   }
00031 
00032   // Copy octomap in order to expand any pruned occupied cells and maintain constness of input.
00033   octomap::OcTree octomapCopy(octomap);
00034 
00035   // Iterate through leaf nodes and project occupied cells to elevation map.
00036   // On the first pass, expand all occupied cells that are not at maximum depth.
00037   unsigned int max_depth = octomapCopy.getTreeDepth();
00038   // Adapted from octomap octree2pointcloud.cpp.
00039   std::vector<octomap::OcTreeNode*> collapsed_occ_nodes;
00040   do {
00041     collapsed_occ_nodes.clear();
00042     for (octomap::OcTree::iterator it = octomapCopy.begin(); it != octomapCopy.end(); ++it) {
00043       if (octomapCopy.isNodeOccupied(*it) && it.getDepth() < max_depth) {
00044         collapsed_occ_nodes.push_back(&(*it));
00045       }
00046     }
00047     for (std::vector<octomap::OcTreeNode*>::iterator it = collapsed_occ_nodes.begin();
00048                                             it != collapsed_occ_nodes.end(); ++it) {
00049       #if OCTOMAP_VERSION_BEFORE_ROS_KINETIC
00050         (*it)->expandNode();
00051       #else
00052         octomapCopy.expandNode(*it);
00053       #endif
00054     }
00055     // std::cout << "Expanded " << collapsed_occ_nodes.size() << " nodes" << std::endl;
00056   } while (collapsed_occ_nodes.size() > 0);
00057 
00058   // Set up grid map geometry.
00059   // TODO Figure out whether to center map.
00060   double resolution = octomapCopy.getResolution();
00061   grid_map::Position3 minBound;
00062   grid_map::Position3 maxBound;
00063   octomapCopy.getMetricMin(minBound(0), minBound(1), minBound(2));
00064   octomapCopy.getMetricMax(maxBound(0), maxBound(1), maxBound(2));
00065 
00066   // User can provide coordinate limits to only convert a bounding box.
00067   octomap::point3d minBbx(minBound(0), minBound(1), minBound(2));
00068   if (minPoint) {
00069     minBbx = octomap::point3d((*minPoint)(0), (*minPoint)(1), (*minPoint)(2));
00070     minBound = grid_map::Position3(minBbx.x(), minBbx.y(), minBbx.z());
00071   }
00072   octomap::point3d maxBbx(maxBound(0), maxBound(1), maxBound(2));
00073   if (maxPoint) {
00074     maxBbx = octomap::point3d((*maxPoint)(0), (*maxPoint)(1), (*maxPoint)(2));
00075     maxBound = grid_map::Position3(maxBbx.x(), maxBbx.y(), maxBbx.z());
00076   }
00077 
00078   grid_map::Length length = grid_map::Length(maxBound(0) - minBound(0), maxBound(1) - minBound(1));
00079   grid_map::Position position = grid_map::Position((maxBound(0) + minBound(0)) / 2.0,
00080                                                    (maxBound(1) + minBound(1)) / 2.0);
00081   gridMap.setGeometry(length, resolution, position);
00082   // std::cout << "grid map geometry: " << std::endl;
00083   // std::cout << "Length: [" << length(0) << ", " << length(1) << "]" << std::endl;
00084   // std::cout << "Position: [" << position(0) << ", " << position(1) << "]" << std::endl;
00085   // std::cout << "Resolution: " << resolution << std::endl;
00086 
00087   // Add elevation layer
00088   gridMap.add(layer);
00089   gridMap.setBasicLayers({layer});
00090 
00091   // For each voxel, if its elevation is higher than the existing value for the
00092   // corresponding grid map cell, overwrite it.
00093   // std::cout << "Iterating from " << min_bbx << " to " << max_bbx << std::endl;
00094   grid_map::Matrix& gridMapData = gridMap[layer];
00095   for(octomap::OcTree::leaf_bbx_iterator it = octomapCopy.begin_leafs_bbx(minBbx, maxBbx),
00096           end = octomapCopy.end_leafs_bbx(); it != end; ++it) {
00097     if (octomapCopy.isNodeOccupied(*it)) {
00098       octomap::point3d octoPos = it.getCoordinate();
00099       grid_map::Position position(octoPos.x(), octoPos.y());
00100       grid_map::Index index;
00101       gridMap.getIndex(position, index);
00102       // If no elevation has been set, use current elevation.
00103       if (!gridMap.isValid(index)) {
00104         gridMapData(index(0), index(1)) = octoPos.z();
00105       }
00106       // Check existing elevation, keep higher.
00107       else {
00108         if (gridMapData(index(0), index(1)) < octoPos.z()) {
00109           gridMapData(index(0), index(1)) = octoPos.z();
00110         }
00111       }
00112     }
00113   }
00114 
00115   return true;
00116 }
00117 
00118 } /* namespace */


grid_map_octomap
Author(s): Jeff Delmerico , Péter Fankhauser
autogenerated on Mon Oct 9 2017 03:09:27