30 #include <boost/filesystem.hpp> 32 #include <OgreEntity.h> 33 #include <OgreMaterial.h> 34 #include <OgreMaterialManager.h> 35 #include <OgreRibbonTrail.h> 36 #include <OgreSceneManager.h> 37 #include <OgreSceneNode.h> 38 #include <OgreSubEntity.h> 39 #include <OgreTextureManager.h> 40 #include <OgreSharedPtr.h> 41 #include <OgreTechnique.h> 46 #include <urdf_model/model.h> 47 #include <urdf_model/link.h> 66 namespace fs=boost::filesystem;
68 #ifndef ROS_PACKAGE_NAME 69 # define ROS_PACKAGE_NAME "rviz" 157 const urdf::LinkConstSharedPtr& link,
158 const std::string& parent_joint_name,
162 , scene_manager_( robot->getDisplayContext()->getSceneManager() )
163 ,
context_( robot->getDisplayContext() )
164 , name_( link->name )
165 , parent_joint_name_( parent_joint_name )
166 , visual_node_(
NULL )
167 , collision_node_(
NULL )
170 , material_alpha_( 1.0 )
172 , only_render_depth_(false)
173 , using_color_( false )
174 , is_selectable_( true )
182 "Amount of transparency to apply to this link.",
186 "Enable/disable a 2 meter \"ribbon\" which follows this link.",
190 "Enable/disable showing the axes of this link.",
194 "Position of this link, in the current Fixed Frame. (Not editable)",
199 "Orientation of this link, in the current Fixed Frame. (Not editable)",
209 std::stringstream ss;
210 static int count = 1;
211 ss <<
"robot link color material " << count++;
228 if (collision || visual)
234 std::stringstream desc;
237 desc <<
"Root Link <b>" <<
name_ <<
"</b>";
241 desc <<
"Link <b>" <<
name_ <<
"</b>";
245 if (link->child_joints.empty())
247 desc <<
" has no children.";
253 << link->child_joints.size();
255 if (link->child_joints.size() > 1)
257 desc <<
" child joints: ";
261 desc <<
" child joint: ";
264 std::vector<urdf::JointSharedPtr >::const_iterator child_it = link->child_joints.begin();
265 std::vector<urdf::JointSharedPtr >::const_iterator child_end = link->child_joints.end();
266 for ( ; child_it != child_end ; ++child_it )
268 urdf::Joint *child_joint = child_it->get();
269 if (child_joint && !child_joint->name.empty())
272 desc <<
"<b>" << child_joint->name <<
"</b>" << ((child_it+1 == child_end) ?
"." :
", ");
278 desc <<
" Check/uncheck to show/hide this link in the display.";
281 desc <<
" This link has collision geometry but no visible geometry.";
285 desc <<
" This link has visible geometry but no collision geometry.";
290 desc <<
" This link has NO geometry.";
348 Ogre::SceneNode::ChildNodeIterator child_it =
visual_node_->getChildIterator();
349 while( child_it.hasMoreElements() )
351 Ogre::SceneNode* child =
dynamic_cast<Ogre::SceneNode*
>( child_it.getNext() );
354 Ogre::SceneNode::ObjectIterator object_it = child->getAttachedObjectIterator();
355 while( object_it.hasMoreElements() )
357 Ogre::MovableObject* obj = object_it.getNext();
358 obj->setRenderQueueGroup(group);
366 setRenderQueueGroup( onlyRenderDepth ? Ogre::RENDER_QUEUE_BACKGROUND : Ogre::RENDER_QUEUE_MAIN );
374 M_SubEntityToMaterial::iterator it =
materials_.begin();
375 M_SubEntityToMaterial::iterator end =
materials_.end();
376 for (; it != end; ++it)
378 const Ogre::MaterialPtr& material = it->second;
382 material->setColourWriteEnabled(
false );
383 material->setDepthWriteEnabled(
true );
387 Ogre::ColourValue color = material->getTechnique(0)->getPass(0)->getDiffuse();
389 material->setDiffuse( color );
391 if ( color.a < 0.9998 )
393 material->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
394 material->setDepthWriteEnabled(
false );
398 material->setSceneBlending( Ogre::SBT_REPLACE );
399 material->setDepthWriteEnabled(
true );
404 Ogre::ColourValue color =
color_material_->getTechnique(0)->getPass(0)->getDiffuse();
408 if ( color.a < 0.9998 )
446 if (!link->visual || !link->visual->material)
448 return Ogre::MaterialManager::getSingleton().getByName(
"RVIZ/ShadedRed");
451 static int count = 0;
452 std::stringstream ss;
453 ss <<
"Robot Link Material" << count++;
455 Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(ss.str(),
ROS_PACKAGE_NAME);
456 mat->getTechnique(0)->setLightingEnabled(
true);
458 urdf::VisualSharedPtr visual = link->visual;
459 std::vector<urdf::VisualSharedPtr>::const_iterator vi;
460 for( vi = link->visual_array.begin(); vi != link->visual_array.end(); vi++ )
462 if( (*vi) && material_name !=
"" && (*vi)->material_name == material_name) {
467 if ( vi == link->visual_array.end() ) {
468 visual = link->visual;
471 if (visual->material->texture_filename.empty())
473 const urdf::Color& col = visual->material->color;
474 mat->getTechnique(0)->setAmbient(col.r * 0.5, col.g * 0.5, col.b * 0.5);
475 mat->getTechnique(0)->setDiffuse(col.r, col.g, col.b, col.a);
481 std::string
filename = visual->material->texture_filename;
482 if (!Ogre::TextureManager::getSingleton().resourceExists(filename))
488 res = retriever.
get(filename);
497 Ogre::DataStreamPtr stream(
new Ogre::MemoryDataStream(res.
data.get(), res.
size));
499 std::string extension = fs::extension(fs::path(filename));
501 if (extension[0] ==
'.')
503 extension = extension.substr(1, extension.size() - 1);
508 image.load(stream, extension);
509 Ogre::TextureManager::getSingleton().loadImage(filename, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, image);
511 catch (Ogre::Exception& e)
513 ROS_ERROR(
"Could not load texture [%s]: %s", filename.c_str(), e.what());
518 Ogre::Pass* pass = mat->getTechnique(0)->getPass(0);
519 Ogre::TextureUnitState* tex_unit = pass->createTextureUnitState();;
520 tex_unit->setTextureName(filename);
526 void RobotLink::createEntityForGeometryElement(
const urdf::LinkConstSharedPtr& link,
const urdf::Geometry& geom,
const urdf::Pose& origin,
const std::string material_name, Ogre::SceneNode* scene_node, Ogre::Entity*& entity)
529 Ogre::SceneNode* offset_node = scene_node->createChildSceneNode();
531 static int count = 0;
532 std::stringstream ss;
533 ss <<
"Robot Link" << count++;
534 std::string entity_name = ss.str();
536 Ogre::Vector3 scale(Ogre::Vector3::UNIT_SCALE);
538 Ogre::Vector3 offset_position(Ogre::Vector3::ZERO);
539 Ogre::Quaternion offset_orientation(Ogre::Quaternion::IDENTITY);
543 Ogre::Vector3 position( origin.position.x, origin.position.y, origin.position.z );
544 Ogre::Quaternion orientation( Ogre::Quaternion::IDENTITY );
545 orientation = orientation * Ogre::Quaternion( origin.rotation.w, origin.rotation.x, origin.rotation.y, origin.rotation.z );
547 offset_position = position;
548 offset_orientation = orientation;
553 case urdf::Geometry::SPHERE:
555 const urdf::Sphere& sphere =
static_cast<const urdf::Sphere&
>(geom);
558 scale = Ogre::Vector3( sphere.radius*2, sphere.radius*2, sphere.radius*2 );
561 case urdf::Geometry::BOX:
563 const urdf::Box& box =
static_cast<const urdf::Box&
>(geom);
566 scale = Ogre::Vector3( box.dim.x, box.dim.y, box.dim.z );
570 case urdf::Geometry::CYLINDER:
572 const urdf::Cylinder& cylinder =
static_cast<const urdf::Cylinder&
>(geom);
574 Ogre::Quaternion rotX;
575 rotX.FromAngleAxis( Ogre::Degree(90), Ogre::Vector3::UNIT_X );
576 offset_orientation = offset_orientation * rotX;
579 scale = Ogre::Vector3( cylinder.radius*2, cylinder.length, cylinder.radius*2 );
582 case urdf::Geometry::MESH:
584 const urdf::Mesh& mesh =
static_cast<const urdf::Mesh&
>(geom);
586 if ( mesh.filename.empty() )
592 scale = Ogre::Vector3(mesh.scale.x, mesh.scale.y, mesh.scale.z);
594 std::string model_name = mesh.filename;
601 catch( Ogre::InvalidParametersException& e )
603 ROS_ERROR(
"Could not convert mesh resource '%s' for link '%s'. It might be an empty mesh: %s", model_name.c_str(), link->name.c_str(), e.what() );
605 catch( Ogre::Exception& e )
607 ROS_ERROR(
"Could not load model '%s' for link '%s': %s", model_name.c_str(), link->name.c_str(), e.what() );
612 ROS_WARN(
"Unsupported geometry type for element: %d", geom.type);
618 offset_node->attachObject(entity);
619 offset_node->setScale(scale);
620 offset_node->setPosition(offset_position);
621 offset_node->setOrientation(offset_orientation);
623 static int count = 0;
628 std::stringstream ss;
630 std::string cloned_name = ss.str();
636 for (uint32_t i = 0; i < entity->getNumSubEntities(); ++i)
639 std::stringstream ss;
641 std::string cloned_name = ss.str();
648 Ogre::SubEntity* sub = entity->getSubEntity(i);
649 const std::string& material_name = sub->getMaterialName();
651 if (material_name ==
"BaseWhite" || material_name ==
"BaseWhiteNoLighting")
659 std::stringstream ss;
660 ss << material_name << count++ <<
"Robot";
661 std::string cloned_name = ss.str();
662 sub->getMaterial()->clone(cloned_name);
663 sub->setMaterialName(cloned_name);
673 bool valid_collision_found =
false;
674 #if URDF_MAJOR_VERSION == 0 && URDF_MINOR_VERSION == 2 675 std::map<std::string, boost::shared_ptr<std::vector<urdf::CollisionSharedPtr > > >::const_iterator mi;
676 for( mi = link->collision_groups.begin(); mi != link->collision_groups.end(); mi++ )
680 std::vector<urdf::CollisionSharedPtr >::const_iterator vi;
681 for( vi = mi->second->begin(); vi != mi->second->end(); vi++ )
683 urdf::CollisionSharedPtr collision = *vi;
684 if( collision && collision->geometry )
686 Ogre::Entity* collision_mesh =
NULL;
691 valid_collision_found =
true;
698 std::vector<urdf::CollisionSharedPtr >::const_iterator vi;
699 for( vi = link->collision_array.begin(); vi != link->collision_array.end(); vi++ )
701 urdf::CollisionSharedPtr collision = *vi;
702 if( collision && collision->geometry )
704 Ogre::Entity* collision_mesh =
NULL;
709 valid_collision_found =
true;
715 if( !valid_collision_found && link->collision && link->collision->geometry )
717 Ogre::Entity* collision_mesh =
NULL;
730 bool valid_visual_found =
false;
731 #if URDF_MAJOR_VERSION == 0 && URDF_MINOR_VERSION == 2 732 std::map<std::string, boost::shared_ptr<std::vector<urdf::VisualSharedPtr > > >::const_iterator mi;
733 for( mi = link->visual_groups.begin(); mi != link->visual_groups.end(); mi++ )
737 std::vector<urdf::VisualSharedPtr >::const_iterator vi;
738 for( vi = mi->second->begin(); vi != mi->second->end(); vi++ )
740 urdf::VisualSharedPtr visual = *vi;
741 if( visual && visual->geometry )
743 Ogre::Entity* visual_mesh =
NULL;
748 valid_visual_found =
true;
755 std::vector<urdf::VisualSharedPtr >::const_iterator vi;
756 for( vi = link->visual_array.begin(); vi != link->visual_array.end(); vi++ )
758 urdf::VisualSharedPtr visual = *vi;
759 if( visual && visual->geometry )
761 Ogre::Entity* visual_mesh =
NULL;
766 valid_visual_found =
true;
772 if( !valid_visual_found && link->visual && link->visual->geometry )
774 Ogre::Entity* visual_mesh =
NULL;
806 static int count = 0;
807 std::stringstream ss;
808 ss <<
"Trail for link " <<
name_ << count++;
810 trail_->setMaxChainElements( 100 );
811 trail_->setInitialWidth( 0, 0.01
f );
812 trail_->setInitialColour( 0, 0.0
f, 0.5
f, 0.5
f );
814 trail_->setTrailLength( 2.0
f );
820 ROS_WARN(
"No visual node for link %s, cannot create a trail",
name_.c_str() );
840 static int count = 0;
841 std::stringstream ss;
842 ss <<
"Axes for link " <<
name_ << count++;
861 const Ogre::Vector3& collision_position,
const Ogre::Quaternion& collision_orientation )
912 M_SubEntityToMaterial::iterator it =
materials_.begin();
913 M_SubEntityToMaterial::iterator end =
materials_.end();
914 for (; it != end; ++it)
916 it->first->setMaterial(it->second);
923 Ogre::ColourValue color =
color_material_->getTechnique(0)->getPass(0)->getDiffuse();
virtual Ogre::Quaternion getQuaternion() const
void updateVisibility()
Update the visibility of the link elements: visual mesh, collision mesh, trail, and axes...
VectorProperty * position_property_
virtual void createProperties(const Picked &obj, Property *parent_property)
Override to create properties of the given picked object(s).
virtual void postRenderPass(uint32_t pass)
std::vector< std::string > child_joint_names_
Property * getParent() const
Return the parent Property.
virtual void expand()
Expand (show the children of) this Property.
static Ogre::Entity * createEntity(const std::string &name, Type shape_type, Ogre::SceneManager *scene_manager)
virtual bool setVector(const Ogre::Vector3 &vector)
Ogre::Vector3 getPosition()
bool setSelectable(bool selectable)
set whether the link is selectable. If false objects behind/inside the link can be selected/manipulat...
void createCollision(const urdf::LinkConstSharedPtr &link)
Ogre::SceneNode * visual_node_
The scene node the visual meshes are attached to.
Ogre::SceneNode * getOtherNode()
Ogre::MaterialPtr getMaterialForLink(const urdf::LinkConstSharedPtr &link, const std::string material_name="")
RobotLinkSelectionHandlerPtr selection_handler_
void expandDetails(bool expand)
virtual bool setValue(const QVariant &new_value)
Set the new value for this property. Returns true if the new value is different from the old value...
A single element of a property tree, with a name, value, description, and possibly children...
virtual float getFloat() const
Ogre::MaterialPtr default_material_
std::vector< Ogre::Entity * > visual_meshes_
The entities representing the visual mesh of this link (if they exist)
float robot_alpha_
Alpha value from top-level robot alpha Property (set via setRobotAlpha()).
virtual void setReadOnly(bool read_only)
Overridden from Property to propagate read-only-ness to children.
Ogre::MeshPtr loadMeshFromResource(const std::string &resource_path)
Property specialized to enforce floating point max/min.
virtual void setDescription(const QString &description)
Set the description.
std::string name_
Name of this link.
bool isCollisionVisible()
Returns whether or not the collision representation is set to be visible To be visible this and isVis...
void calculateJointCheckboxes()
virtual int numChildren() const
Return the number of child objects (Property or otherwise).
void useDetailProperty(bool use_detail)
void setToErrorMaterial()
virtual void setPosition(const Ogre::Vector3 &position)
Set the position of this object.
Property * takeChild(Property *child)
Remove a given child object and return a pointer to it.
virtual void collapse()
Collapse (hide the children of) this Property.
Ogre::SceneNode * getCollisionNode()
virtual void setTransforms(const Ogre::Vector3 &visual_position, const Ogre::Quaternion &visual_orientation, const Ogre::Vector3 &collision_position, const Ogre::Quaternion &collision_orientation)
FloatProperty * alpha_property_
virtual void setIcon(const QIcon &icon)
Set the icon to be displayed next to the property.
void setColor(float red, float green, float blue)
void createEntityForGeometryElement(const urdf::LinkConstSharedPtr &link, const urdf::Geometry &geom, const urdf::Pose &origin, const std::string material_name, Ogre::SceneNode *scene_node, Ogre::Entity *&entity)
const std::string & getName() const
virtual void hideSubProperties(bool hide)
std::string parent_joint_name_
Pure-virtual base class for objects which give Display subclasses context in which to work...
QuaternionProperty * orientation_property_
Property * childAt(int index) const
Return the child Property with the given index, or NULL if the index is out of bounds or if the child...
friend class RobotLinkSelectionHandler
boost::shared_array< uint8_t > data
Ogre::MaterialPtr color_material_
Property * trail_property_
virtual void updateProperties()
Override to update property values.
void setRenderQueueGroup(Ogre::uint8 group)
Ogre::SceneNode * collision_node_
The scene node the collision meshes are attached to.
DisplayContext * context_
bool isVisible()
Returns whether anything is visible.
M_SubEntityToMaterial materials_
virtual void setReadOnly(bool read_only)
Overridden from Property to propagate read-only-ness to children.
Property * axes_property_
virtual bool setQuaternion(const Ogre::Quaternion &quaternion)
DisplayContext * context_
float material_alpha_
If material is not a texture, this saves the alpha value set in the URDF, otherwise is 1...
void createVisual(const urdf::LinkConstSharedPtr &link)
VectorProperty * position_property_
An object that displays a set of X/Y/Z axes, with X=Red, Y=Green, Z=Blue.
std::vector< Ogre::Entity * > collision_meshes_
The entities representing the collision mesh of this link (if they exist)
Ogre::SceneNode * getVisualNode()
Contains any data we need from a link in the robot.
MemoryResource get(const std::string &url)
Ogre::Quaternion getOrientation()
void setToNormalMaterial()
virtual void setHidden(bool hidden)
Hide or show this property in any PropertyTreeWidget viewing its parent.
virtual Ogre::Vector3 getVector() const
RobotLink(Robot *robot, const urdf::LinkConstSharedPtr &link, const std::string &parent_joint_name, bool visual, bool collision)
virtual void setRobotAlpha(float a)
void setOnlyRenderDepth(bool onlyRenderDepth)
std::string default_material_name_
virtual void addChild(Property *child, int index=-1)
Add a child property.
virtual ~RobotLinkSelectionHandler()
Property * link_property_
QList< Property * > properties_
virtual QVariant getValue() const
Return the value of this Property as a QVariant. If the value has never been set, an invalid QVariant...
RobotLinkSelectionHandler(RobotLink *link, DisplayContext *context)
virtual void setOrientation(const Ogre::Quaternion &orientation)
Set the orientation of the object.
void hide()
Hide this Property in any PropertyTreeWidgets.
Ogre::SceneNode * getSceneNode()
Get the scene node associated with this object.
Ogre::RibbonTrail * trail_
QPixmap loadPixmap(QString url, bool fill_cache)
bool isVisualVisible()
Returns whether or not the visual representation is set to be visible To be visible this and isVisibl...
QuaternionProperty * orientation_property_
virtual void preRenderPass(uint32_t pass)
Ogre::SceneManager * scene_manager_
void setParentProperty(Property *new_parent)