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" 104 new Property(
"Link " + QString::fromStdString(
link_->
getName()), QVariant(),
"", parent_property);
154 static std::map<const RobotLink*, std::string>
errors;
157 const urdf::LinkConstSharedPtr& link,
158 const std::string& parent_joint_name,
162 , scene_manager_(robot->getDisplayContext()->getSceneManager())
163 ,
context_(robot->getDisplayContext())
165 , parent_joint_name_(parent_joint_name)
166 , visual_node_(nullptr)
167 , collision_node_(nullptr)
170 , material_alpha_(1.0)
172 , only_render_depth_(false)
173 , is_selectable_(true)
174 , material_mode_flags_(ORIGINAL)
185 new Property(
"Show Trail",
false,
"Enable/disable a 2 meter \"ribbon\" which follows this link.",
193 "Position of this link, in the current Fixed Frame. (Not editable)",
199 "Orientation of this link, in the current Fixed Frame. (Not editable)",
210 Ogre::MaterialPtr(
new Ogre::Material(
nullptr,
"robot link color material", 0,
ROS_PACKAGE_NAME));
226 if (collision || visual)
232 std::stringstream desc;
235 desc <<
"Root Link <b>" <<
name_ <<
"</b>";
239 desc <<
"Link <b>" <<
name_ <<
"</b>";
243 if (link->child_joints.empty())
245 desc <<
" has no children.";
249 desc <<
" has " << link->child_joints.size();
251 if (link->child_joints.size() > 1)
253 desc <<
" child joints: ";
257 desc <<
" child joint: ";
260 std::vector<urdf::JointSharedPtr>::const_iterator child_it = link->child_joints.begin();
261 std::vector<urdf::JointSharedPtr>::const_iterator child_end = link->child_joints.end();
262 for (; child_it != child_end; ++child_it)
264 urdf::Joint* child_joint = child_it->get();
265 if (child_joint && !child_joint->name.empty())
268 desc <<
"<b>" << child_joint->name <<
"</b>" << ((child_it + 1 == child_end) ?
"." :
", ");
274 desc <<
" Check/uncheck to show/hide this link in the display.";
277 desc <<
" This link has collision geometry but no visible geometry.";
281 desc <<
" This link has visible geometry but no collision geometry.";
286 desc <<
" This link has NO geometry.";
329 va_start(args, format);
330 vsnprintf(buffer,
sizeof(buffer), format, args);
364 Ogre::SceneNode::ChildNodeIterator child_it =
visual_node_->getChildIterator();
365 while (child_it.hasMoreElements())
367 Ogre::SceneNode* child =
dynamic_cast<Ogre::SceneNode*
>(child_it.getNext());
370 Ogre::SceneNode::ObjectIterator object_it = child->getAttachedObjectIterator();
371 while (object_it.hasMoreElements())
373 Ogre::MovableObject* obj = object_it.getNext();
374 obj->setRenderQueueGroup(group);
382 setRenderQueueGroup(onlyRenderDepth ? Ogre::RENDER_QUEUE_BACKGROUND : Ogre::RENDER_QUEUE_MAIN);
390 M_SubEntityToMaterial::iterator it =
materials_.begin();
391 M_SubEntityToMaterial::iterator end =
materials_.end();
392 for (; it != end; ++it)
394 const Ogre::MaterialPtr& material = it->second;
398 material->setColourWriteEnabled(
false);
399 material->setDepthWriteEnabled(
true);
403 Ogre::ColourValue color = material->getTechnique(0)->getPass(0)->getDiffuse();
405 material->setDiffuse(color);
407 if (color.a < 0.9998)
409 material->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
410 material->setDepthWriteEnabled(
false);
414 material->setSceneBlending(Ogre::SBT_REPLACE);
415 material->setDepthWriteEnabled(
true);
420 Ogre::ColourValue color =
color_material_->getTechnique(0)->getPass(0)->getDiffuse();
424 if (color.a < 0.9998)
461 urdf::MaterialConstSharedPtr material)
463 Ogre::MaterialPtr mat =
464 Ogre::MaterialPtr(
new Ogre::Material(
nullptr,
"robot link material", 0,
ROS_PACKAGE_NAME));
468 if (material && !material->name.empty())
470 for (
const auto& visual : link->visual_array)
472 if (visual->material_name == material->name)
474 material = visual->material;
479 if (!material && link->visual && link->visual->material)
480 material = link->visual->material;
485 *mat = *Ogre::MaterialManager::getSingleton().getByName(
"RVIZ/ShadedRed");
489 mat->getTechnique(0)->setLightingEnabled(
true);
490 if (material->texture_filename.empty())
492 const urdf::Color& col = material->color;
493 mat->getTechnique(0)->setAmbient(col.r * 0.5, col.g * 0.5, col.b * 0.5);
494 mat->getTechnique(0)->setDiffuse(col.r, col.g, col.b, col.a);
500 std::string
filename = material->texture_filename;
501 if (!Ogre::TextureManager::getSingleton().resourceExists(filename))
507 res = retriever.
get(filename);
516 Ogre::DataStreamPtr stream(
new Ogre::MemoryDataStream(res.
data.get(), res.
size));
518 std::string extension = fs::extension(fs::path(filename));
520 if (extension[0] ==
'.')
522 extension = extension.substr(1, extension.size() - 1);
527 image.load(stream, extension);
528 Ogre::TextureManager::getSingleton().loadImage(
529 filename, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, image);
531 catch (Ogre::Exception& e)
533 ROS_ERROR(
"Could not load texture [%s]: %s", filename.c_str(), e.what());
538 Ogre::Pass* pass = mat->getTechnique(0)->getPass(0);
539 Ogre::TextureUnitState* tex_unit = pass->createTextureUnitState();
541 tex_unit->setTextureName(filename);
548 const urdf::Geometry& geom,
549 const urdf::MaterialSharedPtr& material,
550 const urdf::Pose& origin,
551 Ogre::SceneNode* scene_node,
552 Ogre::Entity*& entity)
555 Ogre::SceneNode* offset_node = scene_node->createChildSceneNode();
557 static unsigned count = 0;
558 std::stringstream ss;
559 ss <<
"Robot Link" << ++count;
560 std::string entity_name = ss.str();
562 Ogre::Vector3 scale(Ogre::Vector3::UNIT_SCALE);
564 Ogre::Vector3 offset_position(Ogre::Vector3::ZERO);
565 Ogre::Quaternion offset_orientation(Ogre::Quaternion::IDENTITY);
569 Ogre::Vector3 position(origin.position.x, origin.position.y, origin.position.z);
570 Ogre::Quaternion orientation(Ogre::Quaternion::IDENTITY);
571 orientation = orientation * Ogre::Quaternion(origin.rotation.w, origin.rotation.x, origin.rotation.y,
574 offset_position = position;
575 offset_orientation = orientation;
580 case urdf::Geometry::SPHERE:
582 const urdf::Sphere& sphere =
static_cast<const urdf::Sphere&
>(geom);
585 scale = Ogre::Vector3(sphere.radius * 2, sphere.radius * 2, sphere.radius * 2);
588 case urdf::Geometry::BOX:
590 const urdf::Box& box =
static_cast<const urdf::Box&
>(geom);
593 scale = Ogre::Vector3(box.dim.x, box.dim.y, box.dim.z);
597 case urdf::Geometry::CYLINDER:
599 const urdf::Cylinder& cylinder =
static_cast<const urdf::Cylinder&
>(geom);
601 Ogre::Quaternion rotX;
602 rotX.FromAngleAxis(Ogre::Degree(90), Ogre::Vector3::UNIT_X);
603 offset_orientation = offset_orientation * rotX;
606 scale = Ogre::Vector3(cylinder.radius * 2, cylinder.length, cylinder.radius * 2);
609 case urdf::Geometry::MESH:
611 const urdf::Mesh& mesh =
static_cast<const urdf::Mesh&
>(geom);
613 if (mesh.filename.empty())
617 scale = Ogre::Vector3(mesh.scale.x, mesh.scale.y, mesh.scale.z);
619 const std::string& model_name = mesh.filename;
624 addError(
"Could not load mesh resource '%s'", model_name.c_str());
628 catch (Ogre::InvalidParametersException& e)
630 addError(
"Could not convert mesh resource '%s': %s", model_name.c_str(), e.what());
632 catch (Ogre::Exception& e)
634 addError(
"Could not load model '%s': %s", model_name.c_str(), e.what());
639 ROS_WARN(
"Unsupported geometry type for element: %d", geom.type);
645 offset_node->attachObject(entity);
646 offset_node->setScale(scale);
647 offset_node->setPosition(offset_position);
648 offset_node->setOrientation(offset_orientation);
656 for (uint32_t i = 0; i < entity->getNumSubEntities(); ++i)
659 Ogre::SubEntity* sub = entity->getSubEntity(i);
660 const std::string& material_name = sub->getMaterialName();
662 if (material_name ==
"BaseWhite" || material_name ==
"BaseWhiteNoLighting")
669 Ogre::MaterialPtr mat =
670 Ogre::MaterialPtr(
new Ogre::Material(
nullptr, material_name, 0,
ROS_PACKAGE_NAME));
671 *mat = *sub->getMaterial();
672 sub->setMaterial(mat);
681 bool valid_collision_found =
false;
682 #if URDF_MAJOR_VERSION == 0 && URDF_MINOR_VERSION == 2 683 std::map<std::string, boost::shared_ptr<std::vector<urdf::CollisionSharedPtr> > >::const_iterator mi;
684 for (mi = link->collision_groups.begin(); mi != link->collision_groups.end(); mi++)
688 std::vector<urdf::CollisionSharedPtr>::const_iterator vi;
689 for (vi = mi->second->begin(); vi != mi->second->end(); vi++)
691 urdf::CollisionSharedPtr collision = *vi;
692 if (collision && collision->geometry)
694 Ogre::Entity* collision_mesh =
NULL;
700 valid_collision_found =
true;
707 std::vector<urdf::CollisionSharedPtr>::const_iterator vi;
708 for (vi = link->collision_array.begin(); vi != link->collision_array.end(); vi++)
710 urdf::CollisionSharedPtr collision = *vi;
711 if (collision && collision->geometry)
713 Ogre::Entity* collision_mesh =
nullptr;
720 valid_collision_found |= collision == link->collision;
725 if (!valid_collision_found && link->collision && link->collision->geometry)
727 Ogre::Entity* collision_mesh =
nullptr;
741 bool valid_visual_found =
false;
742 #if URDF_MAJOR_VERSION == 0 && URDF_MINOR_VERSION == 2 743 std::map<std::string, boost::shared_ptr<std::vector<urdf::VisualSharedPtr> > >::const_iterator mi;
744 for (mi = link->visual_groups.begin(); mi != link->visual_groups.end(); mi++)
748 std::vector<urdf::VisualSharedPtr>::const_iterator vi;
749 for (vi = mi->second->begin(); vi != mi->second->end(); vi++)
751 urdf::VisualSharedPtr visual = *vi;
752 if (visual && visual->geometry)
754 Ogre::Entity* visual_mesh =
NULL;
760 valid_visual_found =
true;
767 std::vector<urdf::VisualSharedPtr>::const_iterator vi;
768 for (vi = link->visual_array.begin(); vi != link->visual_array.end(); vi++)
770 urdf::VisualSharedPtr visual = *vi;
771 if (visual && visual->geometry)
773 Ogre::Entity* visual_mesh =
nullptr;
780 valid_visual_found |= visual == link->visual;
785 if (!valid_visual_found && link->visual && link->visual->geometry)
787 Ogre::Entity* visual_mesh =
nullptr;
820 static int count = 0;
821 std::stringstream ss;
822 ss <<
"Trail for link " <<
name_ << count++;
824 trail_->setMaxChainElements(100);
825 trail_->setInitialWidth(0, 0.01
f);
826 trail_->setInitialColour(0, 0.0
f, 0.5
f, 0.5
f);
834 ROS_WARN(
"No visual node for link %s, cannot create a trail",
name_.c_str());
854 static int count = 0;
855 std::stringstream ss;
856 ss <<
"Axes for link " <<
name_ << count++;
875 const Ogre::Quaternion& visual_orientation,
876 const Ogre::Vector3& collision_position,
877 const Ogre::Quaternion& collision_orientation)
921 item.first->setMaterial(item.second);
925 auto error_material = Ogre::MaterialManager::getSingleton().getByName(
926 "BaseWhiteNoLighting", Ogre::ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME);
930 mesh->setMaterial(material);
932 mesh->setMaterial(material);
937 Ogre::ColourValue color =
color_material_->getTechnique(0)->getPass(0)->getDiffuse();
void updateVisibility()
Update the visibility of the link elements: visual mesh, collision mesh, trail, and axes...
void setOrientation(const Ogre::Quaternion &orientation) override
Set the orientation of the object.
VectorProperty * position_property_
void updateProperties() override
Override to update property values.
std::vector< std::string > child_joint_names_
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)
void createCollision(const urdf::LinkConstSharedPtr &link)
Ogre::SceneNode * visual_node_
The scene node the visual meshes are attached to.
Ogre::SceneNode * getOtherNode()
Property * getParent() const
Return the parent Property.
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...
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
Ogre::MaterialPtr default_material_
unsigned char material_mode_flags_
virtual Ogre::Vector3 getVector() const
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()).
Ogre::MeshPtr loadMeshFromResource(const std::string &resource_path)
Property specialized to enforce floating point max/min.
void setReadOnly(bool read_only) override
Overridden from Property to propagate read-only-ness to children.
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()
Ogre::MaterialPtr getMaterialForLink(const urdf::LinkConstSharedPtr &link, urdf::MaterialConstSharedPtr material)
const std::string & getGeometryErrors() const
void createProperties(const Picked &obj, Property *parent_property) override
Override to create properties of the given picked object(s).
void useDetailProperty(bool use_detail)
void createEntityForGeometryElement(const urdf::LinkConstSharedPtr &link, const urdf::Geometry &geom, const urdf::MaterialSharedPtr &material, const urdf::Pose &origin, Ogre::SceneNode *scene_node, Ogre::Entity *&entity)
void setToErrorMaterial()
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 setMaterialMode(unsigned char mode_flags)
void setColor(float red, float green, float blue)
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_
friend class RobotLinkSelectionHandler
boost::shared_array< uint8_t > data
Ogre::MaterialPtr color_material_
Property * trail_property_
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_
Property * axes_property_
virtual bool setQuaternion(const Ogre::Quaternion &quaternion)
DisplayContext * context_
void createVisual(const urdf::LinkConstSharedPtr &link)
VectorProperty * position_property_
void addError(const char *format,...)
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()
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
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 int numChildren() const
Return the number of child objects (Property or otherwise).
RobotLink(Robot *robot, const urdf::LinkConstSharedPtr &link, const std::string &parent_joint_name, bool visual, bool collision)
virtual void setRobotAlpha(float a)
const std::string & getName() const
void setOnlyRenderDepth(bool onlyRenderDepth)
virtual float getFloat() const
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...
virtual void addChild(Property *child, int index=-1)
Add a child property.
Property * link_property_
QList< Property * > properties_
void preRenderPass(uint32_t pass) override
RobotLinkSelectionHandler(RobotLink *link, DisplayContext *context)
static std::map< const RobotLink *, std::string > errors
void postRenderPass(uint32_t pass) override
void hide()
Hide this Property in any PropertyTreeWidgets.
virtual QVariant getValue() const
Return the value of this Property as a QVariant. If the value has never been set, an invalid QVariant...
~RobotLinkSelectionHandler() override
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...
virtual Ogre::Quaternion getQuaternion() const
QuaternionProperty * orientation_property_
Ogre::SceneManager * scene_manager_
void setParentProperty(Property *new_parent)