19 #include "pinocchio/math/matrix.hpp" 20 #include "pinocchio/parsers/urdf.hpp" 21 #include "pinocchio/parsers/urdf/utils.hpp" 22 #include "pinocchio/multibody/model.hpp" 24 #include <urdf_model/model.h> 25 #include <urdf_parser/urdf_parser.h> 28 #include <boost/foreach.hpp> 38 const double infty = std::numeric_limits<double>::infinity();
40 FrameIndex getParentJointFrame(const ::urdf::LinkConstSharedPtr link,
const Model & model)
42 assert(link && link->getParent());
45 if (!link->getParent()->parent_joint) {
46 if (model.existFrame(
"root_joint", JOINT_OR_FIXED_JOINT))
47 id = model.getFrameId (
"root_joint", JOINT_OR_FIXED_JOINT);
51 if (model.existFrame(link->getParent()->parent_joint->name, JOINT_OR_FIXED_JOINT))
52 id = model.getFrameId (link->getParent()->parent_joint->name, JOINT_OR_FIXED_JOINT);
54 throw std::invalid_argument (
"Model does not have any joints named " 55 + link->getParent()->parent_joint->name);
58 const Frame & f = model.frames[
id];
59 if (f.type == JOINT || f.type == FIXED_JOINT)
61 throw std::invalid_argument (
"Parent frame is not a JOINT neither a FIXED_JOINT");
64 void appendBodyToJoint(Model & model,
const FrameIndex fid,
65 const ::urdf::InertialConstSharedPtr Y_ptr,
66 const SE3 & placement,
67 const std::string & body_name)
69 const Frame& frame = model.frames[fid];
70 const SE3& p = frame.placement * placement;
73 && Y_ptr->mass > Eigen::NumTraits<double>::epsilon()) {
74 model.appendBodyToJoint(frame.parent, convertFromUrdf(*Y_ptr), p);
76 model.addBodyFrame(body_name, frame.parent, p, (
int)fid);
79 if (model.frames[fid].parent > 0) {
80 assert (!hasNaN(model.inertias[model.frames[fid].parent].lever())
81 && !hasNaN(model.inertias[model.frames[fid].parent].inertia().data()));
88 template<
typename Jo
intModel>
89 void addJointAndBody(Model & model,
const JointModelBase<JointModel> & jmodel,
90 const FrameIndex & parentFrameId,
91 const SE3 & joint_placement,
const std::string & joint_name,
92 const ::urdf::InertialConstSharedPtr Y,
93 const std::string & body_name,
94 const typename JointModel::TangentVector_t & max_effort = JointModel::TangentVector_t::Constant( infty),
95 const typename JointModel::TangentVector_t & max_velocity = JointModel::TangentVector_t::Constant( infty),
96 const typename JointModel::ConfigVector_t & min_config = JointModel::ConfigVector_t ::Constant(-infty),
97 const typename JointModel::ConfigVector_t & max_config = JointModel::ConfigVector_t ::Constant( infty))
99 Model::JointIndex idx;
100 const Frame & frame = model.frames[parentFrameId];
102 idx = model.addJoint(frame.parent,jmodel,
103 frame.placement * joint_placement,
105 max_effort,max_velocity,min_config,max_config
107 int res (model.addJointFrame(idx, (
int)parentFrameId));
109 std::ostringstream oss;
110 oss << joint_name <<
" already inserted as a frame. Current frames " 112 for (container::aligned_vector<Frame>::const_iterator it =
113 model.frames.begin (); it != model.frames.end (); ++it) {
114 oss <<
"\"" << it->name <<
"\",";
117 throw std::runtime_error (oss.str ().c_str ());
119 FrameIndex jointFrameId = (FrameIndex) res;
120 appendBodyToJoint(model, jointFrameId, Y, SE3::Identity(), body_name);
126 void addFixedJointAndBody(Model & model,
const FrameIndex& parentFrameId,
127 const SE3 & joint_placement,
const std::string & joint_name,
128 const ::urdf::InertialConstSharedPtr Y,
129 const std::string & body_name)
131 const Frame & frame = model.frames[parentFrameId];
133 int fid = model.addFrame(
134 Frame (joint_name, frame.parent, parentFrameId,
135 frame.placement * joint_placement, FIXED_JOINT)
138 throw std::invalid_argument (
"Fixed joint " + joint_name +
" could not be added.");
139 appendBodyToJoint(model, (FrameIndex)fid, Y, SE3::Identity(), body_name);
145 void addJointAndBody(Model & model,
147 const Model::JointIndex parent_id,
148 const SE3 & joint_placement,
const std::string & joint_name,
149 const ::urdf::InertialConstSharedPtr Y,
150 const std::string & body_name)
152 Model::JointIndex idx;
154 idx = model.addJoint(parent_id,jmodel,
155 joint_placement,joint_name);
157 appendBodyToJoint(model,idx,Y,SE3::Identity(),body_name);
167 void parseTree(::urdf::LinkConstSharedPtr link, Model & model,
bool verbose)
throw (std::invalid_argument)
171 const ::urdf::JointConstSharedPtr joint =
172 ::urdf::const_pointer_cast< ::urdf::Joint>(link->parent_joint);
176 assert(link->getParent());
178 const std::string & joint_name = joint->name;
179 const std::string & link_name = link->name;
180 const std::string & parent_link_name = link->getParent()->name;
181 std::ostringstream joint_info;
183 FrameIndex parentFrameId = getParentJointFrame(link, model);
186 const SE3 jointPlacement = convertFromUrdf(joint->parent_to_joint_origin_transform);
188 const ::urdf::InertialSharedPtr Y =
189 ::urdf::const_pointer_cast< ::urdf::Inertial>(link->inertial);
193 case ::urdf::Joint::FLOATING:
195 joint_info <<
"joint FreeFlyer";
196 addJointAndBody(model,JointModelFreeFlyer(),
197 parentFrameId,jointPlacement,joint->name,
202 case ::urdf::Joint::REVOLUTE:
204 joint_info <<
"joint REVOLUTE with axis";
206 typedef JointModelRX::ConfigVector_t ConfigVector_t;
207 typedef JointModelRX::TangentVector_t TangentVector_t;
209 TangentVector_t max_effort;
210 TangentVector_t max_velocity;
211 ConfigVector_t lower_position;
212 ConfigVector_t upper_position;
216 max_effort << joint->limits->effort;
217 max_velocity << joint->limits->velocity;
218 lower_position << joint->limits->lower;
219 upper_position << joint->limits->upper;
224 CartesianAxis axis = extractCartesianAxis(joint->axis);
230 joint_info <<
" along X";
231 addJointAndBody(model,JointModelRX(),
232 parentFrameId,jointPlacement,joint->name,
234 max_effort,max_velocity,
235 lower_position, upper_position);
240 joint_info <<
" along Y";
241 addJointAndBody(model,JointModelRY(),
242 parentFrameId,jointPlacement,joint->name,
244 max_effort,max_velocity,
245 lower_position, upper_position);
250 joint_info <<
" along Z";
251 addJointAndBody(model,JointModelRZ(),
252 parentFrameId,jointPlacement,joint->name,
254 max_effort,max_velocity,
255 lower_position, upper_position);
260 SE3::Vector3 joint_axis(SE3::Vector3::Zero());
261 joint_axis << joint->axis.x,joint->axis.y,joint->axis.z;
262 joint_info <<
" unaligned along (" << joint_axis.transpose() <<
")";
264 addJointAndBody(model,JointModelRevoluteUnaligned(joint_axis.normalized()),
265 parentFrameId,jointPlacement,joint->name,
267 max_effort,max_velocity,
268 lower_position, upper_position);
273 assert(
false &&
"The axis type of the revolute joint is of wrong type.");
279 case ::urdf::Joint::CONTINUOUS:
281 joint_info <<
"joint CONTINUOUS with axis";
283 typedef JointModelRUBX::ConfigVector_t ConfigVector_t;
284 typedef JointModelRUBX::TangentVector_t TangentVector_t;
286 TangentVector_t max_effort;
287 TangentVector_t max_velocity;
288 const ConfigVector_t::Scalar u = 1.01;
289 ConfigVector_t lower_position(-u, -u);
290 ConfigVector_t upper_position( u, u);
294 max_effort << joint->limits->effort;
295 max_velocity << joint->limits->velocity;
298 CartesianAxis axis = extractCartesianAxis(joint->axis);
304 joint_info <<
" along X";
305 addJointAndBody(model,JointModelRUBX(),
306 parentFrameId,jointPlacement,joint->name,
308 max_effort,max_velocity,
309 lower_position, upper_position);
314 joint_info <<
" along Y";
315 addJointAndBody(model,JointModelRUBY(),
316 parentFrameId,jointPlacement,joint->name,
318 max_effort,max_velocity,
319 lower_position, upper_position);
324 joint_info <<
" along Z";
325 addJointAndBody(model,JointModelRUBZ(),
326 parentFrameId,jointPlacement,joint->name,
328 max_effort,max_velocity,
329 lower_position, upper_position);
334 SE3::Vector3 joint_axis(SE3::Vector3::Zero());
335 joint_axis << joint->axis.x,joint->axis.y,joint->axis.z;
336 joint_info <<
" unaligned along (" << joint_axis.transpose() <<
")";
338 addJointAndBody(model,JointModelRevoluteUnaligned(joint_axis.normalized()),
339 parentFrameId,jointPlacement,joint->name,
341 max_effort,max_velocity);
346 assert(
false &&
"The axis type of the revolute joint is of wrong type.");
352 case ::urdf::Joint::PRISMATIC:
354 joint_info <<
"joint PRISMATIC with axis";
356 typedef JointModelRX::ConfigVector_t ConfigVector_t;
357 typedef JointModelRX::TangentVector_t TangentVector_t;
359 TangentVector_t max_effort;
360 TangentVector_t max_velocity;
361 ConfigVector_t lower_position;
362 ConfigVector_t upper_position;
366 max_effort << joint->limits->effort;
367 max_velocity << joint->limits->velocity;
368 lower_position << joint->limits->lower;
369 upper_position << joint->limits->upper;
372 CartesianAxis axis = extractCartesianAxis(joint->axis);
377 joint_info <<
" along X";
378 addJointAndBody(model,JointModelPX(),
379 parentFrameId,jointPlacement,joint->name,
381 max_effort,max_velocity,
382 lower_position, upper_position);
387 joint_info <<
" along Y";
388 addJointAndBody(model,JointModelPY(),
389 parentFrameId,jointPlacement,joint->name,
391 max_effort,max_velocity,
392 lower_position, upper_position);
397 joint_info <<
" along Z";
398 addJointAndBody(model,JointModelPZ(),
399 parentFrameId,jointPlacement,joint->name,
401 max_effort,max_velocity,
402 lower_position, upper_position);
407 SE3::Vector3 joint_axis(SE3::Vector3::Zero());
408 joint_axis << joint->axis.x,joint->axis.y,joint->axis.z;
409 joint_info <<
" unaligned along (" << joint_axis.transpose() <<
")";
411 addJointAndBody(model,JointModelPrismaticUnaligned(joint_axis.normalized()),
412 parentFrameId,jointPlacement,joint->name,
414 max_effort,max_velocity,
415 lower_position, upper_position);
420 assert(
false &&
"The axis type of the prismatic joint is of wrong type.");
426 case ::urdf::Joint::PLANAR:
428 joint_info <<
"joint PLANAR with normal axis along Z";
430 typedef JointModelPlanar::ConfigVector_t ConfigVector_t;
431 typedef JointModelPlanar::TangentVector_t TangentVector_t;
433 TangentVector_t max_effort;
434 TangentVector_t max_velocity;
435 ConfigVector_t lower_position;
436 ConfigVector_t upper_position;
440 max_effort << joint->limits->effort;
441 max_velocity << joint->limits->velocity;
442 lower_position << joint->limits->lower;
443 upper_position << joint->limits->upper;
446 addJointAndBody(model,JointModelPlanar(),
447 parentFrameId,jointPlacement,joint->name,
449 max_effort,max_velocity,
450 lower_position, upper_position);
454 case ::urdf::Joint::FIXED:
464 joint_info <<
"fixed joint";
465 addFixedJointAndBody(model, parentFrameId, jointPlacement,
466 joint_name, Y, link_name);
472 const std::string exception_message (
"The type of joint " + joint_name +
" is not supported.");
473 throw std::invalid_argument(exception_message);
480 const Inertia YY = (!Y) ? Inertia::Zero() : convertFromUrdf(*Y);
481 std::cout <<
"Adding Body" << std::endl;
482 std::cout <<
"\"" << link_name <<
"\" connected to " <<
"\"" << parent_link_name <<
"\" throw joint " <<
"\"" << joint_name <<
"\"" << std::endl;
483 std::cout <<
"joint type: " << joint_info.str() << std::endl;
484 std::cout <<
"joint placement:\n" << jointPlacement;
485 std::cout <<
"body info: " << std::endl;
486 std::cout <<
" " <<
"mass: " << YY.mass() << std::endl;
487 std::cout <<
" " <<
"lever: " << YY.lever().transpose() << std::endl;
488 std::cout <<
" " <<
"inertia elements (Ixx,Iyx,Iyy,Izx,Izy,Izz): " << YY.inertia().data().transpose() << std::endl << std::endl;
491 else if (link->getParent())
493 const std::string exception_message (link->name +
" - joint information missing.");
494 throw std::invalid_argument(exception_message);
498 BOOST_FOREACH(::urdf::LinkConstSharedPtr child, link->child_links)
500 parseTree(child, model, verbose);
512 void parseRootTree (::urdf::LinkConstSharedPtr root_link, Model & model,
const bool verbose)
throw (std::invalid_argument)
514 addFixedJointAndBody(model, 0, SE3::Identity(),
"root_joint",
515 root_link->inertial, root_link->name);
517 BOOST_FOREACH(::urdf::LinkConstSharedPtr child, root_link->child_links)
519 parseTree(child, model, verbose);
537 template <
typename D>
538 void parseRootTree (::urdf::LinkConstSharedPtr root_link, Model & model,
const JointModelBase<D> & root_joint,
const bool verbose)
throw (std::invalid_argument)
540 addJointAndBody(model,root_joint,
541 0,SE3::Identity(),
"root_joint",
542 root_link->inertial,root_link->name);
544 BOOST_FOREACH(::urdf::LinkConstSharedPtr child, root_link->child_links)
546 parseTree(child, model, verbose);
558 ::urdf::LinkConstSharedPtr m_root_link;
560 const bool m_verbose;
563 : m_root_link(root_link)
568 template<
typename Derived>
571 details::parseRootTree(m_root_link,m_model,root_joint,m_verbose);
574 static void run(::urdf::LinkConstSharedPtr root_link,
Model & model,
const JointModelVariant & root_joint,
const bool verbose)
580 Model& buildModel(
const std::string & filename,
581 const JointModelVariant & root_joint,
584 throw (std::invalid_argument)
586 ::urdf::ModelInterfaceSharedPtr urdfTree = ::urdf::parseURDFFile (filename);
590 return buildModel (urdfTree, root_joint, model, verbose);
594 const std::string exception_message (
"The file " + filename +
" does not contain a valid URDF model.");
595 throw std::invalid_argument(exception_message);
600 Model& buildModel(
const std::string & filename,
Model& model,
const bool verbose)
601 throw (std::invalid_argument)
603 ::urdf::ModelInterfaceSharedPtr urdfTree = ::urdf::parseURDFFile (filename);
606 return buildModel (urdfTree, model, verbose);
610 const std::string exception_message (
"The file " + filename +
" does not contain a valid URDF model.");
611 throw std::invalid_argument(exception_message);
617 Model & buildModelFromXML(
const std::string & xmlStream,
618 const JointModelVariant & rootJoint,
620 const bool verbose)
throw (std::invalid_argument)
622 ::urdf::ModelInterfaceSharedPtr urdfTree = ::urdf::parseURDF(xmlStream);
625 return buildModel(urdfTree, rootJoint, model, verbose);
628 const std::string exception_message (
"The XML stream does not contain a valid URDF model.");
629 throw std::invalid_argument(exception_message);
635 Model & buildModelFromXML(
const std::string & xmlStream,
637 const bool verbose)
throw (std::invalid_argument)
639 ::urdf::ModelInterfaceSharedPtr urdfTree = ::urdf::parseURDF(xmlStream);
642 return buildModel(urdfTree, model, verbose);
645 const std::string exception_message (
"The XML stream does not contain a valid URDF model.");
646 throw std::invalid_argument(exception_message);
652 Model& buildModel(const ::urdf::ModelInterfaceSharedPtr & urdfTree,
653 const JointModelVariant & root_joint,
658 model.
name = urdfTree->getName();
659 ParseRootTreeVisitor::run(urdfTree->getRoot(),model,root_joint,verbose);
663 Model& buildModel(const ::urdf::ModelInterfaceSharedPtr & urdfTree,
668 model.
name = urdfTree->getName();
669 details::parseRootTree(urdfTree->getRoot(),model,verbose);
std::string name
Model name;.
Call parse root tree templated function.
JointIndex id(const JointModelVariant &jmodel)
Visit a JointModelVariant through JointIdVisitor to get the index of the joint in the kinematic chain...
FrameType
Enum on the possible types of frame.