GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/////////////////////////////////////////////////////////////////////////////// |
||
2 |
// BSD 3-Clause License |
||
3 |
// |
||
4 |
// Copyright (C) 2019, LAAS-CNRS |
||
5 |
// Copyright note valid unless otherwise stated in individual files. |
||
6 |
// All rights reserved. |
||
7 |
/////////////////////////////////////////////////////////////////////////////// |
||
8 |
|||
9 |
#include <pinocchio/algorithm/joint-configuration.hpp> |
||
10 |
|||
11 |
#include "crocoddyl/core/utils/exception.hpp" |
||
12 |
#include "crocoddyl/multibody/states/multibody.hpp" |
||
13 |
|||
14 |
namespace crocoddyl { |
||
15 |
|||
16 |
template <typename Scalar> |
||
17 |
11084 |
StateMultibodyTpl<Scalar>::StateMultibodyTpl( |
|
18 |
boost::shared_ptr<PinocchioModel> model) |
||
19 |
11084 |
: Base(model->nq + model->nv, 2 * model->nv), |
|
20 |
pinocchio_(model), |
||
21 |
✓✗✓✗ |
22168 |
x0_(VectorXs::Zero(model->nq + model->nv)) { |
22 |
✓✗✓✗ ✓✗ |
11084 |
x0_.head(nq_) = pinocchio::neutral(*pinocchio_.get()); |
23 |
|||
24 |
// In a multibody system, we could define the first joint using Lie groups. |
||
25 |
// The current cases are free-flyer (SE3) and spherical (S03). |
||
26 |
// Instead simple represents any joint that can model within the Euclidean |
||
27 |
// manifold. The rest of joints use Euclidean algebra. We use this fact for |
||
28 |
// computing Jdiff. |
||
29 |
|||
30 |
// Define internally the limits of the first joint |
||
31 |
|||
32 |
✓✗ | 11084 |
const std::size_t nq0 = model->joints[1].nq(); |
33 |
|||
34 |
✓✗✓✗ ✓✗✓✗ |
22168 |
lb_.head(nq0) = |
35 |
11084 |
-std::numeric_limits<Scalar>::infinity() * VectorXs::Ones(nq0); |
|
36 |
✓✗✓✗ ✓✗✓✗ |
11084 |
ub_.head(nq0) = std::numeric_limits<Scalar>::infinity() * VectorXs::Ones(nq0); |
37 |
✓✗✓✗ ✓✗ |
11084 |
lb_.segment(nq0, nq_ - nq0) = pinocchio_->lowerPositionLimit.tail(nq_ - nq0); |
38 |
✓✗✓✗ ✓✗ |
11084 |
ub_.segment(nq0, nq_ - nq0) = pinocchio_->upperPositionLimit.tail(nq_ - nq0); |
39 |
✓✗✓✗ ✓✗ |
11084 |
lb_.tail(nv_) = -pinocchio_->velocityLimit; |
40 |
✓✗✓✗ |
11084 |
ub_.tail(nv_) = pinocchio_->velocityLimit; |
41 |
✓✗ | 11084 |
Base::update_has_limits(); |
42 |
11084 |
} |
|
43 |
|||
44 |
template <typename Scalar> |
||
45 |
StateMultibodyTpl<Scalar>::StateMultibodyTpl() |
||
46 |
: Base(), x0_(VectorXs::Zero(0)) {} |
||
47 |
|||
48 |
template <typename Scalar> |
||
49 |
22172 |
StateMultibodyTpl<Scalar>::~StateMultibodyTpl() {} |
|
50 |
|||
51 |
template <typename Scalar> |
||
52 |
3560 |
typename MathBaseTpl<Scalar>::VectorXs StateMultibodyTpl<Scalar>::zero() const { |
|
53 |
3560 |
return x0_; |
|
54 |
} |
||
55 |
|||
56 |
template <typename Scalar> |
||
57 |
11884 |
typename MathBaseTpl<Scalar>::VectorXs StateMultibodyTpl<Scalar>::rand() const { |
|
58 |
✓✗ | 11884 |
VectorXs xrand = VectorXs::Random(nx_); |
59 |
✓✗✓✗ ✓✗ |
11884 |
xrand.head(nq_) = pinocchio::randomConfiguration(*pinocchio_.get()); |
60 |
11884 |
return xrand; |
|
61 |
} |
||
62 |
|||
63 |
template <typename Scalar> |
||
64 |
105907 |
void StateMultibodyTpl<Scalar>::diff(const Eigen::Ref<const VectorXs>& x0, |
|
65 |
const Eigen::Ref<const VectorXs>& x1, |
||
66 |
Eigen::Ref<VectorXs> dxout) const { |
||
67 |
✗✓ | 105907 |
if (static_cast<std::size_t>(x0.size()) != nx_) { |
68 |
throw_pretty("Invalid argument: " |
||
69 |
<< "x0 has wrong dimension (it should be " + |
||
70 |
std::to_string(nx_) + ")"); |
||
71 |
} |
||
72 |
✗✓ | 105907 |
if (static_cast<std::size_t>(x1.size()) != nx_) { |
73 |
throw_pretty("Invalid argument: " |
||
74 |
<< "x1 has wrong dimension (it should be " + |
||
75 |
std::to_string(nx_) + ")"); |
||
76 |
} |
||
77 |
✗✓ | 105907 |
if (static_cast<std::size_t>(dxout.size()) != ndx_) { |
78 |
throw_pretty("Invalid argument: " |
||
79 |
<< "dxout has wrong dimension (it should be " + |
||
80 |
std::to_string(ndx_) + ")"); |
||
81 |
} |
||
82 |
|||
83 |
✓✗✓✗ ✓✗ |
105907 |
pinocchio::difference(*pinocchio_.get(), x0.head(nq_), x1.head(nq_), |
84 |
105907 |
dxout.head(nv_)); |
|
85 |
✓✗✓✗ ✓✗✓✗ |
105907 |
dxout.tail(nv_) = x1.tail(nv_) - x0.tail(nv_); |
86 |
105907 |
} |
|
87 |
|||
88 |
template <typename Scalar> |
||
89 |
147694 |
void StateMultibodyTpl<Scalar>::integrate(const Eigen::Ref<const VectorXs>& x, |
|
90 |
const Eigen::Ref<const VectorXs>& dx, |
||
91 |
Eigen::Ref<VectorXs> xout) const { |
||
92 |
✗✓ | 147694 |
if (static_cast<std::size_t>(x.size()) != nx_) { |
93 |
throw_pretty("Invalid argument: " |
||
94 |
<< "x has wrong dimension (it should be " + |
||
95 |
std::to_string(nx_) + ")"); |
||
96 |
} |
||
97 |
✗✓ | 147694 |
if (static_cast<std::size_t>(dx.size()) != ndx_) { |
98 |
throw_pretty("Invalid argument: " |
||
99 |
<< "dx has wrong dimension (it should be " + |
||
100 |
std::to_string(ndx_) + ")"); |
||
101 |
} |
||
102 |
✗✓ | 147694 |
if (static_cast<std::size_t>(xout.size()) != nx_) { |
103 |
throw_pretty("Invalid argument: " |
||
104 |
<< "xout has wrong dimension (it should be " + |
||
105 |
std::to_string(nx_) + ")"); |
||
106 |
} |
||
107 |
|||
108 |
✓✗✓✗ ✓✗ |
147694 |
pinocchio::integrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
109 |
147694 |
xout.head(nq_)); |
|
110 |
✓✗✓✗ ✓✗✓✗ |
147694 |
xout.tail(nv_) = x.tail(nv_) + dx.tail(nv_); |
111 |
147694 |
} |
|
112 |
|||
113 |
template <typename Scalar> |
||
114 |
14159 |
void StateMultibodyTpl<Scalar>::Jdiff(const Eigen::Ref<const VectorXs>& x0, |
|
115 |
const Eigen::Ref<const VectorXs>& x1, |
||
116 |
Eigen::Ref<MatrixXs> Jfirst, |
||
117 |
Eigen::Ref<MatrixXs> Jsecond, |
||
118 |
const Jcomponent firstsecond) const { |
||
119 |
✗✓✗✗ ✗✗✗✗ ✗✗ |
14159 |
assert_pretty( |
120 |
is_a_Jcomponent(firstsecond), |
||
121 |
("firstsecond must be one of the Jcomponent {both, first, second}")); |
||
122 |
✗✓ | 14159 |
if (static_cast<std::size_t>(x0.size()) != nx_) { |
123 |
throw_pretty("Invalid argument: " |
||
124 |
<< "x0 has wrong dimension (it should be " + |
||
125 |
std::to_string(nx_) + ")"); |
||
126 |
} |
||
127 |
✗✓ | 14159 |
if (static_cast<std::size_t>(x1.size()) != nx_) { |
128 |
throw_pretty("Invalid argument: " |
||
129 |
<< "x1 has wrong dimension (it should be " + |
||
130 |
std::to_string(nx_) + ")"); |
||
131 |
} |
||
132 |
|||
133 |
✓✓ | 14159 |
if (firstsecond == first) { |
134 |
✓✗✗✓ |
24 |
if (static_cast<std::size_t>(Jfirst.rows()) != ndx_ || |
135 |
✗✓ | 12 |
static_cast<std::size_t>(Jfirst.cols()) != ndx_) { |
136 |
throw_pretty("Invalid argument: " |
||
137 |
<< "Jfirst has wrong dimension (it should be " + |
||
138 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
139 |
")"); |
||
140 |
} |
||
141 |
|||
142 |
✓✗✓✗ ✓✗ |
12 |
pinocchio::dDifference(*pinocchio_.get(), x0.head(nq_), x1.head(nq_), |
143 |
12 |
Jfirst.topLeftCorner(nv_, nv_), pinocchio::ARG0); |
|
144 |
✓✗✓✗ ✓✗✓✗ |
12 |
Jfirst.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)-1; |
145 |
✓✓ | 14147 |
} else if (firstsecond == second) { |
146 |
✓✗✗✓ |
28240 |
if (static_cast<std::size_t>(Jsecond.rows()) != ndx_ || |
147 |
✗✓ | 14120 |
static_cast<std::size_t>(Jsecond.cols()) != ndx_) { |
148 |
throw_pretty("Invalid argument: " |
||
149 |
<< "Jsecond has wrong dimension (it should be " + |
||
150 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
151 |
")"); |
||
152 |
} |
||
153 |
✓✗✓✗ ✓✗ |
14120 |
pinocchio::dDifference(*pinocchio_.get(), x0.head(nq_), x1.head(nq_), |
154 |
14120 |
Jsecond.topLeftCorner(nv_, nv_), pinocchio::ARG1); |
|
155 |
✓✗✓✗ ✓✗✓✗ |
14120 |
Jsecond.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)1; |
156 |
} else { // computing both |
||
157 |
✓✗✗✓ |
54 |
if (static_cast<std::size_t>(Jfirst.rows()) != ndx_ || |
158 |
✗✓ | 27 |
static_cast<std::size_t>(Jfirst.cols()) != ndx_) { |
159 |
throw_pretty("Invalid argument: " |
||
160 |
<< "Jfirst has wrong dimension (it should be " + |
||
161 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
162 |
")"); |
||
163 |
} |
||
164 |
✓✗✗✓ |
54 |
if (static_cast<std::size_t>(Jsecond.rows()) != ndx_ || |
165 |
✗✓ | 27 |
static_cast<std::size_t>(Jsecond.cols()) != ndx_) { |
166 |
throw_pretty("Invalid argument: " |
||
167 |
<< "Jsecond has wrong dimension (it should be " + |
||
168 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
169 |
")"); |
||
170 |
} |
||
171 |
✓✗✓✗ ✓✗ |
27 |
pinocchio::dDifference(*pinocchio_.get(), x0.head(nq_), x1.head(nq_), |
172 |
27 |
Jfirst.topLeftCorner(nv_, nv_), pinocchio::ARG0); |
|
173 |
✓✗✓✗ ✓✗ |
27 |
pinocchio::dDifference(*pinocchio_.get(), x0.head(nq_), x1.head(nq_), |
174 |
27 |
Jsecond.topLeftCorner(nv_, nv_), pinocchio::ARG1); |
|
175 |
✓✗✓✗ ✓✗✓✗ |
27 |
Jfirst.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)-1; |
176 |
✓✗✓✗ ✓✗✓✗ |
27 |
Jsecond.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)1; |
177 |
} |
||
178 |
14159 |
} |
|
179 |
|||
180 |
template <typename Scalar> |
||
181 |
13263 |
void StateMultibodyTpl<Scalar>::Jintegrate(const Eigen::Ref<const VectorXs>& x, |
|
182 |
const Eigen::Ref<const VectorXs>& dx, |
||
183 |
Eigen::Ref<MatrixXs> Jfirst, |
||
184 |
Eigen::Ref<MatrixXs> Jsecond, |
||
185 |
const Jcomponent firstsecond, |
||
186 |
const AssignmentOp op) const { |
||
187 |
✗✓✗✗ ✗✗✗✗ ✗✗ |
13263 |
assert_pretty( |
188 |
is_a_Jcomponent(firstsecond), |
||
189 |
("firstsecond must be one of the Jcomponent {both, first, second}")); |
||
190 |
✗✓✗✗ ✗✗✗✗ ✗✗ |
13263 |
assert_pretty(is_a_AssignmentOp(op), |
191 |
("op must be one of the AssignmentOp {settop, addto, rmfrom}")); |
||
192 |
✓✓✓✓ |
13263 |
if (firstsecond == first || firstsecond == both) { |
193 |
✓✗✗✓ |
26514 |
if (static_cast<std::size_t>(Jfirst.rows()) != ndx_ || |
194 |
✗✓ | 13257 |
static_cast<std::size_t>(Jfirst.cols()) != ndx_) { |
195 |
throw_pretty("Invalid argument: " |
||
196 |
<< "Jfirst has wrong dimension (it should be " + |
||
197 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
198 |
")"); |
||
199 |
} |
||
200 |
✓✓✗✗ |
13257 |
switch (op) { |
201 |
194 |
case setto: |
|
202 |
✓✗✓✗ ✓✗ |
194 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
203 |
194 |
Jfirst.topLeftCorner(nv_, nv_), pinocchio::ARG0, |
|
204 |
pinocchio::SETTO); |
||
205 |
✓✗✓✗ ✓✗✓✗ |
194 |
Jfirst.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)1; |
206 |
194 |
break; |
|
207 |
13063 |
case addto: |
|
208 |
✓✗✓✗ ✓✗ |
13063 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
209 |
13063 |
Jfirst.topLeftCorner(nv_, nv_), pinocchio::ARG0, |
|
210 |
pinocchio::ADDTO); |
||
211 |
✓✗✓✗ ✓✗✓✗ |
13063 |
Jfirst.bottomRightCorner(nv_, nv_).diagonal().array() += (Scalar)1; |
212 |
13063 |
break; |
|
213 |
case rmfrom: |
||
214 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
||
215 |
Jfirst.topLeftCorner(nv_, nv_), pinocchio::ARG0, |
||
216 |
pinocchio::RMTO); |
||
217 |
Jfirst.bottomRightCorner(nv_, nv_).diagonal().array() -= (Scalar)1; |
||
218 |
break; |
||
219 |
default: |
||
220 |
throw_pretty( |
||
221 |
"Invalid argument: allowed operators: setto, addto, rmfrom"); |
||
222 |
break; |
||
223 |
} |
||
224 |
} |
||
225 |
✓✓✓✓ |
13263 |
if (firstsecond == second || firstsecond == both) { |
226 |
✓✗✗✓ |
388 |
if (static_cast<std::size_t>(Jsecond.rows()) != ndx_ || |
227 |
✗✓ | 194 |
static_cast<std::size_t>(Jsecond.cols()) != ndx_) { |
228 |
throw_pretty("Invalid argument: " |
||
229 |
<< "Jsecond has wrong dimension (it should be " + |
||
230 |
std::to_string(ndx_) + "," + std::to_string(ndx_) + |
||
231 |
")"); |
||
232 |
} |
||
233 |
✓✗✗✗ |
194 |
switch (op) { |
234 |
194 |
case setto: |
|
235 |
✓✗✓✗ ✓✗ |
194 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
236 |
194 |
Jsecond.topLeftCorner(nv_, nv_), pinocchio::ARG1, |
|
237 |
pinocchio::SETTO); |
||
238 |
✓✗✓✗ ✓✗✓✗ |
194 |
Jsecond.bottomRightCorner(nv_, nv_).diagonal().array() = (Scalar)1; |
239 |
194 |
break; |
|
240 |
case addto: |
||
241 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
||
242 |
Jsecond.topLeftCorner(nv_, nv_), pinocchio::ARG1, |
||
243 |
pinocchio::ADDTO); |
||
244 |
Jsecond.bottomRightCorner(nv_, nv_).diagonal().array() += (Scalar)1; |
||
245 |
break; |
||
246 |
case rmfrom: |
||
247 |
pinocchio::dIntegrate(*pinocchio_.get(), x.head(nq_), dx.head(nv_), |
||
248 |
Jsecond.topLeftCorner(nv_, nv_), pinocchio::ARG1, |
||
249 |
pinocchio::RMTO); |
||
250 |
Jsecond.bottomRightCorner(nv_, nv_).diagonal().array() -= (Scalar)1; |
||
251 |
break; |
||
252 |
default: |
||
253 |
throw_pretty( |
||
254 |
"Invalid argument: allowed operators: setto, addto, rmfrom"); |
||
255 |
break; |
||
256 |
} |
||
257 |
} |
||
258 |
13263 |
} |
|
259 |
|||
260 |
template <typename Scalar> |
||
261 |
26138 |
void StateMultibodyTpl<Scalar>::JintegrateTransport( |
|
262 |
const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& dx, |
||
263 |
Eigen::Ref<MatrixXs> Jin, const Jcomponent firstsecond) const { |
||
264 |
✗✓✗✗ ✗✗✗✗ ✗✗ |
26138 |
assert_pretty( |
265 |
is_a_Jcomponent(firstsecond), |
||
266 |
("firstsecond must be one of the Jcomponent {both, first, second}")); |
||
267 |
|||
268 |
✓✓✗ | 26138 |
switch (firstsecond) { |
269 |
6 |
case first: |
|
270 |
✓✗✓✗ |
6 |
pinocchio::dIntegrateTransport(*pinocchio_.get(), x.head(nq_), |
271 |
✓✗ | 6 |
dx.head(nv_), Jin.topRows(nv_), |
272 |
pinocchio::ARG0); |
||
273 |
6 |
break; |
|
274 |
26132 |
case second: |
|
275 |
✓✗✓✗ |
26132 |
pinocchio::dIntegrateTransport(*pinocchio_.get(), x.head(nq_), |
276 |
✓✗ | 26132 |
dx.head(nv_), Jin.topRows(nv_), |
277 |
pinocchio::ARG1); |
||
278 |
26132 |
break; |
|
279 |
default: |
||
280 |
throw_pretty( |
||
281 |
"Invalid argument: firstsecond must be either first or second. both " |
||
282 |
"not supported for this operation."); |
||
283 |
break; |
||
284 |
} |
||
285 |
26138 |
} |
|
286 |
|||
287 |
template <typename Scalar> |
||
288 |
const boost::shared_ptr<pinocchio::ModelTpl<Scalar> >& |
||
289 |
1516411 |
StateMultibodyTpl<Scalar>::get_pinocchio() const { |
|
290 |
1516411 |
return pinocchio_; |
|
291 |
} |
||
292 |
|||
293 |
} // namespace crocoddyl |
Generated by: GCOVR (Version 4.2) |