00001 #include <OGRE/OgreSceneNode.h>
00002 #include <OGRE/OgreSceneManager.h>
00003
00004 #include <rviz/visualization_manager.h>
00005 #include <rviz/properties/property.h>
00006 #include <rviz/properties/property_manager.h>
00007 #include <rviz/frame_manager.h>
00008
00009 #include <boost/foreach.hpp>
00010
00011 #include "point_visual.h"
00012
00013 #include "point_display.h"
00014
00015 namespace jsk_rviz_plugin
00016 {
00017
00018 PointStampedDisplay::PointStampedDisplay()
00019 : Display()
00020 , scene_node_( NULL )
00021 , messages_received_( 0 )
00022 , color_( .8, .2, .8 )
00023 , alpha_( 1.0 )
00024 , radius_( 0.02 )
00025 {
00026 }
00027
00028 void PointStampedDisplay::onInitialize()
00029 {
00030
00031 scene_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00032
00033
00034 setHistoryLength( 1 );
00035
00036
00037
00038
00039 tf_filter_ =
00040 new tf::MessageFilter<geometry_msgs::PointStamped>( *vis_manager_->getTFClient(),
00041 "", 100, update_nh_ );
00042 tf_filter_->connectInput( sub_ );
00043 tf_filter_->registerCallback( boost::bind( &PointStampedDisplay::incomingMessage,
00044 this, _1 ));
00045
00046
00047
00048
00049 vis_manager_->getFrameManager()
00050 ->registerFilterForTransformStatusCheck( tf_filter_, this );
00051
00052 }
00053
00054 PointStampedDisplay::~PointStampedDisplay()
00055 {
00056 unsubscribe();
00057 clear();
00058 visuals_.clear();
00059
00060 delete tf_filter_;
00061 }
00062
00063
00064 void PointStampedDisplay::clear()
00065 {
00066 for( size_t i = 0; i < visuals_.size(); i++ ) {
00067 delete visuals_[ i ];
00068 visuals_[ i ] = NULL;
00069 }
00070 tf_filter_->clear();
00071 messages_received_ = 0;
00072 setStatus( rviz::status_levels::Warn, "Topic", "No messages received" );
00073 }
00074
00075 void PointStampedDisplay::setTopic( const std::string& topic )
00076 {
00077 unsubscribe();
00078 clear();
00079 topic_ = topic;
00080 subscribe();
00081
00082
00083 propertyChanged( topic_property_ );
00084
00085
00086 causeRender();
00087 }
00088
00089 void PointStampedDisplay::setColor( const rviz::Color& color )
00090 {
00091 color_ = color;
00092
00093 propertyChanged( color_property_ );
00094 updateColorAndAlpha();
00095 causeRender();
00096 }
00097
00098 void PointStampedDisplay::setAlpha( float alpha )
00099 {
00100 alpha_ = alpha;
00101
00102 propertyChanged( alpha_property_ );
00103 updateColorAndAlpha();
00104 causeRender();
00105 }
00106
00107 void PointStampedDisplay::setRadius( float radius )
00108 {
00109 radius_ = radius;
00110
00111 propertyChanged( radius_property_ );
00112 updateColorAndAlpha();
00113 causeRender();
00114 }
00115
00116
00117 void PointStampedDisplay::updateColorAndAlpha()
00118 {
00119 BOOST_FOREACH(MapPointStampedVisual::value_type visual, visuals_)
00120 {
00121 if ( visual ) {
00122 visual->setColor( color_.r_, color_.g_, color_.b_, alpha_ );
00123 visual->setRadius( radius_ );
00124 }
00125 }
00126 }
00127
00128
00129 void PointStampedDisplay::setHistoryLength( int length )
00130 {
00131
00132 if( length < 1 )
00133 {
00134 length = 1;
00135 }
00136
00137 if( history_length_ == length )
00138 {
00139 return;
00140 }
00141
00142
00143 history_length_ = length;
00144 propertyChanged( history_length_property_ );
00145
00146
00147 std::vector<PointStampedVisual*> new_visuals( history_length_, (PointStampedVisual*)0 );
00148
00149
00150
00151 size_t copy_len =
00152 (new_visuals.size() > visuals_.size()) ?
00153 visuals_.size() : new_visuals.size();
00154 for( size_t i = 0; i < copy_len; i++ )
00155 {
00156 int new_index = (messages_received_ - i) % new_visuals.size();
00157 int old_index = (messages_received_ - i) % visuals_.size();
00158 new_visuals[ new_index ] = visuals_[ old_index ];
00159 visuals_[ old_index ] = NULL;
00160 }
00161
00162
00163 for( size_t i = 0; i < visuals_.size(); i++ ) {
00164 delete visuals_[ i ];
00165 }
00166
00167
00168
00169
00170
00171
00172 visuals_.swap( new_visuals );
00173 }
00174
00175 void PointStampedDisplay::subscribe()
00176 {
00177
00178 if ( !isEnabled() )
00179 {
00180 return;
00181 }
00182
00183
00184
00185
00186 try
00187 {
00188 sub_.subscribe( update_nh_, topic_, 10 );
00189 setStatus( rviz::status_levels::Ok, "Topic", "OK" );
00190 }
00191 catch( ros::Exception& e )
00192 {
00193 setStatus( rviz::status_levels::Error, "Topic",
00194 std::string( "Error subscribing: " ) + e.what() );
00195 }
00196 }
00197
00198 void PointStampedDisplay::unsubscribe()
00199 {
00200 sub_.unsubscribe();
00201 }
00202
00203 void PointStampedDisplay::onEnable()
00204 {
00205 subscribe();
00206 }
00207
00208 void PointStampedDisplay::onDisable()
00209 {
00210 unsubscribe();
00211 clear();
00212 }
00213
00214
00215
00216 void PointStampedDisplay::fixedFrameChanged()
00217 {
00218 tf_filter_->setTargetFrame( fixed_frame_ );
00219 clear();
00220 }
00221
00222
00223 void PointStampedDisplay::incomingMessage( const geometry_msgs::PointStamped::ConstPtr& msg )
00224 {
00225 ++messages_received_;
00226
00227
00228
00229 std::stringstream ss;
00230 ss << messages_received_ << " messages received";
00231 setStatus( rviz::status_levels::Ok, "Topic", ss.str() );
00232
00233
00234
00235
00236 Ogre::Quaternion orientation;
00237 Ogre::Vector3 position;
00238 if( !vis_manager_->getFrameManager()->getTransform( msg->header.frame_id,
00239 msg->header.stamp,
00240 position, orientation ))
00241 {
00242 ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'",
00243 msg->header.frame_id.c_str(), fixed_frame_.c_str() );
00244 return;
00245 }
00246
00247
00248 PointStampedVisual* visual = visuals_[ messages_received_ % history_length_ ];
00249 if( visual == NULL )
00250 {
00251 visual = new PointStampedVisual( vis_manager_->getSceneManager(), scene_node_ );
00252 visuals_[ messages_received_ % history_length_ ] = visual;
00253 }
00254
00255
00256
00257 visual->setMessage( msg );
00258 visual->setFramePosition( position );
00259 visual->setFrameOrientation( orientation );
00260 visual->setColor( color_.r_, color_.g_, color_.b_, alpha_);
00261 visual->setRadius( radius_ );
00262 }
00263
00264
00265 void PointStampedDisplay::reset()
00266 {
00267 Display::reset();
00268 clear();
00269 }
00270
00271 void PointStampedDisplay::createProperties()
00272 {
00273 topic_property_ =
00274 property_manager_->createProperty<rviz::ROSTopicStringProperty>( "Topic",
00275 property_prefix_,
00276 boost::bind( &PointStampedDisplay::getTopic, this ),
00277 boost::bind( &PointStampedDisplay::setTopic, this, _1 ),
00278 parent_category_,
00279 this );
00280 setPropertyHelpText( topic_property_, "geometry_msgs::Point topic to subscribe to." );
00281 rviz::ROSTopicStringPropertyPtr topic_prop = topic_property_.lock();
00282 topic_prop->setMessageType( ros::message_traits::datatype<geometry_msgs::PointStamped>() );
00283
00284 color_property_ =
00285 property_manager_->createProperty<rviz::ColorProperty>( "Color",
00286 property_prefix_,
00287 boost::bind( &PointStampedDisplay::getColor, this ),
00288 boost::bind( &PointStampedDisplay::setColor, this, _1 ),
00289 parent_category_,
00290 this );
00291 setPropertyHelpText( color_property_, "Color of a point" );
00292
00293 alpha_property_ =
00294 property_manager_->createProperty<rviz::FloatProperty>( "Alpha",
00295 property_prefix_,
00296 boost::bind( &PointStampedDisplay::getAlpha, this ),
00297 boost::bind( &PointStampedDisplay::setAlpha, this, _1 ),
00298 parent_category_,
00299 this );
00300 setPropertyHelpText( alpha_property_, "0 is fully transparent, 1.0 is fully opaque." );
00301
00302 radius_property_ =
00303 property_manager_->createProperty<rviz::FloatProperty>( "Radius",
00304 property_prefix_,
00305 boost::bind( &PointStampedDisplay::getRadius, this ),
00306 boost::bind( &PointStampedDisplay::setRadius, this, _1 ),
00307 parent_category_,
00308 this );
00309 setPropertyHelpText( alpha_property_, "Radius of a point" );
00310
00311 history_length_property_ =
00312 property_manager_->createProperty<rviz::IntProperty>( "History Length",
00313 property_prefix_,
00314 boost::bind( &PointStampedDisplay::getHistoryLength, this ),
00315 boost::bind( &PointStampedDisplay::setHistoryLength, this, _1 ),
00316 parent_category_,
00317 this );
00318 setPropertyHelpText( history_length_property_, "Number of prior measurements to display." );
00319 }
00320 }
00321
00322
00323
00324 #include <pluginlib/class_list_macros.h>
00325 PLUGINLIB_DECLARE_CLASS( jsk_rviz_plugin, PointStamped, jsk_rviz_plugin::PointStampedDisplay, rviz::Display )
00326
00327