octomap_render.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2013, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 /* Author: Julius Kammerl */
00031 
00032 #include <moveit/rviz_plugin_render_tools/octomap_render.h>
00033 
00034 #include <octomap_msgs/Octomap.h>
00035 #include <octomap/octomap.h>
00036 
00037 #include <OGRE/OgreSceneNode.h>
00038 #include <OGRE/OgreSceneManager.h>
00039 
00040 #include <rviz/ogre_helpers/point_cloud.h>
00041 
00042 namespace moveit_rviz_plugin
00043 {
00044 
00045 typedef std::vector<rviz::PointCloud::Point> VPoint;
00046 typedef std::vector<VPoint> VVPoint;
00047 
00048 OcTreeRender::OcTreeRender(const boost::shared_ptr<const octomap::OcTree> &octree,
00049                            OctreeVoxelRenderMode octree_voxel_rendering,
00050                            OctreeVoxelColorMode octree_color_mode,
00051                            std::size_t max_octree_depth,
00052                            Ogre::SceneManager* scene_manager,
00053                            Ogre::SceneNode* parent_node = NULL) :
00054   octree_(octree),
00055   colorFactor_(0.8)
00056 {
00057 
00058   if (!parent_node)
00059   {
00060     parent_node = scene_manager_->getRootSceneNode();
00061   }
00062 
00063   if (!max_octree_depth)
00064   {
00065     octree_depth_ = octree->getTreeDepth();
00066   } else
00067   {
00068     octree_depth_ = std::min(max_octree_depth, (std::size_t)octree->getTreeDepth());
00069   }
00070 
00071 
00072   scene_node_ = parent_node->createChildSceneNode();
00073 
00074   cloud_.resize(octree_depth_);
00075 
00076   for (std::size_t i = 0 ; i < octree_depth_ ; ++i)
00077   {
00078     std::stringstream sname;
00079     sname << "PointCloud Nr." << i;
00080     cloud_[i] = new rviz::PointCloud();
00081     cloud_[i]->setName(sname.str());
00082     cloud_[i]->setRenderMode(rviz::PointCloud::RM_BOXES);
00083     scene_node_->attachObject(cloud_[i]);
00084   }
00085 
00086   octreeDecoding(octree,
00087                  octree_voxel_rendering,
00088                  octree_color_mode);
00089 
00090 }
00091 
00092 OcTreeRender::~OcTreeRender()
00093 {
00094   scene_node_->detachAllObjects();
00095 
00096   for (std::size_t i = 0 ; i < octree_depth_ ; ++i)
00097   {
00098     delete cloud_[i];
00099   }
00100 
00101 }
00102 
00103 // method taken from octomap_server package
00104 void OcTreeRender::setColor( double z_pos, double min_z, double max_z, double color_factor, rviz::PointCloud::Point* point)
00105 {
00106   int i;
00107   double m, n, f;
00108 
00109   double s = 1.0;
00110   double v = 1.0;
00111 
00112   double h = (1.0 - std::min(std::max((z_pos-min_z)/ (max_z - min_z), 0.0), 1.0)) *color_factor;
00113 
00114   h -= floor(h);
00115   h *= 6;
00116   i = floor(h);
00117   f = h - i;
00118   if (!(i & 1))
00119     f = 1 - f; // if i is even
00120   m = v * (1 - s);
00121   n = v * (1 - s * f);
00122 
00123   switch (i) {
00124     case 6:
00125     case 0:
00126       point->setColor(v, n, m);
00127       break;
00128     case 1:
00129       point->setColor(n, v, m);
00130       break;
00131     case 2:
00132       point->setColor(m, v, n);
00133       break;
00134     case 3:
00135       point->setColor(m, n, v);
00136       break;
00137     case 4:
00138       point->setColor(n, m, v);
00139       break;
00140     case 5:
00141       point->setColor(v, m, n);
00142       break;
00143     default:
00144       point->setColor(1, 0.5, 0.5);
00145       break;
00146   }
00147 }
00148 
00149 
00150 void OcTreeRender::octreeDecoding (const boost::shared_ptr<const octomap::OcTree> &octree,
00151                                    OctreeVoxelRenderMode octree_voxel_rendering,
00152                                    OctreeVoxelColorMode octree_color_mode)
00153 {
00154   VVPoint pointBuf_;
00155   pointBuf_.resize(octree_depth_);
00156 
00157   // get dimensions of octree
00158   double minX, minY, minZ, maxX, maxY, maxZ;
00159   octree->getMetricMin(minX, minY, minZ);
00160   octree->getMetricMax(maxX, maxY, maxZ);
00161 
00162   unsigned int render_mode_mask = static_cast<unsigned int>(octree_voxel_rendering);
00163 
00164   size_t pointCount = 0;
00165   {
00166     // traverse all leafs in the tree:
00167     for (octomap::OcTree::iterator it = octree->begin(octree_depth_), end = octree->end(); it != end; ++it)
00168     {
00169       bool display_voxel = false;
00170 
00171       // the left part evaluates to 1 for free voxels and 2 for occupied voxels
00172       if (((int)octree->isNodeOccupied(*it) + 1) & render_mode_mask)
00173       {
00174         // check if current voxel has neighbors on all sides -> no need to be displayed
00175         bool allNeighborsFound = true;
00176 
00177         octomap::OcTreeKey key;
00178         octomap::OcTreeKey nKey = it.getKey();
00179 
00180         for (key[2] = nKey[2] - 1; allNeighborsFound && key[2] <= nKey[2] + 1; ++key[2])
00181         {
00182           for (key[1] = nKey[1] - 1; allNeighborsFound && key[1] <= nKey[1] + 1; ++key[1])
00183           {
00184             for (key[0] = nKey[0] - 1; allNeighborsFound && key[0] <= nKey[0] + 1; ++key[0])
00185             {
00186               if (key != nKey)
00187               {
00188                 octomap::OcTreeNode* node = octree->search(key);
00189 
00190                 // the left part evaluates to 1 for free voxels and 2 for occupied voxels
00191                 if (!(node && (((int)octree->isNodeOccupied(node)) + 1) & render_mode_mask))
00192                 {
00193                   // we do not have a neighbor => break!
00194                   allNeighborsFound = false;
00195                 }
00196               }
00197             }
00198           }
00199         }
00200 
00201         display_voxel |= !allNeighborsFound;
00202       }
00203 
00204 
00205       if (display_voxel)
00206       {
00207         rviz::PointCloud::Point newPoint;
00208 
00209         newPoint.position.x = it.getX();
00210         newPoint.position.y = it.getY();
00211         newPoint.position.z = it.getZ();
00212 
00213         float cell_probability;
00214 
00215         switch (octree_color_mode)
00216         {
00217           case OCTOMAP_Z_AXIS_COLOR:
00218             setColor(newPoint.position.z, minZ, maxZ, colorFactor_, &newPoint);
00219             break;
00220           case OCTOMAP_PROBABLILTY_COLOR:
00221             cell_probability = it->getOccupancy();
00222             newPoint.setColor((1.0f-cell_probability), cell_probability, 0.0);
00223             break;
00224           default:
00225             break;
00226         }
00227 
00228         // push to point vectors
00229         unsigned int depth = it.getDepth();
00230         pointBuf_[depth-1].push_back(newPoint);
00231 
00232         ++pointCount;
00233       }
00234 
00235     }
00236   }
00237 
00238   for (size_t i = 0; i < octree_depth_ ; ++i)
00239   {
00240     double size = octree->getNodeSize(i+1);
00241 
00242     cloud_[i]->clear();
00243     cloud_[i]->setDimensions( size, size, size );
00244 
00245     cloud_[i]->addPoints(&pointBuf_[i].front(), pointBuf_[i].size());
00246     pointBuf_[i].clear();
00247   }
00248 
00249 }
00250 
00251 
00252 }


visualization
Author(s): Ioan Sucan , Dave Coleman
autogenerated on Mon Oct 6 2014 02:34:03