tf_display.cpp
Go to the documentation of this file.
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 "tf_display.h"
00031 #include "rviz/visualization_manager.h"
00032 #include "rviz/selection/selection_manager.h"
00033 #include "rviz/selection/forwards.h"
00034 #include "rviz/properties/property.h"
00035 #include "rviz/properties/property_manager.h"
00036 #include "rviz/frame_manager.h"
00037 #include "rviz/uniform_string_stream.h"
00038 
00039 #include <rviz/ogre_helpers/arrow.h>
00040 #include <rviz/ogre_helpers/axes.h>
00041 #include <rviz/ogre_helpers/movable_text.h>
00042 
00043 #include <boost/bind.hpp>
00044 
00045 #include <OGRE/OgreSceneNode.h>
00046 #include <OGRE/OgreSceneManager.h>
00047 
00048 #include <tf/transform_listener.h>
00049 
00050 
00051 namespace rviz
00052 {
00053 
00054 struct FrameInfo
00055 {
00056   FrameInfo();
00057 
00058   const Ogre::Vector3& getPositionInRobotSpace() { return robot_space_position_; }
00059   const Ogre::Quaternion& getOrientationInRobotSpace() { return robot_space_orientation_; }
00060   const std::string& getParent() { return parent_; }
00061 
00062   bool isEnabled() { return enabled_; }
00063 
00064   std::string name_;
00065   std::string parent_;
00066   Axes* axes_;
00067   CollObjectHandle axes_coll_;
00068   Arrow* parent_arrow_;
00069   MovableText* name_text_;
00070   Ogre::SceneNode* name_node_;
00071 
00072   Ogre::Vector3 position_;
00073   Ogre::Quaternion orientation_;
00074   float distance_to_parent_;
00075   Ogre::Quaternion arrow_orientation_;
00076 
00077   Ogre::Vector3 robot_space_position_;
00078   Ogre::Quaternion robot_space_orientation_;
00079 
00080   bool enabled_;
00081 
00082   ros::Time last_update_;
00083   ros::Time last_time_to_fixed_;
00084 
00085   CategoryPropertyWPtr category_;
00086   Vector3PropertyWPtr position_property_;
00087   QuaternionPropertyWPtr orientation_property_;
00088   StringPropertyWPtr parent_property_;
00089   BoolPropertyWPtr enabled_property_;
00090 
00091   CategoryPropertyWPtr tree_property_;
00092 };
00093 
00094 FrameInfo::FrameInfo()
00095 : axes_( NULL )
00096 , axes_coll_(NULL)
00097 , parent_arrow_( NULL )
00098 , name_text_( NULL )
00099 , position_(Ogre::Vector3::ZERO)
00100 , orientation_(Ogre::Quaternion::IDENTITY)
00101 , distance_to_parent_( 0.0f )
00102 , arrow_orientation_(Ogre::Quaternion::IDENTITY)
00103 , robot_space_position_(Ogre::Vector3::ZERO)
00104 , robot_space_orientation_(Ogre::Quaternion::IDENTITY)
00105 , enabled_(true)
00106 {
00107 
00108 }
00109 
00110 void TFDisplay::setFrameEnabled(FrameInfo* frame, bool enabled)
00111 {
00112   frame->enabled_ = enabled;
00113 
00114   propertyChanged(frame->enabled_property_);
00115 
00116   if (frame->name_node_)
00117   {
00118     frame->name_node_->setVisible(show_names_ && enabled);
00119   }
00120 
00121   if (frame->axes_)
00122   {
00123     frame->axes_->getSceneNode()->setVisible(show_axes_ && enabled);
00124   }
00125 
00126   if (frame->parent_arrow_)
00127   {
00128     if (frame->distance_to_parent_ > 0.001f)
00129     {
00130       frame->parent_arrow_->getSceneNode()->setVisible(show_arrows_ && enabled);
00131     }
00132     else
00133     {
00134       frame->parent_arrow_->getSceneNode()->setVisible(false);
00135     }
00136   }
00137 
00138   if (all_enabled_ && !enabled)
00139   {
00140     all_enabled_ = false;
00141 
00142     propertyChanged(all_enabled_property_);
00143   }
00144 
00145   causeRender();
00146 }
00147 
00148 class FrameSelectionHandler : public SelectionHandler
00149 {
00150 public:
00151   FrameSelectionHandler(FrameInfo* frame, TFDisplay* display);
00152   virtual ~FrameSelectionHandler();
00153 
00154   virtual void createProperties(const Picked& obj, PropertyManager* property_manager);
00155 
00156 private:
00157   FrameInfo* frame_;
00158   TFDisplay* display_;
00159 };
00160 
00161 FrameSelectionHandler::FrameSelectionHandler(FrameInfo* frame, TFDisplay* display)
00162 : frame_(frame)
00163 , display_(display)
00164 {
00165 }
00166 
00167 FrameSelectionHandler::~FrameSelectionHandler()
00168 {
00169 }
00170 
00171 void FrameSelectionHandler::createProperties(const Picked& obj, PropertyManager* property_manager)
00172 {
00173   UniformStringStream ss;
00174   ss << frame_->name_ << " Frame " << frame_->name_;
00175 
00176   CategoryPropertyWPtr cat = property_manager->createCategory( "Frame " + frame_->name_, ss.str(), CategoryPropertyWPtr() );
00177   properties_.push_back(cat);
00178 
00179   properties_.push_back(property_manager->createProperty<BoolProperty>( "Enabled", ss.str(), boost::bind( &FrameInfo::isEnabled, frame_ ),
00180                                                                          boost::bind( &TFDisplay::setFrameEnabled, display_, frame_, _1 ), cat, this ));
00181   properties_.push_back(property_manager->createProperty<StringProperty>( "Parent", ss.str(), boost::bind( &FrameInfo::getParent, frame_ ),
00182                                                                            StringProperty::Setter(), cat, this ));
00183   properties_.push_back(property_manager->createProperty<Vector3Property>( "Position", ss.str(), boost::bind( &FrameInfo::getPositionInRobotSpace, frame_ ),
00184                                                                             Vector3Property::Setter(), cat, this ));
00185   properties_.push_back(property_manager->createProperty<QuaternionProperty>( "Orientation", ss.str(), boost::bind( &FrameInfo::getOrientationInRobotSpace, frame_ ),
00186                                                                                QuaternionProperty::Setter(), cat, this ));
00187 }
00188 
00189 typedef std::set<FrameInfo*> S_FrameInfo;
00190 
00191 TFDisplay::TFDisplay()
00192   : Display()
00193   , update_timer_( 0.0f )
00194   , update_rate_( 0.0f )
00195   , show_names_( true )
00196   , show_arrows_( true )
00197   , show_axes_( true )
00198   , frame_timeout_(15.0f)
00199   , all_enabled_(true)
00200   , scale_( 1 )
00201 {
00202 }
00203 
00204 TFDisplay::~TFDisplay()
00205 {
00206   clear();
00207 
00208   root_node_->removeAndDestroyAllChildren();
00209   scene_manager_->destroySceneNode( root_node_->getName() );
00210 }
00211 
00212 void TFDisplay::onInitialize()
00213 {
00214   root_node_ = scene_manager_->getRootSceneNode()->createChildSceneNode();
00215 
00216   names_node_ = root_node_->createChildSceneNode();
00217   arrows_node_ = root_node_->createChildSceneNode();
00218   axes_node_ = root_node_->createChildSceneNode();
00219 }
00220 
00221 void TFDisplay::clear()
00222 {
00223   property_manager_->deleteChildren(tree_category_.lock());
00224   property_manager_->deleteChildren(frames_category_.lock());
00225   all_enabled_property_ = property_manager_->createProperty<BoolProperty>( "All Enabled", property_prefix_, boost::bind( &TFDisplay::getAllEnabled, this ),
00226                                                                            boost::bind( &TFDisplay::setAllEnabled, this, _1 ), frames_category_, this );
00227   setPropertyHelpText(all_enabled_property_, "Whether all the frames should be enabled or not.");
00228 
00229   S_FrameInfo to_delete;
00230   M_FrameInfo::iterator frame_it = frames_.begin();
00231   M_FrameInfo::iterator frame_end = frames_.end();
00232   for ( ; frame_it != frame_end; ++frame_it )
00233   {
00234     to_delete.insert( frame_it->second );
00235   }
00236 
00237   S_FrameInfo::iterator delete_it = to_delete.begin();
00238   S_FrameInfo::iterator delete_end = to_delete.end();
00239   for ( ; delete_it != delete_end; ++delete_it )
00240   {
00241     deleteFrame( *delete_it, false );
00242   }
00243 
00244   frames_.clear();
00245 
00246   update_timer_ = 0.0f;
00247 
00248   clearStatuses();
00249 }
00250 
00251 void TFDisplay::onEnable()
00252 {
00253   root_node_->setVisible( true );
00254 
00255   names_node_->setVisible( show_names_ );
00256   arrows_node_->setVisible( show_arrows_ );
00257   axes_node_->setVisible( show_axes_ );
00258 }
00259 
00260 void TFDisplay::onDisable()
00261 {
00262   root_node_->setVisible( false );
00263   clear();
00264 }
00265 
00266 void TFDisplay::setShowNames( bool show )
00267 {
00268   show_names_ = show;
00269 
00270   names_node_->setVisible( show );
00271 
00272   M_FrameInfo::iterator it = frames_.begin();
00273   M_FrameInfo::iterator end = frames_.end();
00274   for (; it != end; ++it)
00275   {
00276     FrameInfo* frame = it->second;
00277 
00278     setFrameEnabled(frame, frame->enabled_);
00279   }
00280 
00281   propertyChanged(show_names_property_);
00282 }
00283 
00284 void TFDisplay::setShowAxes( bool show )
00285 {
00286   show_axes_ = show;
00287 
00288   axes_node_->setVisible( show );
00289 
00290   M_FrameInfo::iterator it = frames_.begin();
00291   M_FrameInfo::iterator end = frames_.end();
00292   for (; it != end; ++it)
00293   {
00294     FrameInfo* frame = it->second;
00295 
00296     setFrameEnabled(frame, frame->enabled_);
00297   }
00298 
00299   propertyChanged(show_axes_property_);
00300 }
00301 
00302 void TFDisplay::setShowArrows( bool show )
00303 {
00304   show_arrows_ = show;
00305 
00306   arrows_node_->setVisible( show );
00307 
00308   M_FrameInfo::iterator it = frames_.begin();
00309   M_FrameInfo::iterator end = frames_.end();
00310   for (; it != end; ++it)
00311   {
00312     FrameInfo* frame = it->second;
00313 
00314     setFrameEnabled(frame, frame->enabled_);
00315   }
00316 
00317   propertyChanged(show_arrows_property_);
00318 }
00319 
00320 void TFDisplay::setAllEnabled(bool enabled)
00321 {
00322   all_enabled_ = enabled;
00323 
00324   M_FrameInfo::iterator it = frames_.begin();
00325   M_FrameInfo::iterator end = frames_.end();
00326   for (; it != end; ++it)
00327   {
00328     FrameInfo* frame = it->second;
00329 
00330     setFrameEnabled(frame, enabled);
00331   }
00332 
00333   propertyChanged(all_enabled_property_);
00334 }
00335 
00336 void TFDisplay::setFrameTimeout(float timeout)
00337 {
00338   frame_timeout_ = timeout;
00339   propertyChanged(frame_timeout_property_);
00340 }
00341 
00342 void TFDisplay::setScale(float scale) 
00343 { 
00344   scale_ = scale; 
00345   propertyChanged(scale_property_); 
00346 } 
00347 
00348 void TFDisplay::setUpdateRate( float rate )
00349 {
00350   update_rate_ = rate;
00351 
00352   propertyChanged(update_rate_property_);
00353 }
00354 
00355 void TFDisplay::update(float wall_dt, float ros_dt)
00356 {
00357   update_timer_ += wall_dt;
00358   if ( update_rate_ < 0.0001f || update_timer_ > update_rate_ )
00359   {
00360     updateFrames();
00361 
00362     update_timer_ = 0.0f;
00363   }
00364 }
00365 
00366 FrameInfo* TFDisplay::getFrameInfo( const std::string& frame )
00367 {
00368   M_FrameInfo::iterator it = frames_.find( frame );
00369   if ( it == frames_.end() )
00370   {
00371     return NULL;
00372   }
00373 
00374   return it->second;
00375 }
00376 
00377 void TFDisplay::updateFrames()
00378 {
00379   typedef std::vector<std::string> V_string;
00380   V_string frames;
00381   vis_manager_->getTFClient()->getFrameStrings( frames );
00382   std::sort(frames.begin(), frames.end());
00383 
00384   S_FrameInfo current_frames;
00385 
00386   {
00387     V_string::iterator it = frames.begin();
00388     V_string::iterator end = frames.end();
00389     for ( ; it != end; ++it )
00390     {
00391       const std::string& frame = *it;
00392 
00393       if ( frame.empty() )
00394       {
00395         continue;
00396       }
00397 
00398       FrameInfo* info = getFrameInfo( frame );
00399       if (!info)
00400       {
00401         info = createFrame(frame);
00402       }
00403       else
00404       {
00405         updateFrame(info);
00406       }
00407 
00408       current_frames.insert( info );
00409     }
00410   }
00411 
00412   {
00413     S_FrameInfo to_delete;
00414     M_FrameInfo::iterator frame_it = frames_.begin();
00415     M_FrameInfo::iterator frame_end = frames_.end();
00416     for ( ; frame_it != frame_end; ++frame_it )
00417     {
00418       if ( current_frames.find( frame_it->second ) == current_frames.end() )
00419       {
00420         to_delete.insert( frame_it->second );
00421       }
00422     }
00423 
00424     S_FrameInfo::iterator delete_it = to_delete.begin();
00425     S_FrameInfo::iterator delete_end = to_delete.end();
00426     for ( ; delete_it != delete_end; ++delete_it )
00427     {
00428       deleteFrame( *delete_it, true );
00429     }
00430   }
00431 
00432   causeRender();
00433 }
00434 
00435 static const Ogre::ColourValue ARROW_HEAD_COLOR(1.0f, 0.1f, 0.6f, 1.0f);
00436 static const Ogre::ColourValue ARROW_SHAFT_COLOR(0.8f, 0.8f, 0.3f, 1.0f);
00437 
00438 FrameInfo* TFDisplay::createFrame(const std::string& frame)
00439 {
00440   FrameInfo* info = new FrameInfo;
00441   frames_.insert( std::make_pair( frame, info ) );
00442 
00443   info->name_ = frame;
00444   info->last_update_ = ros::Time::now();
00445   info->axes_ = new Axes( scene_manager_, axes_node_, 0.2, 0.02 );
00446   info->axes_->getSceneNode()->setVisible( show_axes_ );
00447   info->axes_coll_ = vis_manager_->getSelectionManager()->createCollisionForObject(info->axes_, SelectionHandlerPtr(new FrameSelectionHandler(info, this)));
00448 
00449   info->name_text_ = new MovableText( frame, "Arial", 0.1 );
00450   info->name_text_->setTextAlignment(MovableText::H_CENTER, MovableText::V_BELOW);
00451   info->name_node_ = names_node_->createChildSceneNode();
00452   info->name_node_->attachObject( info->name_text_ );
00453   info->name_node_->setVisible( show_names_ );
00454 
00455   info->parent_arrow_ = new Arrow( scene_manager_, arrows_node_, 1.0f, 0.01, 1.0f, 0.08 );
00456   info->parent_arrow_->getSceneNode()->setVisible( false );
00457   info->parent_arrow_->setHeadColor(ARROW_HEAD_COLOR);
00458   info->parent_arrow_->setShaftColor(ARROW_SHAFT_COLOR);
00459 
00460   info->enabled_ = true;
00461 
00462   std::string prefix = property_prefix_ + "Frames.";
00463 
00464   info->category_ = property_manager_->createCategory( info->name_, prefix, frames_category_, this );
00465 
00466   prefix += info->name_ + ".";
00467 
00468   info->enabled_property_ = property_manager_->createProperty<BoolProperty>( "Enabled", prefix, boost::bind( &FrameInfo::isEnabled, info ),
00469                                                                              boost::bind( &TFDisplay::setFrameEnabled, this, info, _1 ), info->category_, this );
00470   setPropertyHelpText(info->enabled_property_, "Enable or disable this individual frame.");
00471   info->parent_property_ = property_manager_->createProperty<StringProperty>( "Parent", prefix, boost::bind( &FrameInfo::getParent, info ),
00472                                                                               StringProperty::Setter(), info->category_, this );
00473   setPropertyHelpText(info->parent_property_, "Parent of this frame.  (Not editable)");
00474   info->position_property_ = property_manager_->createProperty<Vector3Property>( "Position", prefix, boost::bind( &FrameInfo::getPositionInRobotSpace, info ),
00475                                                                                  Vector3Property::Setter(), info->category_, this );
00476   setPropertyHelpText(info->position_property_, "Position of this frame, in the current Fixed Frame.  (Not editable)");
00477   info->orientation_property_ = property_manager_->createProperty<QuaternionProperty>( "Orientation", prefix, boost::bind( &FrameInfo::getOrientationInRobotSpace, info ),
00478                                                                                     QuaternionProperty::Setter(), info->category_, this );
00479   setPropertyHelpText(info->orientation_property_, "Orientation of this frame, in the current Fixed Frame.  (Not editable)");
00480   updateFrame( info );
00481 
00482   return info;
00483 }
00484 
00485 Ogre::ColourValue lerpColor(const Ogre::ColourValue& start, const Ogre::ColourValue& end, float t)
00486 {
00487   return start * t + end * (1 - t);
00488 }
00489 
00490 void TFDisplay::updateFrame(FrameInfo* frame)
00491 {
00492   tf::TransformListener* tf = vis_manager_->getTFClient();
00493 
00494   // Check last received time so we can grey out/fade out frames that have stopped being published
00495   ros::Time latest_time;
00496   tf->getLatestCommonTime(fixed_frame_, frame->name_, latest_time, 0);
00497   if (latest_time != frame->last_time_to_fixed_)
00498   {
00499     frame->last_update_ = ros::Time::now();
00500     frame->last_time_to_fixed_ = latest_time;
00501   }
00502 
00503   // Fade from color -> grey, then grey -> fully transparent
00504   ros::Duration age = ros::Time::now() - frame->last_update_;
00505   float one_third_timeout = frame_timeout_ * 0.3333333f;
00506   if (age > ros::Duration(frame_timeout_))
00507   {
00508     frame->parent_arrow_->getSceneNode()->setVisible(false);
00509     frame->axes_->getSceneNode()->setVisible(false);
00510     frame->name_node_->setVisible(false);
00511     return;
00512   }
00513   else if (age > ros::Duration(one_third_timeout))
00514   {
00515     Ogre::ColourValue grey(0.7, 0.7, 0.7, 1.0);
00516 
00517     if (age > ros::Duration(one_third_timeout * 2))
00518     {
00519       float a = std::max(0.0, (frame_timeout_ - age.toSec())/one_third_timeout);
00520       Ogre::ColourValue c = Ogre::ColourValue(grey.r, grey.g, grey.b, a);
00521 
00522       frame->axes_->setXColor(c);
00523       frame->axes_->setYColor(c);
00524       frame->axes_->setZColor(c);
00525       frame->name_text_->setColor(c);
00526       frame->parent_arrow_->setColor(c.r, c.g, c.b, c.a);
00527     }
00528     else
00529     {
00530       float t = std::max(0.0, (one_third_timeout * 2 - age.toSec())/one_third_timeout);
00531       frame->axes_->setXColor(lerpColor(frame->axes_->getDefaultXColor(), grey, t));
00532       frame->axes_->setYColor(lerpColor(frame->axes_->getDefaultYColor(), grey, t));
00533       frame->axes_->setZColor(lerpColor(frame->axes_->getDefaultZColor(), grey, t));
00534       frame->name_text_->setColor(lerpColor(Ogre::ColourValue::White, grey, t));
00535       frame->parent_arrow_->setShaftColor(lerpColor(ARROW_SHAFT_COLOR, grey, t));
00536       frame->parent_arrow_->setHeadColor(lerpColor(ARROW_HEAD_COLOR, grey, t));
00537     }
00538   }
00539   else
00540   {
00541     frame->axes_->setToDefaultColors();
00542     frame->name_text_->setColor(Ogre::ColourValue::White);
00543     frame->parent_arrow_->setHeadColor(ARROW_HEAD_COLOR);
00544     frame->parent_arrow_->setShaftColor(ARROW_SHAFT_COLOR);
00545   }
00546 
00547   setStatus(status_levels::Ok, frame->name_, "Transform OK");
00548 
00549   if (!vis_manager_->getFrameManager()->getTransform(frame->name_, ros::Time(), frame->position_, frame->orientation_))
00550   {
00551     std::stringstream ss;
00552     ss << "No transform from [" << frame->name_ << "] to frame [" << fixed_frame_ << "]";
00553     setStatus(status_levels::Warn, frame->name_, ss.str());
00554     ROS_DEBUG("Error transforming frame '%s' to frame '%s'", frame->name_.c_str(), fixed_frame_.c_str());
00555   }
00556 
00557   frame->robot_space_position_ = frame->position_;
00558   frame->robot_space_orientation_ = frame->orientation_;
00559 
00560   frame->axes_->setPosition( frame->position_ );
00561   frame->axes_->setOrientation( frame->orientation_ );
00562   frame->axes_->getSceneNode()->setVisible(show_axes_ && frame->enabled_);
00563   frame->axes_->setScale( Ogre::Vector3(scale_,scale_,scale_) );
00564 
00565   frame->name_node_->setPosition( frame->position_ );
00566   frame->name_node_->setVisible(show_names_ && frame->enabled_);
00567   frame->name_node_->setScale(scale_,scale_,scale_);
00568 
00569   propertyChanged(frame->position_property_);
00570   propertyChanged(frame->orientation_property_);
00571 
00572   std::string old_parent = frame->parent_;
00573   frame->parent_.clear();
00574   bool has_parent = tf->getParent( frame->name_, ros::Time(), frame->parent_ );
00575   if ( has_parent )
00576   {
00577     {
00578       CategoryPropertyPtr cat_prop = frame->tree_property_.lock();
00579       if ( !cat_prop || old_parent != frame->parent_ )
00580       {
00581         M_FrameInfo::iterator parent_it = frames_.find( frame->parent_ );
00582 
00583         if ( parent_it != frames_.end() )
00584         {
00585           FrameInfo* parent = parent_it->second;
00586 
00587           property_manager_->deleteProperty( cat_prop );
00588           cat_prop.reset(); // Clear the last remaining reference, deleting the old tree property entirely
00589 
00590           if ( parent->tree_property_.lock() )
00591           {
00592             frame->tree_property_ = property_manager_->createCategory( frame->name_, property_prefix_ + "Tree.", parent->tree_property_, this );
00593           }
00594         }
00595       }
00596     }
00597 
00598     if ( show_arrows_ )
00599     {
00600       Ogre::Vector3 parent_position;
00601       Ogre::Quaternion parent_orientation;
00602       if (!vis_manager_->getFrameManager()->getTransform(frame->parent_, ros::Time(), parent_position, parent_orientation))
00603       {
00604         ROS_DEBUG("Error transforming frame '%s' (parent of '%s') to frame '%s'", frame->parent_.c_str(), frame->name_.c_str(), fixed_frame_.c_str());
00605       }
00606 
00607       Ogre::Vector3 direction = parent_position - frame->position_;
00608       float distance = direction.length();
00609       direction.normalise();
00610 
00611       Ogre::Quaternion orient = Ogre::Vector3::NEGATIVE_UNIT_Z.getRotationTo( direction );
00612 
00613       Ogre::Vector3 old_pos = frame->parent_arrow_->getPosition();
00614 
00615       frame->distance_to_parent_ = distance;
00616       float head_length = ( distance < 0.1*scale_ ) ? (0.1*scale_*distance) : 0.1*scale_;
00617       float shaft_length = distance - head_length;
00618       frame->parent_arrow_->set( shaft_length, 0.02*scale_, head_length, 0.08*scale_ );
00619 
00620       if ( distance > 0.001f )
00621       {
00622         frame->parent_arrow_->getSceneNode()->setVisible( show_arrows_ && frame->enabled_ );
00623       }
00624       else
00625       {
00626         frame->parent_arrow_->getSceneNode()->setVisible( false );
00627       }
00628 
00629       frame->parent_arrow_->setPosition( frame->position_ );
00630       frame->parent_arrow_->setOrientation( orient );
00631     }
00632     else
00633     {
00634       frame->parent_arrow_->getSceneNode()->setVisible( false );
00635     }
00636   }
00637   else
00638   {
00639     CategoryPropertyPtr tree_prop = frame->tree_property_.lock();
00640     if ( !tree_prop || old_parent != frame->parent_ )
00641     {
00642       property_manager_->deleteProperty( tree_prop );
00643       frame->tree_property_ = property_manager_->createCategory( frame->name_, property_prefix_ + "Tree.", tree_category_, this );
00644     }
00645 
00646     frame->parent_arrow_->getSceneNode()->setVisible( false );
00647   }
00648 
00649   propertyChanged(frame->parent_property_);
00650 }
00651 
00652 void TFDisplay::deleteFrame(FrameInfo* frame, bool delete_properties)
00653 {
00654   M_FrameInfo::iterator it = frames_.find( frame->name_ );
00655   ROS_ASSERT( it != frames_.end() );
00656 
00657   frames_.erase( it );
00658 
00659   delete frame->axes_;
00660   vis_manager_->getSelectionManager()->removeObject(frame->axes_coll_);
00661   delete frame->parent_arrow_;
00662   delete frame->name_text_;
00663   scene_manager_->destroySceneNode( frame->name_node_->getName() );
00664   if( delete_properties )
00665   {
00666     property_manager_->deleteProperty( frame->category_.lock() );
00667     property_manager_->deleteProperty( frame->tree_property_.lock() );
00668   }
00669   delete frame;
00670 }
00671 
00672 void TFDisplay::createProperties()
00673 {
00674   show_names_property_ = property_manager_->createProperty<BoolProperty>( "Show Names", property_prefix_, boost::bind( &TFDisplay::getShowNames, this ),
00675                                                                           boost::bind( &TFDisplay::setShowNames, this, _1 ), parent_category_, this );
00676   setPropertyHelpText(show_names_property_, "Whether or not names should be shown next to the frames.");
00677   show_axes_property_ = property_manager_->createProperty<BoolProperty>( "Show Axes", property_prefix_, boost::bind( &TFDisplay::getShowAxes, this ),
00678                                                                           boost::bind( &TFDisplay::setShowAxes, this, _1 ), parent_category_, this );
00679   setPropertyHelpText(show_axes_property_, "Whether or not the axes of each frame should be shown.");
00680   show_arrows_property_ = property_manager_->createProperty<BoolProperty>( "Show Arrows", property_prefix_, boost::bind( &TFDisplay::getShowArrows, this ),
00681                                                                            boost::bind( &TFDisplay::setShowArrows, this, _1 ), parent_category_, this );
00682   setPropertyHelpText(show_arrows_property_, "Whether or not arrows from child to parent should be shown.");
00683   scale_property_ = property_manager_->createProperty<FloatProperty>( "Marker Scale", property_prefix_, boost::bind( &TFDisplay::getScale, this ), 
00684                                                                       boost::bind( &TFDisplay::setScale, this, _1 ), parent_category_, this ); 
00685   setPropertyHelpText(scale_property_, "Scaling factor for all names, axes and arrows.");
00686   update_rate_property_ = property_manager_->createProperty<FloatProperty>( "Update Interval", property_prefix_, boost::bind( &TFDisplay::getUpdateRate, this ),
00687                                                                             boost::bind( &TFDisplay::setUpdateRate, this, _1 ), parent_category_, this );
00688   setPropertyHelpText(update_rate_property_, "The interval, in seconds, at which to update the frame transforms.  0 means to do so every update cycle.");
00689   FloatPropertyPtr float_prop = update_rate_property_.lock();
00690   float_prop->setMin( 0.0 );
00691   float_prop->addLegacyName("Update Rate");
00692 
00693   frame_timeout_property_ = property_manager_->createProperty<FloatProperty>( "Frame Timeout", property_prefix_, boost::bind( &TFDisplay::getFrameTimeout, this ),
00694                                                                               boost::bind( &TFDisplay::setFrameTimeout, this, _1 ), parent_category_, this );
00695   setPropertyHelpText(frame_timeout_property_, "The length of time, in seconds, before a frame that has not been updated is considered \"dead\".  For 1/3 of this time"
00696                                                " the frame will appear correct, for the second 1/3rd it will fade to gray, and then it will fade out completely.");
00697   float_prop = frame_timeout_property_.lock();
00698   float_prop->setMin( 1.0 );
00699 
00700   frames_category_ = property_manager_->createCategory( "Frames", property_prefix_, parent_category_, this );
00701   setPropertyHelpText(frames_category_, "The list of all frames.");
00702   CategoryPropertyPtr cat_prop = frames_category_.lock();
00703   cat_prop->collapse();
00704 
00705   all_enabled_property_ = property_manager_->createProperty<BoolProperty>( "All Enabled", property_prefix_, boost::bind( &TFDisplay::getAllEnabled, this ),
00706                                                                            boost::bind( &TFDisplay::setAllEnabled, this, _1 ), frames_category_, this );
00707   setPropertyHelpText(all_enabled_property_, "Whether all the frames should be enabled or not.");
00708 
00709   tree_category_ = property_manager_->createCategory( "Tree", property_prefix_, parent_category_, this );
00710   setPropertyHelpText(tree_category_, "A tree-view of the frames, showing the parent/child relationships.");
00711   cat_prop = tree_category_.lock();
00712   cat_prop->collapse();
00713 }
00714 
00715 void TFDisplay::fixedFrameChanged()
00716 {
00717   update_timer_ = update_rate_;
00718 }
00719 
00720 void TFDisplay::reset()
00721 {
00722   Display::reset();
00723   clear();
00724 }
00725 
00726 } // namespace rviz
00727 


rviz
Author(s): Dave Hershberger, Josh Faust
autogenerated on Mon Jan 6 2014 11:54:33