planning_scene_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 /* Author: Ioan Sucan */
00031 
00032 #include <moveit/planning_scene_rviz_plugin/planning_scene_display.h>
00033 #include <moveit/rviz_plugin_render_tools/robot_state_visualization.h>
00034 #include <moveit/rviz_plugin_render_tools/octomap_render.h>
00035 
00036 #include <rviz/visualization_manager.h>
00037 #include <rviz/robot/robot.h>
00038 #include <rviz/robot/robot_link.h>
00039 
00040 #include <rviz/properties/property.h>
00041 #include <rviz/properties/string_property.h>
00042 #include <rviz/properties/bool_property.h>
00043 #include <rviz/properties/float_property.h>
00044 #include <rviz/properties/ros_topic_property.h>
00045 #include <rviz/properties/color_property.h>
00046 #include <rviz/properties/enum_property.h>
00047 #include <rviz/display_context.h>
00048 #include <rviz/frame_manager.h>
00049 #include <tf/transform_listener.h>
00050 
00051 #include <OGRE/OgreSceneManager.h>
00052 
00053 namespace moveit_rviz_plugin
00054 {
00055 
00056 // ******************************************************************************************
00057 // Base class contructor
00058 // ******************************************************************************************
00059 PlanningSceneDisplay::PlanningSceneDisplay(bool listen_to_planning_scene, bool show_scene_robot) :
00060   Display(),
00061   model_is_loading_(false),
00062   current_scene_time_(0.0f),
00063   planning_scene_needs_render_(true)
00064 {
00065   robot_description_property_ =
00066     new rviz::StringProperty( "Robot Description", "robot_description", "The name of the ROS parameter where the URDF for the robot is loaded",
00067                               this,
00068                               SLOT( changedRobotDescription() ), this );
00069 
00070   if (listen_to_planning_scene)
00071     planning_scene_topic_property_ =
00072       new rviz::RosTopicProperty( "Planning Scene Topic", "planning_scene",
00073                                   ros::message_traits::datatype<moveit_msgs::PlanningScene>(),
00074                                   "The topic on which the moveit_msgs::PlanningScene messages are received",
00075                                   this,
00076                                   SLOT( changedPlanningSceneTopic() ), this );
00077   else
00078     planning_scene_topic_property_ = NULL;
00079 
00080   // Planning scene category -------------------------------------------------------------------------------------------
00081   scene_category_ = new rviz::Property( "Scene Geometry", QVariant(), "", this );
00082 
00083   scene_name_property_ =
00084     new rviz::StringProperty( "Scene Name", "(noname)", "Shows the name of the planning scene",
00085                               scene_category_,
00086                               SLOT( changedSceneName() ), this );
00087   scene_name_property_->setShouldBeSaved(false);
00088   scene_enabled_property_ =
00089     new rviz::BoolProperty( "Show Scene Geometry", true, "Indicates whether planning scenes should be displayed",
00090                             scene_category_,
00091                             SLOT( changedSceneEnabled() ), this );
00092 
00093   scene_alpha_property_ =
00094     new rviz::FloatProperty( "Scene Alpha", 0.9f, "Specifies the alpha for the scene geometry",
00095                              scene_category_,
00096                              SLOT( changedSceneAlpha() ), this );
00097   scene_alpha_property_->setMin( 0.0 );
00098   scene_alpha_property_->setMax( 1.0 );
00099 
00100   scene_color_property_ = new rviz::ColorProperty( "Scene Color", QColor(50, 230, 50), "The color for the planning scene obstacles (if a color is not defined)",
00101                                                    scene_category_,
00102                                                    SLOT( changedSceneColor() ), this );
00103 
00104   octree_render_property_ = new rviz::EnumProperty( "Voxel Rendering", "Occupied Voxels",
00105                                               "Select voxel type.",
00106                                               scene_category_, SLOT( changedOctreeRenderMode() ), this );
00107 
00108   octree_render_property_->addOption( "Occupied Voxels",  OCTOMAP_OCCUPIED_VOXELS );
00109   octree_render_property_->addOption( "Free Voxels",  OCTOMAP_FREE_VOXELS );
00110   octree_render_property_->addOption( "All Voxels",  OCTOMAP_FREE_VOXELS | OCTOMAP_OCCUPIED_VOXELS);
00111 
00112   octree_coloring_property_ = new rviz::EnumProperty( "Voxel Coloring", "Z-Axis",
00113                                                 "Select voxel coloring mode",
00114                                                 scene_category_, SLOT( changedOctreeColorMode() ), this );
00115 
00116   octree_coloring_property_->addOption( "Z-Axis",  OCTOMAP_Z_AXIS_COLOR );
00117   octree_coloring_property_->addOption( "Cell Probability",  OCTOMAP_PROBABLILTY_COLOR );
00118 
00119   scene_display_time_property_ =
00120     new rviz::FloatProperty( "Scene Display Time", 0.2f, "The amount of wall-time to wait in between rendering updates to the planning scene (if any)",
00121                              scene_category_,
00122                              SLOT( changedSceneDisplayTime() ), this );
00123   scene_display_time_property_->setMin(0.0001);
00124 
00125   if (show_scene_robot)
00126   {
00127     robot_category_  = new rviz::Property( "Scene Robot",   QVariant(), "", this );
00128 
00129     scene_robot_enabled_property_ =
00130       new rviz::BoolProperty( "Show Scene Robot", true, "Indicates whether the robot state specified by the planning scene should be displayed",
00131                               robot_category_,
00132                               SLOT( changedSceneRobotEnabled() ), this );
00133 
00134     robot_alpha_property_ =
00135       new rviz::FloatProperty( "Robot Alpha", 0.5f, "Specifies the alpha for the robot links",
00136                                robot_category_,
00137                                SLOT( changedRobotSceneAlpha() ), this );
00138     robot_alpha_property_->setMin( 0.0 );
00139     robot_alpha_property_->setMax( 1.0 );
00140 
00141     attached_body_color_property_ = new rviz::ColorProperty( "Attached Body Color", QColor(150, 50, 150), "The color for the attached bodies",
00142                                                              robot_category_,
00143                                                              SLOT( changedAttachedBodyColor() ), this );
00144   }
00145   else
00146   {
00147     robot_category_ = NULL;
00148     scene_robot_enabled_property_ = NULL;
00149     robot_alpha_property_ = NULL;
00150     attached_body_color_property_ = NULL;
00151   }
00152 }
00153 
00154 // ******************************************************************************************
00155 // Deconstructor
00156 // ******************************************************************************************
00157 PlanningSceneDisplay::~PlanningSceneDisplay()
00158 {
00159   clearJobs();
00160 
00161   planning_scene_render_.reset();
00162   context_->getSceneManager()->destroySceneNode(planning_scene_node_->getName());
00163   if (planning_scene_robot_)
00164     planning_scene_robot_.reset();
00165   planning_scene_monitor_.reset();
00166 }
00167 
00168 void PlanningSceneDisplay::clearJobs()
00169 {
00170   background_process_.clear();
00171   {
00172     boost::unique_lock<boost::mutex> ulock(main_loop_jobs_lock_);
00173     main_loop_jobs_.clear();
00174   }
00175 }
00176 
00177 void PlanningSceneDisplay::onInitialize()
00178 {
00179   Display::onInitialize();
00180 
00181   // the scene node that contains everything
00182   planning_scene_node_ = scene_node_->createChildSceneNode();
00183 
00184   if (robot_category_)
00185   {
00186     planning_scene_robot_.reset(new RobotStateVisualization(planning_scene_node_, context_, "Planning Scene", robot_category_));
00187     planning_scene_robot_->setVisible(scene_robot_enabled_property_->getBool());
00188   }
00189 }
00190 
00191 void PlanningSceneDisplay::reset()
00192 {
00193   planning_scene_render_.reset();
00194   if (planning_scene_robot_)
00195     planning_scene_robot_->clear();
00196 
00197   addBackgroundJob(boost::bind(&PlanningSceneDisplay::loadRobotModel, this), "loadRobotModel");
00198   Display::reset();
00199 
00200   if (planning_scene_robot_)
00201     planning_scene_robot_->setVisible(scene_robot_enabled_property_->getBool());
00202 }
00203 
00204 void PlanningSceneDisplay::addBackgroundJob(const boost::function<void()> &job, const std::string &name)
00205 {
00206   background_process_.addJob(job, name);
00207 }
00208 
00209 void PlanningSceneDisplay::addMainLoopJob(const boost::function<void()> &job)
00210 {
00211   boost::unique_lock<boost::mutex> ulock(main_loop_jobs_lock_);
00212   main_loop_jobs_.push_back(job);
00213 }
00214 
00215 void PlanningSceneDisplay::waitForAllMainLoopJobs()
00216 {
00217   boost::unique_lock<boost::mutex> ulock(main_loop_jobs_lock_);
00218   while (!main_loop_jobs_.empty())
00219     main_loop_jobs_empty_condition_.wait(ulock);
00220 }
00221 
00222 void PlanningSceneDisplay::executeMainLoopJobs()
00223 {
00224   main_loop_jobs_lock_.lock();
00225   while (!main_loop_jobs_.empty())
00226   {
00227     boost::function<void()> fn = main_loop_jobs_.front();
00228     main_loop_jobs_.pop_front();
00229     main_loop_jobs_lock_.unlock();
00230     try
00231     {
00232       fn();
00233     }
00234     catch(std::runtime_error &ex)
00235     {
00236       ROS_ERROR("Exception caught executing main loop job: %s", ex.what());
00237     }
00238     catch(...)
00239     {
00240       ROS_ERROR("Exception caught executing main loop job");
00241     }
00242     main_loop_jobs_lock_.lock();
00243   }
00244   main_loop_jobs_empty_condition_.notify_all();
00245   main_loop_jobs_lock_.unlock();
00246 }
00247 
00248 const planning_scene_monitor::PlanningSceneMonitorPtr& PlanningSceneDisplay::getPlanningSceneMonitor()
00249 {
00250   return planning_scene_monitor_;
00251 }
00252 
00253 const robot_model::RobotModelConstPtr& PlanningSceneDisplay::getRobotModel() const
00254 {
00255   if (planning_scene_monitor_)
00256     return planning_scene_monitor_->getRobotModel();
00257   else
00258   {
00259     static robot_model::RobotModelConstPtr empty;
00260     return empty;
00261   }
00262 }
00263 
00264 planning_scene_monitor::LockedPlanningSceneRO PlanningSceneDisplay::getPlanningSceneRO() const
00265 {
00266   return planning_scene_monitor::LockedPlanningSceneRO(planning_scene_monitor_);
00267 }
00268 
00269 planning_scene_monitor::LockedPlanningSceneRW PlanningSceneDisplay::getPlanningSceneRW()
00270 {
00271   return planning_scene_monitor::LockedPlanningSceneRW(planning_scene_monitor_);
00272 }
00273 
00274 void PlanningSceneDisplay::changedAttachedBodyColor()
00275 {
00276   queueRenderSceneGeometry();
00277 }
00278 
00279 void PlanningSceneDisplay::changedSceneColor()
00280 {
00281   queueRenderSceneGeometry();
00282 }
00283 
00284 void PlanningSceneDisplay::changedRobotDescription()
00285 {
00286   if (isEnabled())
00287     reset();
00288 }
00289 
00290 void PlanningSceneDisplay::changedSceneName()
00291 {
00292   planning_scene_monitor::LockedPlanningSceneRW ps = getPlanningSceneRW();
00293   if (ps)
00294     ps->setName(scene_name_property_->getStdString());
00295 }
00296 
00297 void PlanningSceneDisplay::renderPlanningScene()
00298 {
00299   if (planning_scene_render_ && planning_scene_needs_render_)
00300   {
00301     QColor color = scene_color_property_->getColor();
00302     rviz::Color env_color(color.redF(), color.greenF(), color.blueF());
00303     if (attached_body_color_property_)
00304       color = attached_body_color_property_->getColor();
00305     rviz::Color attached_color(color.redF(), color.greenF(), color.blueF());
00306 
00307     try
00308     {
00309       const planning_scene_monitor::LockedPlanningSceneRO &ps = getPlanningSceneRO();
00310       planning_scene_render_->renderPlanningScene(ps, env_color,
00311                                                   attached_color,
00312                                                   static_cast<OctreeVoxelRenderMode>(octree_render_property_->getOptionInt()),
00313                                                   static_cast<OctreeVoxelColorMode>(octree_coloring_property_->getOptionInt()),
00314                                                   scene_alpha_property_->getFloat());
00315     }
00316     catch(...)
00317     {
00318       ROS_ERROR("Exception thrown while rendering planning scene");
00319     }
00320     planning_scene_needs_render_ = false;
00321     planning_scene_render_->getGeometryNode()->setVisible(scene_enabled_property_->getBool());
00322   }
00323 }
00324 
00325 void PlanningSceneDisplay::changedSceneAlpha()
00326 {
00327   queueRenderSceneGeometry();
00328 }
00329 
00330 void PlanningSceneDisplay::changedRobotSceneAlpha()
00331 {
00332   if (planning_scene_robot_)
00333   {
00334     planning_scene_robot_->setAlpha(robot_alpha_property_->getFloat());
00335     queueRenderSceneGeometry();
00336   }
00337 }
00338 
00339 void PlanningSceneDisplay::changedPlanningSceneTopic()
00340 {
00341   if (planning_scene_monitor_ && planning_scene_topic_property_)
00342     planning_scene_monitor_->startSceneMonitor(planning_scene_topic_property_->getStdString());
00343 }
00344 
00345 void PlanningSceneDisplay::changedSceneDisplayTime()
00346 {
00347 }
00348 
00349 void PlanningSceneDisplay::changedOctreeRenderMode()
00350 {
00351 }
00352 
00353 void PlanningSceneDisplay::changedOctreeColorMode()
00354 {
00355 }
00356 
00357 void PlanningSceneDisplay::changedSceneRobotEnabled()
00358 {
00359   if (isEnabled() && planning_scene_robot_)
00360     planning_scene_robot_->setVisible(scene_robot_enabled_property_->getBool());
00361 }
00362 
00363 void PlanningSceneDisplay::changedSceneEnabled()
00364 {
00365   if (planning_scene_render_)
00366     planning_scene_render_->getGeometryNode()->setVisible(scene_enabled_property_->getBool());
00367 }
00368 
00369 void PlanningSceneDisplay::setGroupColor(rviz::Robot* robot, const std::string& group_name, const QColor &color)
00370 {
00371   if (getRobotModel())
00372   {
00373     const robot_model::JointModelGroup *jmg = getRobotModel()->getJointModelGroup(group_name);
00374     if (jmg)
00375     {
00376       const std::vector<std::string> &links = jmg->getLinkModelNamesWithCollisionGeometry();
00377       for (std::size_t i = 0 ; i < links.size() ; ++i)
00378         setLinkColor(robot, links[i], color);
00379     }
00380   }
00381 }
00382 
00383 void PlanningSceneDisplay::unsetAllColors(rviz::Robot* robot)
00384 {
00385   if (getRobotModel())
00386   {
00387     const std::vector<std::string> &links = getRobotModel()->getLinkModelNamesWithCollisionGeometry();
00388     for (std::size_t i = 0 ; i < links.size() ; ++i)
00389       unsetLinkColor(robot, links[i]);
00390   }
00391 }
00392 
00393 void PlanningSceneDisplay::unsetGroupColor(rviz::Robot* robot, const std::string& group_name )
00394 {
00395   if (getRobotModel())
00396   {
00397     const robot_model::JointModelGroup *jmg = getRobotModel()->getJointModelGroup(group_name);
00398     if (jmg)
00399     {
00400       const std::vector<std::string> &links = jmg->getLinkModelNamesWithCollisionGeometry();
00401       for (std::size_t i = 0 ; i < links.size() ; ++i)
00402         unsetLinkColor(robot, links[i]);
00403     }
00404   }
00405 }
00406 
00407 void PlanningSceneDisplay::setLinkColor(const std::string& link_name, const QColor &color)
00408 {
00409   if (planning_scene_robot_)
00410     setLinkColor(&planning_scene_robot_->getRobot(), link_name, color );
00411 }
00412 
00413 void PlanningSceneDisplay::unsetLinkColor(const std::string& link_name)
00414 {
00415   if (planning_scene_robot_)
00416     unsetLinkColor(&planning_scene_robot_->getRobot(), link_name);
00417 }
00418 
00419 void PlanningSceneDisplay::setLinkColor(rviz::Robot* robot, const std::string& link_name, const QColor &color )
00420 {
00421   rviz::RobotLink *link = robot->getLink(link_name);
00422 
00423   // Check if link exists
00424   if (link)
00425     link->setColor( color.redF(), color.greenF(), color.blueF() );
00426 }
00427 
00428 void PlanningSceneDisplay::unsetLinkColor(rviz::Robot* robot, const std::string& link_name )
00429 {
00430   rviz::RobotLink *link = robot->getLink(link_name);
00431 
00432   // Check if link exists
00433   if (link)
00434     link->unsetColor();
00435 }
00436 
00437 // ******************************************************************************************
00438 // Load
00439 // ******************************************************************************************
00440 planning_scene_monitor::PlanningSceneMonitorPtr PlanningSceneDisplay::createPlanningSceneMonitor()
00441 {
00442   return planning_scene_monitor::PlanningSceneMonitorPtr
00443     (new planning_scene_monitor::PlanningSceneMonitor(robot_description_property_->getStdString(),
00444                                                       context_->getFrameManager()->getTFClientPtr(),
00445                                                       getNameStd() + "_planning_scene_monitor"));
00446 }
00447 
00448 void PlanningSceneDisplay::clearRobotModel()
00449 {
00450   planning_scene_render_.reset();
00451   planning_scene_monitor_.reset(); // this so that the destructor of the PlanningSceneMonitor gets called before a new instance of a scene monitor is constructed
00452 }
00453 
00454 void PlanningSceneDisplay::loadRobotModel()
00455 {
00456   // wait for other robot loadRobotModel() calls to complete;
00457   boost::mutex::scoped_lock _(robot_model_loading_lock_);
00458   model_is_loading_ = true;
00459 
00460   // we need to make sure the clearing of the robot model is in the main thread,
00461   // so that rendering operations do not have data removed from underneath,
00462   // so the next function is executed in the main loop
00463   addMainLoopJob(boost::bind(&PlanningSceneDisplay::clearRobotModel, this));
00464 
00465   waitForAllMainLoopJobs();
00466 
00467   planning_scene_monitor::PlanningSceneMonitorPtr psm = createPlanningSceneMonitor();
00468   if (psm->getPlanningScene())
00469   {
00470     planning_scene_monitor_.swap(psm);
00471     addMainLoopJob(boost::bind(&PlanningSceneDisplay::onRobotModelLoaded, this));
00472     setStatus(rviz::StatusProperty::Ok, "PlanningScene", "Planning Scene Loaded Successfully");
00473     waitForAllMainLoopJobs();
00474   }
00475   else
00476   {
00477     setStatus(rviz::StatusProperty::Error, "PlanningScene", "No Planning Scene Loaded");
00478   }
00479 
00480   if (planning_scene_monitor_)
00481     planning_scene_monitor_->addUpdateCallback(boost::bind(&PlanningSceneDisplay::sceneMonitorReceivedUpdate, this, _1));
00482 
00483   model_is_loading_ = false;
00484 }
00485 
00486 void PlanningSceneDisplay::onRobotModelLoaded()
00487 {
00488   if (planning_scene_topic_property_)
00489     planning_scene_monitor_->startSceneMonitor(planning_scene_topic_property_->getStdString());
00490   planning_scene_render_.reset(new PlanningSceneRender(planning_scene_node_, context_, planning_scene_robot_));
00491   planning_scene_render_->getGeometryNode()->setVisible(scene_enabled_property_->getBool());
00492 
00493   const planning_scene_monitor::LockedPlanningSceneRO &ps = getPlanningSceneRO();
00494   if (planning_scene_robot_)
00495   {
00496     planning_scene_robot_->load(*getRobotModel()->getURDF());
00497     planning_scene_robot_->update(robot_state::RobotStatePtr(new robot_state::RobotState(ps->getCurrentState())));
00498   }
00499 
00500   bool oldState = scene_name_property_->blockSignals(true);
00501   scene_name_property_->setStdString(ps->getName());
00502   scene_name_property_->blockSignals(oldState);
00503 }
00504 
00505 void PlanningSceneDisplay::sceneMonitorReceivedUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
00506 {
00507   onSceneMonitorReceivedUpdate(update_type);
00508 }
00509 
00510 void PlanningSceneDisplay::onSceneMonitorReceivedUpdate(planning_scene_monitor::PlanningSceneMonitor::SceneUpdateType update_type)
00511 {
00512   bool oldState = scene_name_property_->blockSignals(true);
00513   scene_name_property_->setStdString(getPlanningSceneRO()->getName());
00514   scene_name_property_->blockSignals(oldState);
00515 
00516   planning_scene_needs_render_ = true;
00517 }
00518 
00519 void PlanningSceneDisplay::onEnable()
00520 {
00521   Display::onEnable();
00522 
00523   addBackgroundJob(boost::bind(&PlanningSceneDisplay::loadRobotModel, this), "loadRobotModel");
00524 
00525   if (planning_scene_robot_)
00526     planning_scene_robot_->setVisible(scene_robot_enabled_property_->getBool());
00527   if (planning_scene_render_)
00528     planning_scene_render_->getGeometryNode()->setVisible(scene_enabled_property_->getBool());
00529 
00530   calculateOffsetPosition();
00531 }
00532 
00533 // ******************************************************************************************
00534 // Disable
00535 // ******************************************************************************************
00536 void PlanningSceneDisplay::onDisable()
00537 {
00538   if (planning_scene_monitor_)
00539   {
00540     planning_scene_monitor_->stopSceneMonitor();
00541     if (planning_scene_render_)
00542       planning_scene_render_->getGeometryNode()->setVisible(false);
00543   }
00544   if (planning_scene_robot_)
00545     planning_scene_robot_->setVisible(false);
00546   Display::onDisable();
00547 }
00548 
00549 void PlanningSceneDisplay::queueRenderSceneGeometry()
00550 {
00551   planning_scene_needs_render_ = true;
00552 }
00553 
00554 void PlanningSceneDisplay::update(float wall_dt, float ros_dt)
00555 {
00556   Display::update(wall_dt, ros_dt);
00557 
00558   executeMainLoopJobs();
00559 
00560   if (planning_scene_monitor_)
00561     updateInternal(wall_dt, ros_dt);
00562 }
00563 
00564 void PlanningSceneDisplay::updateInternal(float wall_dt, float ros_dt)
00565 {
00566   current_scene_time_ += wall_dt;
00567   if (current_scene_time_ > scene_display_time_property_->getFloat())
00568   {
00569     renderPlanningScene();
00570     current_scene_time_ = 0.0f;
00571   }
00572 }
00573 
00574 void PlanningSceneDisplay::load( const rviz::Config& config )
00575 {
00576   Display::load(config);
00577 }
00578 
00579 void PlanningSceneDisplay::save( rviz::Config config ) const
00580 {
00581   Display::save(config);
00582 }
00583 
00584 // ******************************************************************************************
00585 // Calculate Offset Position
00586 // ******************************************************************************************
00587 void PlanningSceneDisplay::calculateOffsetPosition()
00588 {
00589   if (!getRobotModel())
00590     return;
00591 
00592   tf::Stamped<tf::Pose> pose(tf::Pose::getIdentity(), ros::Time(0), getRobotModel()->getModelFrame());
00593   static const unsigned int max_attempts = 10;
00594   unsigned int attempts = 0;
00595   while (!context_->getTFClient()->canTransform(fixed_frame_.toStdString(), getRobotModel()->getModelFrame(), ros::Time(0)) && attempts < max_attempts)
00596   {
00597     ros::Duration(0.1).sleep();
00598     attempts++;
00599   }
00600 
00601   if (attempts < max_attempts)
00602   {
00603     try
00604     {
00605       context_->getTFClient()->transformPose(fixed_frame_.toStdString(), pose, pose);
00606     }
00607     catch (tf::TransformException& e)
00608     {
00609       ROS_ERROR( "Error transforming from frame '%s' to frame '%s'", pose.frame_id_.c_str(), fixed_frame_.toStdString().c_str() );
00610     }
00611   }
00612 
00613   Ogre::Vector3 position(pose.getOrigin().x(), pose.getOrigin().y(), pose.getOrigin().z());
00614   const tf::Quaternion &q = pose.getRotation();
00615   Ogre::Quaternion orientation( q.getW(), q.getX(), q.getY(), q.getZ() );
00616   planning_scene_node_->setPosition(position);
00617   planning_scene_node_->setOrientation(orientation);
00618 }
00619 
00620 void PlanningSceneDisplay::fixedFrameChanged()
00621 {
00622   Display::fixedFrameChanged();
00623   calculateOffsetPosition();
00624 }
00625 
00626 
00627 } // namespace moveit_rviz_plugin


visualization
Author(s): Ioan Sucan , Dave Coleman
autogenerated on Mon Oct 6 2014 02:34:03