$search
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 "robot_model_display.h" 00031 #include "rviz/visualization_manager.h" 00032 #include "rviz/robot/robot.h" 00033 #include "rviz/robot/tf_link_updater.h" 00034 #include "rviz/properties/property.h" 00035 #include "rviz/properties/property_manager.h" 00036 00037 #include <urdf/model.h> 00038 00039 #include <OGRE/OgreSceneNode.h> 00040 #include <OGRE/OgreSceneManager.h> 00041 00042 #include <tf/transform_listener.h> 00043 00044 namespace rviz 00045 { 00046 00047 void linkUpdaterStatusFunction(StatusLevel level, const std::string& link_name, const std::string& text, RobotModelDisplay* display) 00048 { 00049 display->setStatus(level, link_name, text); 00050 } 00051 00052 RobotModelDisplay::RobotModelDisplay() 00053 : Display() 00054 , description_param_("robot_description") 00055 , has_new_transforms_( false ) 00056 , time_since_last_transform_( 0.0f ) 00057 , update_rate_( 0.0f ) 00058 { 00059 } 00060 00061 RobotModelDisplay::~RobotModelDisplay() 00062 { 00063 delete robot_; 00064 } 00065 00066 void RobotModelDisplay::onInitialize() 00067 { 00068 robot_ = new Robot( vis_manager_, "Robot: " + name_ ); 00069 00070 setVisualVisible( true ); 00071 setCollisionVisible( false ); 00072 00073 setAlpha(1.0f); 00074 } 00075 00076 void RobotModelDisplay::setAlpha( float alpha ) 00077 { 00078 alpha_ = alpha; 00079 00080 robot_->setAlpha(alpha_); 00081 00082 propertyChanged(alpha_property_); 00083 } 00084 00085 void RobotModelDisplay::setRobotDescription( const std::string& description_param ) 00086 { 00087 description_param_ = description_param; 00088 00089 propertyChanged(robot_description_property_); 00090 00091 if ( isEnabled() ) 00092 { 00093 load(); 00094 causeRender(); 00095 } 00096 } 00097 00098 void RobotModelDisplay::setVisualVisible( bool visible ) 00099 { 00100 robot_->setVisualVisible( visible ); 00101 00102 propertyChanged(visual_enabled_property_); 00103 00104 causeRender(); 00105 } 00106 00107 void RobotModelDisplay::setCollisionVisible( bool visible ) 00108 { 00109 robot_->setCollisionVisible( visible ); 00110 00111 propertyChanged(collision_enabled_property_); 00112 00113 causeRender(); 00114 } 00115 00116 void RobotModelDisplay::setUpdateRate( float rate ) 00117 { 00118 update_rate_ = rate; 00119 00120 propertyChanged(update_rate_property_); 00121 00122 causeRender(); 00123 } 00124 00125 void RobotModelDisplay::setTFPrefix(const std::string& prefix) 00126 { 00127 tf_prefix_ = prefix; 00128 00129 propertyChanged(tf_prefix_property_); 00130 00131 causeRender(); 00132 } 00133 00134 bool RobotModelDisplay::isVisualVisible() 00135 { 00136 return robot_->isVisualVisible(); 00137 } 00138 00139 bool RobotModelDisplay::isCollisionVisible() 00140 { 00141 return robot_->isCollisionVisible(); 00142 } 00143 00144 void RobotModelDisplay::load() 00145 { 00146 std::string content; 00147 if (!update_nh_.getParam(description_param_, content)) 00148 { 00149 std::string loc; 00150 if (update_nh_.searchParam(description_param_, loc)) 00151 { 00152 update_nh_.getParam(loc, content); 00153 } 00154 else 00155 { 00156 clear(); 00157 00158 std::stringstream ss; 00159 ss << "Parameter [" << description_param_ << "] does not exist, and was not found by searchParam()"; 00160 setStatus(status_levels::Error, "URDF", ss.str()); 00161 return; 00162 } 00163 } 00164 00165 if (content.empty()) 00166 { 00167 clear(); 00168 setStatus(status_levels::Error, "URDF", "URDF is empty"); 00169 return; 00170 } 00171 00172 if ( content == robot_description_ ) 00173 { 00174 return; 00175 } 00176 00177 robot_description_ = content; 00178 00179 TiXmlDocument doc; 00180 doc.Parse(robot_description_.c_str()); 00181 if (!doc.RootElement()) 00182 { 00183 clear(); 00184 setStatus(status_levels::Error, "URDF", "URDF failed XML parse"); 00185 return; 00186 } 00187 00188 urdf::Model descr; 00189 if (!descr.initXml(doc.RootElement())) 00190 { 00191 clear(); 00192 setStatus(status_levels::Error, "URDF", "URDF failed Model parse"); 00193 return; 00194 } 00195 00196 setStatus(status_levels::Ok, "URDF", "URDF parsed OK"); 00197 robot_->load( doc.RootElement(), descr ); 00198 robot_->update( TFLinkUpdater(vis_manager_->getFrameManager(), boost::bind(linkUpdaterStatusFunction, _1, _2, _3, this), tf_prefix_) ); 00199 } 00200 00201 void RobotModelDisplay::onEnable() 00202 { 00203 load(); 00204 robot_->setVisible( true ); 00205 } 00206 00207 void RobotModelDisplay::onDisable() 00208 { 00209 robot_->setVisible( false ); 00210 clear(); 00211 } 00212 00213 void RobotModelDisplay::update(float wall_dt, float ros_dt) 00214 { 00215 time_since_last_transform_ += wall_dt; 00216 00217 bool update = update_rate_ < 0.0001f || time_since_last_transform_ >= update_rate_; 00218 00219 if ( has_new_transforms_ || update ) 00220 { 00221 robot_->update(TFLinkUpdater(vis_manager_->getFrameManager(), boost::bind(linkUpdaterStatusFunction, _1, _2, _3, this), tf_prefix_)); 00222 causeRender(); 00223 00224 has_new_transforms_ = false; 00225 time_since_last_transform_ = 0.0f; 00226 } 00227 } 00228 00229 void RobotModelDisplay::targetFrameChanged() 00230 { 00231 has_new_transforms_ = true; 00232 } 00233 00234 void RobotModelDisplay::createProperties() 00235 { 00236 visual_enabled_property_ = property_manager_->createProperty<BoolProperty>( "Visual Enabled", property_prefix_, boost::bind( &RobotModelDisplay::isVisualVisible, this ), 00237 boost::bind( &RobotModelDisplay::setVisualVisible, this, _1 ), parent_category_, this ); 00238 setPropertyHelpText(visual_enabled_property_, "Whether to display the visual representation of the robot."); 00239 collision_enabled_property_ = property_manager_->createProperty<BoolProperty>( "Collision Enabled", property_prefix_, boost::bind( &RobotModelDisplay::isCollisionVisible, this ), 00240 boost::bind( &RobotModelDisplay::setCollisionVisible, this, _1 ), parent_category_, this ); 00241 setPropertyHelpText(collision_enabled_property_, "Whether to display the collision representation of the robot."); 00242 update_rate_property_ = property_manager_->createProperty<FloatProperty>( "Update Interval", property_prefix_, boost::bind( &RobotModelDisplay::getUpdateRate, this ), 00243 boost::bind( &RobotModelDisplay::setUpdateRate, this, _1 ), parent_category_, this ); 00244 setPropertyHelpText(update_rate_property_, "Interval at which to update the links, in seconds. 0 means to update every update cycle."); 00245 FloatPropertyPtr float_prop = update_rate_property_.lock(); 00246 float_prop->setMin( 0.0 ); 00247 float_prop->addLegacyName("Update Rate"); 00248 00249 alpha_property_ = property_manager_->createProperty<FloatProperty>( "Alpha", property_prefix_, boost::bind( &RobotModelDisplay::getAlpha, this ), 00250 boost::bind( &RobotModelDisplay::setAlpha, this, _1 ), parent_category_, this ); 00251 setPropertyHelpText(alpha_property_, "Amount of transparency to apply to the links."); 00252 float_prop = alpha_property_.lock(); 00253 float_prop->setMin( 0.0 ); 00254 float_prop->setMax( 1.0 ); 00255 00256 robot_description_property_ = property_manager_->createProperty<StringProperty>( "Robot Description", property_prefix_, boost::bind( &RobotModelDisplay::getRobotDescription, this ), 00257 boost::bind( &RobotModelDisplay::setRobotDescription, this, _1 ), parent_category_, this ); 00258 setPropertyHelpText(robot_description_property_, "Name of the parameter to search for to load the robot description."); 00259 00260 tf_prefix_property_ = property_manager_->createProperty<StringProperty>( "TF Prefix", property_prefix_, boost::bind( &RobotModelDisplay::getTFPrefix, this ), 00261 boost::bind( &RobotModelDisplay::setTFPrefix, this, _1 ), parent_category_, this ); 00262 setPropertyHelpText(tf_prefix_property_, "Robot Model normally assumes the link name is the same as the tf frame name. This option allows you to set a prefix. Mainly useful for multi-robot situations."); 00263 00264 robot_->setPropertyManager( property_manager_, parent_category_ ); 00265 } 00266 00267 void RobotModelDisplay::clear() 00268 { 00269 robot_->clear(); 00270 clearStatuses(); 00271 robot_description_.clear(); 00272 } 00273 00274 void RobotModelDisplay::reset() 00275 { 00276 Display::reset(); 00277 has_new_transforms_ = true; 00278 } 00279 00280 } // namespace rviz 00281