$search
00001 /* 00002 * Copyright (c) 2008, 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 #include "grid_cells_display.h" 00031 #include "rviz/visualization_manager.h" 00032 #include "rviz/properties/property.h" 00033 #include "rviz/properties/property_manager.h" 00034 #include "rviz/frame_manager.h" 00035 #include "rviz/validate_floats.h" 00036 00037 #include "ogre_tools/arrow.h" 00038 00039 #include <tf/transform_listener.h> 00040 00041 #include <boost/bind.hpp> 00042 00043 #include <OGRE/OgreSceneNode.h> 00044 #include <OGRE/OgreSceneManager.h> 00045 #include <OGRE/OgreManualObject.h> 00046 #include <OGRE/OgreBillboardSet.h> 00047 00048 #include <ogre_tools/point_cloud.h> 00049 00050 namespace rviz 00051 { 00052 00053 GridCellsDisplay::GridCellsDisplay( const std::string& name, VisualizationManager* manager ) 00054 : Display( name, manager ) 00055 , color_( 0.1f, 1.0f, 0.0f ) 00056 , tf_filter_(*manager->getTFClient(), "", 10, update_nh_) 00057 , messages_received_(0) 00058 { 00059 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode(); 00060 00061 static int count = 0; 00062 std::stringstream ss; 00063 ss << "PolyLine" << count++; 00064 00065 cloud_ = new ogre_tools::PointCloud(); 00066 cloud_->setRenderMode( ogre_tools::PointCloud::RM_BILLBOARDS_COMMON_FACING ); 00067 cloud_->setCommonDirection( Ogre::Vector3::UNIT_Z ); 00068 cloud_->setCommonUpVector( Ogre::Vector3::UNIT_Y ); 00069 scene_node_->attachObject(cloud_); 00070 setAlpha( 1.0f ); 00071 00072 tf_filter_.connectInput(sub_); 00073 tf_filter_.registerCallback(boost::bind(&GridCellsDisplay::incomingMessage, this, _1)); 00074 vis_manager_->getFrameManager()->registerFilterForTransformStatusCheck(tf_filter_, this); 00075 } 00076 00077 GridCellsDisplay::~GridCellsDisplay() 00078 { 00079 unsubscribe(); 00080 clear(); 00081 00082 scene_manager_->destroySceneNode(scene_node_->getName()); 00083 delete cloud_; 00084 } 00085 00086 void GridCellsDisplay::clear() 00087 { 00088 cloud_->clear(); 00089 00090 messages_received_ = 0; 00091 setStatus(status_levels::Warn, "Topic", "No messages received"); 00092 } 00093 00094 void GridCellsDisplay::setTopic( const std::string& topic ) 00095 { 00096 unsubscribe(); 00097 00098 topic_ = topic; 00099 00100 subscribe(); 00101 00102 propertyChanged(topic_property_); 00103 00104 causeRender(); 00105 } 00106 00107 void GridCellsDisplay::setColor( const Color& color ) 00108 { 00109 color_ = color; 00110 00111 propertyChanged(color_property_); 00112 00113 processMessage(current_message_); 00114 causeRender(); 00115 } 00116 00117 void GridCellsDisplay::setAlpha( float alpha ) 00118 { 00119 alpha_ = alpha; 00120 00121 cloud_->setAlpha( alpha ); 00122 00123 propertyChanged(alpha_property_); 00124 00125 processMessage(current_message_); 00126 causeRender(); 00127 } 00128 00129 void GridCellsDisplay::subscribe() 00130 { 00131 if ( !isEnabled() ) 00132 { 00133 return; 00134 } 00135 00136 sub_.subscribe(update_nh_, topic_, 10); 00137 } 00138 00139 void GridCellsDisplay::unsubscribe() 00140 { 00141 sub_.unsubscribe(); 00142 } 00143 00144 void GridCellsDisplay::onEnable() 00145 { 00146 scene_node_->setVisible( true ); 00147 subscribe(); 00148 } 00149 00150 void GridCellsDisplay::onDisable() 00151 { 00152 unsubscribe(); 00153 clear(); 00154 scene_node_->setVisible( false ); 00155 } 00156 00157 void GridCellsDisplay::fixedFrameChanged() 00158 { 00159 clear(); 00160 00161 tf_filter_.setTargetFrame( fixed_frame_ ); 00162 } 00163 00164 void GridCellsDisplay::update(float wall_dt, float ros_dt) 00165 { 00166 } 00167 00168 bool validateFloats(const nav_msgs::GridCells& msg) 00169 { 00170 bool valid = true; 00171 valid = valid && validateFloats(msg.cell_width); 00172 valid = valid && validateFloats(msg.cell_height); 00173 valid = valid && validateFloats(msg.cells); 00174 return valid; 00175 } 00176 00177 void GridCellsDisplay::processMessage(const nav_msgs::GridCells::ConstPtr& msg) 00178 { 00179 if (!msg) 00180 { 00181 return; 00182 } 00183 00184 cloud_->clear(); 00185 00186 ++messages_received_; 00187 00188 if (!validateFloats(*msg)) 00189 { 00190 setStatus(status_levels::Error, "Topic", "Message contained invalid floating point values (nans or infs)"); 00191 return; 00192 } 00193 00194 std::stringstream ss; 00195 ss << messages_received_ << " messages received"; 00196 setStatus(status_levels::Ok, "Topic", ss.str()); 00197 00198 Ogre::Vector3 position; 00199 Ogre::Quaternion orientation; 00200 if (!vis_manager_->getFrameManager()->getTransform(msg->header, position, orientation)) 00201 { 00202 ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'", msg->header.frame_id.c_str(), fixed_frame_.c_str() ); 00203 } 00204 00205 scene_node_->setPosition( position ); 00206 scene_node_->setOrientation( orientation ); 00207 00208 Ogre::ColourValue color( color_.r_, color_.g_, color_.b_, alpha_ ); 00209 00210 if( msg->cell_width == 0 ) 00211 { 00212 setStatus(status_levels::Error, "Topic", "Cell width is zero, cells will be invisible."); 00213 } 00214 else if( msg->cell_height == 0 ) 00215 { 00216 setStatus(status_levels::Error, "Topic", "Cell height is zero, cells will be invisible."); 00217 } 00218 00219 cloud_->setDimensions(msg->cell_width, msg->cell_height, 0.0); 00220 00221 uint32_t num_points = msg->cells.size(); 00222 00223 typedef std::vector< ogre_tools::PointCloud::Point > V_Point; 00224 V_Point points; 00225 points.resize( num_points ); 00226 for(uint32_t i = 0; i < num_points; i++) 00227 { 00228 ogre_tools::PointCloud::Point& current_point = points[ i ]; 00229 00230 Ogre::Vector3 pos(msg->cells[i].x, msg->cells[i].y, msg->cells[i].z); 00231 00232 current_point.x = pos.x; 00233 current_point.y = pos.y; 00234 current_point.z = pos.z; 00235 current_point.setColor(color.r, color.g, color.b); 00236 } 00237 00238 cloud_->clear(); 00239 00240 if ( !points.empty() ) 00241 { 00242 cloud_->addPoints( &points.front(), points.size() ); 00243 } 00244 } 00245 00246 void GridCellsDisplay::incomingMessage(const nav_msgs::GridCells::ConstPtr& msg) 00247 { 00248 processMessage(msg); 00249 } 00250 00251 void GridCellsDisplay::reset() 00252 { 00253 Display::reset(); 00254 clear(); 00255 } 00256 00257 void GridCellsDisplay::createProperties() 00258 { 00259 color_property_ = property_manager_->createProperty<ColorProperty>( "Color", property_prefix_, boost::bind( &GridCellsDisplay::getColor, this ), 00260 boost::bind( &GridCellsDisplay::setColor, this, _1 ), parent_category_, this ); 00261 setPropertyHelpText(color_property_, "Color of the grid cells."); 00262 alpha_property_ = property_manager_->createProperty<FloatProperty>( "Alpha", property_prefix_, boost::bind( &GridCellsDisplay::getAlpha, this ), 00263 boost::bind( &GridCellsDisplay::setAlpha, this, _1 ), parent_category_, this ); 00264 setPropertyHelpText(alpha_property_, "Amount of transparency to apply to the cells."); 00265 00266 topic_property_ = property_manager_->createProperty<ROSTopicStringProperty>( "Topic", property_prefix_, boost::bind( &GridCellsDisplay::getTopic, this ), 00267 boost::bind( &GridCellsDisplay::setTopic, this, _1 ), parent_category_, this ); 00268 ROSTopicStringPropertyPtr topic_prop = topic_property_.lock(); 00269 topic_prop->setMessageType(ros::message_traits::datatype<nav_msgs::GridCells>()); 00270 setPropertyHelpText(topic_property_, "nav_msgs::GridCells topic to subscribe to."); 00271 } 00272 00273 const char* GridCellsDisplay::getDescription() 00274 { 00275 return "Displays data from a nav_msgs::GridCells message as either points or lines."; 00276 } 00277 00278 } // namespace rviz 00279