mjcf-graph.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2024 CNRS INRIA
3 //
4 
8 
9 namespace pinocchio
10 {
11  namespace mjcf
12  {
13  namespace details
14  {
16  typedef pinocchio::urdf::details::
17  UrdfVisitor<double, 0, ::pinocchio::JointCollectionDefaultTpl>
19 
20  // supported elements from mjcf
21  static const std::array<std::string, 3> ELEMENTS = {"joint", "geom", "site"};
22 
26  static void copyPtree(const ptree & src, ptree & dst)
27  {
28  for (const ptree::value_type & v : src)
29  dst.put(ptree::path_type(v.first), v.second.data());
30  }
31 
35  static void updateClassElement(ptree & current, const ptree & parent)
36  {
37  for (const std::string & el : ELEMENTS)
38  {
39  std::string path = el + ".<xmlattr>";
40  if (parent.get_child_optional(path))
41  {
42  const ptree default_value = ptree();
43  ptree attr_parent = parent.get_child(path, default_value);
44  const ptree & attr_current = current.get_child(path, default_value);
45  // To only copy non existing attribute in current, we copy all current
46  // attribute (replacing) into a parent copy then we replace current with the new
47  // ptree
48  copyPtree(attr_current, attr_parent);
49  current.put_child(path, attr_parent);
50  }
51  }
52  }
53 
54  static std::string getName(const ptree & el, const boost::filesystem::path & filePath)
55  {
56  auto n = el.get_optional<std::string>("<xmlattr>.name");
57  if (n)
58  return *n;
59  else
60  {
61  if (filePath.extension().empty())
63  std::invalid_argument, "Cannot find extension for one of the mesh/texture");
64 
65  auto st = filePath.stem();
66  if (!st.empty())
67  return st.string();
68  else
70  std::invalid_argument, "Cannot find a name for one of the mesh.texture");
71  }
72  }
73 
75  bool strippath,
76  const std::string & dir,
77  const std::string & modelPath,
78  const boost::filesystem::path & filePath)
79  {
80  namespace fs = boost::filesystem;
81 
82  // Check if filename still has Absolute path, like said in mujoco doc
83  if (filePath.is_absolute() && !strippath)
84  return filePath;
85  else
86  {
87  auto filename = filePath;
88  if (strippath)
89  filename = filePath.filename();
90 
91  fs::path meshPath(dir);
92  if (meshPath.is_absolute())
93  return (meshPath / filename);
94  else
95  {
96  fs::path mainPath(modelPath);
97  return (mainPath.parent_path() / meshPath / filename);
98  }
99  }
100  }
101 
102  double MjcfCompiler::convertAngle(const double & angle_) const
103  {
104  return angle_ * angle_converter;
105  }
106 
107  Eigen::Matrix3d MjcfCompiler::convertEuler(const Eigen::Vector3d & angles) const
108  {
109  Eigen::Matrix3d aa1 =
110  Eigen::AngleAxisd(convertAngle(angles(0)), mapEulerAngles.col(0)).toRotationMatrix();
111  Eigen::Matrix3d aa2 =
112  Eigen::AngleAxisd(convertAngle(angles(1)), mapEulerAngles.col(1)).toRotationMatrix();
113  Eigen::Matrix3d aa3 =
114  Eigen::AngleAxisd(convertAngle(angles(2)), mapEulerAngles.col(2)).toRotationMatrix();
115 
116  return aa1 * aa2 * aa3;
117  }
118 
119  template<int Nq, int Nv>
121  {
122  typedef UrdfVisitor::Vector Vector;
123  const double infty = std::numeric_limits<double>::infinity();
124 
125  RangeJoint ret;
126  ret.maxEffort = Vector::Constant(Nv, infty);
127  ret.maxVel = Vector::Constant(Nv, infty);
128  ret.maxConfig = Vector::Constant(Nq, 1.01);
129  ret.minConfig = Vector::Constant(Nq, -1.01);
130  ret.friction = Vector::Constant(Nv, 0.);
131  ret.damping = Vector::Constant(Nv, 0.);
132  ret.armature = Vector::Constant(Nv, armature[0]);
136  return ret;
137  }
138 
139  template<int Nq, int Nv>
141  {
142  assert(range.maxEffort.size() == Nv);
143  assert(range.minConfig.size() == Nq);
144 
145  RangeJoint ret(*this);
146  ret.maxEffort.conservativeResize(maxEffort.size() + Nv);
147  ret.maxEffort.tail(Nv) = range.maxEffort;
148  ret.maxVel.conservativeResize(maxVel.size() + Nv);
149  ret.maxVel.tail(Nv) = range.maxVel;
150 
151  ret.minConfig.conservativeResize(minConfig.size() + Nq);
152  ret.minConfig.tail(Nq) = range.minConfig;
153  ret.maxConfig.conservativeResize(maxConfig.size() + Nq);
154  ret.maxConfig.tail(Nq) = range.maxConfig;
155 
156  ret.damping.conservativeResize(damping.size() + Nv);
157  ret.damping.tail(Nv) = range.damping;
158  ret.friction.conservativeResize(friction.size() + Nv);
159  ret.friction.tail(Nv) = range.friction;
160 
161  ret.springReference.conservativeResize(springReference.size() + 1);
162  ret.springReference.tail(1) = range.springReference;
163  ret.springStiffness.conservativeResize(springStiffness.size() + 1);
164  ret.springStiffness.tail(1) = range.springStiffness;
165 
166  ret.armature.conservativeResize(armature.size() + Nv);
167  ret.armature.tail(Nv) = range.armature;
168 
169  return ret;
170  }
171 
173  const ptree & el, bool use_limits, const MjcfCompiler & currentCompiler)
174  {
175 
176  if (!use_limits && el.get_optional<std::string>("<xmlattr>.range"))
178  std::invalid_argument, "Range limit is specified but it was not specify to use it.");
179 
180  // Type
181  auto type_s = el.get_optional<std::string>("<xmlattr>.type");
182  if (type_s)
183  jointType = *type_s;
184 
185  // Axis
186  auto ax = el.get_optional<std::string>("<xmlattr>.axis");
187  if (ax)
188  axis = internal::getVectorFromStream<3>(*ax);
189 
190  // Range
191  auto range_ = el.get_optional<std::string>("<xmlattr>.range");
192  if (range_)
193  {
194  Eigen::Vector2d rangeT = internal::getVectorFromStream<2>(*range_);
195  range.minConfig[0] = currentCompiler.convertAngle(rangeT(0));
196  range.maxConfig[0] = currentCompiler.convertAngle(rangeT(1));
197  }
198  // Effort limit
199  range_ = el.get_optional<std::string>("<xmlattr>.actuatorfrcrange");
200  if (range_)
201  {
202  Eigen::Vector2d rangeT = internal::getVectorFromStream<2>(*range_);
203  range.maxEffort[0] = rangeT(1);
204  }
205 
206  // Spring
207  auto value = el.get_optional<double>("<xmlattr>.springref");
208  if (value)
210 
211  // damping
212  value = el.get_optional<double>("<xmlattr>.damping");
213  if (value)
214  range.damping[0] = *value;
215 
216  value = el.get_optional<double>("<xmlattr>.armature");
217  if (value)
218  range.armature[0] = *value;
219 
220  // friction loss
221  value = el.get_optional<double>("<xmlattr>.frictionloss");
222  if (value)
224 
225  value = el.get_optional<double>("<xmlattr>.ref");
226  if (value)
227  {
228  if (jointType == "slide")
229  posRef = *value;
230  else if (jointType == "hinge")
231  posRef = currentCompiler.convertAngle(*value);
232  else
234  std::invalid_argument,
235  "Reference position can only be used with hinge or slide joints.");
236  }
237  }
238 
240  const ptree & el, const MjcfBody & currentBody, const MjcfGraph & currentGraph)
241  {
242  bool use_limit = true;
243  // Name
244  auto name_s = el.get_optional<std::string>("<xmlattr>.name");
245  if (name_s)
246  jointName = *name_s;
247  else
248  jointName =
249  currentBody.bodyName + "Joint_" + std::to_string(currentBody.jointChildren.size());
250 
251  // Check if we need to check for limited argument
252  if (!currentGraph.compilerInfo.autolimits)
253  {
254  use_limit = false;
255  auto use_ls = el.get_optional<std::string>("<xmlattr>.limited");
256  use_limit = *use_ls == "true";
257  }
258 
259  // Placement
260  jointPlacement = currentGraph.convertPosition(el);
261 
262  // default < ChildClass < Class < Real Joint
263  if (currentGraph.mapOfClasses.find("mujoco_default") != currentGraph.mapOfClasses.end())
264  {
265  const MjcfClass & classD = currentGraph.mapOfClasses.at("mujoco_default");
266  if (auto joint_p = classD.classElement.get_child_optional("joint"))
267  goThroughElement(*joint_p, use_limit, currentGraph.compilerInfo);
268  }
269  // childClass
270  if (currentBody.childClass != "")
271  {
272  const MjcfClass & classE = currentGraph.mapOfClasses.at(currentBody.childClass);
273  if (auto joint_p = classE.classElement.get_child_optional("joint"))
274  goThroughElement(*joint_p, use_limit, currentGraph.compilerInfo);
275  }
276  // Class
277  auto cl_s = el.get_optional<std::string>("<xmlattr>.class");
278  if (cl_s)
279  {
280  std::string className = *cl_s;
281  const MjcfClass & classE = currentGraph.mapOfClasses.at(className);
282  if (auto joint_p = classE.classElement.get_child_optional("joint"))
283  goThroughElement(*joint_p, use_limit, currentGraph.compilerInfo);
284  }
285  // Joint
286  goThroughElement(el, use_limit, currentGraph.compilerInfo);
287  }
288 
290  {
291  SE3 placement;
292  placement.setIdentity();
293 
294  // position
295  auto pos = el.get_optional<std::string>("<xmlattr>.pos");
296  if (pos)
297  placement.translation() = internal::getVectorFromStream<3>(*pos);
298 
300  // Quaternion (w, x, y, z)
301  auto rot_s = el.get_optional<std::string>("<xmlattr>.quat");
302  if (rot_s)
303  {
304  Eigen::Vector4d quat = internal::getVectorFromStream<4>(*rot_s);
305 
306  Eigen::Quaterniond quaternion(quat(0), quat(1), quat(2), quat(3));
307  quaternion.normalize();
308  placement.rotation() = quaternion.toRotationMatrix();
309  }
310  // Axis Angle
311  else if ((rot_s = el.get_optional<std::string>("<xmlattr>.axisangle")))
312  {
313  Eigen::Vector4d axis_angle = internal::getVectorFromStream<4>(*rot_s);
314 
315  double angle = axis_angle(3);
316 
317  Eigen::AngleAxisd angleAxis(compilerInfo.convertAngle(angle), axis_angle.head(3));
318  placement.rotation() = angleAxis.toRotationMatrix();
319  }
320  // Euler Angles
321  else if ((rot_s = el.get_optional<std::string>("<xmlattr>.euler")))
322  {
323  Eigen::Vector3d angles = internal::getVectorFromStream<3>(*rot_s);
324 
325  placement.rotation() = compilerInfo.convertEuler(angles);
326  }
327  else if ((rot_s = el.get_optional<std::string>("<xmlattr>.xyaxes")))
328  {
329  Eigen::Matrix<double, 6, 1> xyaxes = internal::getVectorFromStream<6>(*rot_s);
330 
331  Eigen::Vector3d xAxis = xyaxes.head(3);
332  xAxis.normalize();
333  Eigen::Vector3d yAxis = xyaxes.tail(3);
334 
335  // make y axis orthogonal to x axis, normalize
336  double d = xAxis.dot(yAxis);
337  yAxis -= xAxis * d;
338  yAxis.normalize();
339 
340  Eigen::Vector3d zAxis = xAxis.cross(yAxis);
341  zAxis.normalize();
342 
343  Eigen::Matrix3d rotation;
344  rotation.col(0) = xAxis;
345  rotation.col(1) = yAxis;
346  rotation.col(2) = zAxis;
347 
348  placement.rotation() = rotation;
349  }
350  else if ((rot_s = el.get_optional<std::string>("<xmlattr>.zaxis")))
351  {
352  Eigen::Vector3d zaxis = internal::getVectorFromStream<3>(*rot_s);
353  // Compute the rotation matrix that maps z_axis to unit z
354  placement.rotation() =
355  Eigen::Quaterniond::FromTwoVectors(Eigen::Vector3d::UnitZ(), zaxis).toRotationMatrix();
356  }
357  return placement;
358  }
359 
361  {
362  double mass = std::max(el.get<double>("<xmlattr>.mass"), compilerInfo.boundMass);
363  ;
364  if (mass < 0)
366  std::invalid_argument, "Mass of body is not supposed to be negative");
367 
369  auto com_s = el.get_optional<std::string>("<xmlattr>.pos");
370  if (com_s)
371  com = internal::getVectorFromStream<3>(*com_s);
372  else
373  com = Inertia::Vector3::Zero();
374 
375  const Inertia::Matrix3 R = convertPosition(el).rotation();
376 
377  Inertia::Matrix3 I = Eigen::Matrix3d::Identity();
378 
379  auto inertia_s = el.get_optional<std::string>("<xmlattr>.diaginertia");
380  if (inertia_s)
381  {
382  Eigen::Vector3d inertiaDiag = internal::getVectorFromStream<3>(*inertia_s);
383  I = inertiaDiag.asDiagonal();
384  }
385 
386  else if ((inertia_s = el.get_optional<std::string>("<xmlattr>.fullinertia")))
387  {
388  // M(1,1), M(2,2), M(3,3), M(1,2), M(1,3), M(2,3)
389  std::istringstream inertiaStream = internal::getConfiguredStringStream(*inertia_s);
390  inertiaStream >> I(0, 0);
391  inertiaStream >> I(1, 1);
392  inertiaStream >> I(2, 2);
393  inertiaStream >> I(0, 1);
394  inertiaStream >> I(0, 2);
395  inertiaStream >> I(1, 2);
396 
397  I(1, 0) = I(0, 1);
398  I(2, 0) = I(0, 2);
399  I(2, 1) = I(1, 2);
400  }
401 
402  // Extract the diagonal elements as a vector
403  for (int i = 0; i < 3; i++)
404  I(i, i) = std::max(I(i, i), compilerInfo.boundInertia);
405 
406  return Inertia(mass, com, R * I * R.transpose());
407  }
408 
410  const ptree & el,
411  const boost::optional<std::string> & childClass,
412  const std::string & parentName)
413  {
414  MjcfBody currentBody;
415  auto chcl_s = childClass;
416  // if inertiafromgeom is false and inertia does not exist - throw
417  if (!compilerInfo.inertiafromgeom && !el.get_child_optional("inertial"))
419  std::invalid_argument, "Cannot get inertia from geom and no inertia was found");
420 
421  bool usegeominertia = false;
423  usegeominertia = true;
424  else if (
425  boost::indeterminate(compilerInfo.inertiafromgeom) && !el.get_child_optional("inertial"))
426  usegeominertia = true;
427 
428  for (const ptree::value_type & v : el)
429  {
430  // Current body node
431  if (v.first == "<xmlattr>")
432  {
433  // Name
434  auto name_s = v.second.get_optional<std::string>("name");
435  if (name_s)
436  currentBody.bodyName = *name_s;
437  else
438  currentBody.bodyName = parentName + "Bis";
439 
440  currentBody.bodyParent = parentName;
441  currentBody.bodyPlacement = convertPosition(el);
442 
443  bodiesList.push_back(currentBody.bodyName);
444 
445  if (auto chcl_st = v.second.get_optional<std::string>("childclass"))
446  {
447  chcl_s = chcl_st;
448  currentBody.childClass = *chcl_s;
449  }
450  else if (childClass)
451  currentBody.childClass = *chcl_s;
452 
453  // Class
454  auto cl_s = v.second.get_optional<std::string>("class");
455  if (cl_s)
456  currentBody.bodyClassName = *cl_s;
457 
458  // Still need to deal with gravcomp and figure out if we need mocap, and user param...
459  }
460  // Inertia
461  if (v.first == "inertial" && !usegeominertia)
462  currentBody.bodyInertia = convertInertiaFromMjcf(v.second);
463 
464  // Geom
465  if (v.first == "geom")
466  {
467  MjcfGeom currentGeom;
468  currentGeom.fill(v.second, currentBody, *this);
469  currentBody.geomChildren.push_back(currentGeom);
470  }
471 
472  // Joint
473  if (v.first == "joint")
474  {
475  MjcfJoint currentJoint;
476  currentJoint.fill(v.second, currentBody, *this);
477  currentBody.jointChildren.push_back(currentJoint);
478  }
479  if (v.first == "freejoint")
480  {
481  MjcfJoint currentJoint;
482  currentJoint.jointType = "free";
483  auto jointName = v.second.get_optional<std::string>("<xmlattr>.name");
484  if (jointName)
485  currentJoint.jointName = *jointName;
486  else
487  currentJoint.jointName = currentBody.bodyName + "_free";
488 
489  currentBody.jointChildren.push_back(currentJoint);
490  }
491  if (v.first == "site")
492  {
493  MjcfSite currentSite;
494  currentSite.fill(v.second, currentBody, *this);
495  currentBody.siteChildren.push_back(currentSite);
496  }
497  if (v.first == "body")
498  {
499  parseJointAndBody(v.second, chcl_s, currentBody.bodyName);
500  }
501  }
502  // Add all geom inertias if needed
503  if (usegeominertia)
504  {
505  Inertia inert_temp(Inertia::Zero());
506  for (const auto & geom : currentBody.geomChildren)
507  {
508  if (geom.geomKind != MjcfGeom::VISUAL)
509  inert_temp += geom.geomPlacement.act(geom.geomInertia);
510  }
511  currentBody.bodyInertia = inert_temp;
512  }
513  mapOfBodies.insert(std::make_pair(currentBody.bodyName, currentBody));
514  }
515 
517  {
518  namespace fs = boost::filesystem;
519  MjcfTexture text;
520  auto file = el.get_optional<std::string>("<xmlattr>.file");
521  auto name_ = el.get_optional<std::string>("<xmlattr>.name");
522  auto type = el.get_optional<std::string>("<xmlattr>.type");
523 
524  std::string name;
525  if (name_)
526  name = *name_;
527  else if (type && *type == "skybox")
528  name = *type;
529  if (!file)
530  {
531  std::cout << "Warning - Only texture with files are supported" << std::endl;
532  if (name.empty())
533  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Textures need a name.");
534  }
535  else
536  {
537  fs::path filePath(*file);
538  name = getName(el, filePath);
539 
540  text.filePath =
542  .string();
543  }
544  auto str_v = el.get_optional<std::string>("<xmlattr>.type");
545  if (str_v)
546  text.textType = *str_v;
547 
548  if ((str_v = el.get_optional<std::string>("<xmlattr>.gridsize")))
549  text.gridsize = internal::getVectorFromStream<2>(*str_v);
550 
551  mapOfTextures.insert(std::make_pair(name, text));
552  }
553 
555  {
556  std::string name;
558  auto n = el.get_optional<std::string>("<xmlattr>.name");
559  if (n)
560  name = *n;
561  else
562  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Material was given without a name");
563 
564  // default < Class < Attributes
565  if (mapOfClasses.find("mujoco_default") != mapOfClasses.end())
566  {
567  const MjcfClass & classD = mapOfClasses.at("mujoco_default");
568  if (auto mat_p = classD.classElement.get_child_optional("material"))
569  mat.goThroughElement(*mat_p);
570  }
571  auto cl_s = el.get_optional<std::string>("<xmlattr>.class");
572  if (cl_s)
573  {
574  std::string className = *cl_s;
575  const MjcfClass & classE = mapOfClasses.at(className);
576  if (auto mat_p = classE.classElement.get_child_optional("material"))
577  mat.goThroughElement(*mat_p);
578  }
579 
580  mat.goThroughElement(el);
581 
582  mapOfMaterials.insert(std::make_pair(name, mat));
583  }
584 
585  void MjcfGraph::parseMesh(const ptree & el)
586  {
587  namespace fs = boost::filesystem;
588 
589  MjcfMesh mesh;
590  auto file = el.get_optional<std::string>("<xmlattr>.file");
591  auto scale = el.get_optional<std::string>("<xmlattr>.scale");
592  if (scale)
593  mesh.scale = internal::getVectorFromStream<3>(*scale);
594  if (file)
595  {
596  fs::path filePath(*file);
597  std::string name = getName(el, filePath);
598 
599  mesh.filePath =
601  mapOfMeshes.insert(std::make_pair(name, mesh));
602  return;
603  }
604 
605  // Handle vertex-based mesh
606  auto vertex = el.get_optional<std::string>("<xmlattr>.vertex");
607  if (!vertex)
608  {
610  std::invalid_argument, "Only meshes with files/vertices are supported.")
611  }
612 
613  auto name = el.get_optional<std::string>("<xmlattr>.name");
614  if (!name)
615  {
617  std::invalid_argument, "Mesh with vertices without a name is not supported");
618  }
619 
620  // Parse and validate vertices
621  Eigen::VectorXd meshVertices = internal::getUnknownSizeVectorFromStream(*vertex);
622  if (meshVertices.size() % 3 != 0)
623  {
625  std::invalid_argument, "Number of vertices is not a multiple of 3");
626  }
627 
628  // Convert to 3D vertex matrix
629  const auto numVertices = meshVertices.size() / 3;
630  Eigen::MatrixX3d vertices(numVertices, 3);
631  for (auto i = 0; i < numVertices; ++i)
632  {
633  vertices.row(i) = meshVertices.segment<3>(3 * i).transpose();
634  }
635  mesh.vertices = vertices;
636  mapOfMeshes.insert(std::make_pair(*name, mesh));
637  }
638 
639  void MjcfGraph::parseAsset(const ptree & el)
640  {
641  for (const ptree::value_type & v : el)
642  {
643  if (v.first == "mesh")
644  parseMesh(v.second);
645 
646  if (v.first == "material")
647  parseMaterial(v.second);
648 
649  if (v.first == "texture")
650  parseTexture(v.second);
651 
652  if (v.first == "hfield")
653  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "hfields are not supported yet");
654  }
655  }
656 
657  void MjcfGraph::parseDefault(ptree & el, const ptree & parent, const std::string & parentTag)
658  {
659  boost::optional<std::string> nameClass;
660  // Classes
661  for (ptree::value_type & v : el)
662  {
663  if (v.first == "<xmlattr>")
664  {
665  nameClass = v.second.get_optional<std::string>("class");
666  if (nameClass)
667  {
668  MjcfClass classDefault;
669  classDefault.className = *nameClass;
671  classDefault.classElement = el;
672  mapOfClasses.insert(std::make_pair(*nameClass, classDefault));
673  }
674  else
676  std::invalid_argument, "Class does not have a name. Cannot parse model.");
677  }
678  else if (v.first == "default")
679  parseDefault(v.second, el, v.first);
680  else if (parentTag == "mujoco" && v.first != "<xmlattr>")
681  {
682  MjcfClass classDefault;
683  classDefault.className = "mujoco_default";
684  classDefault.classElement = el;
685  mapOfClasses.insert(std::make_pair("mujoco_default", classDefault));
686  }
687  }
688  }
689 
691  {
692  // get autolimits
693  auto auto_s = el.get_optional<std::string>("<xmlattr>.autolimits");
694  if (auto_s)
695  if (*auto_s == "true")
696  compilerInfo.autolimits = true;
697 
698  // strip path
699  auto strip_s = el.get_optional<std::string>("<xmlattr>.strippath");
700  if (strip_s)
701  if (*strip_s == "true")
702  compilerInfo.strippath = true;
703 
704  // get dir to mesh and texture
705  auto dir = el.get_optional<std::string>("<xmlattr>.assetdir");
706  if (dir)
707  {
708  compilerInfo.meshdir = *dir;
709  compilerInfo.texturedir = *dir;
710  }
711 
712  if ((dir = el.get_optional<std::string>("<xmlattr>.meshdir")))
713  compilerInfo.meshdir = *dir;
714 
715  if ((dir = el.get_optional<std::string>("<xmlattr>.texturedir")))
716  compilerInfo.texturedir = *dir;
717 
718  auto value_v = el.get_optional<double>("<xmlattr>.boundmass");
719  if (value_v)
720  compilerInfo.boundMass = *value_v;
721 
722  if ((value_v = el.get_optional<double>("<xmlattr>.boundinertia")))
723  compilerInfo.boundInertia = *value_v;
724 
725  auto in_g = el.get_optional<std::string>("<xmlattr>.inertiafromgeom");
726  if (in_g)
727  {
728  if (*in_g == "true")
730  else if (*in_g == "false")
732  }
733 
734  // angle radian or degree
735  auto angle_s = el.get_optional<std::string>("<xmlattr>.angle");
736  if (angle_s)
737  if (*angle_s == "radian")
739 
740  auto eulerS = el.get_optional<std::string>("<xmlattr>.eulerseq");
741  if (eulerS)
742  {
743  std::string eulerseq = *eulerS;
744  if (eulerseq.find_first_not_of("xyzXYZ") != std::string::npos || eulerseq.size() != 3)
745  {
747  std::invalid_argument, "Model tried to use euler angles but euler sequence is wrong");
748  }
749  else
750  {
751  // get index combination
752  for (std::size_t i = 0; i < eulerseq.size(); i++)
753  {
754  auto ci = static_cast<Eigen::Index>(i);
755  switch (eulerseq[i])
756  {
757  case 'x':
758  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitX();
759  break;
760  case 'X':
761  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitX();
762  break;
763  case 'y':
764  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitY();
765  break;
766  case 'Y':
767  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitY();
768  break;
769  case 'z':
770  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitZ();
771  break;
772  case 'Z':
773  compilerInfo.mapEulerAngles.col(ci) = Eigen::Vector3d::UnitZ();
774  break;
775  default:
776  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Euler Axis does not exist");
777  break;
778  }
779  }
780  }
781  }
782  }
783 
785  {
786  for (const ptree::value_type & v : el)
787  {
788  if (v.first == "key")
789  {
790  auto nameKey = v.second.get_optional<std::string>("<xmlattr>.name");
791  if (nameKey)
792  {
793  auto configVectorS = v.second.get_optional<std::string>("<xmlattr>.qpos");
794  if (configVectorS)
795  {
796  Eigen::VectorXd configVector =
798  mapOfConfigs.insert(std::make_pair(*nameKey, configVector));
799  }
800  }
801  }
802  }
803  }
804 
806  {
807  for (const ptree::value_type & v : el)
808  {
809  std::string type = v.first;
810  // List of supported constraints from mjcf description
811  // equality -> connect
812 
813  // The constraints below are not supported and will be ignored with the following
814  // warning: joint, flex, distance, weld
815  if (type != "connect")
816  {
817  // TODO(jcarpent): support extra constraint types such as joint, flex, distance, weld.
818  continue;
819  }
820 
821  MjcfEquality eq;
822  eq.type = type;
823 
824  // get the name of first body
825  auto body1 = v.second.get_optional<std::string>("<xmlattr>.body1");
826  if (body1)
827  eq.body1 = *body1;
828  else
829  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Equality constraint needs a first body");
830 
831  // get the name of second body
832  auto body2 = v.second.get_optional<std::string>("<xmlattr>.body2");
833  if (body2)
834  eq.body2 = *body2;
835 
836  // get the name of the constraint (if it exists)
837  auto name = v.second.get_optional<std::string>("<xmlattr>.name");
838  if (name)
839  eq.name = *name;
840  else
841  eq.name = eq.body1 + "_" + eq.body2 + "_constraint";
842 
843  // get the anchor position
844  auto anchor = v.second.get_optional<std::string>("<xmlattr>.anchor");
845  if (anchor)
846  eq.anchor = internal::getVectorFromStream<3>(*anchor);
847 
848  mapOfEqualities.insert(std::make_pair(eq.name, eq));
849  }
850  }
851 
853  {
855  if (pt.get_child_optional("mujoco"))
856  el = pt.get_child("mujoco");
857  else
859  std::invalid_argument, "This is not a standard mujoco model. Cannot parse it.");
860 
861  for (const ptree::value_type & v : el)
862  {
863  // get model name
864  if (v.first == "<xmlattr>")
865  {
866  auto n_s = v.second.get_optional<std::string>("model");
867  if (n_s)
868  modelName = *n_s;
869  else
871  std::invalid_argument, "Model is missing a name. Cannot parse it");
872  }
873 
874  if (v.first == "compiler")
875  parseCompiler(el.get_child("compiler"));
876 
877  if (v.first == "default")
878  parseDefault(el.get_child("default"), el, "mujoco");
879 
880  if (v.first == "asset")
881  parseAsset(el.get_child("asset"));
882 
883  if (v.first == "keyframe")
884  parseKeyFrame(el.get_child("keyframe"));
885 
886  if (v.first == "worldbody")
887  {
888  boost::optional<std::string> childClass;
889  parseJointAndBody(el.get_child("worldbody").get_child("body"), childClass);
890  }
891 
892  if (v.first == "equality")
893  {
894  parseEquality(el.get_child("equality"));
895  }
896  }
897  }
898 
899  void MjcfGraph::parseGraphFromXML(const std::string & xmlStr)
900  {
901  boost::property_tree::read_xml(xmlStr, pt);
902  parseGraph();
903  }
904 
905  template<typename TypeX, typename TypeY, typename TypeZ, typename TypeUnaligned>
906  JointModel MjcfGraph::createJoint(const Eigen::Vector3d & axis)
907  {
908  if (axis.isApprox(Eigen::Vector3d::UnitX()))
909  return TypeX();
910  else if (axis.isApprox(Eigen::Vector3d::UnitY()))
911  return TypeY();
912  else if (axis.isApprox(Eigen::Vector3d::UnitZ()))
913  return TypeZ();
914  else
915  return TypeUnaligned(axis.normalized());
916  }
917 
919  const MjcfJoint & joint, const MjcfBody & currentBody, SE3 & bodyInJoint)
920  {
921 
922  FrameIndex parentFrameId = 0;
923  if (!currentBody.bodyParent.empty())
924  parentFrameId = urdfVisitor.getBodyId(currentBody.bodyParent);
925 
926  // get body pose in body parent
927  const SE3 bodyPose = currentBody.bodyPlacement;
928  Inertia inert = currentBody.bodyInertia;
929  SE3 jointInParent = bodyPose * joint.jointPlacement;
930  bodyInJoint = joint.jointPlacement.inverse();
931  UrdfVisitor::JointType jType;
932 
933  RangeJoint range;
934  if (joint.jointType == "free")
935  {
936  urdfVisitor << "Free Joint " << '\n';
937  range = joint.range.setDimension<7, 6>();
938  jType = UrdfVisitor::FLOATING;
939  }
940  else if (joint.jointType == "slide")
941  {
942  urdfVisitor << "joint prismatic with axis " << joint.axis << '\n';
943  range = joint.range;
944  jType = UrdfVisitor::PRISMATIC;
945  }
946  else if (joint.jointType == "ball")
947  {
948  urdfVisitor << "Sphere Joint " << '\n';
949  range = joint.range.setDimension<4, 3>();
950  jType = UrdfVisitor::SPHERICAL;
951  }
952  else if (joint.jointType == "hinge")
953  {
954  urdfVisitor << "joint revolute with axis " << joint.axis << '\n';
955  range = joint.range;
956  jType = UrdfVisitor::REVOLUTE;
957  }
958  else
959  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Unknown joint type");
960 
961  urdfVisitor.addJointAndBody(
962  jType, joint.axis, parentFrameId, jointInParent, joint.jointName, inert, bodyInJoint,
963  currentBody.bodyName, range.maxEffort, range.maxVel, range.minConfig, range.maxConfig,
964  range.friction, range.damping);
965 
966  // Add armature info
967  JointIndex j_id = urdfVisitor.getJointId(joint.jointName);
968  urdfVisitor.model.armature.segment(
969  urdfVisitor.model.joints[j_id].idx_v(), urdfVisitor.model.joints[j_id].nv()) =
970  range.armature;
971  }
972 
973  void MjcfGraph::fillModel(const std::string & nameOfBody)
974  {
975  typedef UrdfVisitor::SE3 SE3;
976 
977  MjcfBody currentBody = mapOfBodies.at(nameOfBody);
978 
979  // get parent body frame
980  FrameIndex parentFrameId = 0;
981  if (!currentBody.bodyParent.empty())
982  parentFrameId = urdfVisitor.getBodyId(currentBody.bodyParent);
983 
984  Frame frame = urdfVisitor.model.frames[parentFrameId];
985  // get body pose in body parent
986  const SE3 bodyPose = currentBody.bodyPlacement;
987  Inertia inert = currentBody.bodyInertia;
988 
989  // Fixed Joint
990  if (currentBody.jointChildren.size() == 0)
991  {
992  if (currentBody.bodyParent.empty())
993  return;
994 
995  std::string jointName = nameOfBody + "_fixed";
996  urdfVisitor << jointName << " being parsed." << '\n';
997 
998  urdfVisitor.addFixedJointAndBody(parentFrameId, bodyPose, jointName, inert, nameOfBody);
999  return;
1000  }
1001 
1002  bool composite = false;
1003  SE3 jointPlacement, firstJointPlacement, prevJointPlacement = SE3::Identity();
1004 
1005  RangeJoint rangeCompo;
1006  JointModelComposite jointM;
1007  std::string jointName;
1008 
1009  if (currentBody.jointChildren.size() > 1)
1010  {
1011  composite = true;
1012 
1013  MjcfJoint firstOne = currentBody.jointChildren.at(0);
1014  jointName = "Composite_" + firstOne.jointName;
1015  }
1016 
1017  fillReferenceConfig(currentBody);
1018 
1019  bool isFirst = true;
1020  SE3 bodyInJoint;
1021 
1022  if (!composite)
1023  {
1024  addSoloJoint(currentBody.jointChildren.at(0), currentBody, bodyInJoint);
1025  }
1026  else
1027  {
1028  for (const auto & joint : currentBody.jointChildren)
1029  {
1030  if (joint.jointType == "free")
1032  std::invalid_argument, "Joint Composite trying to be created with a freeFlyer");
1033 
1034  SE3 jointInParent = bodyPose * joint.jointPlacement;
1035  bodyInJoint = joint.jointPlacement.inverse();
1036  if (isFirst)
1037  {
1038  firstJointPlacement = jointInParent;
1039  jointPlacement = SE3::Identity();
1040  isFirst = false;
1041  }
1042  else
1043  jointPlacement = prevJointPlacement.inverse() * jointInParent;
1044  if (joint.jointType == "slide")
1045  {
1046  jointM.addJoint(
1047  createJoint<JointModelPX, JointModelPY, JointModelPZ, JointModelPrismaticUnaligned>(
1048  joint.axis),
1049  jointPlacement);
1050 
1051  rangeCompo = rangeCompo.concatenate<1, 1>(joint.range);
1052  }
1053  else if (joint.jointType == "ball")
1054  {
1055  jointM.addJoint(JointModelSpherical(), jointPlacement);
1056  rangeCompo = rangeCompo.concatenate<4, 3>(joint.range.setDimension<4, 3>());
1057  }
1058  else if (joint.jointType == "hinge")
1059  {
1060  jointM.addJoint(
1061  createJoint<JointModelRX, JointModelRY, JointModelRZ, JointModelRevoluteUnaligned>(
1062  joint.axis),
1063  jointPlacement);
1064  rangeCompo = rangeCompo.concatenate<1, 1>(joint.range);
1065  }
1066  else
1068  std::invalid_argument, "Unknown joint type trying to be parsed.");
1069 
1070  prevJointPlacement = jointInParent;
1071  }
1073 
1074  joint_id = urdfVisitor.model.addJoint(
1075  frame.parentJoint, jointM, frame.placement * firstJointPlacement, jointName,
1076  rangeCompo.maxEffort, rangeCompo.maxVel, rangeCompo.minConfig, rangeCompo.maxConfig,
1077  rangeCompo.friction, rangeCompo.damping);
1078  FrameIndex jointFrameId = urdfVisitor.model.addJointFrame(joint_id, (int)parentFrameId);
1079  urdfVisitor.appendBodyToJoint(jointFrameId, inert, bodyInJoint, nameOfBody);
1080 
1081  urdfVisitor.model.armature.segment(
1082  urdfVisitor.model.joints[joint_id].idx_v(), urdfVisitor.model.joints[joint_id].nv()) =
1083  rangeCompo.armature;
1084  }
1085 
1086  FrameIndex bodyId = urdfVisitor.model.getFrameId(nameOfBody, BODY);
1087  frame = urdfVisitor.model.frames[bodyId];
1088  for (const auto & site : currentBody.siteChildren)
1089  {
1090  SE3 placement = bodyInJoint * site.sitePlacement;
1091  urdfVisitor.model.addFrame(
1092  Frame(site.siteName, frame.parentJoint, bodyId, placement, OP_FRAME));
1093  }
1094  }
1095 
1096  void MjcfGraph::fillReferenceConfig(const MjcfBody & currentBody)
1097  {
1098  for (const auto & joint : currentBody.jointChildren)
1099  {
1100  if (joint.jointType == "free")
1101  {
1102  referenceConfig.conservativeResize(referenceConfig.size() + 7);
1103  referenceConfig.tail(7) << Eigen::Matrix<double, 7, 1>::Zero();
1104  }
1105  else if (joint.jointType == "ball")
1106  {
1107  referenceConfig.conservativeResize(referenceConfig.size() + 4);
1108  referenceConfig.tail(4) << Eigen::Vector4d::Zero();
1109  }
1110  else if (joint.jointType == "slide" || joint.jointType == "hinge")
1111  {
1112  referenceConfig.conservativeResize(referenceConfig.size() + 1);
1113  referenceConfig.tail(1) << joint.posRef;
1114  }
1115  }
1116  }
1117 
1118  void MjcfGraph::addKeyFrame(const Eigen::VectorXd & keyframe, const std::string & keyName)
1119  {
1120  // Check config vectors and add them if size is right
1121  const int model_nq = urdfVisitor.model.nq;
1122  if (keyframe.size() == model_nq)
1123  {
1124  Eigen::VectorXd qpos(model_nq);
1125  for (std::size_t i = 1; i < urdfVisitor.model.joints.size(); i++)
1126  {
1127  const auto & joint = urdfVisitor.model.joints[i];
1128  int idx_q = joint.idx_q();
1129  int nq = joint.nq();
1130 
1131  Eigen::VectorXd qpos_j = keyframe.segment(idx_q, nq);
1132  Eigen::VectorXd q_ref = referenceConfig.segment(idx_q, nq);
1133  if (joint.shortname() == "JointModelFreeFlyer")
1134  {
1135  Eigen::Vector4d new_quat(qpos_j(4), qpos_j(5), qpos_j(6), qpos_j(3));
1136  qpos_j.tail(4) = new_quat;
1137  }
1138  else if (joint.shortname() == "JointModelSpherical")
1139  {
1140  Eigen::Vector4d new_quat(qpos_j(1), qpos_j(2), qpos_j(3), qpos_j(0));
1141  qpos_j = new_quat;
1142  }
1143  else if (joint.shortname() == "JointModelComposite")
1144  {
1145  for (const auto & joint_ : boost::get<JointModelComposite>(joint.toVariant()).joints)
1146  {
1147  int idx_q_ = joint_.idx_q() - idx_q;
1148  int nq_ = joint_.nq();
1149  if (joint_.shortname() == "JointModelSpherical")
1150  {
1151  Eigen::Vector4d new_quat(
1152  qpos_j(idx_q_ + 1), qpos_j(idx_q_ + 2), qpos_j(idx_q_ + 3), qpos_j(idx_q_));
1153  qpos_j.segment(idx_q_, nq_) = new_quat;
1154  }
1155  else
1156  qpos_j.segment(idx_q_, nq_) -= q_ref.segment(idx_q_, nq_);
1157  }
1158  }
1159  else
1160  qpos_j -= q_ref;
1161 
1162  qpos.segment(idx_q, nq) = qpos_j;
1163  }
1164 
1165  urdfVisitor.model.referenceConfigurations.insert(std::make_pair(keyName, qpos));
1166  }
1167  else
1168  PINOCCHIO_THROW_PRETTY(std::invalid_argument, "Keyframe size does not match model size");
1169  }
1170 
1172  const Model & model,
1174  {
1175  for (const auto & entry : mapOfEqualities)
1176  {
1177  const MjcfEquality & eq = entry.second;
1178 
1179  SE3 jointPlacement;
1180  jointPlacement.setIdentity();
1181  jointPlacement.translation() = eq.anchor;
1182 
1183  // Get Joint Indices from the model
1184  const JointIndex body1 = urdfVisitor.getParentId(eq.body1);
1185 
1186  // when body2 is not specified, we link to the world
1187  if (eq.body2 == "")
1188  {
1189  RigidConstraintModel rcm(CONTACT_3D, model, body1, jointPlacement, LOCAL);
1190  contact_models.push_back(rcm);
1191  }
1192  else
1193  {
1194  const JointIndex body2 = urdfVisitor.getParentId(eq.body2);
1196  CONTACT_3D, model, body1, jointPlacement, body2, jointPlacement.inverse(), LOCAL);
1197  contact_models.push_back(rcm);
1198  }
1199  }
1200  }
1201 
1203  {
1204  urdfVisitor.setName(modelName);
1205  // get name and inertia of first root link
1206  std::string rootLinkName = bodiesList.at(0);
1207  MjcfBody rootBody = mapOfBodies.find(rootLinkName)->second;
1208  if (rootBody.jointChildren.size() == 0)
1209  urdfVisitor.addRootJoint(rootBody.bodyInertia, rootLinkName);
1210 
1211  fillReferenceConfig(rootBody);
1212  for (const auto & entry : bodiesList)
1213  {
1214  fillModel(entry);
1215  }
1216 
1217  for (const auto & entry : mapOfConfigs)
1218  {
1219  addKeyFrame(entry.second, entry.first);
1220  }
1221  }
1222  } // namespace details
1223  } // namespace mjcf
1224 } // namespace pinocchio
meshcat-viewer.mesh
mesh
Definition: meshcat-viewer.py:54
ax
ax
pinocchio::mjcf::details::MjcfEquality::type
std::string type
Definition: mjcf-graph.hpp:353
pinocchio::InertiaTpl< context::Scalar, context::Options >
pinocchio::mjcf::details::MjcfCompiler::angle_converter
double angle_converter
Definition: mjcf-graph.hpp:53
pinocchio::FrameIndex
Index FrameIndex
Definition: multibody/fwd.hpp:28
common_symbols.type
type
Definition: common_symbols.py:34
pinocchio::mjcf::details::MjcfJoint::goThroughElement
void goThroughElement(const ptree &el, bool use_limits, const MjcfCompiler &currentCompiler)
Go through a joint node (default class or not) and parse info into the structure.
Definition: mjcf-graph.cpp:172
quadrotor-ocp.path
string path
Definition: quadrotor-ocp.py:11
pinocchio::mjcf::details::MjcfCompiler::mapEulerAngles
Eigen::Matrix3d mapEulerAngles
Definition: mjcf-graph.hpp:55
pinocchio::mjcf::details::MjcfClass
Structure to stock all default classes information.
Definition: mjcf-graph.hpp:77
pinocchio::mjcf::details::RangeJoint::setDimension
RangeJoint setDimension() const
Set dimension to the limits to match the joint nq and nv.
Definition: mjcf-graph.cpp:120
pinocchio::mjcf::details::MjcfGraph::mapOfTextures
TextureMap_t mapOfTextures
Definition: mjcf-graph.hpp:405
pinocchio::mjcf::details::MjcfCompiler
Informations that are stocked in the XML tag compile.
Definition: mjcf-graph.hpp:39
pinocchio::mjcf::details::MjcfGraph::ptree
boost::property_tree::ptree ptree
Definition: mjcf-graph.hpp:384
pinocchio::SE3Tpl::inverse
SE3Tpl inverse() const
aXb = bXa.inverse()
Definition: spatial/se3-tpl.hpp:149
pinocchio::mjcf::details::MjcfCompiler::boundInertia
double boundInertia
Definition: mjcf-graph.hpp:60
pinocchio::mjcf::details::MjcfTexture::textType
std::string textType
Definition: mjcf-graph.hpp:220
pinocchio::idx_q
int idx_q(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointIdxQVisitor to get the index in the full model configuration space...
pinocchio::mjcf::details::MjcfJoint::fill
void fill(const ptree &el, const MjcfBody &currentBody, const MjcfGraph &currentGraph)
Definition: mjcf-graph.cpp:239
pinocchio::mjcf::details::MjcfBody::bodyInertia
Inertia bodyInertia
Definition: mjcf-graph.hpp:105
pinocchio::mjcf::details::MjcfGraph::referenceConfig
Eigen::VectorXd referenceConfig
Definition: mjcf-graph.hpp:412
pinocchio::mjcf::details::MjcfMesh
All informations related to a mesh are stored here.
Definition: mjcf-graph.hpp:206
lambdas.parent
parent
Definition: lambdas.py:21
pinocchio::mjcf::details::MjcfCompiler::convertAngle
double convertAngle(const double &angle_) const
Convert the angle in radian if model was declared to use degree.
Definition: mjcf-graph.cpp:102
quat
quat
pinocchio::mjcf::details::MjcfGraph::mapOfClasses
ClassMap_t mapOfClasses
Definition: mjcf-graph.hpp:397
pinocchio::mjcf::details::RangeJoint::maxConfig
Eigen::VectorXd maxConfig
Definition: mjcf-graph.hpp:123
pinocchio::mjcf::details::MjcfEquality::anchor
Eigen::Vector3d anchor
Definition: mjcf-graph.hpp:368
pinocchio::mjcf::details::RangeJoint
All joint limits.
Definition: mjcf-graph.hpp:116
pinocchio::mjcf::details::MjcfGraph::mapOfEqualities
EqualityMap_t mapOfEqualities
Definition: mjcf-graph.hpp:409
pinocchio::mjcf::details::UrdfVisitor
pinocchio::urdf::details::UrdfVisitor< double, 0, ::pinocchio::JointCollectionDefaultTpl > UrdfVisitor
Definition: mjcf-graph.cpp:18
pinocchio::mjcf::details::RangeJoint::maxVel
Eigen::VectorXd maxVel
Definition: mjcf-graph.hpp:121
pinocchio::Inertia
InertiaTpl< context::Scalar, context::Options > Inertia
Definition: spatial/fwd.hpp:69
pinocchio::SE3Tpl< context::Scalar, context::Options >
pinocchio::mjcf::details::MjcfGraph::parseRootTree
void parseRootTree()
Fill the pinocchio model with all the infos from the graph.
Definition: mjcf-graph.cpp:1202
pinocchio::nq
int nq(const JointModelTpl< Scalar, Options, JointCollectionTpl > &jmodel)
Visit a JointModelTpl through JointNqVisitor to get the dimension of the joint configuration space.
inverse-kinematics.i
int i
Definition: inverse-kinematics.py:17
pinocchio::name
std::string name(const LieGroupGenericTpl< LieGroupCollection > &lg)
Visit a LieGroupVariant to get the name of it.
mjcf-graph.hpp
model.hpp
simulation-closed-kinematic-chains.rotation
rotation
Definition: simulation-closed-kinematic-chains.py:26
pinocchio::mjcf::details::MjcfTexture::gridsize
Eigen::Vector2d gridsize
Definition: mjcf-graph.hpp:224
pinocchio::mjcf::details::MjcfGeom
Definition: mjcf-graph.hpp:249
pinocchio::JointModelSpherical
JointModelSphericalTpl< context::Scalar > JointModelSpherical
Definition: multibody/joint/fwd.hpp:73
pinocchio::mjcf::details::MjcfEquality::body1
std::string body1
Definition: mjcf-graph.hpp:362
pinocchio::mjcf::details::MjcfCompiler::inertiafromgeom
boost::logic::tribool inertiafromgeom
Definition: mjcf-graph.hpp:63
pinocchio::mjcf::details::MjcfCompiler::convertEuler
Eigen::Matrix3d convertEuler(const Eigen::Vector3d &angles) const
Convert the euler angles according to the convention declared in the compile tag.
Definition: mjcf-graph.cpp:107
pinocchio::mjcf::details::MjcfJoint
All joint information parsed from the mjcf model.
Definition: mjcf-graph.hpp:174
pinocchio::mjcf::details::RangeJoint::minConfig
Eigen::VectorXd minConfig
Definition: mjcf-graph.hpp:125
R
R
pinocchio::mjcf::details::RangeJoint::concatenate
RangeJoint concatenate(const RangeJoint &range) const
Concatenate 2 rangeJoint.
Definition: mjcf-graph.cpp:140
pinocchio::mjcf::details::MjcfMaterial
All informations related to material are stored here.
Definition: mjcf-graph.hpp:228
pinocchio::mjcf::details::MjcfGraph::parseJointAndBody
void parseJointAndBody(const ptree &el, const boost::optional< std::string > &childClass, const std::string &parentName="")
Go through the main body of the mjcf file "worldbody" to get all the info ready to create the model.
Definition: mjcf-graph.cpp:409
pinocchio::mjcf::details::MjcfClass::className
std::string className
Definition: mjcf-graph.hpp:83
pinocchio::mjcf::details::MjcfGraph::modelName
std::string modelName
Definition: mjcf-graph.hpp:421
pinocchio::mjcf::details::RangeJoint::friction
Eigen::VectorXd friction
Definition: mjcf-graph.hpp:133
pinocchio::mjcf::details::MjcfCompiler::boundMass
double boundMass
Definition: mjcf-graph.hpp:58
pinocchio::mjcf::details::MjcfJoint::axis
Eigen::Vector3d axis
Definition: mjcf-graph.hpp:185
pinocchio::mjcf::details::MjcfJoint::jointType
std::string jointType
Definition: mjcf-graph.hpp:190
pinocchio::JointModelCompositeTpl::addJoint
JointModelDerived & addJoint(const JointModelBase< JointModel > &jmodel, const SE3 &placement=SE3::Identity())
Add a joint to the vector of joints.
Definition: joint-composite.hpp:278
pinocchio::mjcf::details::MjcfGraph::convertInertiaFromMjcf
Inertia convertInertiaFromMjcf(const ptree &el) const
Convert Inertia of an mjcf element into Inertia model of pinocchio.
Definition: mjcf-graph.cpp:360
pinocchio::mjcf::details::copyPtree
static void copyPtree(const ptree &src, ptree &dst)
Copy the value of ptree src into dst.
Definition: mjcf-graph.cpp:26
pinocchio::FrameTpl
A Plucker coordinate frame attached to a parent joint inside a kinematic tree.
Definition: multibody/frame.hpp:55
pinocchio::Index
PINOCCHIO_COMPILER_DIAGNOSTIC_POP typedef std::size_t Index
Definition: multibody/fwd.hpp:22
pinocchio::mjcf::details::MjcfGraph::parseGraphFromXML
void parseGraphFromXML(const std::string &xmlStr)
parse the mjcf file into a graph
Definition: mjcf-graph.cpp:899
pinocchio::mjcf::details::MjcfGraph::mapOfConfigs
ConfigMap_t mapOfConfigs
Definition: mjcf-graph.hpp:407
pinocchio::SE3Tpl::translation
ConstLinearRef translation() const
Definition: se3-base.hpp:52
pinocchio::InertiaTpl< context::Scalar, context::Options >::Zero
static InertiaTpl Zero()
Definition: spatial/inertia.hpp:337
pinocchio::mjcf::details::MjcfGraph::parseEquality
void parseEquality(const ptree &el)
Parse all the info from the equality tag.
Definition: mjcf-graph.cpp:805
pinocchio::mjcf::details::MjcfClass::classElement
ptree classElement
Definition: mjcf-graph.hpp:85
pinocchio::mjcf::details::MjcfBody::geomChildren
std::vector< MjcfGeom > geomChildren
Definition: mjcf-graph.hpp:110
pinocchio::mjcf::details::MjcfGraph::parseTexture
void parseTexture(const ptree &el)
Parse all the info from a texture node.
Definition: mjcf-graph.cpp:516
pinocchio::mjcf::details::RangeJoint::springReference
Eigen::VectorXd springReference
Definition: mjcf-graph.hpp:130
details
pinocchio::mjcf::details::MjcfJoint::ptree
boost::property_tree::ptree ptree
Definition: mjcf-graph.hpp:177
pinocchio::placement
const MotionDense< Motion2 > const SE3Tpl< SE3Scalar, SE3Options > & placement
Definition: spatial/classic-acceleration.hpp:122
pinocchio::mjcf::details::RangeJoint::damping
Eigen::VectorXd damping
Definition: mjcf-graph.hpp:135
pinocchio::RigidConstraintModelTpl
Definition: algorithm/constraints/fwd.hpp:14
pinocchio::mjcf::details::MjcfTexture::filePath
std::string filePath
Definition: mjcf-graph.hpp:222
filename
filename
pinocchio::mjcf::details::MjcfGraph::parseCompiler
void parseCompiler(const ptree &el)
Parse all the info from the compile node into compilerInfo.
Definition: mjcf-graph.cpp:690
pinocchio::JointModelTpl< context::Scalar >
mat
mat
PINOCCHIO_THROW_PRETTY
#define PINOCCHIO_THROW_PRETTY(exception, message)
Definition: include/pinocchio/macros.hpp:164
pinocchio::SE3Tpl::rotation
ConstAngularRef rotation() const
Definition: se3-base.hpp:48
pinocchio::mjcf::details::MjcfGraph::fillModel
void fillModel(const std::string &nameOfBody)
Use all the infos that were parsed from the xml file to add a body and joint to the model.
Definition: mjcf-graph.cpp:973
value
float value
pinocchio::mjcf::details::ELEMENTS
static const std::array< std::string, 3 > ELEMENTS
Definition: mjcf-graph.cpp:21
pinocchio::mjcf::details::MjcfGraph::parseContactInformation
void parseContactInformation(const Model &model, PINOCCHIO_STD_VECTOR_WITH_EIGEN_ALLOCATOR(RigidConstraintModel) &contact_models)
Parse the equality constraints and add them to the model.
Definition: mjcf-graph.cpp:1171
pinocchio::mjcf::details::MjcfGraph::bodiesList
VectorOfStrings bodiesList
Definition: mjcf-graph.hpp:418
pinocchio::mjcf::details::RangeJoint::springStiffness
Eigen::VectorXd springStiffness
Definition: mjcf-graph.hpp:128
pinocchio::mjcf::details::MjcfBody::siteChildren
std::vector< MjcfSite > siteChildren
Definition: mjcf-graph.hpp:112
pinocchio::mjcf::details::MjcfGraph::addKeyFrame
void addKeyFrame(const Eigen::VectorXd &keyframe, const std::string &keyName)
Add a keyframe to the model (ie reference configuration)
Definition: mjcf-graph.cpp:1118
pinocchio::mjcf::details::MjcfGraph::parseDefault
void parseDefault(ptree &el, const ptree &parent, const std::string &parentTag)
Go through the default part of the file and get all the class name. Fill the mapOfDefault for later u...
Definition: mjcf-graph.cpp:657
pos
pos
pinocchio::mjcf::details::MjcfGraph::parseMesh
void parseMesh(const ptree &el)
Parse all the info from a mesh node.
Definition: mjcf-graph.cpp:585
pinocchio::mjcf::details::MjcfGraph::mapOfMeshes
MeshMap_t mapOfMeshes
Definition: mjcf-graph.hpp:403
pinocchio::mjcf::details::MjcfJoint::jointPlacement
SE3 jointPlacement
Definition: mjcf-graph.hpp:182
pinocchio::mjcf::details::MjcfGraph::mapOfBodies
BodyMap_t mapOfBodies
Definition: mjcf-graph.hpp:399
pinocchio::context::Vector3
Eigen::Matrix< Scalar, 3, 1, Options > Vector3
Definition: context/generic.hpp:53
pinocchio::mjcf::details::MjcfGraph::parseMaterial
void parseMaterial(const ptree &el)
Parse all the info from a material node.
Definition: mjcf-graph.cpp:554
axis
axis
pinocchio::mjcf::details::RangeJoint::frictionLoss
double frictionLoss
Definition: mjcf-graph.hpp:140
pinocchio::mjcf::details::ptree
boost::property_tree::ptree ptree
Definition: mjcf-graph.cpp:15
contact-cholesky.frame
frame
Definition: contact-cholesky.py:24
pinocchio::mjcf::details::MjcfGraph::parseKeyFrame
void parseKeyFrame(const ptree &el)
Parse all the info from the meta tag keyframe.
Definition: mjcf-graph.cpp:784
PINOCCHIO_STD_VECTOR_WITH_EIGEN_ALLOCATOR
#define PINOCCHIO_STD_VECTOR_WITH_EIGEN_ALLOCATOR(T)
Definition: container/aligned-vector.hpp:13
meshcat-viewer-solo.q_ref
q_ref
Definition: meshcat-viewer-solo.py:26
pinocchio::Frame
FrameTpl< context::Scalar, context::Options > Frame
Definition: multibody/fwd.hpp:31
anymal-simulation.mass
mass
Definition: anymal-simulation.py:62
pinocchio::mjcf::details::MjcfGeom::fill
void fill(const ptree &el, const MjcfBody &currentBody, const MjcfGraph &currentGraph)
Fill Geometry element with info from ptree nodes.
Definition: mjcf-graph-geom.cpp:416
value_type
Scalar value_type
Definition: eigen_plugin.hpp:2
pinocchio::mjcf::details::MjcfJoint::jointName
std::string jointName
Definition: mjcf-graph.hpp:180
pinocchio::mjcf::details::MjcfBody::bodyClassName
std::string bodyClassName
Definition: mjcf-graph.hpp:97
pinocchio::v
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > const Eigen::MatrixBase< TangentVectorType > & v
Definition: joint-configuration.hpp:1084
pinocchio::mjcf::details::MjcfGraph::mapOfMaterials
MaterialMap_t mapOfMaterials
Definition: mjcf-graph.hpp:401
pinocchio::mjcf::details::MjcfCompiler::meshdir
std::string meshdir
Definition: mjcf-graph.hpp:48
pinocchio::mjcf::details::MjcfCompiler::texturedir
std::string texturedir
Definition: mjcf-graph.hpp:50
pinocchio::JointModelCompositeTpl
Definition: multibody/joint/fwd.hpp:141
pinocchio::mjcf::details::MjcfGraph::fillReferenceConfig
void fillReferenceConfig(const MjcfBody &currentBody)
Fill reference configuration for a body and all it's associated dof.
Definition: mjcf-graph.cpp:1096
pinocchio::OP_FRAME
@ OP_FRAME
operational frame: user-defined frames that are defined at runtime
Definition: multibody/frame.hpp:33
pinocchio::mjcf::details::MjcfGraph::urdfVisitor
UrdfVisitor & urdfVisitor
Definition: mjcf-graph.hpp:428
pinocchio::mjcf::details::MjcfGraph::parseGraph
void parseGraph()
parse the mjcf file into a graph
Definition: mjcf-graph.cpp:852
pinocchio::mjcf::details::MjcfGraph::compilerInfo
MjcfCompiler compilerInfo
Definition: mjcf-graph.hpp:395
pinocchio::mjcf::details::MjcfGraph::pt
ptree pt
Definition: mjcf-graph.hpp:415
pinocchio::mjcf::details::MjcfEquality::name
std::string name
Definition: mjcf-graph.hpp:350
pinocchio::mjcf::details::MjcfCompiler::autolimits
bool autolimits
Definition: mjcf-graph.hpp:43
pinocchio::mjcf::details::MjcfCompiler::strippath
bool strippath
Definition: mjcf-graph.hpp:46
pinocchio::mjcf::details::MjcfGraph::parseAsset
void parseAsset(const ptree &el)
Parse all the info from the meta tag asset (mesh, material, texture)
Definition: mjcf-graph.cpp:639
pinocchio::mjcf::details::MjcfGraph::convertPosition
SE3 convertPosition(const ptree &el) const
Convert pose of an mjcf element into SE3.
Definition: mjcf-graph.cpp:289
pinocchio::SE3Tpl::Identity
static SE3Tpl Identity()
Definition: spatial/se3-tpl.hpp:136
pinocchio::mjcf::details::MjcfGraph::addSoloJoint
void addSoloJoint(const MjcfJoint &jointInfo, const MjcfBody &currentBody, SE3 &bodyInJoint)
Add a joint to the model. only needed when a body has a solo joint child.
Definition: mjcf-graph.cpp:918
pinocchio::mjcf::details::updatePath
static boost::filesystem::path updatePath(bool strippath, const std::string &dir, const std::string &modelPath, const boost::filesystem::path &filePath)
Definition: mjcf-graph.cpp:74
pinocchio::mjcf::details::MjcfBody::bodyName
std::string bodyName
Definition: mjcf-graph.hpp:93
pinocchio::mjcf::details::updateClassElement
static void updateClassElement(ptree &current, const ptree &parent)
Update class Element in order to have all info of parent classes.
Definition: mjcf-graph.cpp:35
pinocchio::mjcf::details::MjcfJoint::posRef
double posRef
Definition: mjcf-graph.hpp:192
pinocchio::mjcf::details::MjcfBody::bodyParent
std::string bodyParent
Definition: mjcf-graph.hpp:95
pinocchio::JointIndex
Index JointIndex
Definition: multibody/fwd.hpp:26
pinocchio::mjcf::details::MjcfGraph
The graph which contains all information taken from the mjcf file.
Definition: mjcf-graph.hpp:381
pinocchio::mjcf::details::MjcfBody::jointChildren
std::vector< MjcfJoint > jointChildren
Definition: mjcf-graph.hpp:108
pinocchio::mjcf::details::RangeJoint::armature
Eigen::VectorXd armature
Definition: mjcf-graph.hpp:138
pinocchio::mjcf::details::MjcfBody
All Bodies informations extracted from mjcf model.
Definition: mjcf-graph.hpp:89
pinocchio::mjcf::details::MjcfEquality
Definition: mjcf-graph.hpp:345
pinocchio::mjcf::details::internal::getConfiguredStringStream
std::istringstream getConfiguredStringStream(const std::string &str)
Definition: mjcf-graph.hpp:549
pinocchio::mjcf::details::MjcfSite
Definition: mjcf-graph.hpp:319
contact-cholesky.contact_models
list contact_models
Definition: contact-cholesky.py:22
pinocchio::mjcf::details::MjcfEquality::body2
std::string body2
Definition: mjcf-graph.hpp:364
pinocchio::mjcf::details::MjcfBody::bodyPlacement
SE3 bodyPlacement
Definition: mjcf-graph.hpp:103
contact-info.hpp
pinocchio::python::context::SE3
SE3Tpl< Scalar, Options > SE3
Definition: bindings/python/context/generic.hpp:53
pinocchio::SE3
SE3Tpl< context::Scalar, context::Options > SE3
Definition: spatial/fwd.hpp:64
append-urdf-model-with-another-model.joint_id
joint_id
Definition: append-urdf-model-with-another-model.py:34
pinocchio::ModelTpl
Definition: context/generic.hpp:20
pinocchio::mjcf::details::MjcfGraph::createJoint
JointModel createJoint(const Eigen::Vector3d &axis)
Create a joint to add to the joint composite if needed.
Definition: mjcf-graph.cpp:906
pinocchio::CONTACT_3D
@ CONTACT_3D
Definition: algorithm/contact-info.hpp:21
pinocchio::mjcf::details::MjcfBody::childClass
std::string childClass
Definition: mjcf-graph.hpp:100
pinocchio::BODY
@ BODY
body frame: attached to the collision, inertial or visual properties of a link
Definition: multibody/frame.hpp:36
CppAD::max
AD< Scalar > max(const AD< Scalar > &x, const AD< Scalar > &y)
Definition: autodiff/cppad.hpp:181
pinocchio::SE3Tpl::setIdentity
SE3Tpl & setIdentity()
Definition: spatial/se3-tpl.hpp:141
pinocchio::mjcf::details::getName
static std::string getName(const ptree &el, const boost::filesystem::path &filePath)
Definition: mjcf-graph.cpp:54
d
FCL_REAL d
pinocchio::mjcf::details::internal::getUnknownSizeVectorFromStream
Eigen::VectorXd getUnknownSizeVectorFromStream(const std::string &str)
Definition: mjcf-graph.hpp:567
n
Vec3f n
robot-wrapper-viewer.com
com
Definition: robot-wrapper-viewer.py:45
pinocchio::mjcf::details::RangeJoint::maxEffort
Eigen::VectorXd maxEffort
Definition: mjcf-graph.hpp:119
pinocchio::mjcf::details::MjcfTexture
All informations related to a texture are stored here.
Definition: mjcf-graph.hpp:217
pinocchio::model
JointCollectionTpl & model
Definition: joint-configuration.hpp:1082
pinocchio::mjcf::details::MjcfGraph::modelPath
std::string modelPath
Definition: mjcf-graph.hpp:422
pinocchio::mjcf::details::MjcfSite::fill
void fill(const ptree &el, const MjcfBody &currentBody, const MjcfGraph &currentGraph)
Definition: mjcf-graph-geom.cpp:486
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27
pinocchio::mjcf::details::MjcfGeom::VISUAL
@ VISUAL
Definition: mjcf-graph.hpp:257
pinocchio::mjcf::details::MjcfJoint::range
RangeJoint range
Definition: mjcf-graph.hpp:187
pinocchio::LOCAL
@ LOCAL
Definition: multibody/fwd.hpp:50


pinocchio
Author(s):
autogenerated on Sun Feb 16 2025 03:42:48