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