mjcf.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015-2024 CNRS INRIA
3 //
4 
5 #include <iostream>
6 #include <cstdio> // for std::tmpnam
7 
9 
12 
15 
17 
18 #include <boost/test/unit_test.hpp>
19 #include <boost/filesystem/fstream.hpp>
20 
21 namespace
22 {
23 
24  struct TemporaryFileHolder
25  {
26  TemporaryFileHolder()
27  : path(boost::filesystem::temp_directory_path() / boost::filesystem::unique_path())
28  {
29  }
30 
31  ~TemporaryFileHolder()
32  {
33  boost::filesystem::remove(path);
34  }
35 
36  TemporaryFileHolder(const TemporaryFileHolder &) = delete;
37  TemporaryFileHolder & operator=(const TemporaryFileHolder &) = delete;
38 
39  TemporaryFileHolder(TemporaryFileHolder &&) = default;
40  TemporaryFileHolder & operator=(TemporaryFileHolder &&) = default;
41 
42  std::string name() const
43  {
44  return path.string();
45  }
46 
48  };
49 
50 } // namespace
51 
52 static TemporaryFileHolder createTempFile(const std::istringstream & data)
53 {
54  TemporaryFileHolder temp_file;
55 
56  // Write the XML data to the temporary file
57  boost::filesystem::ofstream file_stream(temp_file.path);
58  if (!file_stream)
59  {
60  std::cerr << "Error opening file for writing" << std::endl;
61  exit(EXIT_FAILURE);
62  }
63  file_stream << data.rdbuf();
64  file_stream.close();
65 
66  return temp_file;
67 }
68 
71 {
72  // Check if the number of children is the same
73  if (pt1.size() != pt2.size())
74  return false;
75 
76  // Iterate over all children
77  for (auto it1 = pt1.begin(), it2 = pt2.begin(); it1 != pt1.end(); ++it1, ++it2)
78  {
79  // Compare keys
80  if (it1->first != it2->first)
81  return false;
82 
83  // Compare values
84  if (it1->second.data() != it2->second.data())
85  return false;
86 
87  // Recursively compare child trees
88  if (!comparePropertyTrees(it1->second, it2->second))
89  return false;
90  }
91 
92  return true;
93 }
94 
95 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
96 
97 // /// @brief Test for the inertia conversion from mjcf to pinocchio inertia
98 // /// @param
99 BOOST_AUTO_TEST_CASE(convert_inertia_fullinertia)
100 {
102  typedef pinocchio::SE3::Matrix3 Matrix3;
103  // Parse the XML
104  std::istringstream xmlData(R"(
105  <inertial mass="0.629769" pos="-0.041018 -0.00014 0.049974"
106  fullinertia="0.00315 0.00388 0.004285 8.2904e-7 0.00015 8.2299e-6"/>
107  )");
108 
109  // Create a Boost Property Tree
111  boost::property_tree::read_xml(xmlData, pt);
112 
113  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
115  MjcfGraph::UrdfVisitor visitor(model);
116 
117  MjcfGraph graph(visitor, "fakeMjcf");
118 
119  // // Try to get the "name" element using get_optional
120  pinocchio::Inertia inertia = graph.convertInertiaFromMjcf(pt.get_child("inertial"));
121 
122  Matrix3 inertia_matrix;
123  // M(1,1), M(2,2), M(3,3), M(1,2), M(1,3), M(2,3)
124  inertia_matrix << 0.00315, 8.2904e-7, 0.00015, 8.2904e-7, 0.00388, 8.2299e-6, 0.00015, 8.2299e-6,
125  0.004285;
126 
127  pinocchio::Inertia real_inertia(0.629769, Vector3(-0.041018, -0.00014, 0.049974), inertia_matrix);
128  BOOST_CHECK(inertia.isEqual(real_inertia));
129 }
130 
131 // /// @brief Test for the inertia conversion from mjcf to pinocchio inertia
132 // /// @param
133 BOOST_AUTO_TEST_CASE(convert_inertia_diaginertia)
134 {
136  typedef pinocchio::SE3::Matrix3 Matrix3;
137  // Parse the XML
138  std::istringstream xmlData(R"(
139  <inertial mass="0.629769" pos="-0.041018 -0.00014 0.049974"
140  diaginertia="0.00315 0.00388 0.004285"/>
141  )");
142 
143  // Create a Boost Property Tree
145  boost::property_tree::read_xml(xmlData, pt);
146 
147  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
149  MjcfGraph::UrdfVisitor visitor(model);
150 
151  MjcfGraph graph(visitor, "fakeMjcf");
152 
153  // // Try to get the "name" element using get_optional
154  pinocchio::Inertia inertia = graph.convertInertiaFromMjcf(pt.get_child("inertial"));
155 
156  Matrix3 inertia_matrix = Eigen::Matrix3d::Zero();
157  inertia_matrix(0, 0) = 0.00315;
158  inertia_matrix(1, 1) = 0.00388;
159  inertia_matrix(2, 2) = 0.004285;
160  pinocchio::Inertia real_inertia(0.629769, Vector3(-0.041018, -0.00014, 0.049974), inertia_matrix);
161 
162  BOOST_CHECK(inertia.isApprox(real_inertia, 1e-7));
163 }
164 
166 BOOST_AUTO_TEST_CASE(geoms_construction)
167 {
168  double pi = boost::math::constants::pi<double>();
169  // Parse the XML
170  std::istringstream xmlData(R"(<mujoco model="inertiaFromGeom">
171  <compiler inertiafromgeom="true" />
172  <worldbody>
173  <body pos="0 0 0" name="bodyCylinder">
174  <geom type="cylinder" size=".01" fromto="0 0 0 0 0 .5"/>
175  <geom type="cylinder" size=".01 0.25" pos="0 0 0" quat="1 0 0 0"/>
176  <body pos="0 0 0" name="bodyBox">
177  <geom type="box" size=".01" fromto="0 0 0 0 0 .5"/>
178  <geom type="box" size=".01 0.01 0.25" pos="0 0 0" quat="1 0 0 0"/>
179  </body>
180  <body pos="0 0 0" name="bodyCapsule">
181  <geom type="capsule" size=".01" fromto="0 0 0 0 0 .5"/>
182  <geom type="capsule" size=".01 0.25" pos="0 0 0" quat="1 0 0 0"/>
183  </body>
184  <body pos="0 0 0" name="bodySphere">
185  <geom type="sphere" size=".01 0.25" pos="0 0 0" quat="1 0 0 0"/>
186  </body>
187  <body pos="0 0 0" name="bodyEllip">
188  <geom type="ellipsoid" size=".01" fromto="0 0 0 0 0 .5"/>
189  <geom type="ellipsoid" size=".01 0.01 0.25" pos="0 0 0" quat="1 0 0 0"/>
190  </body>
191  </body>
192  </worldbody>
193  </mujoco>)");
194 
195  auto namefile = createTempFile(xmlData);
196 
197  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
198  pinocchio::Model model_m;
199  MjcfGraph::UrdfVisitor visitor(model_m);
200 
201  MjcfGraph graph(visitor, "fakeMjcf");
202  graph.parseGraphFromXML(namefile.name());
203 
204  // Test Cylinder
205  pinocchio::mjcf::details::MjcfBody bodyTest = graph.mapOfBodies.at("bodyCylinder");
206  double mass = 1000 * std::pow(0.01, 2) * 0.25 * pi * 2;
207  pinocchio::Inertia inertTest = pinocchio::Inertia::FromCylinder(mass, 0.01, 0.25 * 2);
208  Eigen::Vector2d sizeCy;
209  sizeCy << 0.01, 0.25;
210  for (const auto & geom : bodyTest.geomChildren)
211  {
212  // Check size
213  BOOST_CHECK(geom.size == sizeCy);
214  // Check inertia
215  BOOST_CHECK(geom.geomInertia.isApprox(inertTest));
216  }
217  // Test Box
218  bodyTest = graph.mapOfBodies.at("bodyBox");
219  mass = 1000 * 0.02 * 0.02 * 0.5;
220  inertTest = pinocchio::Inertia::FromBox(mass, 0.02, 0.02, 0.5);
221  Eigen::Vector3d sizeB;
222  sizeB << 0.02, 0.02, .5;
223  for (const auto & geom : bodyTest.geomChildren)
224  {
225  // Check size
226  BOOST_CHECK(geom.size == sizeB);
227  // Check inertia
228  BOOST_CHECK(geom.geomInertia.isApprox(inertTest));
229  }
230  // Test Capsule
231  bodyTest = graph.mapOfBodies.at("bodyCapsule");
232  mass = 1000 * (4.0 / 3 * pi * std::pow(0.01, 3) + 2 * pi * std::pow(0.01, 2) * 0.25);
233  inertTest = pinocchio::Inertia::FromCapsule(mass, 0.01, 0.25 * 2);
234  Eigen::Vector2d sizeCa;
235  sizeCa << 0.01, 0.25;
236  for (const auto & geom : bodyTest.geomChildren)
237  {
238  // Check size
239  BOOST_CHECK(geom.size == sizeCa);
240  // Check inertia
241  BOOST_CHECK(geom.geomInertia.isApprox(inertTest));
242  }
243  // Test Sphere
244  bodyTest = graph.mapOfBodies.at("bodySphere");
245  mass = 1000 * 4.0 / 3 * pi * std::pow(0.01, 3);
246  inertTest = pinocchio::Inertia::FromSphere(mass, 0.01);
247  Eigen::VectorXd sizeS(1);
248  sizeS << 0.01;
249  for (const auto & geom : bodyTest.geomChildren)
250  {
251  // Check size
252  BOOST_CHECK(geom.size == sizeS);
253  // Check inertia
254  BOOST_CHECK(geom.geomInertia.isApprox(inertTest));
255  }
256  // Test Ellipsoid
257  bodyTest = graph.mapOfBodies.at("bodyEllip");
258  mass = 1000 * 4.0 / 3 * pi * 0.01 * 0.01 * 0.25;
259  inertTest = pinocchio::Inertia::FromEllipsoid(mass, 0.01, 0.01, 0.25);
260  Eigen::Vector3d sizeEl;
261  sizeEl << 0.01, 0.01, 0.25;
262  for (const auto & geom : bodyTest.geomChildren)
263  {
264  // Check size
265  BOOST_CHECK(geom.size == sizeEl);
266  // Check inertia
267  BOOST_CHECK(geom.geomInertia.isApprox(inertTest));
268  }
269 }
270 
273 BOOST_AUTO_TEST_CASE(inertia_from_geom)
274 {
275  // Parse the XML
276  std::istringstream xmlData(R"(<mujoco model="inertiaFromGeom">
277  <compiler inertiafromgeom="true" />
278  <worldbody>
279  <body pos="0 0 0" name="body0">
280  <geom type="box" size=".01 .01 .01" pos="0 0 0.01"/>
281  <geom type="box" size=".01 .01 .01" pos="0 0 0.03"/>
282  </body>
283  </worldbody>
284  </mujoco>)");
285 
286  auto namefile = createTempFile(xmlData);
287 
288  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
289  pinocchio::Model model_m;
290  MjcfGraph::UrdfVisitor visitor(model_m);
291 
292  MjcfGraph graph(visitor, "fakeMjcf");
293  graph.parseGraphFromXML(namefile.name());
294  graph.parseRootTree();
295 
296  // only one inertias since only one body
297  pinocchio::Inertia inertBody = model_m.inertias[0];
298 
299  double massBigBox = 1000 * 0.02 * 0.02 * 0.04; // density * volume
300  pinocchio::Inertia inertBigBox = pinocchio::Inertia::FromBox(massBigBox, 0.02, 0.02, 0.04);
301  // Create a frame on the bottom face of BigBox and express inertia
302  Eigen::Vector3d pl;
303  pl << 0, 0, 0.02;
304  pinocchio::SE3 placementBigBox(Eigen::Matrix3d::Identity(), pl);
305  inertBigBox = placementBigBox.act(inertBigBox);
306 
307  BOOST_CHECK(inertBigBox.isApprox(inertBody));
308 }
309 
310 // /// @brief Test for the pose conversion from mjcf model to pinocchio
311 // /// @param
312 BOOST_AUTO_TEST_CASE(convert_orientation)
313 {
315  typedef pinocchio::SE3::Matrix3 Matrix3;
316 
317  std::istringstream xmlData(R"(
318  <compiler angle="radian" eulerseq="xyz"/>
319  <quaternion pos="0.3 0.2 0.5" quat="1 -1 0 0"/>
320  <axis pos="0.3 0.2 0.5" axisangle="-1 0 0 1.5707963"/>
321  <euler pos="0.3 0.2 0.5" euler="-1.57079633 0 0"/>
322  <xyaxes pos="0.3 0.2 0.5" xyaxes="1 0 0 0 0 -1"/>
323  <zaxis pos="0.3 0.2 0.5" zaxis="0 1 0"/>
324  )");
325 
326  // Create a Boost Property Tree
328  boost::property_tree::read_xml(xmlData, pt);
329 
330  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
332  MjcfGraph::UrdfVisitor visitor(model);
333 
334  MjcfGraph graph(visitor, "fakeMjcf");
335 
336  graph.parseCompiler(pt.get_child("compiler"));
337 
338  pinocchio::SE3 placement_q = graph.convertPosition(pt.get_child("quaternion"));
339  pinocchio::SE3 placement_a = graph.convertPosition(pt.get_child("axis"));
340  pinocchio::SE3 placement_e = graph.convertPosition(pt.get_child("euler"));
341  pinocchio::SE3 placement_xy = graph.convertPosition(pt.get_child("xyaxes"));
342  pinocchio::SE3 placement_z = graph.convertPosition(pt.get_child("zaxis"));
343 
344  Matrix3 rotation_matrix;
345  rotation_matrix << 1., 0., 0., 0., 0., 1., 0., -1., 0.;
346 
347  pinocchio::SE3 real_placement(rotation_matrix, Vector3(0.3, 0.2, 0.5));
348 
349  BOOST_CHECK(placement_q.isApprox(real_placement, 1e-7));
350  BOOST_CHECK(placement_e.isApprox(real_placement, 1e-7));
351  BOOST_CHECK(placement_a.isApprox(real_placement, 1e-7));
352  BOOST_CHECK(placement_xy.isApprox(real_placement, 1e-7));
353  BOOST_CHECK(placement_z.isApprox(real_placement, 1e-7));
354 }
355 
358 BOOST_AUTO_TEST_CASE(merge_default)
359 {
360  namespace pt = boost::property_tree;
361  std::istringstream xmlIn(R"(
362  <default>
363  <default class="mother">
364  <joint A="a0" B="b0" />
365  <geom A="a0" />
366  <default class="layer1">
367  <joint A="a1" C="c1" />
368  <default class="layer2">
369  <joint B="b2" />
370  <geom C="c2" />
371  </default>
372  </default>
373  <default class="layerP">
374  <joint K="b2" />
375  <site H="f1"/>
376  </default>
377  </default>
378  </default>)");
379 
380  // Create a Boost Property Tree
381  pt::ptree ptr;
382  pt::read_xml(xmlIn, ptr, pt::xml_parser::trim_whitespace);
383 
384  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
386  MjcfGraph::UrdfVisitor visitor(model);
387 
388  MjcfGraph graph(visitor, "fakeMjcf");
389  graph.parseDefault(ptr.get_child("default"), ptr);
390 
391  std::unordered_map<std::string, pt::ptree> TrueMap;
392 
393  std::istringstream xml1(R"(<default class="mother">
394  <joint A="a0" B="b0" />
395  <geom A="a0" />
396  <default class="layer1">
397  <joint A="a1" C="c1" />
398  <default class="layer2">
399  <joint B="b2" />
400  <geom C="c2" />
401  </default>
402  </default>
403  <default class="layerP">
404  <joint K="b2" />
405  <site H="f1"/>
406  </default>
407  </default>)");
408  pt::ptree p1;
409  pt::read_xml(xml1, p1, pt::xml_parser::trim_whitespace);
410  BOOST_CHECK(
411  comparePropertyTrees(graph.mapOfClasses.at("mother").classElement, p1.get_child("default")));
412 
413  std::istringstream xml2(R"(<default class="layer1">
414  <joint A="a1" B="b0" C="c1" />
415  <default class="layer2">
416  <joint B="b2" />
417  <geom C="c2" />
418  </default>
419  <geom A="a0" />
420  </default>)");
421  pt::ptree p2;
422  pt::read_xml(xml2, p2, pt::xml_parser::trim_whitespace);
423  BOOST_CHECK(
424  comparePropertyTrees(graph.mapOfClasses.at("layer1").classElement, p2.get_child("default")));
425  std::string name = "layer1";
426  TrueMap.insert(std::make_pair(name, p2.get_child("default")));
427 
428  std::istringstream xml3(R"(<default class="layer2">
429  <joint A="a1" B="b2" C="c1"/>
430  <geom A="a0" C="c2"/>
431  </default>)");
432  pt::ptree p3;
433  pt::read_xml(xml3, p3, pt::xml_parser::trim_whitespace);
434  BOOST_CHECK(
435  comparePropertyTrees(graph.mapOfClasses.at("layer2").classElement, p3.get_child("default")));
436 
437  std::istringstream xml4(R"(<default class="layerP">
438  <joint A="a0" B="b0" K="b2"/>
439  <site H="f1"/>
440  <geom A="a0"/>
441  </default>)");
442  pt::ptree p4;
443  pt::read_xml(xml4, p4, pt::xml_parser::trim_whitespace);
444  BOOST_CHECK(
445  comparePropertyTrees(graph.mapOfClasses.at("layerP").classElement, p4.get_child("default")));
446 }
447 
448 #ifdef PINOCCHIO_WITH_URDFDOM
449 // @brief Test to check that default classes and child classes are taken into account
450 BOOST_AUTO_TEST_CASE(parse_default_class)
451 {
453  typedef pinocchio::SE3::Matrix3 Matrix3;
454 
455  std::string filename = PINOCCHIO_MODEL_DIR + std::string("/../unittest/models/test_mjcf.xml");
456 
457  pinocchio::Model model_m;
458  pinocchio::mjcf::buildModel(filename, model_m);
459 
460  std::string file_u = PINOCCHIO_MODEL_DIR + std::string("/../unittest/models/test_mjcf.urdf");
461  pinocchio::Model model_u;
462  pinocchio::urdf::buildModel(file_u, model_u);
463 
465  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
466  idx = model_u.addJoint(
468  model_u.appendBodyToJoint(idx, inertia);
469 
470  for (int i = 0; i < model_m.njoints; i++)
471  BOOST_CHECK_EQUAL(model_m.joints[i], model_u.joints[i]);
472 }
473 #endif // PINOCCHIO_WITH_URDFDOM
474 
476 BOOST_AUTO_TEST_CASE(parse_dirs_no_strippath)
477 {
478 #ifdef _WIN32
479  std::istringstream xmlDataNoStrip(R"(<mujoco model="parseDirs">
480  <compiler meshdir="meshes" texturedir="textures"/>
481  <asset>
482  <texture name="testTexture" file="texture.png" type="2d"/>
483  <material name="matTest" texture="testTexture"/>
484  <mesh file="C://auto/mesh.obj"/>
485  </asset>
486  </mujoco>)");
487 #else
488  std::istringstream xmlDataNoStrip(R"(<mujoco model="parseDirs">
489  <compiler meshdir="meshes" texturedir="textures"/>
490  <asset>
491  <texture name="testTexture" file="texture.png" type="2d"/>
492  <material name="matTest" texture="testTexture"/>
493  <mesh file="/auto/mesh.obj"/>
494  </asset>
495  </mujoco>)");
496 #endif
497 
498  auto namefile = createTempFile(xmlDataNoStrip);
499 
500  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
501  pinocchio::Model model_m;
502  MjcfGraph::UrdfVisitor visitor(model_m);
503 
504  MjcfGraph graph(visitor, "/fakeMjcf/fake.xml");
505  graph.parseGraphFromXML(namefile.name());
506 
507  // Test texture
508  pinocchio::mjcf::details::MjcfTexture text = graph.mapOfTextures.at("testTexture");
509  BOOST_CHECK_EQUAL(text.textType, "2d");
510  BOOST_CHECK_EQUAL(
511  boost::filesystem::path(text.filePath).generic_string(), "/fakeMjcf/textures/texture.png");
512  // Test Material
513  pinocchio::mjcf::details::MjcfMaterial mat = graph.mapOfMaterials.at("matTest");
514  BOOST_CHECK_EQUAL(mat.texture, "testTexture");
515  // Test Meshes
516  pinocchio::mjcf::details::MjcfMesh mesh = graph.mapOfMeshes.at("mesh");
517 #ifdef _WIN32
518  BOOST_CHECK_EQUAL(boost::filesystem::path(mesh.filePath).generic_string(), "C://auto/mesh.obj");
519 #else
520  BOOST_CHECK_EQUAL(boost::filesystem::path(mesh.filePath).generic_string(), "/auto/mesh.obj");
521 #endif
522 }
523 
526 BOOST_AUTO_TEST_CASE(parse_dirs_strippath)
527 {
528  std::istringstream xmlDataNoStrip(R"(<mujoco model="parseDirs">
529  <compiler meshdir="meshes" texturedir="textures" strippath="true"/>
530  <asset>
531  <mesh file="/auto/mesh.obj"/>
532  </asset>
533  </mujoco>)");
534 
535  auto namefile = createTempFile(xmlDataNoStrip);
536 
537  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
538  pinocchio::Model model_m;
539  MjcfGraph::UrdfVisitor visitor(model_m);
540 
541  MjcfGraph graph(visitor, "/fakeMjcf/fake.xml");
542  graph.parseGraphFromXML(namefile.name());
543 
544  // Test Meshes
545  pinocchio::mjcf::details::MjcfMesh mesh = graph.mapOfMeshes.at("mesh");
546  BOOST_CHECK_EQUAL(
547  boost::filesystem::path(mesh.filePath).generic_string(), "/fakeMjcf/meshes/mesh.obj");
548 }
549 
550 // Test for parsing Revolute
552 {
554  typedef pinocchio::SE3::Matrix3 Matrix3;
555 
556  std::istringstream xmlData(R"(
557  <mujoco model="model_RX">
558  <worldbody>
559  <body name="link0">
560  <body name="link1" pos="0 0 0">
561  <joint name="joint1" type="hinge" axis="1 0 0"/>
562  </body>
563  </body>
564  </worldbody>
565  </mujoco>)");
566 
567  auto namefile = createTempFile(xmlData);
568 
569  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
570  pinocchio::Model model_m, modelRX;
571  MjcfGraph::UrdfVisitor visitor(model_m);
572 
573  MjcfGraph graph(visitor, "fakeMjcf");
574  graph.parseGraphFromXML(namefile.name());
575  graph.parseRootTree();
576 
578  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
579 
580  idx = modelRX.addJoint(0, pinocchio::JointModelRX(), pinocchio::SE3::Identity(), "rx");
581  modelRX.appendBodyToJoint(idx, inertia);
582 
583  for (int i = 0; i < model_m.njoints; i++)
584  BOOST_CHECK_EQUAL(model_m.joints[i], modelRX.joints[i]);
585 }
586 
587 // Test for parsing prismatic
589 {
591  typedef pinocchio::SE3::Matrix3 Matrix3;
592 
593  std::istringstream xmlData(R"(
594  <mujoco model="model_PX">
595  <worldbody>
596  <body name="link0">
597  <body name="link1" pos="0 0 0">
598  <joint name="joint1" type="slide" axis="1 0 0"/>
599  </body>
600  </body>
601  </worldbody>
602  </mujoco>)");
603 
604  auto namefile = createTempFile(xmlData);
605 
606  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
607  pinocchio::Model model_m, modelPX;
608  MjcfGraph::UrdfVisitor visitor(model_m);
609 
610  MjcfGraph graph(visitor, "fakeMjcf");
611  graph.parseGraphFromXML(namefile.name());
612  graph.parseRootTree();
613 
615  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
616 
617  idx = modelPX.addJoint(0, pinocchio::JointModelPX(), pinocchio::SE3::Identity(), "px");
618  modelPX.appendBodyToJoint(idx, inertia);
619 
620  for (int i = 0; i < model_m.njoints; i++)
621  BOOST_CHECK_EQUAL(model_m.joints[i], modelPX.joints[i]);
622 }
623 
624 // Test parsing sphere
625 BOOST_AUTO_TEST_CASE(parse_Sphere)
626 {
628  typedef pinocchio::SE3::Matrix3 Matrix3;
629 
630  std::istringstream xmlData(R"(
631  <mujoco model="model_Sphere">
632  <worldbody>
633  <body name="link0">
634  <body name="link1" pos="0 0 0">
635  <joint name="joint1" type="ball"/>
636  </body>
637  </body>
638  </worldbody>
639  </mujoco>)");
640 
641  auto namefile = createTempFile(xmlData);
642 
643  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
644  pinocchio::Model model_m, modelS;
645  MjcfGraph::UrdfVisitor visitor(model_m);
646 
647  MjcfGraph graph(visitor, "fakeMjcf");
648  graph.parseGraphFromXML(namefile.name());
649  graph.parseRootTree();
650 
652  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
653 
655  modelS.appendBodyToJoint(idx, inertia);
656 
657  for (int i = 0; i < model_m.njoints; i++)
658  BOOST_CHECK_EQUAL(model_m.joints[i], modelS.joints[i]);
659 }
660 
661 // Test parsing free flyer
663 {
665  typedef pinocchio::SE3::Matrix3 Matrix3;
666 
667  std::istringstream xmlData(R"(
668  <mujoco model="model_Free">
669  <worldbody>
670  <body name="link0">
671  <body name="link1" pos="0 0 0">
672  <freejoint name="joint1"/>
673  </body>
674  </body>
675  </worldbody>
676  </mujoco>)");
677 
678  auto namefile = createTempFile(xmlData);
679 
680  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
681  pinocchio::Model model_m, modelF;
682  MjcfGraph::UrdfVisitor visitor(model_m);
683 
684  MjcfGraph graph(visitor, "fakeMjcf");
685  graph.parseGraphFromXML(namefile.name());
686  graph.parseRootTree();
687 
689  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
690 
692  modelF.appendBodyToJoint(idx, inertia);
693 
694  for (int i = 0; i < model_m.njoints; i++)
695  BOOST_CHECK_EQUAL(model_m.joints[i], modelF.joints[i]);
696 }
697 
698 // Test for Composite RXRY
699 BOOST_AUTO_TEST_CASE(parse_composite_RXRY)
700 {
702  typedef pinocchio::SE3::Matrix3 Matrix3;
703 
704  std::istringstream xmlData(R"(
705  <mujoco model="composite_RXRY">
706  <worldbody>
707  <body name="link0">
708  <body name="link1" pos="0 0 0">
709  <joint name="joint1" type="hinge" axis="1 0 0"/>
710  <joint name="joint2" type="hinge" axis="0 1 0"/>
711  </body>
712  </body>
713  </worldbody>
714  </mujoco>)");
715 
716  auto namefile = createTempFile(xmlData);
717 
718  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
719  pinocchio::Model model_m, modelRXRY;
720  MjcfGraph::UrdfVisitor visitor(model_m);
721 
722  MjcfGraph graph(visitor, "fakeMjcf");
723  graph.parseGraphFromXML(namefile.name());
724  graph.parseRootTree();
725 
727  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
728 
729  pinocchio::JointModelComposite joint_model_RXRY;
730  joint_model_RXRY.addJoint(pinocchio::JointModelRX());
731  joint_model_RXRY.addJoint(pinocchio::JointModelRY());
732 
733  idx = modelRXRY.addJoint(0, joint_model_RXRY, pinocchio::SE3::Identity(), "rxry");
734  modelRXRY.appendBodyToJoint(idx, inertia);
735 
736  for (int i = 0; i < model_m.njoints; i++)
737  BOOST_CHECK_EQUAL(model_m.joints[i], modelRXRY.joints[i]);
738 }
739 
740 // Test for Composite PXPY
741 BOOST_AUTO_TEST_CASE(parse_composite_PXPY)
742 {
744  typedef pinocchio::SE3::Matrix3 Matrix3;
745 
746  std::istringstream xmlData(R"(
747  <mujoco model="composite_PXPY">
748  <worldbody>
749  <body name="link0">
750  <body name="link1" pos="0 0 0">
751  <joint name="joint1" type="slide" axis="1 0 0"/>
752  <joint name="joint2" type="slide" axis="0 1 0"/>
753  </body>
754  </body>
755  </worldbody>
756  </mujoco>)");
757 
758  auto namefile = createTempFile(xmlData);
759 
760  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
761  pinocchio::Model model_m, modelPXPY;
762  MjcfGraph::UrdfVisitor visitor(model_m);
763 
764  MjcfGraph graph(visitor, "fakeMjcf");
765  graph.parseGraphFromXML(namefile.name());
766  graph.parseRootTree();
767 
769  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
770 
771  pinocchio::JointModelComposite joint_model_PXPY;
772  joint_model_PXPY.addJoint(pinocchio::JointModelPX());
773  joint_model_PXPY.addJoint(pinocchio::JointModelPY());
774 
775  idx = modelPXPY.addJoint(0, joint_model_PXPY, pinocchio::SE3::Identity(), "pxpy");
776  modelPXPY.appendBodyToJoint(idx, inertia);
777 
778  for (int i = 0; i < model_m.njoints; i++)
779  BOOST_CHECK_EQUAL(model_m.joints[i], modelPXPY.joints[i]);
780 }
781 
782 // Test for Composite PXRY
783 BOOST_AUTO_TEST_CASE(parse_composite_PXRY)
784 {
786  typedef pinocchio::SE3::Matrix3 Matrix3;
787 
788  std::istringstream xmlData(R"(
789  <mujoco model="composite_PXRY">
790  <worldbody>
791  <body name="link0">
792  <body name="link1" pos="0 0 0">
793  <joint name="joint1" type="slide" axis="1 0 0"/>
794  <joint name="joint2" type="hinge" axis="0 1 0"/>
795  </body>
796  </body>
797  </worldbody>
798  </mujoco>)");
799 
800  auto namefile = createTempFile(xmlData);
801 
802  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
803  pinocchio::Model model_m, modelPXRY;
804  MjcfGraph::UrdfVisitor visitor(model_m);
805 
806  MjcfGraph graph(visitor, "fakeMjcf");
807  graph.parseGraphFromXML(namefile.name());
808  graph.parseRootTree();
809 
811  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
812 
813  pinocchio::JointModelComposite joint_model_PXRY;
814  joint_model_PXRY.addJoint(pinocchio::JointModelPX());
815  joint_model_PXRY.addJoint(pinocchio::JointModelRY());
816 
817  idx = modelPXRY.addJoint(0, joint_model_PXRY, pinocchio::SE3::Identity(), "pxry");
818  modelPXRY.appendBodyToJoint(idx, inertia);
819 
820  for (int i = 0; i < model_m.njoints; i++)
821  BOOST_CHECK_EQUAL(model_m.joints[i], modelPXRY.joints[i]);
822 }
823 
824 // Test for Composite PXSphere
825 BOOST_AUTO_TEST_CASE(parse_composite_PXSphere)
826 {
828  typedef pinocchio::SE3::Matrix3 Matrix3;
829 
830  std::istringstream xmlData(R"(
831  <mujoco model="composite_PXSphere">
832  <worldbody>
833  <body name="link0">
834  <body name="link1" pos="0 0 0">
835  <joint name="joint1" type="slide" axis="1 0 0"/>
836  <joint name="joint2" type="ball"/>
837  </body>
838  </body>
839  </worldbody>
840  </mujoco>)");
841 
842  auto namefile = createTempFile(xmlData);
843 
844  typedef ::pinocchio::mjcf::details::MjcfGraph MjcfGraph;
845  pinocchio::Model model_m, modelPXSphere;
846  MjcfGraph::UrdfVisitor visitor(model_m);
847 
848  MjcfGraph graph(visitor, "fakeMjcf");
849  graph.parseGraphFromXML(namefile.name());
850  graph.parseRootTree();
851 
853  pinocchio::Inertia inertia(0, Vector3(0.0, 0., 0.0), Matrix3::Identity());
854 
855  pinocchio::JointModelComposite joint_model_PXSphere;
856  joint_model_PXSphere.addJoint(pinocchio::JointModelPX());
857  joint_model_PXSphere.addJoint(pinocchio::JointModelSpherical());
858 
859  idx = modelPXSphere.addJoint(0, joint_model_PXSphere, pinocchio::SE3::Identity(), "pxsphere");
860  modelPXSphere.appendBodyToJoint(idx, inertia);
861 
862  for (int i = 0; i < model_m.njoints; i++)
863  BOOST_CHECK_EQUAL(model_m.joints[i], modelPXSphere.joints[i]);
864 }
865 
866 // Test loading a mujoco composite and compare body position with mujoco results
867 BOOST_AUTO_TEST_CASE(parse_composite_Mujoco_comparison)
868 {
869  using namespace pinocchio;
870  std::string filename =
871  PINOCCHIO_MODEL_DIR + std::string("/../unittest/models/test_composite.xml");
872 
875 
876  Data data(model);
877  Eigen::Vector3d q;
878  q << 1.57079633, 0.3, 0.5;
880 
881  FrameIndex f_id = model.getFrameId("body1");
882  SE3 pinPos = data.oMf[f_id];
883 
884  Eigen::Matrix3d refOrient;
885  refOrient << 0, -.9553, .2955, 1, 0, 0, 0, .2955, .9553;
886  Eigen::Vector3d pos;
887  pos << .8522, 2, 0.5223;
888  BOOST_CHECK(pinPos.isApprox(SE3(refOrient, pos), 1e-4));
889 
890  f_id = model.getFrameId("body2");
891  pinPos = data.oMf[f_id];
892 
893  refOrient << 0, -.9553, .2955, 1, 0, 0, 0, .2955, .9553;
894 
895  pos << .8522, 4, 0.5223;
896  BOOST_CHECK(pinPos.isApprox(SE3(refOrient, pos), 1e-4));
897 }
898 
899 // Test laoding a model with a spherical joint and verify that keyframe is valid
900 BOOST_AUTO_TEST_CASE(adding_keyframes)
901 {
902  std::istringstream xmlData(R"(
903  <mujoco model="testKeyFrame">
904  <default>
905  <position ctrllimited="true" ctrlrange="-.1 .1" kp="30"/>
906  <default class="joint">
907  <geom type="cylinder" size=".006" fromto="0 0 0 0 0 .05" rgba=".9 .6 1 1"/>
908  </default>
909  </default>
910  <worldbody>
911  <body name="body1">
912  <freejoint/>
913  <geom type="capsule" size=".01" fromto="0 0 0 .2 0 0"/>
914  <body pos=".2 0 0" name="body2">
915  <joint type="ball" damping=".1"/>
916  <geom type="capsule" size=".01" fromto="0 -.15 0 0 0 0"/>
917  </body>
918  </body>
919  </worldbody>
920  <keyframe>
921  <key name="test"
922  qpos="0 0 0.596
923  0.988015 0 0.154359 0
924  0.988015 0 0.154359 0"/>
925  </keyframe>
926  </mujoco>)");
927 
928  auto namefile = createTempFile(xmlData);
929 
930  pinocchio::Model model_m;
931  pinocchio::mjcf::buildModel(namefile.name(), pinocchio::JointModelFreeFlyer(), model_m);
932 
933  Eigen::VectorXd vect_model = model_m.referenceConfigurations.at("test");
934 
935  Eigen::VectorXd vect_ref(model_m.nq);
936  vect_ref << 0, 0, 0.596, 0, 0.154359, 0, 0.988015, 0, 0.154359, 0, 0.988015;
937 
938  BOOST_CHECK(vect_model.size() == vect_ref.size());
939  BOOST_CHECK(vect_model == vect_ref);
940 }
941 
942 // Test reference positions and how it's included in keyframe
943 BOOST_AUTO_TEST_CASE(reference_positions)
944 {
945  std::istringstream xmlData(R"(
946  <mujoco model="testRefPose">
947  <compiler angle="radian"/>
948  <worldbody>
949  <body name="body1">
950  <body pos=".2 0 0" name="body2">
951  <joint type="slide" ref="0.14"/>
952  <body pos=".2 0 0" name="body3">
953  <joint type="hinge" ref="0.1"/>
954  </body>
955  </body>
956  </body>
957  </worldbody>
958  <keyframe>
959  <key name="test" qpos=".8 .5"/>
960  </keyframe>
961  </mujoco>)");
962 
963  auto namefile = createTempFile(xmlData);
964 
965  pinocchio::Model model_m;
966  pinocchio::mjcf::buildModel(namefile.name(), model_m);
967 
968  Eigen::VectorXd vect_model = model_m.referenceConfigurations.at("test");
969  Eigen::VectorXd vect_ref(model_m.nq);
970  vect_ref << 0.66, 0.4;
971 
972  BOOST_CHECK(vect_model.size() == vect_ref.size());
973  BOOST_CHECK(vect_model == vect_ref);
974 }
975 
976 // Test keyframe and composite joint
977 BOOST_AUTO_TEST_CASE(keyframe_and_composite)
978 {
979  std::istringstream xmlData(R"(
980  <mujoco model="keyframeComposite">
981  <compiler angle="radian"/>
982  <worldbody>
983  <body name="body1">
984  <body pos=".2 0 0" name="body2">
985  <joint type="slide"/>
986  <joint type="hinge"/>
987  <body pos=".2 0 0" name="body3">
988  <joint type="hinge"/>
989  </body>
990  </body>
991  </body>
992  </worldbody>
993  <keyframe>
994  <key name="test" qpos=".8 .5 .5"/>
995  </keyframe>
996  </mujoco>)");
997 
998  auto namefile = createTempFile(xmlData);
999 
1000  pinocchio::Model model_m;
1001  pinocchio::mjcf::buildModel(namefile.name(), model_m);
1002 
1003  Eigen::VectorXd vect_model = model_m.referenceConfigurations.at("test");
1004  Eigen::VectorXd vect_ref(model_m.nq);
1005  vect_ref << 0.8, 0.5, 0.5;
1006 
1007  BOOST_CHECK(vect_model.size() == vect_ref.size());
1008  BOOST_CHECK(vect_model == vect_ref);
1009 }
1010 
1011 // Test site of mjcf model
1013 {
1015  typedef pinocchio::SE3::Matrix3 Matrix3;
1016 
1017  std::istringstream xmlData(R"(
1018  <mujoco model="site">
1019  <compiler angle="radian"/>
1020  <worldbody>
1021  <body name="body1">
1022  <body pos=".2 0 0" name="body2">
1023  <joint type="hinge"/>
1024  <body pos=".2 0 0" name="body3">
1025  <joint type="hinge"/>
1026  <site name="testSite" pos="0.03 0 -0.05"/>
1027  </body>
1028  </body>
1029  </body>
1030  </worldbody>
1031  </mujoco>)");
1032 
1033  auto namefile = createTempFile(xmlData);
1034 
1035  pinocchio::Model model_m;
1036  pinocchio::mjcf::buildModel(namefile.name(), model_m);
1037 
1038  pinocchio::Data data(model_m);
1039 
1040  Matrix3 rotation_matrix;
1041  rotation_matrix << 1., 0., 0., 0., 1., 0., 0., 0., 1.;
1042  pinocchio::SE3 real_placement(rotation_matrix, Vector3(0.03, 0, -0.05));
1043 
1044  BOOST_CHECK(model_m.frames[model_m.getFrameId("testSite")].placement.isApprox(real_placement));
1045 }
1046 
1049 BOOST_AUTO_TEST_CASE(build_model_no_root_joint)
1050 {
1051  using namespace pinocchio;
1052  const std::string filename = PINOCCHIO_MODEL_DIR + std::string("/simple_humanoid.xml");
1053 
1054  pinocchio::Model model_m;
1056 
1057  BOOST_CHECK_EQUAL(model_m.nq, 29);
1058 }
1059 
1060 #ifdef PINOCCHIO_WITH_URDFDOM
1061 BOOST_AUTO_TEST_CASE(compare_to_urdf)
1064 {
1065  using namespace pinocchio;
1066  typedef typename pinocchio::Model::ConfigVectorMap ConfigVectorMap;
1067 
1068  const std::string filename = PINOCCHIO_MODEL_DIR + std::string("/simple_humanoid.xml");
1069 
1070  Model model_m;
1072 
1073  const std::string filename_urdf = PINOCCHIO_MODEL_DIR + std::string("/simple_humanoid.urdf");
1074  const std::string dir_urdf = PINOCCHIO_MODEL_DIR;
1075  pinocchio::Model model_urdf;
1076  pinocchio::urdf::buildModel(filename_urdf, pinocchio::JointModelFreeFlyer(), model_urdf);
1077 
1078  BOOST_CHECK(model_urdf.nq == model_m.nq);
1079  BOOST_CHECK(model_urdf.nv == model_m.nv);
1080  BOOST_CHECK(model_urdf.njoints == model_m.njoints);
1081  BOOST_CHECK(model_urdf.nbodies == model_m.nbodies);
1082  BOOST_CHECK(model_urdf.nframes == model_m.nframes);
1083  BOOST_CHECK(model_urdf.parents == model_m.parents);
1084  BOOST_CHECK(model_urdf.children == model_m.children);
1085  BOOST_CHECK(model_urdf.names == model_m.names);
1086  BOOST_CHECK(model_urdf.subtrees == model_m.subtrees);
1087  BOOST_CHECK(model_urdf.gravity == model_m.gravity);
1088  BOOST_CHECK(model_urdf.name == model_m.name);
1089  BOOST_CHECK(model_urdf.idx_qs == model_m.idx_qs);
1090  BOOST_CHECK(model_urdf.nqs == model_m.nqs);
1091  BOOST_CHECK(model_urdf.idx_vs == model_m.idx_vs);
1092  BOOST_CHECK(model_urdf.nvs == model_m.nvs);
1093 
1094  typename ConfigVectorMap::const_iterator it = model_m.referenceConfigurations.begin();
1095  typename ConfigVectorMap::const_iterator it_model_urdf =
1096  model_urdf.referenceConfigurations.begin();
1097  for (long k = 0; k < (long)model_m.referenceConfigurations.size(); ++k)
1098  {
1099  std::advance(it, k);
1100  std::advance(it_model_urdf, k);
1101  BOOST_CHECK(it->second.size() == it_model_urdf->second.size());
1102  BOOST_CHECK(it->second == it_model_urdf->second);
1103  }
1104 
1105  BOOST_CHECK(model_urdf.armature.size() == model_m.armature.size());
1106 
1107  BOOST_CHECK(model_urdf.armature == model_m.armature);
1108  BOOST_CHECK(model_urdf.friction.size() == model_m.friction.size());
1109  BOOST_CHECK(model_urdf.friction == model_m.friction);
1110 
1111  BOOST_CHECK(model_urdf.damping.size() == model_m.damping.size());
1112 
1113  BOOST_CHECK(model_urdf.damping == model_m.damping);
1114 
1115  BOOST_CHECK(model_urdf.rotorInertia.size() == model_m.rotorInertia.size());
1116 
1117  BOOST_CHECK(model_urdf.rotorInertia == model_m.rotorInertia);
1118 
1119  BOOST_CHECK(model_urdf.rotorGearRatio.size() == model_m.rotorGearRatio.size());
1120 
1121  BOOST_CHECK(model_urdf.rotorGearRatio == model_m.rotorGearRatio);
1122 
1123  BOOST_CHECK(model_urdf.effortLimit.size() == model_m.effortLimit.size());
1124  BOOST_CHECK(model_urdf.effortLimit == model_m.effortLimit);
1125  // Cannot test velocity limit since it does not exist in mjcf
1126 
1127  BOOST_CHECK(model_urdf.lowerPositionLimit.size() == model_m.lowerPositionLimit.size());
1128  BOOST_CHECK(model_urdf.lowerPositionLimit == model_m.lowerPositionLimit);
1129 
1130  BOOST_CHECK(model_urdf.upperPositionLimit.size() == model_m.upperPositionLimit.size());
1131  BOOST_CHECK(model_urdf.upperPositionLimit == model_m.upperPositionLimit);
1132 
1133  for (size_t k = 1; k < model_m.inertias.size(); ++k)
1134  {
1135  BOOST_CHECK(model_urdf.inertias[k].isApprox(model_m.inertias[k]));
1136  }
1137 
1138  for (size_t k = 1; k < model_urdf.jointPlacements.size(); ++k)
1139  {
1140  BOOST_CHECK(model_urdf.jointPlacements[k] == model_m.jointPlacements[k]);
1141  }
1142 
1143  BOOST_CHECK(model_urdf.joints == model_m.joints);
1144 
1145  BOOST_CHECK(model_urdf.frames.size() == model_m.frames.size());
1146  for (size_t k = 1; k < model_urdf.frames.size(); ++k)
1147  {
1148  BOOST_CHECK(model_urdf.frames[k] == model_m.frames[k]);
1149  }
1150 }
1151 #endif // PINOCCHIO_WITH_URDFDOM
1152 
1153 #if defined(PINOCCHIO_WITH_HPP_FCL)
1154 BOOST_AUTO_TEST_CASE(test_geometry_parsing)
1155 {
1156  typedef pinocchio::Model Model;
1158 
1159  // Parse the XML
1160  std::istringstream xmlData(R"(<mujoco model="inertiaFromGeom">
1161  <compiler inertiafromgeom="true" />
1162  <worldbody>
1163  <body pos="0 0 0" name="bodyCylinder">
1164  <geom type="cylinder" size=".01 0.25" pos="0 0 0" quat="1 0 0 0"/>
1165  <body pos="0 0 0" name="bodyBox">
1166  <geom type="box" size=".01 0.01 0.25" pos="0 0 0" quat="1 0 0 0"/>
1167  </body>
1168  <body pos="0 0 0" name="bodyCapsule">
1169  <geom type="capsule" size=".01 0.25" pos="0 0 0" quat="1 0 0 0"/>
1170  </body>
1171  <body pos="0 0 0" name="bodySphere">
1172  <geom type="sphere" size=".01" pos="0 0 0" quat="1 0 0 0"/>
1173  </body>
1174  <body pos="0 0 0" name="bodyEllip">
1175  <geom type="ellipsoid" size=".01 0.01 0.25" pos="0 0 0" quat="1 0 0 0"/>
1176  </body>
1177  </body>
1178  </worldbody>
1179  </mujoco>)");
1180 
1181  auto namefile = createTempFile(xmlData);
1182 
1183  Model model_m;
1184  pinocchio::mjcf::buildModel(namefile.name(), model_m);
1185 
1186  GeometryModel geomModel_m;
1187  pinocchio::mjcf::buildGeom(model_m, namefile.name(), pinocchio::COLLISION, geomModel_m);
1188 
1189  BOOST_CHECK(geomModel_m.ngeoms == 5);
1190 
1191  auto * cyl = dynamic_cast<hpp::fcl::Cylinder *>(geomModel_m.geometryObjects.at(0).geometry.get());
1192  BOOST_REQUIRE(cyl);
1193  BOOST_CHECK(cyl->halfLength == 0.25);
1194  BOOST_CHECK(cyl->radius == 0.01);
1195 
1196  auto * cap = dynamic_cast<hpp::fcl::Capsule *>(geomModel_m.geometryObjects.at(2).geometry.get());
1197  BOOST_REQUIRE(cap);
1198  BOOST_CHECK(cap->halfLength == 0.25);
1199  BOOST_CHECK(cap->radius == 0.01);
1200 
1201  auto * s = dynamic_cast<hpp::fcl::Sphere *>(geomModel_m.geometryObjects.at(3).geometry.get());
1202  BOOST_REQUIRE(s);
1203  BOOST_CHECK(s->radius == 0.01);
1204 
1205  auto * b = dynamic_cast<hpp::fcl::Box *>(geomModel_m.geometryObjects.at(1).geometry.get());
1206  BOOST_REQUIRE(b);
1207  Eigen::Vector3d sides;
1208  sides << 0.01, 0.01, 0.25;
1209  BOOST_CHECK(b->halfSide == sides);
1210 
1211  auto * e = dynamic_cast<hpp::fcl::Ellipsoid *>(geomModel_m.geometryObjects.at(4).geometry.get());
1212  BOOST_REQUIRE(e);
1213  BOOST_CHECK(e->radii == sides);
1214 }
1215 #endif // if defined(PINOCCHIO_WITH_HPP_FCL)
1216 
1217 BOOST_AUTO_TEST_SUITE_END()
meshcat-viewer.mesh
mesh
Definition: meshcat-viewer.py:53
pinocchio::InertiaTpl< context::Scalar, context::Options >
pinocchio::InertiaTpl::isEqual
bool isEqual(const InertiaTpl &Y2) const
Definition: spatial/inertia.hpp:578
pinocchio::FrameIndex
Index FrameIndex
Definition: multibody/fwd.hpp:28
frames.hpp
pinocchio::ModelTpl::names
std::vector< std::string > names
Name of the joints.
Definition: multibody/model.hpp:143
pinocchio::InertiaTpl< context::Scalar, context::Options >::FromEllipsoid
static InertiaTpl FromEllipsoid(const Scalar mass, const Scalar x, const Scalar y, const Scalar z)
Computes the Inertia of an ellipsoid defined by its mass and main semi-axis dimensions (x,...
Definition: spatial/inertia.hpp:384
pinocchio::SE3Tpl< context::Scalar, context::Options >::Vector3
traits< SE3Tpl >::Vector3 Vector3
Definition: spatial/se3-tpl.hpp:55
pinocchio::ModelTpl::frames
FrameVector frames
Vector of operational frames registered on the model.
Definition: multibody/model.hpp:177
pinocchio::DataTpl
Definition: context/generic.hpp:25
pinocchio::mjcf::details::MjcfTexture::textType
std::string textType
Definition: mjcf-graph.hpp:217
pinocchio::ModelTpl::jointPlacements
SE3Vector jointPlacements
Vector of joint placements: placement of a joint i wrt its parent joint frame.
Definition: multibody/model.hpp:117
pinocchio::mjcf::details::MjcfMesh
All informations related to a mesh are stored here.
Definition: mjcf-graph.hpp:205
pinocchio::ModelTpl::lowerPositionLimit
ConfigVectorType lowerPositionLimit
Lower joint configuration limit.
Definition: multibody/model.hpp:171
pinocchio::mjcf::details::UrdfVisitor
pinocchio::urdf::details::UrdfVisitor< double, 0, ::pinocchio::JointCollectionDefaultTpl > UrdfVisitor
Definition: mjcf-graph.cpp:16
mjcf.hpp
pinocchio::SE3Tpl< context::Scalar, context::Options >
pinocchio::mjcf::buildModel
ModelTpl< Scalar, Options, JointCollectionTpl > & buildModel(const std::string &filename, const typename ModelTpl< Scalar, Options, JointCollectionTpl >::JointModel &rootJoint, ModelTpl< Scalar, Options, JointCollectionTpl > &model, const bool verbose=false)
Build the model from a MJCF file with a particular joint as root of the model tree inside the model g...
inverse-kinematics.i
int i
Definition: inverse-kinematics.py:20
model.hpp
hpp::fcl::Sphere
setup.data
data
Definition: cmake/cython/setup.in.py:48
boost
pinocchio::ModelTpl::joints
JointModelVector joints
Vector of joint models.
Definition: multibody/model.hpp:120
pinocchio::JointModelFreeFlyerTpl
Definition: multibody/joint/fwd.hpp:110
pinocchio::mjcf::details::MjcfMaterial
All informations related to material are stored here.
Definition: mjcf-graph.hpp:225
pinocchio::ModelTpl::name
std::string name
Model name.
Definition: multibody/model.hpp:198
pinocchio::python::context::Model
ModelTpl< Scalar, Options > Model
Definition: bindings/python/context/generic.hpp:61
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:279
hpp::fcl::Cylinder
pinocchio::ModelTpl::addJoint
JointIndex addJoint(const JointIndex parent, const JointModel &joint_model, const SE3 &joint_placement, const std::string &joint_name)
Add a joint to the kinematic tree with infinite bounds.
b
Vec3f b
pinocchio::ModelTpl::rotorInertia
TangentVectorType rotorInertia
Vector of rotor inertia parameters.
Definition: multibody/model.hpp:153
anymal-simulation.model
model
Definition: anymal-simulation.py:12
pinocchio::ModelTpl::inertias
InertiaVector inertias
Vector of spatial inertias supported by each joint.
Definition: multibody/model.hpp:114
pinocchio::SE3Tpl< context::Scalar, context::Options >::Matrix3
traits< SE3Tpl >::Matrix3 Matrix3
Definition: spatial/se3-tpl.hpp:56
pinocchio::ModelTpl::JointIndex
pinocchio::JointIndex JointIndex
Definition: multibody/model.hpp:68
pinocchio::ModelTpl::referenceConfigurations
ConfigVectorMap referenceConfigurations
Map of reference configurations, indexed by user given names.
Definition: multibody/model.hpp:146
pinocchio::ModelTpl::subtrees
std::vector< IndexVector > subtrees
Vector of joint subtrees. subtree[j] corresponds to the subtree supported by the joint j....
Definition: multibody/model.hpp:189
pinocchio::GeometryModel::geometryObjects
GeometryObjectVector geometryObjects
Vector of GeometryObjects used for collision computations.
Definition: multibody/geometry.hpp:217
hpp::fcl::Ellipsoid
pinocchio::mjcf::details::MjcfBody::geomChildren
std::vector< MjcfGeom > geomChildren
Definition: mjcf-graph.hpp:109
joint-configuration.hpp
meshcat-viewer-dae.s
s
Definition: meshcat-viewer-dae.py:28
pinocchio::JointModelPrismaticTpl
Definition: multibody/joint/fwd.hpp:89
pinocchio::ModelTpl::nqs
std::vector< int > nqs
Vector of dimension of the joint configuration subspace.
Definition: multibody/model.hpp:126
pinocchio::ModelTpl::nvs
std::vector< int > nvs
Dimension of the *i*th joint tangent subspace.
Definition: multibody/model.hpp:132
pinocchio::ModelTpl::appendBodyToJoint
void appendBodyToJoint(const JointIndex joint_index, const Inertia &Y, const SE3 &body_placement=SE3::Identity())
Append a body to a given joint of the kinematic tree.
pinocchio::ModelTpl::children
std::vector< IndexVector > children
Vector of children index. Chidren of the i*th joint, denoted *mu(i) corresponds to the set (i==parent...
Definition: multibody/model.hpp:140
pinocchio::urdf::buildModel
ModelTpl< Scalar, Options, JointCollectionTpl > & buildModel(const std::string &filename, const typename ModelTpl< Scalar, Options, JointCollectionTpl >::JointModel &rootJoint, ModelTpl< Scalar, Options, JointCollectionTpl > &model, const bool verbose=false)
Build the model from a URDF file with a particular joint as root of the model tree inside the model g...
pinocchio::ModelTpl::idx_qs
std::vector< int > idx_qs
Vector of starting index of the *i*th joint in the configuration space.
Definition: multibody/model.hpp:123
pinocchio::mjcf::details::MjcfTexture::filePath
std::string filePath
Definition: mjcf-graph.hpp:219
filename
filename
pinocchio::ModelTpl::getFrameId
FrameIndex getFrameId(const std::string &name, const FrameType &type=(FrameType)(JOINT|FIXED_JOINT|BODY|OP_FRAME|SENSOR)) const
Returns the index of a frame given by its name.
urdf.hpp
mat
mat
pinocchio::ModelTpl::rotorGearRatio
TangentVectorType rotorGearRatio
Vector of rotor gear ratio parameters.
Definition: multibody/model.hpp:156
pinocchio::ModelTpl::armature
VectorXs armature
Vector of armature values expressed at the joint level This vector may contain the contribution of ro...
Definition: multibody/model.hpp:150
pinocchio::InertiaTpl< context::Scalar, context::Options >::FromCapsule
static InertiaTpl FromCapsule(const Scalar mass, const Scalar radius, const Scalar height)
Computes the Inertia of a capsule defined by its mass, radius and length along the Z axis....
Definition: spatial/inertia.hpp:434
comparePropertyTrees
static bool comparePropertyTrees(const boost::property_tree::ptree &pt1, const boost::property_tree::ptree &pt2)
Definition: mjcf.cpp:69
pinocchio::JointModelSphericalTpl
Definition: multibody/joint/fwd.hpp:73
pos
pos
pinocchio::ModelTpl::nframes
int nframes
Number of operational frames.
Definition: multibody/model.hpp:111
pinocchio::context::Vector3
Eigen::Matrix< Scalar, 3, 1, Options > Vector3
Definition: context/generic.hpp:53
pinocchio::mjcf::details::ptree
boost::property_tree::ptree ptree
Definition: mjcf-graph.cpp:13
pinocchio::ModelTpl::nbodies
int nbodies
Number of bodies.
Definition: multibody/model.hpp:108
pinocchio::ModelTpl::friction
TangentVectorType friction
Vector of joint friction parameters.
Definition: multibody/model.hpp:159
setup.name
name
Definition: cmake/cython/setup.in.py:179
hpp::fcl::Capsule
pinocchio::GeometryModel::ngeoms
Index ngeoms
The number of GeometryObjects.
Definition: multibody/geometry.hpp:214
pinocchio::framesForwardKinematics
void framesForwardKinematics(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< ConfigVectorType > &q)
First calls the forwardKinematics on the model, then computes the placement of each frame....
pinocchio::mjcf::buildGeom
GeometryModel & buildGeom(ModelTpl< Scalar, Options, JointCollectionTpl > &model, const std::string &filename, const GeometryType type, GeometryModel &geom_model, ::hpp::fcl::MeshLoaderPtr mesh_loader=::hpp::fcl::MeshLoaderPtr())
Build The GeometryModel from a Mjcf file.
BOOST_AUTO_TEST_CASE
BOOST_AUTO_TEST_CASE(convert_inertia_fullinertia)
Definition: mjcf.cpp:99
pinocchio::JointModelRevoluteTpl
Definition: multibody/joint/fwd.hpp:33
anymal-simulation.mass
mass
Definition: anymal-simulation.py:77
pinocchio::ModelTpl::gravity
Motion gravity
Spatial gravity of the model.
Definition: multibody/model.hpp:192
pinocchio::q
JointCollectionTpl const Eigen::MatrixBase< ConfigVectorType > & q
Definition: joint-configuration.hpp:1117
p1
tuple p1
pinocchio::JointModelCompositeTpl
Definition: multibody/joint/fwd.hpp:141
createTempFile
static TemporaryFileHolder createTempFile(const std::istringstream &data)
Definition: mjcf.cpp:52
pinocchio::ModelTpl::damping
TangentVectorType damping
Vector of joint damping parameters.
Definition: multibody/model.hpp:162
pinocchio::ModelTpl::nv
int nv
Dimension of the velocity vector space.
Definition: multibody/model.hpp:102
pinocchio::ModelTpl::ConfigVectorMap
std::map< std::string, ConfigVectorType > ConfigVectorMap
Map between a string (key) and a configuration vector.
Definition: multibody/model.hpp:91
pinocchio::SE3Tpl< context::Scalar, context::Options >::Identity
static SE3Tpl Identity()
Definition: spatial/se3-tpl.hpp:136
graph
Definition: graph.py:1
pinocchio::mjcf::details::MjcfBody
All Bodies informations extracted from mjcf model.
Definition: mjcf-graph.hpp:88
joints.hpp
pinocchio::ModelTpl::effortLimit
TangentVectorType effortLimit
Vector of maximal joint torques.
Definition: multibody/model.hpp:165
pinocchio::InertiaTpl< context::Scalar, context::Options >::FromBox
static InertiaTpl FromBox(const Scalar mass, const Scalar x, const Scalar y, const Scalar z)
Computes the Inertia of a box defined by its mass and main dimensions (x,y,z).
Definition: spatial/inertia.hpp:418
pinocchio::GeometryModel
Definition: multibody/geometry.hpp:50
pinocchio::ModelTpl::parents
std::vector< JointIndex > parents
Vector of parent joint indexes. The parent of joint i, denoted li, corresponds to li==parents[i].
Definition: multibody/model.hpp:136
pinocchio::COLLISION
@ COLLISION
Definition: multibody/geometry-object.hpp:27
pinocchio::InertiaTpl< context::Scalar, context::Options >::FromSphere
static InertiaTpl FromSphere(const Scalar mass, const Scalar radius)
Computes the Inertia of a sphere defined by its mass and its radius.
Definition: spatial/inertia.hpp:369
pinocchio::ModelTpl::idx_vs
std::vector< int > idx_vs
Starting index of the *i*th joint in the tangent configuration space.
Definition: multibody/model.hpp:129
casadi-quadrotor-ocp.path
path
Definition: casadi-quadrotor-ocp.py:10
pinocchio::ModelTpl
Definition: context/generic.hpp:20
pinocchio::ModelTpl::upperPositionLimit
ConfigVectorType upperPositionLimit
Upper joint configuration limit.
Definition: multibody/model.hpp:174
pinocchio::InertiaTpl< context::Scalar, context::Options >::FromCylinder
static InertiaTpl FromCylinder(const Scalar mass, const Scalar radius, const Scalar length)
Computes the Inertia of a cylinder defined by its mass, radius and length along the Z axis.
Definition: spatial/inertia.hpp:401
operator=
AABB & operator=(const AABB &other)=default
pinocchio::ModelTpl::nq
int nq
Dimension of the configuration vector representation.
Definition: multibody/model.hpp:99
pinocchio::mjcf::details::MjcfTexture
All informations related to a texture are stored here.
Definition: mjcf-graph.hpp:214
pinocchio::model
JointCollectionTpl & model
Definition: joint-configuration.hpp:1116
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27
pinocchio::ModelTpl::njoints
int njoints
Number of joints.
Definition: multibody/model.hpp:105
hpp::fcl::Box
BOOST_CHECK
#define BOOST_CHECK(check)
Definition: overview-urdf.cpp:34
PINOCCHIO_MODEL_DIR
#define PINOCCHIO_MODEL_DIR
Definition: build-reduced-model.cpp:11


pinocchio
Author(s):
autogenerated on Sat Jun 22 2024 02:41:49