The library contains parser for SRDF describing robot grippers, object handles, object and environment contact surfaces.
In order to load HRP2 from a pair of URDF and SRDF files, one can do:
#include <hpp/manipulation/device.hh> #include <hpp/manipulation/srdf/util.hh> int main (int argc, char** argv) { using hpp::manipulation::DevicePtr_t; using hpp::manipulation::Device; using hpp::manipulation::srdf::loadRobotModel; DevicePtr_t robot = Device::create ("hrp-2"); loadRobotModel (robot, "freeflyer", "hrp2_14_description", "hrp2_14", "", ""); }
<handle name="name">
<!-- Exactly 1 -->
<!-- position should contains 7 numbers, treated as a 3D vector (translation) and a quaternion (rotation) -->
<position>0 0 0 1 0 0 0</position>
<!-- the position represents the position of the handle relatively to the following link -->
<link name="link_name" />
</handle>
<gripper name="name">
<!-- Exactly 1 -->
<!-- position should contains 7 numbers, treated as a 3D vector (translation) and a quaternion (rotation) -->
<position>0 0 0 1 0 0 0</position>
<!-- the position represents the position of the gripper relatively to the following link -->
<link name="link_name" />
<!-- Any number -->
<!-- Collision can be disabled between the listed link and any handle -->
<disable_collision link="link_name" />
<disable_collision link="link_name2" />
</gripper>
<contact name="name"> <!-- Exactly 1 of --> <!-- Set the link used to build the reference frame In the first case, the contact surfaces are mobile and the following coordinates are expressed in the frame of the joint of "link_name". Use this to describe object contact surfaces. In the second case, the contact surfaces are static and the following coordinates are expressed in the frame of the object. As an object can be present in two links, a link name must be provided. If the link has only one object, the link name must still be provided. --> <link name="link_name" /> <link name="link_name" object="object_name" /> <!-- Exactly 1 --> <!-- Sequence of 3D points expressed in the frame defined above --> <point>-0.025 -0.025 -0.025 -0.025 0.025 -0.025 -0.025 -0.025 0.025 -0.025 0.025 0.025 </point> <!-- Sequence of triangles, where a triangle is 3 point indexes in the above list of points WARNING: Triangle 0 1 2 and 0 2 1 are different because their respective orientations are opposites 01 ^ 02 points outside the object --> <triangle> 0 2 1 2 1 3</triangle> </contact>
To extend the parser, you must write a class that inherits from parser::ObjectFactory. Some factories such as parser::SequenceFactory might be useful. You also have to declare the new factory to the parser:
#include <hpp/manipulation/parser/parser.hh> // See ObjectFactory documentation for more details. // This factory parses something like: // <tagname> // <position>0 0 0 1 0 0 0</position> // <link name="linkname"/> // </tagname> class YourFactory : public hpp::manipulation::parser::ObjectFactory { public: YourFactory (ObjectFactory* parent, const XMLElement* element) : ObjectFactory (parent, element) {} void YourFactory::finishTags () { ObjectFactory* o (NULL); if (!getChildOfType ("position", o)) { // There is more than one tag <position> // o is a pointer to the first one. } PositionFactory* pf = o->as <PositionFactory> (); Transform3f position = pf->position (); if (!getChildOfType ("link", o)) { // There is more than one tag <link> // o is a pointer to the first one. } std::string linkName = root ()->prependPrefix (o->name ()); if (!root ()->device ()) { hppDout (error, "Device not found"); return; } root ()->device ()->yourfunction (linkName, position); } }; int main (int argc, char** argv) { // Parameter false tells the constructor not to include default factories. hpp::manipulation::parser::Parser p (false); p.addObjectFactory ("tagname", hpp::manipulation::parser::create <YourFactory>); }