00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
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;
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
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
00167 for (octomap::OcTree::iterator it = octree->begin(octree_depth_), end = octree->end(); it != end; ++it)
00168 {
00169 bool display_voxel = false;
00170
00171
00172 if (((int)octree->isNodeOccupied(*it) + 1) & render_mode_mask)
00173 {
00174
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
00191 if (!(node && (((int)octree->isNodeOccupied(node)) + 1) & render_mode_mask))
00192 {
00193
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
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 }