5 #include "pinocchio/parsers/urdf.hpp" 6 #include "pinocchio/parsers/urdf/types.hpp" 7 #include "pinocchio/parsers/utils.hpp" 9 #include <boost/property_tree/xml_parser.hpp> 10 #include <boost/property_tree/ptree.hpp> 12 #include <urdf_model/model.h> 13 #include <urdf_parser/urdf_parser.h> 24 typedef boost::property_tree::ptree ptree;
25 typedef std::map<std::string, const ptree&> LinkMap_t;
27 void parse (
const std::string & xmlStr)
29 urdf_ = ::urdf::parseURDF(xmlStr);
31 throw std::invalid_argument (
"Enable to parse URDF");
34 std::istringstream iss(xmlStr);
35 using namespace boost::property_tree;
36 read_xml(iss, tree_, xml_parser::no_comments);
38 BOOST_FOREACH(
const ptree::value_type & link, tree_.get_child(
"robot")) {
39 if (link.first ==
"link") {
40 std::string
name = link.second.get<std::string>(
"<xmlattr>.name");
41 links_.insert(std::pair<std::string,const ptree&>(name, link.second));
46 bool isCapsule (
const std::string & linkName,
47 const std::string & geomName)
const 49 LinkMap_t::const_iterator _link = links_.find(linkName);
50 assert (_link != links_.end());
51 const ptree& link = _link->second;
52 if (link.count (
"collision_checking") == 0)
54 BOOST_FOREACH(
const ptree::value_type & cc, link.get_child(
"collision_checking")) {
55 if (cc.first ==
"capsule") {
56 #ifdef PINOCCHIO_URDFDOM_COLLISION_WITH_GROUP_NAME 57 std::cerr <<
"Warning: support for tag link/collision_checking/capsule" 58 " is not available for URDFDOM < 0.3.0" << std::endl;
60 std::string
name = cc.second.get<std::string>(
"<xmlattr>.name");
61 if (geomName == name)
return true;
69 bool isMeshConvex (
const std::string & linkName,
70 const std::string & geomName)
const 72 LinkMap_t::const_iterator _link = links_.find(linkName);
73 assert (_link != links_.end());
74 const ptree& link = _link->second;
75 if (link.count (
"collision_checking") == 0)
77 BOOST_FOREACH(
const ptree::value_type & cc, link.get_child(
"collision_checking")) {
78 if (cc.first ==
"convex") {
79 #ifdef PINOCCHIO_URDFDOM_COLLISION_WITH_GROUP_NAME 80 std::cerr <<
"Warning: support for tag link/collision_checking/convex" 81 " is not available for URDFDOM < 0.3.0" << std::endl;
83 std::string
name = cc.second.get<std::string>(
"<xmlattr>.name");
84 if (geomName == name)
return true;
93 ::urdf::ModelInterfaceSharedPtr urdf_;
109 const ::urdf::Vector3 & p = M.position;
110 const ::urdf::Rotation & q = M.rotation;
111 return SE3( Eigen::Quaterniond(q.w,q.x,q.y,q.z).matrix(), Eigen::Vector3d(p.x,p.y,p.z));
114 template<
typename Vector3>
115 static void retrieveMeshScale(const ::urdf::MeshSharedPtr & mesh,
116 const Eigen::MatrixBase<Vector3> & scale)
118 Vector3 & scale_ = PINOCCHIO_EIGEN_CONST_CAST(Vector3,scale);
125 #ifdef PINOCCHIO_WITH_HPP_FCL 126 # if ( HPP_FCL_MAJOR_VERSION>1 || ( HPP_FCL_MAJOR_VERSION==1 && \ 127 ( HPP_FCL_MINOR_VERSION>1 || ( HPP_FCL_MINOR_VERSION==1 && \ 128 HPP_FCL_PATCH_VERSION>3)))) 129 # define PINOCCHIO_HPP_FCL_SUPERIOR_TO_1_1_3 143 boost::shared_ptr<fcl::CollisionGeometry>
145 fcl::MeshLoaderPtr& meshLoader,
146 const std::string& linkName,
147 const std::string& geomName,
148 const ::urdf::GeometrySharedPtr urdf_geometry,
149 const std::vector<std::string> & package_dirs,
150 std::string & meshPath,
151 Eigen::Vector3d & meshScale)
153 boost::shared_ptr<fcl::CollisionGeometry> geometry;
156 if (urdf_geometry->type == ::urdf::Geometry::MESH)
158 const ::urdf::MeshSharedPtr urdf_mesh = ::urdf::dynamic_pointer_cast< ::urdf::Mesh> (urdf_geometry);
159 std::string collisionFilename = urdf_mesh->filename;
162 if (meshPath ==
"") {
163 std::stringstream ss;
164 ss <<
"Mesh " << collisionFilename <<
" could not be found.";
165 throw std::invalid_argument (ss.str());
168 fcl::Vec3f scale = fcl::Vec3f(urdf_mesh->scale.x,
173 retrieveMeshScale(urdf_mesh, meshScale);
176 #ifdef PINOCCHIO_HPP_FCL_SUPERIOR_TO_1_1_3 177 hpp::fcl::BVHModelPtr_t bvh = meshLoader->load (meshPath, scale);
178 bool convex = tree.isMeshConvex (linkName, geomName);
180 bvh->buildConvexRepresentation (
false);
181 geometry = bvh->convex;
185 geometry = meshLoader->load (meshPath, scale);
191 else if (urdf_geometry->type == ::urdf::Geometry::CYLINDER)
193 const bool is_capsule = tree.isCapsule(linkName, geomName);
195 const ::urdf::CylinderSharedPtr collisionGeometry = ::urdf::dynamic_pointer_cast< ::urdf::Cylinder> (urdf_geometry);
197 double radius = collisionGeometry->radius;
198 double length = collisionGeometry->length;
202 meshPath =
"CAPSULE";
203 geometry = boost::shared_ptr < fcl::CollisionGeometry >(
new fcl::Capsule (radius, length));
205 meshPath =
"CYLINDER";
206 geometry = boost::shared_ptr < fcl::CollisionGeometry >(
new fcl::Cylinder (radius, length));
210 else if (urdf_geometry->type == ::urdf::Geometry::BOX)
214 const ::urdf::BoxSharedPtr collisionGeometry = ::urdf::dynamic_pointer_cast< ::urdf::Box> (urdf_geometry);
216 double x = collisionGeometry->dim.x;
217 double y = collisionGeometry->dim.y;
218 double z = collisionGeometry->dim.z;
220 geometry = boost::shared_ptr < fcl::CollisionGeometry > (
new fcl::Box (x, y, z));
223 else if (urdf_geometry->type == ::urdf::Geometry::SPHERE)
227 const ::urdf::SphereSharedPtr collisionGeometry = ::urdf::dynamic_pointer_cast< ::urdf::Sphere> (urdf_geometry);
229 double radius = collisionGeometry->radius;
231 geometry = boost::shared_ptr < fcl::CollisionGeometry > (
new fcl::Sphere (radius));
233 else throw std::invalid_argument(
"Unknown geometry type :");
237 throw std::invalid_argument(
"The polyhedron retrived is empty");
242 #endif // PINOCCHIO_WITH_HPP_FCL 252 inline PINOCCHIO_URDF_SHARED_PTR(
const T)
253 getLinkGeometry(const ::urdf::LinkConstSharedPtr link);
256 inline ::urdf::CollisionConstSharedPtr
257 getLinkGeometry< ::urdf::Collision>(const ::urdf::LinkConstSharedPtr link)
259 return link->collision;
263 inline ::urdf::VisualConstSharedPtr
264 getLinkGeometry< ::urdf::Visual>(const ::urdf::LinkConstSharedPtr link)
279 template<
typename urdfObject>
280 inline bool getVisualMaterial(
const PINOCCHIO_URDF_SHARED_PTR(urdfObject) urdf_object,std::string & meshTexturePath,
281 Eigen::Vector4d & meshColor,
const std::vector<std::string> & package_dirs);
284 inline bool getVisualMaterial< ::urdf::Collision>
285 (const ::urdf::CollisionSharedPtr, std::string& meshTexturePath,
286 Eigen::Vector4d & meshColor,
const std::vector<std::string> &)
288 meshColor << 0.9, 0.9, 0.9, 1.;
289 meshTexturePath =
"";
294 inline bool getVisualMaterial< ::urdf::Visual>
295 (const ::urdf::VisualSharedPtr urdf_visual, std::string& meshTexturePath,
296 Eigen::Vector4d & meshColor,
const std::vector<std::string> & package_dirs)
299 meshTexturePath =
"";
300 bool overrideMaterial =
false;
301 if(urdf_visual->material) {
302 overrideMaterial =
true;
303 meshColor << urdf_visual->material->color.r, urdf_visual->material->color.g,
304 urdf_visual->material->color.b, urdf_visual->material->color.a;
305 if(urdf_visual->material->texture_filename!=
"")
306 meshTexturePath =
retrieveResourcePath((urdf_visual)->material->texture_filename, package_dirs);
308 return overrideMaterial;
319 inline const std::vector< PINOCCHIO_URDF_SHARED_PTR(T) > &
323 inline const std::vector< ::urdf::CollisionSharedPtr> &
324 getLinkGeometryArray< ::urdf::Collision>(const ::urdf::LinkConstSharedPtr link)
326 return link->collision_array;
330 inline const std::vector< ::urdf::VisualSharedPtr> &
331 getLinkGeometryArray< ::urdf::Visual>(const ::urdf::LinkConstSharedPtr link)
333 return link->visual_array;
348 template<
typename GeometryType>
350 ::hpp::fcl::MeshLoaderPtr & meshLoader,
351 ::urdf::LinkConstSharedPtr link,
352 UrdfGeomVisitorBase& visitor,
354 const std::vector<std::string> & package_dirs)
356 #ifndef PINOCCHIO_WITH_HPP_FCL 357 PINOCCHIO_UNUSED_VARIABLE(tree);
358 PINOCCHIO_UNUSED_VARIABLE(meshLoader);
359 #endif // PINOCCHIO_WITH_HPP_FCL 361 typedef std::vector< PINOCCHIO_URDF_SHARED_PTR(GeometryType) > VectorSharedT;
364 if(getLinkGeometry<GeometryType>(link))
366 std::string meshPath =
"";
368 Eigen::Vector3d meshScale(Eigen::Vector3d::Ones());
370 const std::string & link_name = link->name;
372 VectorSharedT geometries_array = getLinkGeometryArray<GeometryType>(link);
375 UrdfGeomVisitorBase::Frame frame = visitor.getBodyFrame (link_name, frame_id);
376 SE3 body_placement = frame.placement;
378 std::size_t objectId = 0;
379 for (
typename VectorSharedT::const_iterator i = geometries_array.begin();i != geometries_array.end(); ++i)
382 #ifdef PINOCCHIO_WITH_HPP_FCL 384 #ifdef PINOCCHIO_URDFDOM_COLLISION_WITH_GROUP_NAME 385 const std::string & geom_name = (*i)->group_name;
387 const std::string & geom_name = (*i)->name;
388 #endif // PINOCCHIO_URDFDOM_COLLISION_WITH_GROUP_NAME 389 const GeometryObject::CollisionGeometryPtr geometry =
391 (*i)->geometry, package_dirs, meshPath, meshScale);
393 ::urdf::MeshSharedPtr urdf_mesh = ::urdf::dynamic_pointer_cast< ::urdf::Mesh> ((*i)->geometry);
397 retrieveMeshScale(urdf_mesh, meshScale);
400 const boost::shared_ptr<fcl::CollisionGeometry> geometry(
new fcl::CollisionGeometry());
401 #endif // PINOCCHIO_WITH_HPP_FCL 403 Eigen::Vector4d meshColor;
404 std::string meshTexturePath;
405 bool overrideMaterial = getVisualMaterial<GeometryType>((*i), meshTexturePath, meshColor, package_dirs);
408 std::ostringstream geometry_object_suffix;
409 geometry_object_suffix <<
"_" << objectId;
410 const std::string & geometry_object_name = std::string(link_name + geometry_object_suffix.str());
412 frame_id, frame.parent,
414 geomPlacement, meshPath, meshScale,
415 overrideMaterial, meshColor, meshTexturePath);
436 ::hpp::fcl::MeshLoaderPtr& meshLoader,
437 ::urdf::LinkConstSharedPtr link,
438 UrdfGeomVisitorBase& visitor,
440 const std::vector<std::string> & package_dirs,
441 const GeometryType type)
447 addLinkGeometryToGeomModel< ::urdf::Collision >(tree, meshLoader, link, visitor, geomModel, package_dirs);
450 addLinkGeometryToGeomModel< ::urdf::Visual >(tree, meshLoader, link, visitor, geomModel, package_dirs);
456 BOOST_FOREACH(::urdf::LinkConstSharedPtr child,link->child_links)
463 void parseTreeForGeom(UrdfGeomVisitorBase& visitor,
464 const std::istream& xmlStream,
465 const GeometryType type,
467 const std::vector<std::string> & package_dirs,
468 ::hpp::fcl::MeshLoaderPtr meshLoader)
472 std::ostringstream os;
473 os << xmlStream.rdbuf();
480 std::vector<std::string> hint_directories(package_dirs);
483 std::vector<std::string> ros_pkg_paths =
rosPaths();
484 hint_directories.insert(hint_directories.end(), ros_pkg_paths.begin(), ros_pkg_paths.end());
486 #ifdef PINOCCHIO_WITH_HPP_FCL 487 if (!meshLoader) meshLoader = fcl::MeshLoaderPtr(
new fcl::MeshLoader);
488 #endif // ifdef PINOCCHIO_WITH_HPP_FCL 491 visitor, geomModel, hint_directories,type);
void recursiveParseTreeForGeom(const UrdfTree &tree, ::hpp::fcl::MeshLoaderPtr &meshLoader, ::urdf::LinkConstSharedPtr link, UrdfGeomVisitorBase &visitor, GeometryModel &geomModel, const std::vector< std::string > &package_dirs, const GeometryType type)
Recursive procedure for reading the URDF tree, looking for geometries This function fill the geometri...
GeomIndex addGeometryObject(const GeometryObject &object, const ModelTpl< S2, O2, _JointCollectionTpl > &model)
Add a geometry object to a GeometryModel and set its parent joint.
SE3 convertFromUrdf(const ::urdf::Pose &M)
Convert URDF Pose quantity to SE3.
std::string name(const LieGroupGenericTpl< LieGroupCollection > &lg)
Visit a LieGroupVariant to get the name of it.
boost::shared_ptr< fcl::CollisionGeometry > retrieveCollisionGeometry(const UrdfTree &tree, fcl::MeshLoaderPtr &meshLoader, const std::string &linkName, const std::string &geomName, const ::urdf::GeometrySharedPtr urdf_geometry, const std::vector< std::string > &package_dirs, std::string &meshPath, Eigen::Vector3d &meshScale)
Get a fcl::CollisionObject from an urdf geometry, searching for it in specified package directories...
std::vector< std::string > rosPaths()
Parse the environment variable ROS_PACKAGE_PATH and extract paths.
Main pinocchio namespace.
const std::vector< PINOCCHIO_URDF_SHARED_PTR(T) > & getLinkGeometryArray(const ::urdf::LinkConstSharedPtr link)
Get the array of geometries attached to a link.
std::string retrieveResourcePath(const std::string &string, const std::vector< std::string > &package_dirs)
Retrieve the path of the file whose path is given in an url-format. Currently convert from the follow...
bool getVisualMaterial(const PINOCCHIO_URDF_SHARED_PTR(urdfObject) urdf_object, std::string &meshTexturePath, Eigen::Vector4d &meshColor, const std::vector< std::string > &package_dirs)
Get the material values from the link visual object.
void addLinkGeometryToGeomModel(const UrdfTree &tree, ::hpp::fcl::MeshLoaderPtr &meshLoader, ::urdf::LinkConstSharedPtr link, UrdfGeomVisitorBase &visitor, GeometryModel &geomModel, const std::vector< std::string > &package_dirs)
Add the geometries attached to an URDF link to a GeometryModel, looking either for collisions or visu...