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 #include <OgreManualObject.h>
00031 #include <OgreSceneManager.h>
00032 #include <OgreSceneNode.h>
00033 
00034 #include "rviz/display_context.h"
00035 #include "rviz/frame_manager.h"
00036 #include "rviz/properties/color_property.h"
00037 #include "rviz/properties/float_property.h"
00038 #include "rviz/properties/enum_property.h"
00039 #include "rviz/validate_floats.h"
00040 #include "rviz/ogre_helpers/arrow.h"
00041 #include "rviz/ogre_helpers/axes.h"
00042 
00043 #include "pose_array_display.h"
00044 
00045 namespace jsk_rviz_plugins
00046 {
00047 
00048 PoseArrayDisplay::PoseArrayDisplay()
00049   : manual_object_( NULL )
00050 {
00051   color_property_ = new rviz::ColorProperty( "Color", QColor( 255, 25, 0 ), "Color to draw the arrows.", this );
00052   length_property_ = new rviz::FloatProperty( "Arrow Length", 0.3, "Length of the arrows.", this );
00053   axes_length_property_ = new rviz::FloatProperty( "Axes Length", 1, "Length of each axis, in meters.",
00054                                              this, SLOT( updateAxisGeometry() ));
00055   axes_radius_property_ = new rviz::FloatProperty( "Axes Radius", 0.1, "Radius of each axis, in meters.",
00056                                              this, SLOT( updateAxisGeometry() ));
00057   shape_property_ = new rviz::EnumProperty( "Shape", "Arrow", "Shape to display the pose as.",
00058                                       this, SLOT( updateShapeChoice() ));
00059   shape_property_->addOption( "Arrow", Arrow );
00060   shape_property_->addOption( "Axes", Axes );
00061 }
00062 
00063 PoseArrayDisplay::~PoseArrayDisplay()
00064 {
00065   if ( initialized() )
00066   {
00067     scene_manager_->destroyManualObject( manual_object_ );
00068   }
00069 }
00070 
00071 void PoseArrayDisplay::onInitialize()
00072 {
00073   MFDClass::onInitialize();
00074   manual_object_ = scene_manager_->createManualObject();
00075   manual_object_->setDynamic( true );
00076   scene_node_->attachObject( manual_object_ );
00077 
00078   updateShapeChoice();
00079   updateShapeVisibility();
00080   updateAxisGeometry();
00081 }
00082 
00083 void PoseArrayDisplay::updateShapeChoice()
00084 {
00085     bool use_arrow = ( shape_property_->getOptionInt() == Arrow );
00086 
00087   color_property_->setHidden( !use_arrow );
00088   length_property_->setHidden( !use_arrow );
00089 
00090   axes_length_property_->setHidden( use_arrow );
00091   axes_radius_property_->setHidden( use_arrow );
00092 
00093   updateShapeVisibility();
00094 
00095   context_->queueRender();
00096 }
00097 
00098 void PoseArrayDisplay::updateShapeVisibility()
00099 {
00100 
00101   if( !pose_valid_ )
00102   {
00103     manual_object_->setVisible(false);
00104     for (int i = 0; i < coords_nodes_.size() ; i++)
00105       coords_nodes_[i]->setVisible(false);
00106   }
00107   else
00108   {
00109     bool use_arrow = (shape_property_->getOptionInt() == Arrow);
00110     for (int i = 0; i < coords_nodes_.size() ; i++)
00111       coords_nodes_[i]->setVisible(!use_arrow);
00112 
00113     manual_object_->setVisible(use_arrow);
00114   }
00115 }
00116 
00117 void PoseArrayDisplay::updateAxisGeometry()
00118 {
00119   for(size_t i = 0; i < coords_objects_.size() ; i++)
00120     coords_objects_[i]->set( axes_length_property_->getFloat(),
00121                              axes_radius_property_->getFloat() );
00122   context_->queueRender();
00123 }
00124 
00125 void PoseArrayDisplay::allocateCoords(int num)
00126 {
00127   if (num > coords_objects_.size()) {
00128     for (size_t i = coords_objects_.size(); i < num; i++) {
00129       Ogre::SceneNode* scene_node = scene_node_->createChildSceneNode();
00130       rviz::Axes* axes = new rviz::Axes( scene_manager_, scene_node,
00131                                         axes_length_property_->getFloat(),
00132                                         axes_radius_property_->getFloat());
00133       coords_nodes_.push_back(scene_node);
00134       coords_objects_.push_back(axes);
00135     }
00136   }
00137   else if (num < coords_objects_.size()) {
00138     for (int i = coords_objects_.size() - 1; num <= i; i--) {
00139       delete coords_objects_[i];
00140       scene_manager_->destroySceneNode(coords_nodes_[i]);
00141     }
00142     coords_objects_.resize(num);
00143     coords_nodes_.resize(num);
00144   }
00145 }
00146 
00147 
00148 bool validateFloats( const geometry_msgs::PoseArray& msg )
00149 {
00150   return rviz::validateFloats( msg.poses );
00151 }
00152 
00153 void PoseArrayDisplay::processMessage( const geometry_msgs::PoseArray::ConstPtr& msg )
00154 {
00155   if( !validateFloats( *msg ))
00156   {
00157     setStatus( rviz::StatusProperty::Error, "Topic", "Message contained invalid floating point values (nans or infs)" );
00158     return;
00159   }
00160 
00161   manual_object_->clear();
00162 
00163   Ogre::Vector3 position;
00164   Ogre::Quaternion orientation;
00165   if( !context_->getFrameManager()->getTransform( msg->header, position, orientation ))
00166   {
00167     ROS_DEBUG( "Error transforming from frame '%s' to frame '%s'", msg->header.frame_id.c_str(), qPrintable( fixed_frame_ ));
00168   }
00169 
00170   pose_valid_ = true;
00171   updateShapeVisibility();
00172 
00173   scene_node_->setPosition( position );
00174   scene_node_->setOrientation( orientation );
00175 
00176   manual_object_->clear();
00177 
00178   if(shape_property_->getOptionInt() == Arrow ) {
00179     for (int i = 0; i < coords_nodes_.size() ; i++)
00180       coords_nodes_[i]->setVisible(false);
00181     Ogre::ColourValue color = color_property_->getOgreColor();
00182     float length = length_property_->getFloat();
00183     size_t num_poses = msg->poses.size();
00184     manual_object_->estimateVertexCount( num_poses * 6 );
00185     manual_object_->begin( "BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST );
00186     for( size_t i=0; i < num_poses; ++i )
00187       {
00188         Ogre::Vector3 pos( msg->poses[i].position.x,
00189                            msg->poses[i].position.y,
00190                            msg->poses[i].position.z );
00191         Ogre::Quaternion orient( msg->poses[i].orientation.w,
00192                                  msg->poses[i].orientation.x,
00193                                  msg->poses[i].orientation.y,
00194                                  msg->poses[i].orientation.z );
00195         
00196         
00197 
00198         Ogre::Vector3 vertices[6];
00199         vertices[0] = pos; 
00200         vertices[1] = pos + orient * Ogre::Vector3( length, 0, 0 ); 
00201         vertices[2] = vertices[ 1 ];
00202         vertices[3] = pos + orient * Ogre::Vector3( 0.75*length, 0.2*length, 0 );
00203         vertices[4] = vertices[ 1 ];
00204         vertices[5] = pos + orient * Ogre::Vector3( 0.75*length, -0.2*length, 0 );
00205 
00206         for( int i = 0; i < 6; ++i )
00207           {
00208             manual_object_->position( vertices[i] );
00209             manual_object_->colour( color );
00210           }
00211       }
00212     manual_object_->end();
00213   }
00214   else{
00215     allocateCoords(msg->poses.size());
00216     for (int i = 0; i < msg->poses.size() ; i++){
00217       geometry_msgs::Pose pose = msg->poses[i];
00218       Ogre::SceneNode* scene_node = coords_nodes_[i];
00219       scene_node->setVisible(true);
00220 
00221       Ogre::Vector3 position( msg->poses[i].position.x,
00222                               msg->poses[i].position.y,
00223                               msg->poses[i].position.z );
00224       Ogre::Quaternion orientation( msg->poses[i].orientation.w,
00225                                     msg->poses[i].orientation.x,
00226                                     msg->poses[i].orientation.y,
00227                                     msg->poses[i].orientation.z );
00228       scene_node->setPosition(position);
00229       scene_node->setOrientation(orientation); 
00230     }
00231   }
00232 
00233   context_->queueRender();
00234 }
00235 
00236 void PoseArrayDisplay::reset()
00237 {
00238   MFDClass::reset();
00239   if( manual_object_ )
00240   {
00241     manual_object_->clear();
00242   }
00243   if ( coords_objects_.size() > 0 ) {
00244     allocateCoords(0);
00245   }
00246   
00247 }
00248 
00249 } 
00250 
00251 #include <pluginlib/class_list_macros.h>
00252 PLUGINLIB_EXPORT_CLASS( jsk_rviz_plugins::PoseArrayDisplay, rviz::Display )