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 <OGRE/OgreEntity.h>
00031 #include <OGRE/OgreSceneNode.h>
00032
00033 #include "rviz/display_context.h"
00034 #include "rviz/frame_manager.h"
00035 #include "rviz/ogre_helpers/arrow.h"
00036 #include "rviz/ogre_helpers/axes.h"
00037 #include "rviz/ogre_helpers/shape.h"
00038 #include "rviz/properties/color_property.h"
00039 #include "rviz/properties/enum_property.h"
00040 #include "rviz/properties/float_property.h"
00041 #include "rviz/properties/quaternion_property.h"
00042 #include "rviz/properties/string_property.h"
00043 #include "rviz/properties/vector_property.h"
00044 #include "rviz/selection/selection_manager.h"
00045 #include "rviz/validate_floats.h"
00046
00047 #include "rviz/default_plugin/pose_display.h"
00048
00049 namespace rviz
00050 {
00051
00052 class PoseDisplaySelectionHandler: public SelectionHandler
00053 {
00054 public:
00055 PoseDisplaySelectionHandler( PoseDisplay* display, DisplayContext* context )
00056 : SelectionHandler( context )
00057 , display_( display )
00058 {}
00059
00060 void createProperties( const Picked& obj, Property* parent_property )
00061 {
00062 Property* cat = new Property( "Pose " + display_->getName(), QVariant(), "", parent_property );
00063 properties_.push_back( cat );
00064
00065 frame_property_ = new StringProperty( "Frame", "", "", cat );
00066 frame_property_->setReadOnly( true );
00067
00068 position_property_ = new VectorProperty( "Position", Ogre::Vector3::ZERO, "", cat );
00069 position_property_->setReadOnly( true );
00070
00071 orientation_property_ = new QuaternionProperty( "Orientation", Ogre::Quaternion::IDENTITY, "", cat );
00072 orientation_property_->setReadOnly( true );
00073 }
00074
00075 void getAABBs( const Picked& obj, V_AABB& aabbs )
00076 {
00077 if( display_->pose_valid_ )
00078 {
00079 if( display_->shape_property_->getOptionInt() == PoseDisplay::Arrow )
00080 {
00081 aabbs.push_back( display_->arrow_->getHead()->getEntity()->getWorldBoundingBox() );
00082 aabbs.push_back( display_->arrow_->getShaft()->getEntity()->getWorldBoundingBox() );
00083 }
00084 else
00085 {
00086 aabbs.push_back( display_->axes_->getXShape()->getEntity()->getWorldBoundingBox() );
00087 aabbs.push_back( display_->axes_->getYShape()->getEntity()->getWorldBoundingBox() );
00088 aabbs.push_back( display_->axes_->getZShape()->getEntity()->getWorldBoundingBox() );
00089 }
00090 }
00091 }
00092
00093 void setMessage(const geometry_msgs::PoseStampedConstPtr& message)
00094 {
00095
00096
00097
00098
00099 if( properties_.size() > 0 )
00100 {
00101 frame_property_->setStdString( message->header.frame_id );
00102 position_property_->setVector( Ogre::Vector3( message->pose.position.x,
00103 message->pose.position.y,
00104 message->pose.position.z ));
00105 orientation_property_->setQuaternion( Ogre::Quaternion( message->pose.orientation.w,
00106 message->pose.orientation.x,
00107 message->pose.orientation.y,
00108 message->pose.orientation.z ));
00109 }
00110 }
00111
00112 private:
00113 PoseDisplay* display_;
00114 StringProperty* frame_property_;
00115 VectorProperty* position_property_;
00116 QuaternionProperty* orientation_property_;
00117 };
00118
00119 PoseDisplay::PoseDisplay()
00120 : pose_valid_( false )
00121 {
00122 shape_property_ = new EnumProperty( "Shape", "Arrow", "Shape to display the pose as.",
00123 this, SLOT( updateShapeChoice() ));
00124 shape_property_->addOption( "Arrow", Arrow );
00125 shape_property_->addOption( "Axes", Axes );
00126
00127 color_property_ = new ColorProperty( "Color", QColor( 255, 25, 0 ), "Color to draw the arrow.",
00128 this, SLOT( updateColorAndAlpha() ));
00129
00130 alpha_property_ = new FloatProperty( "Alpha", 1, "Amount of transparency to apply to the arrow.",
00131 this, SLOT( updateColorAndAlpha() ));
00132 alpha_property_->setMin( 0 );
00133 alpha_property_->setMax( 1 );
00134
00135 shaft_length_property_ = new FloatProperty( "Shaft Length", 1, "Length of the arrow's shaft, in meters.",
00136 this, SLOT( updateArrowGeometry() ));
00137
00138
00139 shaft_radius_property_ = new FloatProperty( "Shaft Radius", 0.05, "Radius of the arrow's shaft, in meters.",
00140 this, SLOT( updateArrowGeometry() ));
00141
00142 head_length_property_ = new FloatProperty( "Head Length", 0.3, "Length of the arrow's head, in meters.",
00143 this, SLOT( updateArrowGeometry() ));
00144
00145
00146 head_radius_property_ = new FloatProperty( "Head Radius", 0.1, "Radius of the arrow's head, in meters.",
00147 this, SLOT( updateArrowGeometry() ));
00148
00149 axes_length_property_ = new FloatProperty( "Axes Length", 1, "Length of each axis, in meters.",
00150 this, SLOT( updateAxisGeometry() ));
00151
00152 axes_radius_property_ = new FloatProperty( "Axes Radius", 0.1, "Radius of each axis, in meters.",
00153 this, SLOT( updateAxisGeometry() ));
00154 }
00155
00156 void PoseDisplay::onInitialize()
00157 {
00158 MFDClass::onInitialize();
00159
00160 arrow_ = new rviz::Arrow( scene_manager_, scene_node_,
00161 shaft_length_property_->getFloat(),
00162 shaft_radius_property_->getFloat(),
00163 head_length_property_->getFloat(),
00164 head_radius_property_->getFloat() );
00165
00166
00167 arrow_->setOrientation( Ogre::Quaternion( Ogre::Degree( -90 ), Ogre::Vector3::UNIT_Y ));
00168
00169 axes_ = new rviz::Axes( scene_manager_, scene_node_,
00170 axes_length_property_->getFloat(),
00171 axes_radius_property_->getFloat() );
00172
00173 updateShapeChoice();
00174 updateColorAndAlpha();
00175
00176 coll_handler_.reset( new PoseDisplaySelectionHandler( this, context_ ));
00177 coll_handler_->addTrackedObjects( arrow_->getSceneNode() );
00178 coll_handler_->addTrackedObjects( axes_->getSceneNode() );
00179 }
00180
00181 PoseDisplay::~PoseDisplay()
00182 {
00183 delete arrow_;
00184 delete axes_;
00185 }
00186
00187 void PoseDisplay::onEnable()
00188 {
00189 MFDClass::onEnable();
00190 updateShapeVisibility();
00191 }
00192
00193 void PoseDisplay::updateColorAndAlpha()
00194 {
00195 Ogre::ColourValue color = color_property_->getOgreColor();
00196 color.a = alpha_property_->getFloat();
00197
00198 arrow_->setColor( color );
00199
00200 context_->queueRender();
00201 }
00202
00203 void PoseDisplay::updateArrowGeometry()
00204 {
00205 arrow_->set( shaft_length_property_->getFloat(),
00206 shaft_radius_property_->getFloat(),
00207 head_length_property_->getFloat(),
00208 head_radius_property_->getFloat() );
00209 context_->queueRender();
00210 }
00211
00212 void PoseDisplay::updateAxisGeometry()
00213 {
00214 axes_->set( axes_length_property_->getFloat(),
00215 axes_radius_property_->getFloat() );
00216 context_->queueRender();
00217 }
00218
00219 void PoseDisplay::updateShapeChoice()
00220 {
00221 bool use_arrow = ( shape_property_->getOptionInt() == Arrow );
00222
00223 color_property_->setHidden( !use_arrow );
00224 alpha_property_->setHidden( !use_arrow );
00225 shaft_length_property_->setHidden( !use_arrow );
00226 shaft_radius_property_->setHidden( !use_arrow );
00227 head_length_property_->setHidden( !use_arrow );
00228 head_radius_property_->setHidden( !use_arrow );
00229
00230 axes_length_property_->setHidden( use_arrow );
00231 axes_radius_property_->setHidden( use_arrow );
00232
00233 updateShapeVisibility();
00234
00235 context_->queueRender();
00236 }
00237
00238 void PoseDisplay::updateShapeVisibility()
00239 {
00240 if( !pose_valid_ )
00241 {
00242 arrow_->getSceneNode()->setVisible( false );
00243 axes_->getSceneNode()->setVisible( false );
00244 }
00245 else
00246 {
00247 bool use_arrow = (shape_property_->getOptionInt() == Arrow);
00248 arrow_->getSceneNode()->setVisible( use_arrow );
00249 axes_->getSceneNode()->setVisible( !use_arrow );
00250 }
00251 }
00252
00253 void PoseDisplay::processMessage( const geometry_msgs::PoseStamped::ConstPtr& message )
00254 {
00255 if( !validateFloats( *message ))
00256 {
00257 setStatus( StatusProperty::Error, "Topic", "Message contained invalid floating point values (nans or infs)" );
00258 return;
00259 }
00260
00261 Ogre::Vector3 position;
00262 Ogre::Quaternion orientation;
00263 if( !context_->getFrameManager()->transform( message->header, message->pose, position, orientation ))
00264 {
00265 ROS_ERROR( "Error transforming pose '%s' from frame '%s' to frame '%s'",
00266 qPrintable( getName() ), message->header.frame_id.c_str(), qPrintable( fixed_frame_ ));
00267 return;
00268 }
00269
00270 pose_valid_ = true;
00271 updateShapeVisibility();
00272
00273 scene_node_->setPosition( position );
00274 scene_node_->setOrientation( orientation );
00275
00276 coll_handler_->setMessage( message );
00277
00278 context_->queueRender();
00279 }
00280
00281 void PoseDisplay::reset()
00282 {
00283 MFDClass::reset();
00284 pose_valid_ = false;
00285 updateShapeVisibility();
00286 }
00287
00288 }
00289
00290 #include <pluginlib/class_list_macros.h>
00291 PLUGINLIB_EXPORT_CLASS( rviz::PoseDisplay, rviz::Display )