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 "polygonal_map_display.h"
00033 #include "rviz/visualization_manager.h"
00034 #include "rviz/properties/property.h"
00035 #include "rviz/properties/property_manager.h"
00036 #include "rviz/common.h"
00037
00038 #include "ogre_tools/arrow.h"
00039
00040 #include <tf/transform_listener.h>
00041
00042 #include <boost/bind.hpp>
00043
00044 #include <OGRE/OgreSceneNode.h>
00045 #include <OGRE/OgreSceneManager.h>
00046 #include <OGRE/OgreManualObject.h>
00047 #include <OGRE/OgreBillboardSet.h>
00048
00049 #include <ogre_tools/point_cloud.h>
00050
00051 namespace mapping_rviz_plugin
00052 {
00053
00054 PolygonalMapDisplay::PolygonalMapDisplay(const std::string & name,
00055 rviz::VisualizationManager * manager)
00056 : Display(name, manager)
00057 , color_(0.1f, 1.0f, 0.0f)
00058 , render_operation_(polygon_render_ops::PLines)
00059 , tf_filter_(*manager->getTFClient(), "", 2, update_nh_)
00060 {
00061 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00062
00063 static int count = 0;
00064 std::stringstream ss;
00065 ss << "Polygonal Map" << count++;
00066 manual_object_ = scene_manager_->createManualObject(ss.str());
00067 manual_object_->setDynamic(true);
00068 scene_node_->attachObject(manual_object_);
00069
00070 cloud_ = new ogre_tools::PointCloud ();
00071 scene_node_->attachObject(cloud_);
00072 billboard_line_ = new ogre_tools::BillboardLine (scene_manager_, scene_node_);
00073
00074 setAlpha (1.0f);
00075 setPointSize (0.02f);
00076 setLineWidth(0.02f);
00077
00078 tf_filter_.connectInput(sub_);
00079 tf_filter_.registerCallback(boost::bind(&PolygonalMapDisplay::incomingMessage, this, _1));
00080 }
00081
00082 PolygonalMapDisplay::~PolygonalMapDisplay()
00083 {
00084 unsubscribe();
00085 clear();
00086
00087 scene_manager_->destroyManualObject(manual_object_);
00088
00089 delete cloud_;
00090 delete billboard_line_;
00091 }
00092
00093 void PolygonalMapDisplay::clear()
00094 {
00095 manual_object_->clear ();
00096 cloud_->clear ();
00097 billboard_line_->clear ();
00098 }
00099
00100 void PolygonalMapDisplay::setTopic(const std::string & topic)
00101 {
00102 unsubscribe();
00103 topic_ = topic;
00104 subscribe();
00105
00106 propertyChanged(topic_property_);
00107
00108 causeRender();
00109 }
00110
00111 void PolygonalMapDisplay::setColor(const rviz::Color & color)
00112 {
00113 color_ = color;
00114
00115 propertyChanged(color_property_);
00116
00117 processMessage(current_message_);
00118 causeRender();
00119 }
00120
00121 void PolygonalMapDisplay::setRenderOperation(int op)
00122 {
00123 render_operation_ = op;
00124
00125 propertyChanged(render_operation_property_);
00126
00127 processMessage(current_message_);
00128 causeRender();
00129 }
00130
00131 void PolygonalMapDisplay::setLineWidth (float width)
00132 {
00133 line_width_ = width;
00134
00135 propertyChanged(line_width_property_);
00136
00137 processMessage(current_message_);
00138 causeRender ();
00139 }
00140
00141 void PolygonalMapDisplay::setPointSize (float size)
00142 {
00143 point_size_ = size;
00144
00145 propertyChanged(point_size_property_);
00146
00147 cloud_->setDimensions (size, size, size);
00148 causeRender ();
00149 }
00150
00151
00152 void PolygonalMapDisplay::setAlpha(float alpha)
00153 {
00154 alpha_ = alpha;
00155 cloud_->setAlpha (alpha);
00156
00157 propertyChanged(alpha_property_);
00158
00159 processMessage(current_message_);
00160 causeRender();
00161 }
00162
00163 void PolygonalMapDisplay::subscribe()
00164 {
00165 if (!isEnabled())
00166 return;
00167
00168 sub_.subscribe(update_nh_, topic_, 1);
00169 }
00170
00171 void PolygonalMapDisplay::unsubscribe()
00172 {
00173 sub_.unsubscribe();
00174 }
00175
00176 void PolygonalMapDisplay::onEnable()
00177 {
00178 scene_node_->setVisible(true);
00179 subscribe();
00180 }
00181
00182 void PolygonalMapDisplay::onDisable()
00183 {
00184 unsubscribe();
00185 clear();
00186 scene_node_->setVisible(false);
00187 }
00188
00189 void PolygonalMapDisplay::fixedFrameChanged()
00190 {
00191 tf_filter_.setTargetFrame( fixed_frame_ );
00192 clear();
00193 }
00194
00195 void PolygonalMapDisplay::update(float wall_dt, float ros_dt)
00196 {
00197 }
00198
00199 void PolygonalMapDisplay::processMessage (const mapping_msgs::PolygonalMap::ConstPtr& msg)
00200 {
00201 clear();
00202
00203 if (!msg)
00204 {
00205 return;
00206 }
00207
00208 tf::Stamped<tf::Pose> pose(btTransform(btQuaternion(0.0f, 0.0f, 0.0f),
00209 btVector3(0.0f, 0.0f, 0.0f)), msg->header.stamp,
00210 msg->header.frame_id);
00211
00212 try
00213 {
00214 vis_manager_->getTFClient()->transformPose(fixed_frame_, pose, pose);
00215 }
00216 catch (tf::TransformException & e)
00217 {
00218 ROS_ERROR("Error transforming from frame 'map' to frame '%s'",
00219 fixed_frame_.c_str());
00220 }
00221
00222 Ogre::Vector3 position = Ogre::Vector3(pose.getOrigin().x(),
00223 pose.getOrigin().y(), pose.getOrigin().z());
00224 rviz::robotToOgre(position);
00225
00226 btScalar yaw, pitch, roll;
00227 pose.getBasis().getEulerZYX(yaw, pitch, roll);
00228
00229 Ogre::Matrix3 orientation(rviz::ogreMatrixFromRobotEulers(yaw, pitch, roll));
00230
00231 Ogre::ColourValue color;
00232
00233 uint32_t num_polygons = msg->get_polygons_size ();
00234 uint32_t num_total_points = 0;
00235 for (uint32_t i = 0; i < num_polygons; i++)
00236 num_total_points += msg->polygons[i].points.size ();
00237
00238
00239 if (render_operation_ == polygon_render_ops::PPoints)
00240 {
00241 typedef std::vector<ogre_tools::PointCloud::Point> V_Point;
00242 V_Point points;
00243 points.resize (num_total_points);
00244 uint32_t cnt_total_points = 0;
00245 for (uint32_t i = 0; i < num_polygons; i++)
00246 {
00247 for (uint32_t j = 0; j < msg->polygons[i].points.size(); j++)
00248 {
00249 ogre_tools::PointCloud::Point ¤t_point = points[cnt_total_points];
00250
00251 current_point.x = msg->polygons[i].points[j].x;
00252 current_point.y = msg->polygons[i].points[j].y;
00253 current_point.z = msg->polygons[i].points[j].z;
00254 color = Ogre::ColourValue (color_.r_, color_.g_, color_.b_, alpha_);
00255 current_point.setColor(color.r, color.g, color.b);
00256 cnt_total_points++;
00257 }
00258 }
00259
00260 cloud_->clear();
00261
00262 if (!points.empty())
00263 cloud_->addPoints(&points.front(), points.size());
00264 }
00265
00266 else if (render_operation_ == polygon_render_ops::PLines)
00267 {
00268 for (uint32_t i = 0; i < num_polygons; i++)
00269 {
00270 manual_object_->estimateVertexCount (msg->polygons[i].points.size ());
00271 manual_object_->begin ("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_STRIP);
00272 for (uint32_t j = 0; j < msg->polygons[i].points.size (); j++)
00273 {
00274 manual_object_->position (msg->polygons[i].points[j].x,
00275 msg->polygons[i].points[j].y,
00276 msg->polygons[i].points[j].z);
00277 color = Ogre::ColourValue(color_.r_, color_.g_, color_.b_, alpha_);
00278 manual_object_->colour (color);
00279 }
00280 manual_object_->end ();
00281 }
00282 }
00283
00284 else if (render_operation_ == polygon_render_ops::PBillboards)
00285 {
00286 billboard_line_->setMaxPointsPerLine (2);
00287 billboard_line_->setLineWidth (line_width_);
00288 billboard_line_->setColor (color_.r_, color_.g_, color_.b_, alpha_);
00289
00290 billboard_line_->setNumLines (num_total_points);
00291
00292
00293 for (uint32_t i = 0; i < num_polygons; i++)
00294 {
00295
00296 if (msg->polygons[i].points.size () == 0)
00297 continue;
00298 uint32_t j = 0;
00299 for (j = 0; j < msg->polygons[i].points.size () - 1; j++)
00300 {
00301 Ogre::Vector3 p1 (msg->polygons[i].points[j].x,
00302 msg->polygons[i].points[j].y,
00303 msg->polygons[i].points[j].z);
00304 Ogre::Vector3 p2 (msg->polygons[i].points[j+1].x,
00305 msg->polygons[i].points[j+1].y,
00306 msg->polygons[i].points[j+1].z);
00307
00308 billboard_line_->newLine ();
00309 billboard_line_->addPoint (p1);
00310 billboard_line_->addPoint (p2);
00311 }
00312 }
00313 }
00314
00315 scene_node_->setPosition(position);
00316 scene_node_->setOrientation(orientation);
00317 }
00318
00319 void PolygonalMapDisplay::incomingMessage(const mapping_msgs::PolygonalMap::ConstPtr& msg)
00320 {
00321 processMessage(msg);
00322 }
00323
00324 void PolygonalMapDisplay::reset()
00325 {
00326 clear();
00327 }
00328
00329 void PolygonalMapDisplay::targetFrameChanged()
00330 {
00331 }
00332
00333 void PolygonalMapDisplay::createProperties()
00334 {
00335 color_property_ = property_manager_->createProperty<rviz::ColorProperty> ("Color", property_prefix_, boost::bind(&PolygonalMapDisplay::getColor, this),
00336 boost::bind(&PolygonalMapDisplay::setColor, this, _1), parent_category_, this);
00337 render_operation_property_ = property_manager_->createProperty<rviz::EnumProperty> ("Render Operation", property_prefix_, boost::bind(&PolygonalMapDisplay::getRenderOperation, this),
00338 boost::bind(&PolygonalMapDisplay::setRenderOperation, this, _1), parent_category_, this);
00339 rviz::EnumPropertyPtr enum_prop = render_operation_property_.lock();
00340 enum_prop->addOption("Lines", polygon_render_ops::PLines);
00341 enum_prop->addOption("Points", polygon_render_ops::PPoints);
00342 enum_prop->addOption("Billboard Lines", polygon_render_ops::PBillboards);
00343
00344 line_width_property_ = property_manager_->createProperty<rviz::FloatProperty> ("Line Width", property_prefix_, boost::bind (&PolygonalMapDisplay::getLineWidth, this),
00345 boost::bind (&PolygonalMapDisplay::setLineWidth, this, _1 ), parent_category_, this );
00346 rviz::FloatPropertyPtr float_prop = line_width_property_.lock();
00347 float_prop->setMin (0.001);
00348
00349 point_size_property_ = property_manager_->createProperty<rviz::FloatProperty>("Point Size", property_prefix_, boost::bind(&PolygonalMapDisplay::getPointSize, this),
00350 boost::bind( &PolygonalMapDisplay::setPointSize, this, _1 ), parent_category_, this);
00351
00352 alpha_property_ = property_manager_->createProperty<rviz::FloatProperty> ("Alpha", property_prefix_, boost::bind(&PolygonalMapDisplay::getAlpha, this),
00353 boost::bind(&PolygonalMapDisplay::setAlpha, this, _1), parent_category_,this);
00354 topic_property_ = property_manager_->createProperty<rviz::ROSTopicStringProperty> ("Topic", property_prefix_, boost::bind(&PolygonalMapDisplay::getTopic, this),
00355 boost::bind(&PolygonalMapDisplay::setTopic, this, _1), parent_category_, this);
00356 rviz::ROSTopicStringPropertyPtr topic_prop = topic_property_.lock();
00357 topic_prop->setMessageType(mapping_msgs::PolygonalMap::__s_getDataType());
00358
00359
00360 }
00361
00362 }