GCC Code Coverage Report


Directory: ./
File: unittest/joint-generic.cpp
Date: 2024-08-27 18:20:05
Exec Total Coverage
Lines: 0 169 0.0%
Branches: 0 1281 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2016-2019 CNRS INRIA
3 //
4
5 #include "pinocchio/multibody/joint/joint-generic.hpp"
6
7 #include "pinocchio/multibody/liegroup/liegroup.hpp"
8
9 #include "pinocchio/multibody/model.hpp"
10
11 #include "pinocchio/algorithm/joint-configuration.hpp"
12
13 #include <iostream>
14 #include <boost/test/unit_test.hpp>
15 #include <boost/utility/binary.hpp>
16
17 using namespace pinocchio;
18
19 template<typename JointModel>
20 void test_joint_methods(
21 JointModelBase<JointModel> & jmodel, JointDataBase<typename JointModel::JointDataDerived> & jdata)
22 {
23 typedef typename LieGroup<JointModel>::type LieGroupType;
24 typedef typename JointModel::JointDataDerived JointData;
25
26 std::cout << "Testing Joint over " << jmodel.shortname() << std::endl;
27
28 Eigen::VectorXd q1, q2;
29 Eigen::VectorXd armature =
30 Eigen::VectorXd::Random(jdata.S().nv()) + Eigen::VectorXd::Ones(jdata.S().nv());
31
32 q1 = LieGroupType().random();
33 q2 = LieGroupType().random();
34
35 Eigen::VectorXd v1(Eigen::VectorXd::Random(jdata.S().nv())),
36 v2(Eigen::VectorXd::Random(jdata.S().nv()));
37
38 Inertia::Matrix6 Ia(pinocchio::Inertia::Random().matrix()),
39 Ia2(pinocchio::Inertia::Random().matrix());
40 bool update_I = false;
41
42 jmodel.calc(jdata.derived(), q1, v1);
43 jmodel.calc_aba(jdata.derived(), armature, Ia, update_I);
44
45 pinocchio::JointModel jma(jmodel);
46 BOOST_CHECK(jmodel == jma);
47 BOOST_CHECK(jma == jmodel);
48 BOOST_CHECK(jma.hasSameIndexes(jmodel));
49
50 pinocchio::JointData jda(jdata.derived());
51 BOOST_CHECK(jda == jdata);
52 BOOST_CHECK(jdata == jda);
53
54 jma.calc(jda, q1, v1);
55 jma.calc_aba(jda, armature, Ia, update_I);
56 pinocchio::JointData jda_other(jdata);
57
58 jma.calc(jda_other, q2, v2);
59 jma.calc_aba(jda_other, armature, Ia2, update_I);
60
61 BOOST_CHECK(jda_other != jda);
62 BOOST_CHECK(jda != jda_other);
63 BOOST_CHECK(jda_other != jdata);
64 BOOST_CHECK(jdata != jda_other);
65
66 const std::string error_prefix("JointModel on " + jma.shortname());
67 BOOST_CHECK_MESSAGE(jmodel.nq() == jma.nq(), std::string(error_prefix + " - nq "));
68 BOOST_CHECK_MESSAGE(jmodel.nv() == jma.nv(), std::string(error_prefix + " - nv "));
69
70 BOOST_CHECK_MESSAGE(jmodel.idx_q() == jma.idx_q(), std::string(error_prefix + " - Idx_q "));
71 BOOST_CHECK_MESSAGE(jmodel.idx_v() == jma.idx_v(), std::string(error_prefix + " - Idx_v "));
72 BOOST_CHECK_MESSAGE(jmodel.id() == jma.id(), std::string(error_prefix + " - JointId "));
73
74 BOOST_CHECK_MESSAGE(
75 jda.S().matrix().isApprox(jdata.S().matrix()),
76 std::string(error_prefix + " - JointMotionSubspaceXd "));
77 BOOST_CHECK_MESSAGE(
78 (jda.M()).isApprox((jdata.M())),
79 std::string(error_prefix + " - Joint transforms ")); // == or isApprox ?
80 BOOST_CHECK_MESSAGE(
81 (jda.v()).isApprox((pinocchio::Motion(jdata.v()))),
82 std::string(error_prefix + " - Joint motions "));
83 BOOST_CHECK_MESSAGE((jda.c()) == (jdata.c()), std::string(error_prefix + " - Joint bias "));
84
85 BOOST_CHECK_MESSAGE(
86 (jda.U()).isApprox(jdata.U()),
87 std::string(error_prefix + " - Joint U inertia matrix decomposition "));
88 BOOST_CHECK_MESSAGE(
89 (jda.Dinv()).isApprox(jdata.Dinv()),
90 std::string(error_prefix + " - Joint DInv inertia matrix decomposition "));
91 BOOST_CHECK_MESSAGE(
92 (jda.UDinv()).isApprox(jdata.UDinv()),
93 std::string(error_prefix + " - Joint UDInv inertia matrix decomposition "));
94
95 // Test vxS
96 typedef typename JointModel::Constraint_t Constraint_t;
97 typedef typename Constraint_t::DenseBase ConstraintDense;
98
99 Motion v(Motion::Random());
100 ConstraintDense vxS(v.cross(jdata.S()));
101 ConstraintDense vxS_ref = v.toActionMatrix() * jdata.S().matrix();
102
103 BOOST_CHECK_MESSAGE(vxS.isApprox(vxS_ref), std::string(error_prefix + "- Joint vxS operation "));
104
105 // Test Y*S
106 const Inertia Isparse(Inertia::Random());
107 const Inertia::Matrix6 Idense(Isparse.matrix());
108
109 const ConstraintDense IsparseS = Isparse * jdata.S();
110 const ConstraintDense IdenseS = Idense * jdata.S();
111
112 BOOST_CHECK_MESSAGE(
113 IdenseS.isApprox(IsparseS), std::string(error_prefix + "- Joint YS operation "));
114
115 // Test calc
116 {
117 JointData jdata1(jdata.derived());
118
119 jmodel.calc(jdata1.derived(), q1, v1);
120 jmodel.calc(jdata1.derived(), Blank(), v2);
121
122 JointData jdata_ref(jdata.derived());
123 jmodel.calc(jdata_ref.derived(), q1, v2);
124
125 BOOST_CHECK_MESSAGE(
126 pinocchio::JointData(jdata1).v() == pinocchio::JointData(jdata_ref).v(),
127 std::string(error_prefix + "- joint.calc(jdata,*,v) "));
128 }
129 }
130
131 template<typename JointModel_>
132 struct init;
133
134 template<typename JointModel_>
135 struct init
136 {
137 static JointModel_ run()
138 {
139 JointModel_ jmodel;
140 jmodel.setIndexes(0, 0, 0);
141 return jmodel;
142 }
143 };
144
145 template<typename Scalar, int Options>
146 struct init<pinocchio::JointModelRevoluteUnalignedTpl<Scalar, Options>>
147 {
148 typedef pinocchio::JointModelRevoluteUnalignedTpl<Scalar, Options> JointModel;
149
150 static JointModel run()
151 {
152 typedef typename JointModel::Vector3 Vector3;
153 JointModel jmodel(Vector3::Random().normalized());
154
155 jmodel.setIndexes(0, 0, 0);
156 return jmodel;
157 }
158 };
159
160 template<typename Scalar, int Options>
161 struct init<pinocchio::JointModelRevoluteUnboundedUnalignedTpl<Scalar, Options>>
162 {
163 typedef pinocchio::JointModelRevoluteUnboundedUnalignedTpl<Scalar, Options> JointModel;
164
165 static JointModel run()
166 {
167 typedef typename JointModel::Vector3 Vector3;
168 JointModel jmodel(Vector3::Random().normalized());
169
170 jmodel.setIndexes(0, 0, 0);
171 return jmodel;
172 }
173 };
174
175 template<typename Scalar, int Options>
176 struct init<pinocchio::JointModelPrismaticUnalignedTpl<Scalar, Options>>
177 {
178 typedef pinocchio::JointModelPrismaticUnalignedTpl<Scalar, Options> JointModel;
179
180 static JointModel run()
181 {
182 typedef typename JointModel::Vector3 Vector3;
183 JointModel jmodel(Vector3::Random().normalized());
184
185 jmodel.setIndexes(0, 0, 0);
186 return jmodel;
187 }
188 };
189
190 template<typename Scalar, int Options, template<typename, int> class JointCollection>
191 struct init<pinocchio::JointModelTpl<Scalar, Options, JointCollection>>
192 {
193 typedef pinocchio::JointModelTpl<Scalar, Options, JointCollection> JointModel;
194
195 static JointModel run()
196 {
197 typedef pinocchio::JointModelRevoluteTpl<Scalar, Options, 0> JointModelRX;
198 JointModel jmodel((JointModelRX()));
199
200 jmodel.setIndexes(0, 0, 0);
201 return jmodel;
202 }
203 };
204
205 template<typename Scalar, int Options, template<typename, int> class JointCollection>
206 struct init<pinocchio::JointModelCompositeTpl<Scalar, Options, JointCollection>>
207 {
208 typedef pinocchio::JointModelCompositeTpl<Scalar, Options, JointCollection> JointModel;
209
210 static JointModel run()
211 {
212 typedef pinocchio::JointModelRevoluteTpl<Scalar, Options, 0> JointModelRX;
213 typedef pinocchio::JointModelRevoluteTpl<Scalar, Options, 1> JointModelRY;
214 JointModel jmodel((JointModelRX()));
215 jmodel.addJoint(JointModelRY());
216
217 jmodel.setIndexes(0, 0, 0);
218 return jmodel;
219 }
220 };
221
222 template<typename JointModel_>
223 struct init<pinocchio::JointModelMimic<JointModel_>>
224 {
225 typedef pinocchio::JointModelMimic<JointModel_> JointModel;
226
227 static JointModel run()
228 {
229 JointModel_ jmodel_ref = init<JointModel_>::run();
230
231 JointModel jmodel(jmodel_ref, 1., 0.);
232 jmodel.setIndexes(0, 0, 0);
233
234 return jmodel;
235 }
236 };
237
238 template<typename Scalar, int Options>
239 struct init<pinocchio::JointModelUniversalTpl<Scalar, Options>>
240 {
241 typedef pinocchio::JointModelUniversalTpl<Scalar, Options> JointModel;
242
243 static JointModel run()
244 {
245 typedef typename JointModel::Vector3 Vector3;
246 JointModel jmodel(XAxis::vector(), YAxis::vector());
247
248 jmodel.setIndexes(0, 0, 0);
249 return jmodel;
250 }
251 };
252
253 template<typename Scalar, int Options, int axis>
254 struct init<pinocchio::JointModelHelicalTpl<Scalar, Options, axis>>
255 {
256 typedef pinocchio::JointModelHelicalTpl<Scalar, Options, axis> JointModel;
257
258 static JointModel run()
259 {
260 JointModel jmodel(static_cast<Scalar>(0.5));
261
262 jmodel.setIndexes(0, 0, 0);
263 return jmodel;
264 }
265 };
266
267 template<typename Scalar, int Options>
268 struct init<pinocchio::JointModelHelicalUnalignedTpl<Scalar, Options>>
269 {
270 typedef pinocchio::JointModelHelicalUnalignedTpl<Scalar, Options> JointModel;
271
272 static JointModel run()
273 {
274 typedef typename JointModel::Vector3 Vector3;
275 JointModel jmodel(Vector3::Random().normalized());
276
277 jmodel.setIndexes(0, 0, 0);
278 return jmodel;
279 }
280 };
281
282 struct TestJoint
283 {
284
285 template<typename JointModel>
286 void operator()(const JointModelBase<JointModel> &) const
287 {
288 JointModel jmodel = init<JointModel>::run();
289 jmodel.setIndexes(0, 0, 0);
290 typename JointModel::JointDataDerived jdata = jmodel.createData();
291
292 test_joint_methods(jmodel, jdata);
293 }
294
295 void operator()(const pinocchio::JointModelComposite &) const
296 {
297 }
298 };
299
300 namespace pinocchio
301 {
302
303 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
304 struct JointTest;
305 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
306 struct JointModelTest;
307 template<typename Scalar, int Options, template<typename, int> class JointCollectionTpl>
308 struct JointDataTest;
309
310 template<typename _Scalar, int _Options, template<typename, int> class JointCollectionTpl>
311 struct traits<JointDataTest<_Scalar, _Options, JointCollectionTpl>>
312 {
313 typedef JointTpl<_Scalar, _Options, JointCollectionTpl> JointDerived;
314 typedef _Scalar Scalar;
315 };
316
317 template<typename _Scalar, int _Options, template<typename, int> class JointCollectionTpl>
318 struct traits<JointModelTest<_Scalar, _Options, JointCollectionTpl>>
319 {
320 typedef JointTpl<_Scalar, _Options, JointCollectionTpl> JointDerived;
321 typedef _Scalar Scalar;
322 };
323
324 template<typename _Scalar, int _Options, template<typename, int> class JointCollectionTpl>
325 struct traits<JointTest<_Scalar, _Options, JointCollectionTpl>>
326 {
327 enum
328 {
329 Options = _Options,
330 NQ = Eigen::Dynamic, // Dynamic because unknown at compile time
331 NV = Eigen::Dynamic
332 };
333 typedef _Scalar Scalar;
334
335 typedef JointDataTpl<Scalar, Options, JointCollectionTpl> JointDataDerived;
336 typedef JointModelTpl<Scalar, Options, JointCollectionTpl> JointModelDerived;
337 typedef JointMotionSubspaceTpl<Eigen::Dynamic, Scalar, Options> Constraint_t;
338 typedef SE3Tpl<Scalar, Options> Transformation_t;
339 typedef MotionTpl<Scalar, Options> Motion_t;
340 typedef MotionTpl<Scalar, Options> Bias_t;
341
342 // [ABA]
343 typedef Eigen::Matrix<Scalar, 6, Eigen::Dynamic, Options> U_t;
344 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Options> D_t;
345 typedef Eigen::Matrix<Scalar, 6, Eigen::Dynamic, Options> UD_t;
346
347 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> ConfigVector_t;
348 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, Options> TangentVector_t;
349 };
350
351 template<typename _Scalar, int _Options, template<typename, int> class JointCollectionTpl>
352 struct JointModelTest
353 : JointCollectionTpl<_Scalar, _Options>::JointModelVariant
354 , JointModelBase<JointModelTest<_Scalar, _Options, JointCollectionTpl>>
355 {
356 typedef JointTest<_Scalar, _Options, JointCollectionTpl> JointDerived;
357 typedef JointCollectionTpl<_Scalar, _Options> JointCollection;
358 typedef typename JointCollection::JointModelVariant VariantBase;
359 typedef typename JointCollection::JointModelVariant JointModelVariant;
360
361 PINOCCHIO_JOINT_TYPEDEF_TEMPLATE(JointDerived);
362
363 JointModelTest(const JointModelVariant & jmodel)
364 : VariantBase(jmodel)
365 {
366 }
367 };
368
369 } // namespace pinocchio
370
371 BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE)
372
373 BOOST_AUTO_TEST_CASE(test_joint_from_joint_composite)
374 {
375 typedef JointCollectionDefault JointCollection;
376 typedef JointCollection::JointModelVariant JointModelVariant;
377
378 JointModelRX jmodel_revolute_x;
379 JointModel jmodel_generic(jmodel_revolute_x);
380 JointModelVariant jmodel_variant(jmodel_revolute_x);
381
382 JointModelTest<double, 0, JointCollectionDefaultTpl> jmodel_test(jmodel_revolute_x);
383 std::vector<JointModelTest<double, 0, JointCollectionDefaultTpl>> jmodel_test_vector;
384 jmodel_test_vector.push_back(
385 JointModelTest<double, 0, JointCollectionDefaultTpl>(jmodel_revolute_x));
386
387 std::vector<JointModelVariant> jmodel_variant_vector;
388 jmodel_variant_vector.push_back(jmodel_revolute_x);
389
390 std::vector<JointModel> jmodel_generic_vector;
391 jmodel_generic_vector.push_back((JointModel)jmodel_revolute_x);
392 JointModelComposite jmodel_composite(jmodel_revolute_x);
393 }
394
395 BOOST_AUTO_TEST_CASE(test_all_joints)
396 {
397 boost::mpl::for_each<JointModelVariant::types>(TestJoint());
398 }
399
400 BOOST_AUTO_TEST_CASE(test_empty_model)
401 {
402 JointModel jmodel;
403 std::cout << "nq " << jmodel.nq() << std::endl;
404 std::cout << "nv " << jmodel.nv() << std::endl;
405 std::cout << "idx_q " << jmodel.idx_q() << std::endl;
406 std::cout << "idx_v " << jmodel.idx_v() << std::endl;
407 std::cout << "id " << jmodel.id() << std::endl;
408 std::cout << "name " << jmodel.shortname() << std::endl;
409
410 BOOST_CHECK(jmodel.idx_q() == -1);
411 BOOST_CHECK(jmodel.idx_v() == -1);
412 }
413
414 BOOST_AUTO_TEST_CASE(isEqual)
415 {
416 JointModelRX joint_revolutex;
417 JointModelRY joint_revolutey;
418
419 BOOST_CHECK(joint_revolutex != joint_revolutey);
420
421 JointModel jmodelx(joint_revolutex);
422 jmodelx.setIndexes(0, 0, 0);
423
424 JointModel jmodelx_copy = jmodelx;
425 BOOST_CHECK(jmodelx_copy == jmodelx);
426 BOOST_CHECK(jmodelx_copy == jmodelx.derived());
427
428 JointModel jmodely(joint_revolutey);
429 // TODO: the comparison of two variants is not supported by some old version of BOOST
430 // BOOST_CHECK(jmodely.toVariant() != jmodelx.toVariant());
431 BOOST_CHECK(jmodely != jmodelx);
432 }
433
434 BOOST_AUTO_TEST_CASE(cast)
435 {
436 JointModelRX joint_revolutex;
437
438 JointModel jmodelx(joint_revolutex);
439 jmodelx.setIndexes(0, 0, 0);
440
441 BOOST_CHECK(jmodelx.cast<double>() == jmodelx);
442 BOOST_CHECK(jmodelx.cast<long double>().cast<double>() == jmodelx);
443 }
444
445 struct TestJointOperatorEqual
446 {
447
448 template<typename JointModel>
449 void operator()(const JointModelBase<JointModel> &) const
450 {
451 JointModel jmodel_init = init<JointModel>::run();
452 typedef typename JointModel::JointDataDerived JointData;
453
454 Model model;
455 model.addJoint(0, jmodel_init, SE3::Random(), "toto");
456 model.lowerPositionLimit.fill(-1.);
457 model.upperPositionLimit.fill(1.);
458
459 const JointModel & jmodel = boost::get<JointModel>(model.joints[1]);
460
461 Eigen::VectorXd q = randomConfiguration(model);
462 Eigen::VectorXd v = Eigen::VectorXd::Random(model.nv);
463
464 JointData jdata = jmodel.createData();
465
466 jmodel.calc(jdata, q, v);
467
468 Eigen::VectorXd armature =
469 Eigen::VectorXd::Random(jmodel.nv()) + Eigen::VectorXd::Ones(jmodel.nv());
470 Inertia::Matrix6 I = Inertia::Matrix6::Identity();
471 jmodel.calc_aba(jdata, armature, I, false);
472 test(jdata);
473 }
474
475 template<typename JointModel>
476 void operator()(const pinocchio::JointModelMimic<JointModel> &) const
477 {
478 }
479
480 template<typename JointData>
481 static void test(const JointData & jdata)
482 {
483 pinocchio::JointData jdata_generic1(jdata);
484
485 std::cout << "name: " << jdata_generic1.shortname() << std::endl;
486 BOOST_CHECK(jdata_generic1 == jdata_generic1);
487 }
488 };
489
490 BOOST_AUTO_TEST_CASE(test_operator_equal)
491 {
492 boost::mpl::for_each<JointModelVariant::types>(TestJointOperatorEqual());
493 }
494
495 BOOST_AUTO_TEST_SUITE_END()
496