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
00031
00032 #include <moveit/robot_state_rviz_plugin/robot_state_display.h>
00033 #include <moveit/robot_state/conversions.h>
00034
00035 #include <rviz/visualization_manager.h>
00036 #include <rviz/robot/robot.h>
00037 #include <rviz/robot/robot_link.h>
00038
00039 #include <rviz/properties/property.h>
00040 #include <rviz/properties/string_property.h>
00041 #include <rviz/properties/bool_property.h>
00042 #include <rviz/properties/float_property.h>
00043 #include <rviz/properties/ros_topic_property.h>
00044 #include <rviz/properties/color_property.h>
00045 #include <rviz/display_context.h>
00046 #include <rviz/frame_manager.h>
00047 #include <tf/transform_listener.h>
00048
00049 #include <OGRE/OgreSceneManager.h>
00050
00051 namespace moveit_rviz_plugin
00052 {
00053
00054
00055
00056
00057 RobotStateDisplay::RobotStateDisplay() :
00058 Display(),
00059 update_state_(false)
00060 {
00061 robot_description_property_ =
00062 new rviz::StringProperty( "Robot Description", "robot_description", "The name of the ROS parameter where the URDF for the robot is loaded",
00063 this,
00064 SLOT( changedRobotDescription() ), this );
00065
00066 robot_state_topic_property_ =
00067 new rviz::RosTopicProperty( "Robot State Topic", "display_robot_state",
00068 ros::message_traits::datatype<moveit_msgs::DisplayRobotState>(),
00069 "The topic on which the moveit_msgs::RobotState messages are received",
00070 this,
00071 SLOT( changedRobotStateTopic() ), this );
00072
00073
00074 root_link_name_property_ =
00075 new rviz::StringProperty( "Robot Root Link", "", "Shows the name of the root link for the robot model",
00076 this,
00077 SLOT( changedRootLinkName() ), this );
00078 root_link_name_property_->setReadOnly(true);
00079
00080 robot_alpha_property_ =
00081 new rviz::FloatProperty( "Robot Alpha", 1.0f, "Specifies the alpha for the robot links",
00082 this,
00083 SLOT( changedRobotSceneAlpha() ), this );
00084 robot_alpha_property_->setMin( 0.0 );
00085 robot_alpha_property_->setMax( 1.0 );
00086
00087 attached_body_color_property_ = new rviz::ColorProperty( "Attached Body Color", QColor(150, 50, 150), "The color for the attached bodies",
00088 this,
00089 SLOT( changedAttachedBodyColor() ), this );
00090
00091 enable_link_highlight_ = new rviz::BoolProperty("Show Highlights", true, "Specifies whether link highlighting is enabled",
00092 this, SLOT( changedEnableLinkHighlight() ), this);
00093 enable_visual_visible_ = new rviz::BoolProperty("Visual Enabled", true, "Whether to display the visual representation of the robot.",
00094 this, SLOT( changedEnableVisualVisible() ), this);
00095 enable_collision_visible_ = new rviz::BoolProperty("Collision Enabled", false, "Whether to display the collision representation of the robot.",
00096 this, SLOT( changedEnableCollisionVisible() ), this);
00097
00098 show_all_links_ = new rviz::BoolProperty("Show All Links", true, "Toggle all links visibility on or off.",
00099 this, SLOT( changedAllLinks() ), this);
00100 }
00101
00102
00103
00104
00105 RobotStateDisplay::~RobotStateDisplay()
00106 {
00107 }
00108
00109 void RobotStateDisplay::onInitialize()
00110 {
00111 Display::onInitialize();
00112 robot_.reset(new RobotStateVisualization(scene_node_, context_, "Robot State", this));
00113 changedEnableVisualVisible();
00114 changedEnableCollisionVisible();
00115 robot_->setVisible(true);
00116 }
00117
00118 void RobotStateDisplay::reset()
00119 {
00120 robot_->clear();
00121 rdf_loader_.reset();
00122
00123 loadRobotModel();
00124 Display::reset();
00125
00126 changedEnableVisualVisible();
00127 changedEnableCollisionVisible();
00128 robot_->setVisible(true);
00129 }
00130
00131 void RobotStateDisplay::changedAllLinks()
00132 {
00133 Property *links_prop = subProp("Links");
00134 QVariant value(show_all_links_->getBool());
00135
00136 for (int i=0 ; i<links_prop->numChildren() ; ++i)
00137 {
00138 Property *link_prop = links_prop->childAt(i);
00139 link_prop->setValue(value);
00140 }
00141 }
00142
00143 void RobotStateDisplay::setHighlight(const std::string& link_name, const std_msgs::ColorRGBA& color)
00144 {
00145 rviz::RobotLink *link = robot_->getRobot().getLink(link_name);
00146 if (link)
00147 {
00148 link->setColor(color.r, color.g, color.b);
00149 link->setRobotAlpha(color.a * robot_alpha_property_->getFloat());
00150 }
00151 }
00152
00153 void RobotStateDisplay::unsetHighlight(const std::string& link_name)
00154 {
00155 rviz::RobotLink *link = robot_->getRobot().getLink(link_name);
00156 if (link)
00157 {
00158 link->unsetColor();
00159 link->setRobotAlpha(robot_alpha_property_->getFloat());
00160 }
00161 }
00162
00163 void RobotStateDisplay::changedEnableLinkHighlight()
00164 {
00165 if (enable_link_highlight_->getBool())
00166 {
00167 for (std::map<std::string, std_msgs::ColorRGBA>::iterator it = highlights_.begin() ;
00168 it != highlights_.end() ;
00169 ++it)
00170 {
00171 setHighlight(it->first, it->second);
00172 }
00173 }
00174 else
00175 {
00176 for (std::map<std::string, std_msgs::ColorRGBA>::iterator it = highlights_.begin() ;
00177 it != highlights_.end() ;
00178 ++it)
00179 {
00180 unsetHighlight(it->first);
00181 }
00182 }
00183 }
00184
00185 void RobotStateDisplay::changedEnableVisualVisible()
00186 {
00187 robot_->setVisualVisible(enable_visual_visible_->getBool());
00188 }
00189
00190 void RobotStateDisplay::changedEnableCollisionVisible()
00191 {
00192 robot_->setCollisionVisible(enable_collision_visible_->getBool());
00193 }
00194
00195 static bool operator!=(const std_msgs::ColorRGBA& a, const std_msgs::ColorRGBA& b)
00196 {
00197 return a.r != b.r ||
00198 a.g != b.g ||
00199 a.b != b.b ||
00200 a.a != b.a;
00201 }
00202
00203 void RobotStateDisplay::setRobotHighlights(const moveit_msgs::DisplayRobotState::_highlight_links_type& highlight_links)
00204 {
00205 if (highlight_links.empty() && highlights_.empty())
00206 return;
00207
00208 std::map<std::string, std_msgs::ColorRGBA> highlights;
00209 for (moveit_msgs::DisplayRobotState::_highlight_links_type::const_iterator it = highlight_links.begin() ;
00210 it != highlight_links.end() ;
00211 ++it)
00212 {
00213 highlights[it->id] = it->color;
00214 }
00215
00216 if (enable_link_highlight_->getBool())
00217 {
00218 std::map<std::string, std_msgs::ColorRGBA>::iterator ho = highlights_.begin();
00219 std::map<std::string, std_msgs::ColorRGBA>::iterator hn = highlights.begin();
00220 while (ho != highlights_.end() || hn != highlights.end())
00221 {
00222 if (ho == highlights_.end())
00223 {
00224 setHighlight(hn->first, hn->second);
00225 ++hn;
00226 }
00227 else if (hn == highlights.end())
00228 {
00229 unsetHighlight(ho->first);
00230 ++ho;
00231 }
00232 else if (hn->first < ho->first)
00233 {
00234 setHighlight(hn->first, hn->second);
00235 ++hn;
00236 }
00237 else if (hn->first > ho->first)
00238 {
00239 unsetHighlight(ho->first);
00240 ++ho;
00241 }
00242 else if (hn->second != ho->second)
00243 {
00244 setHighlight(hn->first, hn->second);
00245 ++ho;
00246 ++hn;
00247 }
00248 else
00249 {
00250 ++ho;
00251 ++hn;
00252 }
00253 }
00254 }
00255
00256 swap(highlights, highlights_);
00257 }
00258
00259 void RobotStateDisplay::changedAttachedBodyColor()
00260 {
00261 if (robot_)
00262 {
00263 QColor color = attached_body_color_property_->getColor();
00264 std_msgs::ColorRGBA color_msg;
00265 color_msg.r = color.redF();
00266 color_msg.g = color.greenF();
00267 color_msg.b = color.blueF();
00268 color_msg.a = robot_alpha_property_->getFloat();
00269 robot_->setDefaultAttachedObjectColor(color_msg);
00270 update_state_ = true;
00271 }
00272 }
00273
00274 void RobotStateDisplay::changedRobotDescription()
00275 {
00276 if (isEnabled())
00277 reset();
00278 }
00279
00280 void RobotStateDisplay::changedRootLinkName()
00281 {
00282 }
00283
00284 void RobotStateDisplay::changedRobotSceneAlpha()
00285 {
00286 if (robot_)
00287 {
00288 robot_->setAlpha(robot_alpha_property_->getFloat());
00289 QColor color = attached_body_color_property_->getColor();
00290 std_msgs::ColorRGBA color_msg;
00291 color_msg.r = color.redF();
00292 color_msg.g = color.greenF();
00293 color_msg.b = color.blueF();
00294 color_msg.a = robot_alpha_property_->getFloat();
00295 robot_->setDefaultAttachedObjectColor(color_msg);
00296 update_state_ = true;
00297 }
00298 }
00299
00300 void RobotStateDisplay::changedRobotStateTopic()
00301 {
00302 robot_state_subscriber_.shutdown();
00303 robot_state_subscriber_ = root_nh_.subscribe(robot_state_topic_property_->getStdString(), 10, &RobotStateDisplay::newRobotStateCallback, this);
00304 robot_->clear();
00305 loadRobotModel();
00306 }
00307
00308 void RobotStateDisplay::newRobotStateCallback(const moveit_msgs::DisplayRobotStateConstPtr &state_msg)
00309 {
00310 if (!kmodel_)
00311 return;
00312 if (!kstate_)
00313 kstate_.reset(new robot_state::RobotState(kmodel_));
00314
00315 robot_state::robotStateMsgToRobotState(state_msg->state, *kstate_);
00316 setRobotHighlights(state_msg->highlight_links);
00317 update_state_ = true;
00318 }
00319
00320 void RobotStateDisplay::setLinkColor(const std::string& link_name, const QColor &color)
00321 {
00322 setLinkColor(&robot_->getRobot(), link_name, color );
00323 }
00324
00325 void RobotStateDisplay::unsetLinkColor(const std::string& link_name)
00326 {
00327 unsetLinkColor(&robot_->getRobot(), link_name);
00328 }
00329
00330 void RobotStateDisplay::setLinkColor(rviz::Robot* robot, const std::string& link_name, const QColor &color )
00331 {
00332 rviz::RobotLink *link = robot->getLink(link_name);
00333
00334
00335 if (link)
00336 link->setColor( color.redF(), color.greenF(), color.blueF() );
00337 }
00338
00339 void RobotStateDisplay::unsetLinkColor(rviz::Robot* robot, const std::string& link_name )
00340 {
00341 rviz::RobotLink *link = robot->getLink(link_name);
00342
00343
00344 if (link)
00345 link->unsetColor();
00346 }
00347
00348
00349
00350
00351 void RobotStateDisplay::loadRobotModel()
00352 {
00353 if (!rdf_loader_)
00354 rdf_loader_.reset(new rdf_loader::RDFLoader(robot_description_property_->getStdString()));
00355
00356 if (rdf_loader_->getURDF())
00357 {
00358 const boost::shared_ptr<srdf::Model> &srdf = rdf_loader_->getSRDF() ? rdf_loader_->getSRDF() : boost::shared_ptr<srdf::Model>(new srdf::Model());
00359 kmodel_.reset(new robot_model::RobotModel(rdf_loader_->getURDF(), srdf));
00360 robot_->load(*kmodel_->getURDF());
00361 kstate_.reset(new robot_state::RobotState(kmodel_));
00362 kstate_->setToDefaultValues();
00363 bool oldState = root_link_name_property_->blockSignals(true);
00364 root_link_name_property_->setStdString(getRobotModel()->getRootLinkName());
00365 root_link_name_property_->blockSignals(oldState);
00366 update_state_ = true;
00367 setStatus( rviz::StatusProperty::Ok, "RobotState", "Planning Model Loaded Successfully" );
00368 }
00369 else
00370 setStatus( rviz::StatusProperty::Error, "RobotState", "No Planning Model Loaded" );
00371
00372 highlights_.clear();
00373 }
00374
00375 void RobotStateDisplay::onEnable()
00376 {
00377 Display::onEnable();
00378 loadRobotModel();
00379 if (robot_)
00380 {
00381 changedEnableVisualVisible();
00382 changedEnableCollisionVisible();
00383 robot_->setVisible(true);
00384 }
00385 calculateOffsetPosition();
00386 }
00387
00388
00389
00390
00391 void RobotStateDisplay::onDisable()
00392 {
00393 if (robot_)
00394 robot_->setVisible(false);
00395 Display::onDisable();
00396 }
00397
00398 void RobotStateDisplay::update(float wall_dt, float ros_dt)
00399 {
00400 Display::update(wall_dt, ros_dt);
00401 if (robot_ && update_state_)
00402 {
00403 update_state_ = false;
00404 robot_->update(kstate_);
00405 }
00406 }
00407
00408
00409
00410
00411 void RobotStateDisplay::calculateOffsetPosition()
00412 {
00413 if (!getRobotModel())
00414 return;
00415
00416 ros::Time stamp;
00417 std::string err_string;
00418 if (context_->getTFClient()->getLatestCommonTime(fixed_frame_.toStdString(), getRobotModel()->getModelFrame(), stamp, &err_string) != tf::NO_ERROR)
00419 return;
00420
00421 tf::Stamped<tf::Pose> pose(tf::Pose::getIdentity(), stamp, getRobotModel()->getModelFrame());
00422
00423 if (context_->getTFClient()->canTransform(fixed_frame_.toStdString(), getRobotModel()->getModelFrame(), stamp))
00424 {
00425 try
00426 {
00427 context_->getTFClient()->transformPose(fixed_frame_.toStdString(), pose, pose);
00428 }
00429 catch (tf::TransformException& e)
00430 {
00431 ROS_ERROR( "Error transforming from frame '%s' to frame '%s'", pose.frame_id_.c_str(), fixed_frame_.toStdString().c_str() );
00432 }
00433 }
00434
00435 Ogre::Vector3 position(pose.getOrigin().x(), pose.getOrigin().y(), pose.getOrigin().z());
00436 const tf::Quaternion &q = pose.getRotation();
00437 Ogre::Quaternion orientation( q.getW(), q.getX(), q.getY(), q.getZ() );
00438 scene_node_->setPosition(position);
00439 scene_node_->setOrientation(orientation);
00440 }
00441
00442 void RobotStateDisplay::fixedFrameChanged()
00443 {
00444 Display::fixedFrameChanged();
00445 calculateOffsetPosition();
00446 }
00447
00448
00449 }