GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/////////////////////////////////////////////////////////////////////////////// |
||
2 |
// BSD 3-Clause License |
||
3 |
// |
||
4 |
// Copyright (C) 2019-2022, LAAS-CNRS, University of Edinburgh, |
||
5 |
// Heriot-Watt University |
||
6 |
// Copyright note valid unless otherwise stated in individual files. |
||
7 |
// All rights reserved. |
||
8 |
/////////////////////////////////////////////////////////////////////////////// |
||
9 |
|||
10 |
#include <pinocchio/algorithm/aba-derivatives.hpp> |
||
11 |
#include <pinocchio/algorithm/aba.hpp> |
||
12 |
#include <pinocchio/algorithm/cholesky.hpp> |
||
13 |
#include <pinocchio/algorithm/compute-all-terms.hpp> |
||
14 |
#include <pinocchio/algorithm/frames.hpp> |
||
15 |
#include <pinocchio/algorithm/jacobian.hpp> |
||
16 |
#include <pinocchio/algorithm/kinematics.hpp> |
||
17 |
#include <pinocchio/algorithm/rnea-derivatives.hpp> |
||
18 |
#include <pinocchio/algorithm/rnea.hpp> |
||
19 |
|||
20 |
#include "crocoddyl/core/utils/exception.hpp" |
||
21 |
#include "crocoddyl/multibody/actions/free-fwddyn.hpp" |
||
22 |
|||
23 |
namespace crocoddyl { |
||
24 |
|||
25 |
template <typename Scalar> |
||
26 |
160 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>:: |
|
27 |
DifferentialActionModelFreeFwdDynamicsTpl( |
||
28 |
boost::shared_ptr<StateMultibody> state, |
||
29 |
boost::shared_ptr<ActuationModelAbstract> actuation, |
||
30 |
boost::shared_ptr<CostModelSum> costs, |
||
31 |
boost::shared_ptr<ConstraintModelManager> constraints) |
||
32 |
: Base(state, actuation->get_nu(), costs->get_nr()), |
||
33 |
actuation_(actuation), |
||
34 |
costs_(costs), |
||
35 |
constraints_(constraints), |
||
36 |
160 |
pinocchio_(*state->get_pinocchio().get()), |
|
37 |
without_armature_(true), |
||
38 |
✓✗✓✗ ✓✗ |
320 |
armature_(VectorXs::Zero(state->get_nv())) { |
39 |
✗✓ | 160 |
if (costs_->get_nu() != nu_) { |
40 |
throw_pretty( |
||
41 |
"Invalid argument: " |
||
42 |
<< "Costs doesn't have the same control dimension (it should be " + |
||
43 |
std::to_string(nu_) + ")"); |
||
44 |
} |
||
45 |
✓✗✓✗ ✓✗✓✗ |
160 |
Base::set_u_lb(Scalar(-1.) * pinocchio_.effortLimit.tail(nu_)); |
46 |
✓✗✓✗ ✓✗✓✗ |
160 |
Base::set_u_ub(Scalar(+1.) * pinocchio_.effortLimit.tail(nu_)); |
47 |
160 |
} |
|
48 |
|||
49 |
template <typename Scalar> |
||
50 |
324 |
DifferentialActionModelFreeFwdDynamicsTpl< |
|
51 |
324 |
Scalar>::~DifferentialActionModelFreeFwdDynamicsTpl() {} |
|
52 |
|||
53 |
template <typename Scalar> |
||
54 |
7780 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::calc( |
|
55 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
56 |
const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { |
||
57 |
✓✗✗✓ |
7780 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
58 |
throw_pretty("Invalid argument: " |
||
59 |
<< "x has wrong dimension (it should be " + |
||
60 |
std::to_string(state_->get_nx()) + ")"); |
||
61 |
} |
||
62 |
✓✗✗✓ |
7780 |
if (static_cast<std::size_t>(u.size()) != nu_) { |
63 |
throw_pretty("Invalid argument: " |
||
64 |
<< "u has wrong dimension (it should be " + |
||
65 |
std::to_string(nu_) + ")"); |
||
66 |
} |
||
67 |
|||
68 |
7780 |
Data* d = static_cast<Data*>(data.get()); |
|
69 |
✓✗ | 7780 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> q = |
70 |
x.head(state_->get_nq()); |
||
71 |
✓✗ | 7780 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v = |
72 |
x.tail(state_->get_nv()); |
||
73 |
|||
74 |
✓✗ | 7780 |
actuation_->calc(d->multibody.actuation, x, u); |
75 |
|||
76 |
// Computing the dynamics using ABA or manually for armature case |
||
77 |
✓✓ | 7780 |
if (without_armature_) { |
78 |
✓✗ | 7778 |
d->xout = pinocchio::aba(pinocchio_, d->pinocchio, q, v, |
79 |
✓✗ | 7778 |
d->multibody.actuation->tau); |
80 |
✓✗ | 7778 |
pinocchio::updateGlobalPlacements(pinocchio_, d->pinocchio); |
81 |
} else { |
||
82 |
✓✗ | 2 |
pinocchio::computeAllTerms(pinocchio_, d->pinocchio, q, v); |
83 |
✓✗✓✗ |
2 |
d->pinocchio.M.diagonal() += armature_; |
84 |
✓✗ | 2 |
pinocchio::cholesky::decompose(pinocchio_, d->pinocchio); |
85 |
✓✗ | 2 |
d->Minv.setZero(); |
86 |
✓✗ | 2 |
pinocchio::cholesky::computeMinv(pinocchio_, d->pinocchio, d->Minv); |
87 |
✓✗✓✗ |
2 |
d->u_drift = d->multibody.actuation->tau - d->pinocchio.nle; |
88 |
✓✗✓✗ ✓✗ |
2 |
d->xout.noalias() = d->Minv * d->u_drift; |
89 |
} |
||
90 |
✓✗ | 7780 |
d->multibody.joint->a = d->xout; |
91 |
✓✗ | 7780 |
d->multibody.joint->tau = u; |
92 |
✓✗ | 7780 |
costs_->calc(d->costs, x, u); |
93 |
7780 |
d->cost = d->costs->cost; |
|
94 |
✓✓ | 7780 |
if (constraints_ != nullptr) { |
95 |
✓✗ | 4829 |
d->constraints->resize(this, d); |
96 |
✓✗ | 4829 |
constraints_->calc(d->constraints, x, u); |
97 |
} |
||
98 |
7780 |
} |
|
99 |
|||
100 |
template <typename Scalar> |
||
101 |
688 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::calc( |
|
102 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
103 |
const Eigen::Ref<const VectorXs>& x) { |
||
104 |
✓✗✗✓ |
688 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
105 |
throw_pretty("Invalid argument: " |
||
106 |
<< "x has wrong dimension (it should be " + |
||
107 |
std::to_string(state_->get_nx()) + ")"); |
||
108 |
} |
||
109 |
|||
110 |
688 |
Data* d = static_cast<Data*>(data.get()); |
|
111 |
✓✗ | 688 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> q = |
112 |
x.head(state_->get_nq()); |
||
113 |
✓✗ | 688 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v = |
114 |
x.tail(state_->get_nv()); |
||
115 |
|||
116 |
✓✗ | 688 |
pinocchio::computeAllTerms(pinocchio_, d->pinocchio, q, v); |
117 |
|||
118 |
✓✗ | 688 |
costs_->calc(d->costs, x); |
119 |
688 |
d->cost = d->costs->cost; |
|
120 |
✓✓ | 688 |
if (constraints_ != nullptr) { |
121 |
✓✗ | 394 |
d->constraints->resize(this, d); |
122 |
✓✗ | 394 |
constraints_->calc(d->constraints, x); |
123 |
} |
||
124 |
688 |
} |
|
125 |
|||
126 |
template <typename Scalar> |
||
127 |
2346 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::calcDiff( |
|
128 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
129 |
const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { |
||
130 |
✓✗✗✓ |
2346 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
131 |
throw_pretty("Invalid argument: " |
||
132 |
<< "x has wrong dimension (it should be " + |
||
133 |
std::to_string(state_->get_nx()) + ")"); |
||
134 |
} |
||
135 |
✓✗✗✓ |
2346 |
if (static_cast<std::size_t>(u.size()) != nu_) { |
136 |
throw_pretty("Invalid argument: " |
||
137 |
<< "u has wrong dimension (it should be " + |
||
138 |
std::to_string(nu_) + ")"); |
||
139 |
} |
||
140 |
|||
141 |
2346 |
const std::size_t nv = state_->get_nv(); |
|
142 |
✓✗ | 2346 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> q = |
143 |
x.head(state_->get_nq()); |
||
144 |
✓✗ | 2346 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v = |
145 |
x.tail(nv); |
||
146 |
|||
147 |
2346 |
Data* d = static_cast<Data*>(data.get()); |
|
148 |
|||
149 |
✓✗ | 2346 |
actuation_->calcDiff(d->multibody.actuation, x, u); |
150 |
|||
151 |
// Computing the dynamics derivatives |
||
152 |
✓✓ | 2346 |
if (without_armature_) { |
153 |
pinocchio::computeABADerivatives( |
||
154 |
✓✗ | 2345 |
pinocchio_, d->pinocchio, q, v, d->multibody.actuation->tau, |
155 |
✓✗✓✗ |
2345 |
d->Fx.leftCols(nv), d->Fx.rightCols(nv), d->pinocchio.Minv); |
156 |
✓✗✓✗ ✓✗ |
2345 |
d->Fx.noalias() += d->pinocchio.Minv * d->multibody.actuation->dtau_dx; |
157 |
✓✗✓✗ ✓✗ |
2345 |
d->Fu.noalias() = d->pinocchio.Minv * d->multibody.actuation->dtau_du; |
158 |
} else { |
||
159 |
✓✗ | 1 |
pinocchio::computeRNEADerivatives(pinocchio_, d->pinocchio, q, v, d->xout); |
160 |
✓✗✓✗ ✓✗ |
1 |
d->dtau_dx.leftCols(nv) = |
161 |
✓✗ | 1 |
d->multibody.actuation->dtau_dx.leftCols(nv) - d->pinocchio.dtau_dq; |
162 |
✓✗✓✗ ✓✗ |
1 |
d->dtau_dx.rightCols(nv) = |
163 |
✓✗ | 1 |
d->multibody.actuation->dtau_dx.rightCols(nv) - d->pinocchio.dtau_dv; |
164 |
✓✗✓✗ ✓✗ |
1 |
d->Fx.noalias() = d->Minv * d->dtau_dx; |
165 |
✓✗✓✗ ✓✗ |
1 |
d->Fu.noalias() = d->Minv * d->multibody.actuation->dtau_du; |
166 |
} |
||
167 |
✓✗ | 2346 |
d->multibody.joint->da_dx = d->Fx; |
168 |
✓✗ | 2346 |
d->multibody.joint->da_du = d->Fu; |
169 |
✓✗ | 2346 |
costs_->calcDiff(d->costs, x, u); |
170 |
✓✓ | 2346 |
if (constraints_ != nullptr) { |
171 |
✓✗ | 1254 |
constraints_->calcDiff(d->constraints, x, u); |
172 |
} |
||
173 |
2346 |
} |
|
174 |
|||
175 |
template <typename Scalar> |
||
176 |
136 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::calcDiff( |
|
177 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
178 |
const Eigen::Ref<const VectorXs>& x) { |
||
179 |
✗✓ | 136 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
180 |
throw_pretty("Invalid argument: " |
||
181 |
<< "x has wrong dimension (it should be " + |
||
182 |
std::to_string(state_->get_nx()) + ")"); |
||
183 |
} |
||
184 |
136 |
Data* d = static_cast<Data*>(data.get()); |
|
185 |
|||
186 |
136 |
costs_->calcDiff(d->costs, x); |
|
187 |
✓✓ | 136 |
if (constraints_ != nullptr) { |
188 |
44 |
constraints_->calcDiff(d->constraints, x); |
|
189 |
} |
||
190 |
136 |
} |
|
191 |
|||
192 |
template <typename Scalar> |
||
193 |
boost::shared_ptr<DifferentialActionDataAbstractTpl<Scalar> > |
||
194 |
10259 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::createData() { |
|
195 |
✓✗ | 10259 |
return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this); |
196 |
} |
||
197 |
|||
198 |
template <typename Scalar> |
||
199 |
1971 |
bool DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::checkData( |
|
200 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data) { |
||
201 |
3942 |
boost::shared_ptr<Data> d = boost::dynamic_pointer_cast<Data>(data); |
|
202 |
✓✗ | 1971 |
if (d != NULL) { |
203 |
1971 |
return true; |
|
204 |
} else { |
||
205 |
return false; |
||
206 |
} |
||
207 |
} |
||
208 |
|||
209 |
template <typename Scalar> |
||
210 |
962 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::quasiStatic( |
|
211 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
212 |
Eigen::Ref<VectorXs> u, const Eigen::Ref<const VectorXs>& x, |
||
213 |
const std::size_t, const Scalar) { |
||
214 |
✓✗✗✓ |
962 |
if (static_cast<std::size_t>(u.size()) != nu_) { |
215 |
throw_pretty("Invalid argument: " |
||
216 |
<< "u has wrong dimension (it should be " + |
||
217 |
std::to_string(nu_) + ")"); |
||
218 |
} |
||
219 |
✓✗✗✓ |
962 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
220 |
throw_pretty("Invalid argument: " |
||
221 |
<< "x has wrong dimension (it should be " + |
||
222 |
std::to_string(state_->get_nx()) + ")"); |
||
223 |
} |
||
224 |
// Static casting the data |
||
225 |
962 |
Data* d = static_cast<Data*>(data.get()); |
|
226 |
✓✗ | 962 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> q = |
227 |
x.head(state_->get_nq()); |
||
228 |
|||
229 |
962 |
const std::size_t nq = state_->get_nq(); |
|
230 |
962 |
const std::size_t nv = state_->get_nv(); |
|
231 |
|||
232 |
✓✗✓✗ |
962 |
d->tmp_xstatic.head(nq) = q; |
233 |
✓✗✓✗ |
962 |
d->tmp_xstatic.tail(nv).setZero(); |
234 |
✓✗ | 962 |
u.setZero(); |
235 |
|||
236 |
✓✗✓✗ |
962 |
pinocchio::rnea(pinocchio_, d->pinocchio, q, d->tmp_xstatic.tail(nv), |
237 |
✓✗ | 962 |
d->tmp_xstatic.tail(nv)); |
238 |
✓✗✓✗ ✓✗ |
962 |
actuation_->calc(d->multibody.actuation, d->tmp_xstatic, u); |
239 |
✓✗✓✗ ✓✗ |
962 |
actuation_->calcDiff(d->multibody.actuation, d->tmp_xstatic, u); |
240 |
|||
241 |
✓✗✓✗ |
962 |
u.noalias() = |
242 |
✓✗✓✗ |
1924 |
pseudoInverse(d->multibody.actuation->dtau_du) * d->pinocchio.tau; |
243 |
✓✗ | 962 |
d->pinocchio.tau.setZero(); |
244 |
962 |
} |
|
245 |
|||
246 |
template <typename Scalar> |
||
247 |
49991 |
std::size_t DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_ng() const { |
|
248 |
✓✓ | 49991 |
if (constraints_ != nullptr) { |
249 |
33508 |
return constraints_->get_ng(); |
|
250 |
} else { |
||
251 |
16483 |
return Base::get_ng(); |
|
252 |
} |
||
253 |
} |
||
254 |
|||
255 |
template <typename Scalar> |
||
256 |
49991 |
std::size_t DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_nh() const { |
|
257 |
✓✓ | 49991 |
if (constraints_ != nullptr) { |
258 |
33508 |
return constraints_->get_nh(); |
|
259 |
} else { |
||
260 |
16483 |
return Base::get_nh(); |
|
261 |
} |
||
262 |
} |
||
263 |
|||
264 |
template <typename Scalar> |
||
265 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
266 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_g_lb() const { |
||
267 |
if (constraints_ != nullptr) { |
||
268 |
return constraints_->get_lb(); |
||
269 |
} else { |
||
270 |
return g_lb_; |
||
271 |
} |
||
272 |
} |
||
273 |
|||
274 |
template <typename Scalar> |
||
275 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
276 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_g_ub() const { |
||
277 |
if (constraints_ != nullptr) { |
||
278 |
return constraints_->get_ub(); |
||
279 |
} else { |
||
280 |
return g_lb_; |
||
281 |
} |
||
282 |
} |
||
283 |
|||
284 |
template <typename Scalar> |
||
285 |
30 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::print( |
|
286 |
std::ostream& os) const { |
||
287 |
30 |
os << "DifferentialActionModelFreeFwdDynamics {nx=" << state_->get_nx() |
|
288 |
30 |
<< ", ndx=" << state_->get_ndx() << ", nu=" << nu_ << "}"; |
|
289 |
30 |
} |
|
290 |
|||
291 |
template <typename Scalar> |
||
292 |
pinocchio::ModelTpl<Scalar>& |
||
293 |
10259 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_pinocchio() const { |
|
294 |
10259 |
return pinocchio_; |
|
295 |
} |
||
296 |
|||
297 |
template <typename Scalar> |
||
298 |
const boost::shared_ptr<ActuationModelAbstractTpl<Scalar> >& |
||
299 |
20518 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_actuation() const { |
|
300 |
20518 |
return actuation_; |
|
301 |
} |
||
302 |
|||
303 |
template <typename Scalar> |
||
304 |
const boost::shared_ptr<CostModelSumTpl<Scalar> >& |
||
305 |
10259 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_costs() const { |
|
306 |
10259 |
return costs_; |
|
307 |
} |
||
308 |
|||
309 |
template <typename Scalar> |
||
310 |
const boost::shared_ptr<ConstraintModelManagerTpl<Scalar> >& |
||
311 |
16922 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_constraints() const { |
|
312 |
16922 |
return constraints_; |
|
313 |
} |
||
314 |
|||
315 |
template <typename Scalar> |
||
316 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
317 |
DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::get_armature() const { |
||
318 |
return armature_; |
||
319 |
} |
||
320 |
|||
321 |
template <typename Scalar> |
||
322 |
1 |
void DifferentialActionModelFreeFwdDynamicsTpl<Scalar>::set_armature( |
|
323 |
const VectorXs& armature) { |
||
324 |
✗✓ | 1 |
if (static_cast<std::size_t>(armature.size()) != state_->get_nv()) { |
325 |
throw_pretty("Invalid argument: " |
||
326 |
<< "The armature dimension is wrong (it should be " + |
||
327 |
std::to_string(state_->get_nv()) + ")"); |
||
328 |
} |
||
329 |
|||
330 |
1 |
armature_ = armature; |
|
331 |
1 |
without_armature_ = false; |
|
332 |
1 |
} |
|
333 |
|||
334 |
} // namespace crocoddyl |
Generated by: GCOVR (Version 4.2) |