GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: unittest/joint-configurations.cpp Lines: 275 275 100.0 %
Date: 2024-01-23 21:41:47 Branches: 1139 2264 50.3 %

Line Branch Exec Source
1
//
2
// Copyright (c) 2016-2020 CNRS INRIA
3
//
4
5
#include "utils/model-generator.hpp"
6
#include "pinocchio/parsers/sample-models.hpp"
7
#include "pinocchio/algorithm/joint-configuration.hpp"
8
#include "pinocchio/math/quaternion.hpp"
9
10
#include <boost/test/unit_test.hpp>
11
#include <boost/utility/binary.hpp>
12
13
using namespace pinocchio;
14
15
BOOST_AUTO_TEST_SUITE ( BOOST_TEST_MODULE )
16
17
















4
BOOST_AUTO_TEST_CASE ( integration_test )
18
{
19

4
  Model model; buildAllJointsModel(model);
20
21
4
  std::vector<Eigen::VectorXd> qs(2);
22
4
  std::vector<Eigen::VectorXd> qdots(2);
23
4
  std::vector<Eigen::VectorXd> results(2);
24
25
  //
26
  // Test Case 0 : Integration of a config with zero velocity
27
  //
28

2
  qs[0] = Eigen::VectorXd::Ones(model.nq);
29
2
  normalize(model,qs[0]);
30
31

2
  qdots[0] = Eigen::VectorXd::Zero(model.nv);
32
2
  results[0] = integrate(model,qs[0],qdots[0]);
33
34



2
  BOOST_CHECK_MESSAGE(results[0].isApprox(qs[0], 1e-12), "integration of full body with zero velocity - wrong results");
35
2
}
36
37
















