GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
// |
||
2 |
// Copyright (c) 2017-2020 CNRS INRIA |
||
3 |
// |
||
4 |
|||
5 |
#include "pinocchio/multibody/model.hpp" |
||
6 |
#include "pinocchio/multibody/data.hpp" |
||
7 |
#include "pinocchio/algorithm/jacobian.hpp" |
||
8 |
#include "pinocchio/algorithm/joint-configuration.hpp" |
||
9 |
#include "pinocchio/algorithm/rnea-second-order-derivatives.hpp" |
||
10 |
#include "pinocchio/algorithm/rnea-derivatives.hpp" |
||
11 |
#include "pinocchio/parsers/sample-models.hpp" |
||
12 |
|||
13 |
#include <iostream> |
||
14 |
|||
15 |
#include <boost/test/unit_test.hpp> |
||
16 |
#include <boost/utility/binary.hpp> |
||
17 |
|||
18 |
BOOST_AUTO_TEST_SUITE(BOOST_TEST_MODULE) |
||
19 |
|||
20 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
4 |
BOOST_AUTO_TEST_CASE(test_rnea_derivatives_SO) { |
21 |
using namespace Eigen; |
||
22 |
using namespace pinocchio; |
||
23 |
|||
24 |
✓✗ | 4 |
Model model; |
25 |
✓✗ | 2 |
buildModels::humanoidRandom(model); |
26 |
|||
27 |
✓✗✓✗ |
4 |
Data data(model), data_fd(model); |
28 |
|||
29 |
✓✗✓✗ |
2 |
model.lowerPositionLimit.head<3>().fill(-1.); |
30 |
✓✗✓✗ |
2 |
model.upperPositionLimit.head<3>().fill(1.); |
31 |
|||
32 |
✓✗ | 4 |
VectorXd q = randomConfiguration(model); |
33 |
✓✗✓✗ |
4 |
VectorXd v(VectorXd::Random(model.nv)); |
34 |
✓✗✓✗ |
4 |
VectorXd a(VectorXd::Random(model.nv)); |
35 |
|||
36 |
// check with only q non-zero |
||
37 |
✓✗ | 4 |
Data::Tensor3x dtau2_dq(model.nv, model.nv, model.nv); |
38 |
✓✗ | 4 |
Data::Tensor3x dtau2_dv(model.nv, model.nv, model.nv); |
39 |
✓✗ | 4 |
Data::Tensor3x dtau2_dqdv(model.nv, model.nv, model.nv); |
40 |
✓✗ | 4 |
Data::Tensor3x dtau2_dadq(model.nv, model.nv, model.nv); |
41 |
✓✗ | 2 |
dtau2_dq.setZero(); |
42 |
✓✗ | 2 |
dtau2_dv.setZero(); |
43 |
✓✗ | 2 |
dtau2_dqdv.setZero(); |
44 |
✓✗ | 2 |
dtau2_dadq.setZero(); |
45 |
|||
46 |
✓✗✓✗ |
2 |
ComputeRNEASecondOrderDerivatives(model, data, q, VectorXd::Zero(model.nv), |
47 |
✓✗ | 2 |
VectorXd::Zero(model.nv), dtau2_dq, dtau2_dv, |
48 |
dtau2_dqdv, dtau2_dadq); |
||
49 |
|||
50 |
✓✗ | 4 |
Data::Tensor3x dtau2_dq_fd(model.nv, model.nv, model.nv); |
51 |
✓✗ | 4 |
Data::Tensor3x dtau2_dv_fd(model.nv, model.nv, model.nv); |
52 |
✓✗ | 4 |
Data::Tensor3x dtau2_dqdv_fd(model.nv, model.nv, model.nv); |
53 |
✓✗ | 4 |
Data::Tensor3x dtau2_dadq_fd(model.nv, model.nv, model.nv); |
54 |
✓✗ | 2 |
dtau2_dq_fd.setZero(); |
55 |
✓✗ | 2 |
dtau2_dv_fd.setZero(); |
56 |
✓✗ | 2 |
dtau2_dqdv_fd.setZero(); |
57 |
✓✗ | 2 |
dtau2_dadq_fd.setZero(); |
58 |
|||
59 |
✓✗✓✗ |
4 |
MatrixXd drnea_dq_plus(MatrixXd::Zero(model.nv, model.nv)); |
60 |
✓✗✓✗ |
4 |
MatrixXd drnea_dv_plus(MatrixXd::Zero(model.nv, model.nv)); |
61 |
✓✗✓✗ |
4 |
MatrixXd drnea_da_plus(MatrixXd::Zero(model.nv, model.nv)); |
62 |
|||
63 |
✓✗✓✗ |
4 |
MatrixXd temp1(MatrixXd::Zero(model.nv, model.nv)); |
64 |
✓✗✓✗ |
4 |
MatrixXd temp2(MatrixXd::Zero(model.nv, model.nv)); |
65 |
|||
66 |
✓✗✓✗ |
4 |
VectorXd v_eps(VectorXd::Zero(model.nv)); |
67 |
✓✗ | 4 |
VectorXd q_plus(model.nq); |
68 |
✓✗ | 4 |
VectorXd v_plus(model.nv); |
69 |
|||
70 |
✓✗✓✗ |
4 |
MatrixXd rnea_partial_dq(MatrixXd::Zero(model.nv, model.nv)); |
71 |
✓✗✓✗ |
4 |
MatrixXd rnea_partial_dv(MatrixXd::Zero(model.nv, model.nv)); |
72 |
✓✗✓✗ |
4 |
MatrixXd rnea_partial_da(MatrixXd::Zero(model.nv, model.nv)); |
73 |
|||
74 |
✓✗✓✗ |
2 |
computeRNEADerivatives(model, data, q, VectorXd::Zero(model.nv), |
75 |
✓✗ | 2 |
VectorXd::Zero(model.nv), rnea_partial_dq, |
76 |
rnea_partial_dv, rnea_partial_da); |
||
77 |
|||
78 |
2 |
const double alpha = 1e-7; |
|
79 |
|||
80 |
✓✓ | 66 |
for (int k = 0; k < model.nv; ++k) { |
81 |
✓✗ | 64 |
v_eps[k] += alpha; |
82 |
✓✗ | 64 |
q_plus = integrate(model, q, v_eps); |
83 |
✓✗✓✗ |
64 |
computeRNEADerivatives(model, data_fd, q_plus, VectorXd::Zero(model.nv), |
84 |
✓✗ | 64 |
VectorXd::Zero(model.nv), drnea_dq_plus, |
85 |
drnea_dv_plus, drnea_da_plus); |
||
86 |
✓✗✓✗ ✓✗ |
64 |
temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha; |
87 |
✓✓ | 2112 |
for (int ii = 0; ii < model.nv; ii++) { |
88 |
✓✓ | 67584 |
for (int jj = 0; jj < model.nv; jj++) { |
89 |
✓✗✓✗ |
65536 |
dtau2_dq_fd(jj, ii, k) = temp1(jj, ii); |
90 |
} |
||
91 |
} |
||
92 |
✓✗ | 64 |
v_eps[k] -= alpha; |
93 |
} |
||
94 |
|||
95 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mq(dtau2_dq.data(), dtau2_dq.size()); |
96 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mq_fd(dtau2_dq_fd.data(), dtau2_dq_fd.size()); |
97 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha))); |
98 |
|||
99 |
// Check with q and a non zero |
||
100 |
✓✗ | 2 |
dtau2_dq.setZero(); |
101 |
✓✗ | 2 |
dtau2_dv.setZero(); |
102 |
✓✗ | 2 |
dtau2_dqdv.setZero(); |
103 |
✓✗ | 2 |
dtau2_dadq.setZero(); |
104 |
✓✗✓✗ |
2 |
ComputeRNEASecondOrderDerivatives(model, data, q, VectorXd::Zero(model.nv), a, |
105 |
dtau2_dq, dtau2_dv, dtau2_dqdv, dtau2_dadq); |
||
106 |
|||
107 |
✓✗ | 2 |
rnea_partial_dq.setZero(); |
108 |
✓✗ | 2 |
rnea_partial_dv.setZero(); |
109 |
✓✗ | 2 |
rnea_partial_da.setZero(); |
110 |
|||
111 |
✓✗ | 2 |
dtau2_dq_fd.setZero(); |
112 |
✓✗ | 2 |
dtau2_dadq_fd.setZero(); |
113 |
✓✗ | 2 |
drnea_dq_plus.setZero(); |
114 |
✓✗ | 2 |
drnea_dv_plus.setZero(); |
115 |
✓✗ | 2 |
drnea_da_plus.setZero(); |
116 |
|||
117 |
✓✗✓✗ |
2 |
computeRNEADerivatives(model, data, q, VectorXd::Zero(model.nv), a, |
118 |
rnea_partial_dq, rnea_partial_dv, rnea_partial_da); |
||
119 |
|||
120 |
✓✓ | 66 |
for (int k = 0; k < model.nv; ++k) { |
121 |
✓✗ | 64 |
v_eps[k] += alpha; |
122 |
✓✗ | 64 |
q_plus = integrate(model, q, v_eps); |
123 |
✓✗✓✗ |
64 |
computeRNEADerivatives(model, data_fd, q_plus, VectorXd::Zero(model.nv), a, |
124 |
drnea_dq_plus, drnea_dv_plus, drnea_da_plus); |
||
125 |
✓✗✓✗ ✓✗ |
64 |
temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha; |
126 |
✓✗✓✗ ✓✗ |
64 |
temp2 = (drnea_da_plus - rnea_partial_da) / alpha; |
127 |
✓✗ | 64 |
temp2.triangularView<Eigen::StrictlyLower>() = |
128 |
✓✗✓✗ ✓✗ |
128 |
temp2.transpose().triangularView<Eigen::StrictlyLower>(); |
129 |
✓✓ | 2112 |
for (int ii = 0; ii < model.nv; ii++) { |
130 |
✓✓ | 67584 |
for (int jj = 0; jj < model.nv; jj++) { |
131 |
✓✗✓✗ |
65536 |
dtau2_dq_fd(jj, ii, k) = temp1(jj, ii); |
132 |
✓✗✓✗ |
65536 |
dtau2_dadq_fd(jj, ii, k) = temp2(jj, ii); |
133 |
} |
||
134 |
} |
||
135 |
✓✗ | 64 |
v_eps[k] -= alpha; |
136 |
} |
||
137 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> maq(dtau2_dadq.data(), dtau2_dadq.size()); |
138 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> maq_fd(dtau2_dadq_fd.data(), dtau2_dadq_fd.size()); |
139 |
|||
140 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha))); |
141 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(maq.isApprox(maq_fd, sqrt(alpha))); |
142 |
|||
143 |
// Check with q,v and a non zero |
||
144 |
✓✗ | 2 |
dtau2_dq.setZero(); |
145 |
✓✗ | 2 |
dtau2_dv.setZero(); |
146 |
✓✗ | 2 |
dtau2_dqdv.setZero(); |
147 |
✓✗ | 2 |
dtau2_dadq.setZero(); |
148 |
✓✗ | 2 |
ComputeRNEASecondOrderDerivatives(model, data, q, v, a, dtau2_dq, dtau2_dv, dtau2_dqdv, |
149 |
dtau2_dadq); |
||
150 |
|||
151 |
✓✗ | 2 |
rnea_partial_dq.setZero(); |
152 |
✓✗ | 2 |
rnea_partial_dv.setZero(); |
153 |
✓✗ | 2 |
rnea_partial_da.setZero(); |
154 |
✓✗ | 2 |
computeRNEADerivatives(model, data, q, v, a, rnea_partial_dq, rnea_partial_dv, |
155 |
rnea_partial_da); |
||
156 |
|||
157 |
✓✗ | 2 |
dtau2_dq_fd.setZero(); |
158 |
✓✗ | 2 |
dtau2_dadq_fd.setZero(); |
159 |
✓✗ | 2 |
drnea_dq_plus.setZero(); |
160 |
✓✗ | 2 |
drnea_dv_plus.setZero(); |
161 |
✓✗ | 2 |
drnea_da_plus.setZero(); |
162 |
|||
163 |
✓✓ | 66 |
for (int k = 0; k < model.nv; ++k) { |
164 |
✓✗ | 64 |
v_eps[k] += alpha; |
165 |
✓✗ | 64 |
q_plus = integrate(model, q, v_eps); |
166 |
✓✗ | 64 |
computeRNEADerivatives(model, data_fd, q_plus, v, a, drnea_dq_plus, |
167 |
drnea_dv_plus, drnea_da_plus); |
||
168 |
✓✗✓✗ ✓✗ |
64 |
temp1 = (drnea_dq_plus - rnea_partial_dq) / alpha; |
169 |
✓✗✓✗ ✓✗ |
64 |
temp2 = (drnea_da_plus - rnea_partial_da) / alpha; |
170 |
✓✗ | 64 |
temp2.triangularView<Eigen::StrictlyLower>() = |
171 |
✓✗✓✗ ✓✗ |
128 |
temp2.transpose().triangularView<Eigen::StrictlyLower>(); |
172 |
✓✓ | 2112 |
for (int ii = 0; ii < model.nv; ii++) { |
173 |
✓✓ | 67584 |
for (int jj = 0; jj < model.nv; jj++) { |
174 |
✓✗✓✗ |
65536 |
dtau2_dq_fd(jj, ii, k) = temp1(jj, ii); |
175 |
✓✗✓✗ |
65536 |
dtau2_dadq_fd(jj, ii, k) = temp2(jj, ii); |
176 |
} |
||
177 |
} |
||
178 |
✓✗ | 64 |
v_eps[k] -= alpha; |
179 |
} |
||
180 |
✓✗ | 2 |
dtau2_dv_fd.setZero(); |
181 |
✓✗ | 2 |
dtau2_dqdv_fd.setZero(); |
182 |
✓✓ | 66 |
for (int k = 0; k < model.nv; ++k) { |
183 |
✓✗ | 64 |
v_eps[k] += alpha; |
184 |
✓✗✓✗ |
64 |
v_plus = v + v_eps; |
185 |
✓✗ | 64 |
computeRNEADerivatives(model, data_fd, q, v_plus, a, drnea_dq_plus, |
186 |
drnea_dv_plus, drnea_da_plus); |
||
187 |
✓✗✓✗ ✓✗ |
64 |
temp1 = (drnea_dv_plus - rnea_partial_dv) / alpha; |
188 |
✓✗✓✗ ✓✗ |
64 |
temp2 = (drnea_dq_plus - rnea_partial_dq) / alpha; |
189 |
✓✓ | 2112 |
for (int ii = 0; ii < model.nv; ii++) { |
190 |
✓✓ | 67584 |
for (int jj = 0; jj < model.nv; jj++) { |
191 |
✓✗✓✗ |
65536 |
dtau2_dv_fd(jj, ii, k) = temp1(jj, ii); |
192 |
✓✗✓✗ |
65536 |
dtau2_dqdv_fd(jj, ii, k) = temp2(jj, ii); |
193 |
} |
||
194 |
} |
||
195 |
✓✗ | 64 |
v_eps[k] -= alpha; |
196 |
} |
||
197 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mv(dtau2_dv.data(), dtau2_dv.size()); |
198 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mv_fd(dtau2_dv_fd.data(), dtau2_dv_fd.size()); |
199 |
|||
200 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mqv(dtau2_dqdv.data(), dtau2_dqdv.size()); |
201 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mqv_fd(dtau2_dqdv_fd.data(), dtau2_dqdv_fd.size()); |
202 |
|||
203 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mq.isApprox(mq_fd, sqrt(alpha))); |
204 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(maq.isApprox(maq_fd, sqrt(alpha))); |
205 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mv.isApprox(mv_fd, sqrt(alpha))); |
206 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mqv.isApprox(mqv_fd, sqrt(alpha))); |
207 |
|||
208 |
✓✗ | 4 |
Data data2(model); |
209 |
✓✗ | 2 |
ComputeRNEASecondOrderDerivatives(model, data2, q, v, a); |
210 |
|||
211 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mq2(data2.d2tau_dqdq.data(), (data2.d2tau_dqdq).size()); |
212 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mv2(data2.d2tau_dvdv.data(), (data2.d2tau_dvdv).size()); |
213 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> mqv2(data2.d2tau_dqdv.data(), (data2.d2tau_dqdv).size()); |
214 |
✓✗✓✗ ✓✗✓✗ |
2 |
Map<VectorXd> maq2(data2.d2tau_dadq.data(), (data2.d2tau_dadq).size()); |
215 |
|||
216 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mq.isApprox(mq2, sqrt(alpha))); |
217 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mv.isApprox(mv2, sqrt(alpha))); |
218 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(mqv.isApprox(mqv2, sqrt(alpha))); |
219 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
2 |
BOOST_CHECK(maq.isApprox(maq2, sqrt(alpha))); |
220 |
2 |
} |
|
221 |
|||
222 |
BOOST_AUTO_TEST_SUITE_END() |
Generated by: GCOVR (Version 4.2) |