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 "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
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
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();
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 }
00727