4
BOOST_AUTO_TEST_CASE ( interpolate_test )
38
{
39

4
  Model model; buildAllJointsModel(model);
40
41


4
  Eigen::VectorXd q0(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
42


4
  Eigen::VectorXd q1(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
43
44
4
  Eigen::VectorXd q01_0 = interpolate(model,q0,q1,0.0);
45



2
  BOOST_CHECK_MESSAGE(isSameConfiguration(model,q01_0,q0), "interpolation: q01_0 != q0");
46
47
4
  Eigen::VectorXd q01_1 = interpolate(model,q0,q1,1.0);
48



2
  BOOST_CHECK_MESSAGE(isSameConfiguration(model,q01_1,q1), "interpolation: q01_1 != q1");
49
2
}
50
51
















4
BOOST_AUTO_TEST_CASE ( diff_integration_test )
52
{
53

4
  Model model; buildAllJointsModel(model);
54
55
4
  std::vector<Eigen::VectorXd> qs(2);
56
4
  std::vector<Eigen::VectorXd> vs(2);
57

6
  std::vector<Eigen::MatrixXd> results(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
58

6
  std::vector<Eigen::MatrixXd> results_fd(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
59
60

2
  qs[0] = Eigen::VectorXd::Ones(model.nq);
61
2
  normalize(model,qs[0]);
62
63

2
  vs[0] = Eigen::VectorXd::Zero(model.nv);
64

2
  vs[1] = Eigen::VectorXd::Ones(model.nv);
65
2
  dIntegrate(model,qs[0],vs[0],results[0],ARG0);
66
67

4
  Eigen::VectorXd q_fd(model.nq), v_fd(model.nv); v_fd.setZero();
68
2
  const double eps = 1e-8;
69
46
  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
70
  {
71
44
    v_fd[k] = eps;
72
44
    q_fd = integrate(model,qs[0],v_fd);
73


44
    results_fd[0].col(k) = difference(model,qs[0],q_fd)/eps;
74
44
    v_fd[k] = 0.;
75
  }
76



2
  BOOST_CHECK(results[0].isIdentity(sqrt(eps)));
77



2
  BOOST_CHECK(results[0].isApprox(results_fd[0],sqrt(eps)));
78
79
2
  dIntegrate(model,qs[0],vs[0],results[1],ARG1);
80



2
  BOOST_CHECK(results[1].isApprox(results[0]));
81
82
2
  dIntegrate(model,qs[0],vs[1],results[0],ARG0);
83
4
  Eigen::VectorXd q_fd_intermediate(model.nq);
84
4
  Eigen::VectorXd q0_plus_v = integrate(model,qs[0],vs[1]);
85
46
  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
86
  {
87
44
    v_fd[k] = eps;
88
44
    q_fd_intermediate = integrate(model,qs[0],v_fd);
89
44
    q_fd = integrate(model,q_fd_intermediate,vs[1]);
90


44
    results_fd[0].col(k) = difference(model,q0_plus_v,q_fd)/eps;
91
44
    v_fd[k] = 0.;
92
  }
93
94



2
  BOOST_CHECK(results[0].isApprox(results_fd[0],sqrt(eps)));
95
96
2
  dIntegrate(model,qs[0],vs[1],results[1],ARG1);
97
2
  v_fd = vs[1];
98
46
  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
99
  {
100
44
    v_fd[k] += eps;
101
44
    q_fd = integrate(model,qs[0],v_fd);
102


44
    results_fd[1].col(k) = difference(model,q0_plus_v,q_fd)/eps;
103
44
    v_fd[k] -= eps;
104
  }
105
106



2
  BOOST_CHECK(results[1].isApprox(results_fd[1],sqrt(eps)));
107
2
}
108
109
















4
BOOST_AUTO_TEST_CASE ( diff_difference_test )
110
{
111

4
  Model model; buildAllJointsModel(model);
112
113
4
  std::vector<Eigen::VectorXd> qs(2);
114
4
  std::vector<Eigen::VectorXd> vs(2);
115

6
  std::vector<Eigen::MatrixXd> results(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
116

6
  std::vector<Eigen::MatrixXd> results_fd(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
117
118

2
  qs[0] = Eigen::VectorXd::Random(model.nq);
119
2
  normalize(model,qs[0]);
120
2
  const Eigen::VectorXd & q0 = qs[0];
121

2
  qs[1] = Eigen::VectorXd::Random(model.nq);
122
2
  normalize(model,qs[1]);
123
2
  const Eigen::VectorXd & q1 = qs[1];
124
125

2
  vs[0] = Eigen::VectorXd::Zero(model.nv);
126

2
  vs[1] = Eigen::VectorXd::Ones(model.nv);
127
2
  dDifference(model,q0,q1,results[0],ARG0);
128
129

4
  Eigen::VectorXd q_fd(model.nq), v_fd(model.nv); v_fd.setZero();
130
2
  const double eps = 1e-8;
131
4
  const Eigen::VectorXd v_ref = difference(model,q0,q1);
132
46
  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
133
  {
134
44
    v_fd[k] = eps;
135
44
    q_fd = integrate(model,q0,v_fd);
136


44
    results_fd[0].col(k) = (difference(model,q_fd,q1) - v_ref)/eps;
137
44
    v_fd[k] = 0.;
138
  }
139



2
  BOOST_CHECK(results[0].isApprox(results_fd[0],sqrt(eps)));
140
141
2
  dDifference(model,q0,q0,results[0],ARG0);
142




2
  BOOST_CHECK((-results[0]).isIdentity());
143
144
2
  dDifference(model,q0,q0,results[1],ARG1);
145



2
  BOOST_CHECK(results[1].isIdentity());
146
147
2
  dDifference(model,q0,q1,results[1],ARG1);
148
46
  for(Eigen::DenseIndex k = 0; k < model.nv; ++k)
149
  {
150
44
    v_fd[k] = eps;
151
44
    q_fd = integrate(model,q1,v_fd);
152


44
    results_fd[1].col(k) = (difference(model,q0,q_fd) - v_ref)/eps;
153
44
    v_fd[k] = 0.;
154
  }
155



2
  BOOST_CHECK(results[1].isApprox(results_fd[1],sqrt(eps)));
156
2
}
157
158
















4
BOOST_AUTO_TEST_CASE ( diff_difference_vs_diff_integrate )
159
{
160

4
  Model model; buildAllJointsModel(model);
161
162
4
  std::vector<Eigen::VectorXd> qs(2);
163
4
  std::vector<Eigen::VectorXd> vs(2);
164

6
  std::vector<Eigen::MatrixXd> results(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
165

6
  std::vector<Eigen::MatrixXd> results_fd(2,Eigen::MatrixXd::Zero(model.nv,model.nv));
166
167

4
  Eigen::VectorXd q0 = Eigen::VectorXd::Random(model.nq);
168
2
  normalize(model,q0);
169
170

4
  Eigen::VectorXd v = Eigen::VectorXd::Random(model.nv);
171
4
  Eigen::VectorXd q1 = integrate(model,q0,v);
172
173
4
  Eigen::VectorXd v_diff = difference(model,q0,q1);
174



2
  BOOST_CHECK(v_diff.isApprox(v));
175
176

4
  Eigen::MatrixXd J_int_dq = Eigen::MatrixXd::Zero(model.nv,model.nv);
177

4
  Eigen::MatrixXd J_int_dv = Eigen::MatrixXd::Zero(model.nv,model.nv);
178
2
  dIntegrate(model,q0,v,J_int_dq,ARG0);
179
2
  dIntegrate(model,q0,v,J_int_dv,ARG1);
180
181

4
  Eigen::MatrixXd J_diff_dq0 = Eigen::MatrixXd::Zero(model.nv,model.nv);
182

4
  Eigen::MatrixXd J_diff_dq1 = Eigen::MatrixXd::Zero(model.nv,model.nv);
183
2
  dDifference(model,q0,q1,J_diff_dq0,ARG0);
184
2
  dDifference(model,q0,q1,J_diff_dq1,ARG1);
185
186





2
  BOOST_CHECK(J_int_dq.isApprox(Eigen::MatrixXd(-(J_int_dv * J_diff_dq0))));
187




2
  BOOST_CHECK(Eigen::MatrixXd(J_int_dv * J_diff_dq1).isIdentity());
188
2
}
189
190
191
















4
BOOST_AUTO_TEST_CASE ( dIntegrate_assignementop_test )
192
{
193

4
  Model model; buildAllJointsModel(model);
194
195

6
  std::vector<Eigen::MatrixXd> results(3,Eigen::MatrixXd::Zero(model.nv,model.nv));
196
197

4
  Eigen::VectorXd qs = Eigen::VectorXd::Ones(model.nq);
198
2
  normalize(model,qs);
199
200

4
  Eigen::VectorXd vs = Eigen::VectorXd::Random(model.nv);
201
202
  //SETTO
203
2
  dIntegrate(model,qs,vs,results[0],ARG0);
204
2
  dIntegrate(model,qs,vs,results[1],ARG0,SETTO);
205



2
  BOOST_CHECK(results[0].isApprox(results[1]));
206
207
  //ADDTO
208

2
  results[1] = Eigen::MatrixXd::Random(model.nv, model.nv);
209
2
  results[2] = results[1];
210
2
  results[0].setZero();
211
2
  dIntegrate(model,qs,vs,results[0],ARG0,SETTO);
212
2
  dIntegrate(model,qs,vs,results[1],ARG0,ADDTO);
213




2
  BOOST_CHECK(results[1].isApprox(results[2] + results[0]));
214
215
  //RMTO
216

2
  results[1] = Eigen::MatrixXd::Random(model.nv, model.nv);
217
2
  results[2] = results[1];
218
2
  results[0].setZero();
219
2
  dIntegrate(model,qs,vs,results[0],ARG0,SETTO);
220
2
  dIntegrate(model,qs,vs,results[1],ARG0,RMTO);
221




2
  BOOST_CHECK(results[1].isApprox(results[2] - results[0]));
222
223
  //SETTO
224
2
  results[0].setZero();
225
2
  results[1].setZero();
226
2
  dIntegrate(model,qs,vs,results[0],ARG1);
227
2
  dIntegrate(model,qs,vs,results[1],ARG1,SETTO);
228



2
  BOOST_CHECK(results[0].isApprox(results[1]));
229
230
  //ADDTO
231

2
  results[1] = Eigen::MatrixXd::Random(model.nv, model.nv);
232
2
  results[2] = results[1];
233
2
  results[0].setZero();
234
2
  dIntegrate(model,qs,vs,results[0],ARG1,SETTO);
235
2
  dIntegrate(model,qs,vs,results[1],ARG1,ADDTO);
236




2
  BOOST_CHECK(results[1].isApprox(results[2] + results[0]));
237
238
  //RMTO
239

2
  results[1] = Eigen::MatrixXd::Random(model.nv, model.nv);
240
2
  results[2] = results[1];
241
2
  results[0].setZero();
242
2
  dIntegrate(model,qs,vs,results[0],ARG1,SETTO);
243
2
  dIntegrate(model,qs,vs,results[1],ARG1,RMTO);
244




2
  BOOST_CHECK(results[1].isApprox(results[2] - results[0]));
245
246
  //Transport
247

6
  std::vector<Eigen::MatrixXd> J(2,Eigen::MatrixXd::Zero(model.nv,2*model.nv));
248

2
  J[0] = Eigen::MatrixXd::Random(model.nv, 2*model.nv);
249
2
  results[0].setZero();
250
2
  dIntegrate(model,qs,vs,results[0],ARG0,SETTO);
251
2
  dIntegrateTransport(model,qs,vs,J[0],J[1],ARG0);
252




2
  BOOST_CHECK(J[1].isApprox(results[0] * J[0]));
253
254

2
  J[0] = Eigen::MatrixXd::Random(model.nv, 2*model.nv);
255
2
  results[0].setZero();
256
2
  dIntegrate(model,qs,vs,results[0],ARG1,SETTO);
257
2
  dIntegrateTransport(model,qs,vs,J[0],J[1],ARG1);
258




2
  BOOST_CHECK(J[1].isApprox(results[0] * J[0]));
259
260
  //TransportInPlace
261

2
  J[1] = Eigen::MatrixXd::Random(model.nv, 2*model.nv);
262
2
  J[0] = J[1];
263
2
  results[0].setZero();
264
2
  dIntegrate(model,qs,vs,results[0],ARG0,SETTO);
265
2
  dIntegrateTransport(model,qs,vs,J[1],ARG0);
266




2
  BOOST_CHECK(J[1].isApprox(results[0] * J[0]));
267
268

2
  J[1] = Eigen::MatrixXd::Random(model.nv, 2*model.nv);
269
2
  J[0] = J[1];
270
2
  results[0].setZero();
271
2
  dIntegrate(model,qs,vs,results[0],ARG1,SETTO);
272
2
  dIntegrateTransport(model,qs,vs,J[1],ARG1);
273




2
  BOOST_CHECK(J[1].isApprox(results[0] * J[0]));
274
275
2
}
276
277
















4
BOOST_AUTO_TEST_CASE ( integrate_difference_test )
278
{
279

4
 Model model; buildAllJointsModel(model);
280
281


4
 Eigen::VectorXd q0(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
282


4
 Eigen::VectorXd q1(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
283

4
 Eigen::VectorXd qdot(Eigen::VectorXd::Random(model.nv));
284
285




2
 BOOST_CHECK_MESSAGE(isSameConfiguration(model, integrate(model, q0, difference(model, q0,q1)), q1), "Integrate (difference) - wrong results");
286
287




2
 BOOST_CHECK_MESSAGE(difference(model, q0, integrate(model,q0, qdot)).isApprox(qdot),"difference (integrate) - wrong results");
288
2
}
289
290
291
















4
BOOST_AUTO_TEST_CASE ( neutral_configuration_test )
292
{
293

4
  Model model; buildAllJointsModel(model);
294
295
4
  Eigen::VectorXd expected(model.nq);
296



2
  expected << 0,0,0,0,0,0,1,
297


2
              0,0,0,1,
298


2
              0,0,1,0,
299
2
              0,
300
2
              0,
301
2
              0,
302
2
              0,
303

2
              0,0,0,
304

2
              0,0,0;
305
306
307
4
  Eigen::VectorXd neutral_config = neutral(model);
308



2
  BOOST_CHECK_MESSAGE(neutral_config.isApprox(expected, 1e-12), "neutral configuration - wrong results");
309
2
}
310
311
















4
BOOST_AUTO_TEST_CASE ( distance_configuration_test )
312
{
313

4
  Model model; buildAllJointsModel(model);
314
315
4
  Model::ConfigVectorType q0 = neutral(model);
316

4
  Model::ConfigVectorType q1(integrate (model, q0, Model::TangentVectorType::Ones(model.nv)));
317
318
2
  double dist = distance(model,q0,q1);
319
320



2
  BOOST_CHECK_MESSAGE(dist > 0., "distance - wrong results");
321



2
  BOOST_CHECK_SMALL(dist-difference(model,q0,q1).norm(), 1e-12);
322
2
}
323
324
















4
BOOST_AUTO_TEST_CASE ( squared_distance_test )
325
{
326

4
  Model model; buildAllJointsModel(model);
327
328


4
  Eigen::VectorXd q0(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
329


4
  Eigen::VectorXd q1(randomConfiguration(model, -1 * Eigen::VectorXd::Ones(model.nq), Eigen::VectorXd::Ones(model.nq) ));
330
331
2
  double dist = distance(model,q0,q1);
332
4
  Eigen::VectorXd squaredDistance_ = squaredDistance(model,q0,q1);
333
334



2
  BOOST_CHECK_SMALL(dist-math::sqrt(squaredDistance_.sum()), 1e-12);
335
2
}
336
337
















4
BOOST_AUTO_TEST_CASE ( uniform_sampling_test )
338
{
339

4
  Model model; buildAllJointsModel(model);
340
341

2
  model.lowerPositionLimit = -1 * Eigen::VectorXd::Ones(model.nq);
342

2
  model.upperPositionLimit = Eigen::VectorXd::Ones(model.nq);
343
4
  Eigen::VectorXd q1(randomConfiguration(model));
344
345
52
  for (int i = 0; i < model.nq; ++i)
346
  {
347






50
    BOOST_CHECK_MESSAGE(q1[i] >= model.lowerPositionLimit[i] && q1[i] <= model.upperPositionLimit[i], " UniformlySample : Generated config not in bounds");
348
  }
349
2
}
350
351
















4
BOOST_AUTO_TEST_CASE ( normalize_test )
352
{
353

4
  Model model; buildAllJointsModel(model);
354
355

4
  Eigen::VectorXd q (Eigen::VectorXd::Ones(model.nq));
356
2
  pinocchio::normalize(model, q);
357
358




2
  BOOST_CHECK(q.head<3>().isApprox(Eigen::VectorXd::Ones(3)));
359




2
  BOOST_CHECK(fabs(q.segment<4>(3).norm() - 1) < Eigen::NumTraits<double>::epsilon()); // quaternion of freeflyer
360




2
  BOOST_CHECK(fabs(q.segment<4>(7).norm() - 1) < Eigen::NumTraits<double>::epsilon()); // quaternion of spherical joint
361
2
  const int n = model.nq - 7 - 4 - 4; // free flyer + spherical + planar
362




2
  BOOST_CHECK(q.tail(n).isApprox(Eigen::VectorXd::Ones(n)));
363
2
}
364
365
















4
BOOST_AUTO_TEST_CASE ( is_normalized_test )
366
{
367

4
  Model model; buildAllJointsModel(model);
368
369
4
  Eigen::VectorXd q;
370

2
  q = Eigen::VectorXd::Ones(model.nq);
371



2
  BOOST_CHECK(!pinocchio::isNormalized(model, q));
372



2
  BOOST_CHECK(!pinocchio::isNormalized(model, q, 1e-8));
373



2
  BOOST_CHECK(pinocchio::isNormalized(model, q, 1e2));
374
375
2
  pinocchio::normalize(model, q);
376



2
  BOOST_CHECK(pinocchio::isNormalized(model, q));
377



2
  BOOST_CHECK(pinocchio::isNormalized(model, q, 1e-8));
378
379
2
  q = pinocchio::neutral(model);
380



2
  BOOST_CHECK(pinocchio::isNormalized(model, q));
381



2
  BOOST_CHECK(pinocchio::isNormalized(model, q, 1e-8));
382
383

2
  model.lowerPositionLimit = -1 * Eigen::VectorXd::Ones(model.nq);
384

2
  model.upperPositionLimit = Eigen::VectorXd::Ones(model.nq);
385
2
  q = pinocchio::randomConfiguration(model);
386



2
  BOOST_CHECK(pinocchio::isNormalized(model, q));
387



2
  BOOST_CHECK(pinocchio::isNormalized(model, q, 1e-8));
388
2
}
389
390
















4
BOOST_AUTO_TEST_CASE ( integrateCoeffWiseJacobian_test )
391
{
392

4
  Model model; buildModels::humanoidRandom(model);
393
394

4
  Eigen::VectorXd q(Eigen::VectorXd::Ones(model.nq));
395
2
  pinocchio::normalize(model, q);
396
397

4
  Eigen::MatrixXd jac(model.nq,model.nv); jac.setZero();
398
399
2
  integrateCoeffWiseJacobian(model,q,jac);
400
401
402
4
  Eigen::MatrixXd jac_fd(model.nq,model.nv);
403
4
  Eigen::VectorXd q_plus;
404
2
  const double eps = 1e-8;
405
406

4
  Eigen::VectorXd v_eps(Eigen::VectorXd::Zero(model.nv));
407
66
  for(int k = 0; k < model.nv; ++k)
408
  {
409
64
    v_eps[k] = eps;
410
64
    q_plus = integrate(model,q,v_eps);
411


64
    jac_fd.col(k) = (q_plus - q)/eps;
412
413
64
    v_eps[k] = 0.;
414
  }
415



2
  BOOST_CHECK(jac.isApprox(jac_fd,sqrt(eps)));
416
2
}
417
418
BOOST_AUTO_TEST_SUITE_END ()