GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/////////////////////////////////////////////////////////////////////////////// |
||
2 |
// BSD 3-Clause License |
||
3 |
// |
||
4 |
// Copyright (C) 2019-2021, LAAS-CNRS, University of Edinburgh |
||
5 |
// Copyright note valid unless otherwise stated in individual files. |
||
6 |
// All rights reserved. |
||
7 |
/////////////////////////////////////////////////////////////////////////////// |
||
8 |
|||
9 |
#include "crocoddyl/core/actions/diff-lqr.hpp" |
||
10 |
#include "crocoddyl/core/utils/exception.hpp" |
||
11 |
|||
12 |
namespace crocoddyl { |
||
13 |
|||
14 |
template <typename Scalar> |
||
15 |
105 |
DifferentialActionModelLQRTpl<Scalar>::DifferentialActionModelLQRTpl( |
|
16 |
const std::size_t nq, const std::size_t nu, const bool drift_free) |
||
17 |
: Base(boost::make_shared<StateVector>(2 * nq), nu), |
||
18 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗ |
105 |
drift_free_(drift_free) { |
19 |
// TODO(cmastalli): substitute by random (vectors) and random-orthogonal |
||
20 |
// (matrices) |
||
21 |
✓✗✓✗ |
105 |
Fq_ = MatrixXs::Identity(state_->get_nq(), state_->get_nq()); |
22 |
✓✗✓✗ |
105 |
Fv_ = MatrixXs::Identity(state_->get_nv(), state_->get_nv()); |
23 |
✓✗✓✗ |
105 |
Fu_ = MatrixXs::Identity(state_->get_nq(), nu_); |
24 |
✓✗✓✗ |
105 |
f0_ = VectorXs::Ones(state_->get_nv()); |
25 |
✓✗✓✗ |
105 |
Lxx_ = MatrixXs::Identity(state_->get_nx(), state_->get_nx()); |
26 |
✓✗✓✗ |
105 |
Lxu_ = MatrixXs::Identity(state_->get_nx(), nu_); |
27 |
✓✗✓✗ |
105 |
Luu_ = MatrixXs::Identity(nu_, nu_); |
28 |
✓✗✓✗ |
105 |
lx_ = VectorXs::Ones(state_->get_nx()); |
29 |
✓✗✓✗ |
105 |
lu_ = VectorXs::Ones(nu_); |
30 |
105 |
} |
|
31 |
|||
32 |
template <typename Scalar> |
||
33 |
214 |
DifferentialActionModelLQRTpl<Scalar>::~DifferentialActionModelLQRTpl() {} |
|
34 |
|||
35 |
template <typename Scalar> |
||
36 |
12980 |
void DifferentialActionModelLQRTpl<Scalar>::calc( |
|
37 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
38 |
const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { |
||
39 |
✓✗✗✓ |
12980 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
40 |
throw_pretty("Invalid argument: " |
||
41 |
<< "x has wrong dimension (it should be " + |
||
42 |
std::to_string(state_->get_nx()) + ")"); |
||
43 |
} |
||
44 |
✓✗✗✓ |
12980 |
if (static_cast<std::size_t>(u.size()) != nu_) { |
45 |
throw_pretty("Invalid argument: " |
||
46 |
<< "u has wrong dimension (it should be " + |
||
47 |
std::to_string(nu_) + ")"); |
||
48 |
} |
||
49 |
✓✗ | 12980 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> q = |
50 |
x.head(state_->get_nq()); |
||
51 |
✓✗ | 12980 |
const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v = |
52 |
x.tail(state_->get_nv()); |
||
53 |
|||
54 |
✓✓ | 12980 |
if (drift_free_) { |
55 |
✓✗✓✗ ✓✗ |
6491 |
data->xout.noalias() = Fq_ * q; |
56 |
✓✗✓✗ ✓✗ |
6491 |
data->xout.noalias() += Fv_ * v; |
57 |
✓✗✓✗ ✓✗ |
6491 |
data->xout.noalias() += Fu_ * u; |
58 |
} else { |
||
59 |
✓✗✓✗ ✓✗ |
6489 |
data->xout.noalias() = Fq_ * q; |
60 |
✓✗✓✗ ✓✗ |
6489 |
data->xout.noalias() += Fv_ * v; |
61 |
✓✗✓✗ ✓✗ |
6489 |
data->xout.noalias() += Fu_ * u; |
62 |
✓✗ | 6489 |
data->xout += f0_; |
63 |
} |
||
64 |
✓✗✓✗ ✓✗✓✗ ✓✗ |
25960 |
data->cost = Scalar(0.5) * x.dot(Lxx_ * x) + Scalar(0.5) * u.dot(Luu_ * u) + |
65 |
✓✗✓✗ ✓✗ |
25960 |
x.dot(Lxu_ * u) + lx_.dot(x) + lu_.dot(u); |
66 |
12980 |
} |
|
67 |
|||
68 |
template <typename Scalar> |
||
69 |
1716 |
void DifferentialActionModelLQRTpl<Scalar>::calc( |
|
70 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
71 |
const Eigen::Ref<const VectorXs>& x) { |
||
72 |
✗✓ | 1716 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
73 |
throw_pretty("Invalid argument: " |
||
74 |
<< "x has wrong dimension (it should be " + |
||
75 |
std::to_string(state_->get_nx()) + ")"); |
||
76 |
} |
||
77 |
|||
78 |
✓✗✓✗ |
1716 |
data->cost = Scalar(0.5) * x.dot(Lxx_ * x) + lx_.dot(x); |
79 |
1716 |
} |
|
80 |
|||
81 |
template <typename Scalar> |
||
82 |
2539 |
void DifferentialActionModelLQRTpl<Scalar>::calcDiff( |
|
83 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
84 |
const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) { |
||
85 |
✗✓ | 2539 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
86 |
throw_pretty("Invalid argument: " |
||
87 |
<< "x has wrong dimension (it should be " + |
||
88 |
std::to_string(state_->get_nx()) + ")"); |
||
89 |
} |
||
90 |
✗✓ | 2539 |
if (static_cast<std::size_t>(u.size()) != nu_) { |
91 |
throw_pretty("Invalid argument: " |
||
92 |
<< "u has wrong dimension (it should be " + |
||
93 |
std::to_string(nu_) + ")"); |
||
94 |
} |
||
95 |
|||
96 |
2539 |
data->Lx = lx_; |
|
97 |
✓✗✓✗ |
2539 |
data->Lx.noalias() += Lxx_ * x; |
98 |
✓✗✓✗ |
2539 |
data->Lx.noalias() += Lxu_ * u; |
99 |
2539 |
data->Lu = lu_; |
|
100 |
✓✗✓✗ ✓✗ |
2539 |
data->Lu.noalias() += Lxu_.transpose() * x; |
101 |
✓✗✓✗ |
2539 |
data->Lu.noalias() += Luu_ * u; |
102 |
✓✗ | 2539 |
data->Fx.leftCols(state_->get_nq()) = Fq_; |
103 |
✓✗ | 2539 |
data->Fx.rightCols(state_->get_nv()) = Fv_; |
104 |
2539 |
data->Fu = Fu_; |
|
105 |
2539 |
data->Lxx = Lxx_; |
|
106 |
2539 |
data->Lxu = Lxu_; |
|
107 |
2539 |
data->Luu = Luu_; |
|
108 |
2539 |
} |
|
109 |
|||
110 |
template <typename Scalar> |
||
111 |
45 |
void DifferentialActionModelLQRTpl<Scalar>::calcDiff( |
|
112 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data, |
||
113 |
const Eigen::Ref<const VectorXs>& x) { |
||
114 |
✗✓ | 45 |
if (static_cast<std::size_t>(x.size()) != state_->get_nx()) { |
115 |
throw_pretty("Invalid argument: " |
||
116 |
<< "x has wrong dimension (it should be " + |
||
117 |
std::to_string(state_->get_nx()) + ")"); |
||
118 |
} |
||
119 |
|||
120 |
45 |
data->Lx = lx_; |
|
121 |
✓✗✓✗ |
45 |
data->Lx.noalias() += Lxx_ * x; |
122 |
45 |
data->Lxx = Lxx_; |
|
123 |
45 |
} |
|
124 |
|||
125 |
template <typename Scalar> |
||
126 |
boost::shared_ptr<DifferentialActionDataAbstractTpl<Scalar> > |
||
127 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::createData() { |
|
128 |
✓✗ | 13554 |
return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this); |
129 |
} |
||
130 |
|||
131 |
template <typename Scalar> |
||
132 |
1314 |
bool DifferentialActionModelLQRTpl<Scalar>::checkData( |
|
133 |
const boost::shared_ptr<DifferentialActionDataAbstract>& data) { |
||
134 |
2628 |
boost::shared_ptr<Data> d = boost::dynamic_pointer_cast<Data>(data); |
|
135 |
✓✗ | 1314 |
if (d != NULL) { |
136 |
1314 |
return true; |
|
137 |
} else { |
||
138 |
return false; |
||
139 |
} |
||
140 |
} |
||
141 |
|||
142 |
template <typename Scalar> |
||
143 |
20 |
void DifferentialActionModelLQRTpl<Scalar>::print(std::ostream& os) const { |
|
144 |
20 |
os << "DifferentialActionModelLQR {nq=" << state_->get_nq() << ", nu=" << nu_ |
|
145 |
20 |
<< ", drift_free=" << drift_free_ << "}"; |
|
146 |
20 |
} |
|
147 |
|||
148 |
template <typename Scalar> |
||
149 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
150 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Fq() const { |
|
151 |
13554 |
return Fq_; |
|
152 |
} |
||
153 |
|||
154 |
template <typename Scalar> |
||
155 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
156 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Fv() const { |
|
157 |
13554 |
return Fv_; |
|
158 |
} |
||
159 |
|||
160 |
template <typename Scalar> |
||
161 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
162 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Fu() const { |
|
163 |
13554 |
return Fu_; |
|
164 |
} |
||
165 |
|||
166 |
template <typename Scalar> |
||
167 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
168 |
DifferentialActionModelLQRTpl<Scalar>::get_f0() const { |
||
169 |
return f0_; |
||
170 |
} |
||
171 |
|||
172 |
template <typename Scalar> |
||
173 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
174 |
DifferentialActionModelLQRTpl<Scalar>::get_lx() const { |
||
175 |
return lx_; |
||
176 |
} |
||
177 |
|||
178 |
template <typename Scalar> |
||
179 |
const typename MathBaseTpl<Scalar>::VectorXs& |
||
180 |
DifferentialActionModelLQRTpl<Scalar>::get_lu() const { |
||
181 |
return lu_; |
||
182 |
} |
||
183 |
|||
184 |
template <typename Scalar> |
||
185 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
186 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Lxx() const { |
|
187 |
13554 |
return Lxx_; |
|
188 |
} |
||
189 |
|||
190 |
template <typename Scalar> |
||
191 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
192 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Lxu() const { |
|
193 |
13554 |
return Lxu_; |
|
194 |
} |
||
195 |
|||
196 |
template <typename Scalar> |
||
197 |
const typename MathBaseTpl<Scalar>::MatrixXs& |
||
198 |
13554 |
DifferentialActionModelLQRTpl<Scalar>::get_Luu() const { |
|
199 |
13554 |
return Luu_; |
|
200 |
} |
||
201 |
|||
202 |
template <typename Scalar> |
||
203 |
void DifferentialActionModelLQRTpl<Scalar>::set_Fq(const MatrixXs& Fq) { |
||
204 |
if (static_cast<std::size_t>(Fq.rows()) != state_->get_nq() || |
||
205 |
static_cast<std::size_t>(Fq.cols()) != state_->get_nq()) { |
||
206 |
throw_pretty("Invalid argument: " |
||
207 |
<< "Fq has wrong dimension (it should be " + |
||
208 |
std::to_string(state_->get_nq()) + "," + |
||
209 |
std::to_string(state_->get_nq()) + ")"); |
||
210 |
} |
||
211 |
Fq_ = Fq; |
||
212 |
} |
||
213 |
|||
214 |
template <typename Scalar> |
||
215 |
void DifferentialActionModelLQRTpl<Scalar>::set_Fv(const MatrixXs& Fv) { |
||
216 |
if (static_cast<std::size_t>(Fv.rows()) != state_->get_nv() || |
||
217 |
static_cast<std::size_t>(Fv.cols()) != state_->get_nv()) { |
||
218 |
throw_pretty("Invalid argument: " |
||
219 |
<< "Fv has wrong dimension (it should be " + |
||
220 |
std::to_string(state_->get_nv()) + "," + |
||
221 |
std::to_string(state_->get_nv()) + ")"); |
||
222 |
} |
||
223 |
Fv_ = Fv; |
||
224 |
} |
||
225 |
|||
226 |
template <typename Scalar> |
||
227 |
void DifferentialActionModelLQRTpl<Scalar>::set_Fu(const MatrixXs& Fu) { |
||
228 |
if (static_cast<std::size_t>(Fu.rows()) != state_->get_nq() || |
||
229 |
static_cast<std::size_t>(Fu.cols()) != nu_) { |
||
230 |
throw_pretty("Invalid argument: " |
||
231 |
<< "Fu has wrong dimension (it should be " + |
||
232 |
std::to_string(state_->get_nq()) + "," + |
||
233 |
std::to_string(nu_) + ")"); |
||
234 |
} |
||
235 |
Fu_ = Fu; |
||
236 |
} |
||
237 |
|||
238 |
template <typename Scalar> |
||
239 |
void DifferentialActionModelLQRTpl<Scalar>::set_f0(const VectorXs& f0) { |
||
240 |
if (static_cast<std::size_t>(f0.size()) != state_->get_nv()) { |
||
241 |
throw_pretty("Invalid argument: " |
||
242 |
<< "f0 has wrong dimension (it should be " + |
||
243 |
std::to_string(state_->get_nv()) + ")"); |
||
244 |
} |
||
245 |
f0_ = f0; |
||
246 |
} |
||
247 |
|||
248 |
template <typename Scalar> |
||
249 |
void DifferentialActionModelLQRTpl<Scalar>::set_lx(const VectorXs& lx) { |
||
250 |
if (static_cast<std::size_t>(lx.size()) != state_->get_nx()) { |
||
251 |
throw_pretty("Invalid argument: " |
||
252 |
<< "lx has wrong dimension (it should be " + |
||
253 |
std::to_string(state_->get_nx()) + ")"); |
||
254 |
} |
||
255 |
lx_ = lx; |
||
256 |
} |
||
257 |
|||
258 |
template <typename Scalar> |
||
259 |
void DifferentialActionModelLQRTpl<Scalar>::set_lu(const VectorXs& lu) { |
||
260 |
if (static_cast<std::size_t>(lu.size()) != nu_) { |
||
261 |
throw_pretty("Invalid argument: " |
||
262 |
<< "lu has wrong dimension (it should be " + |
||
263 |
std::to_string(nu_) + ")"); |
||
264 |
} |
||
265 |
lu_ = lu; |
||
266 |
} |
||
267 |
|||
268 |
template <typename Scalar> |
||
269 |
void DifferentialActionModelLQRTpl<Scalar>::set_Lxx(const MatrixXs& Lxx) { |
||
270 |
if (static_cast<std::size_t>(Lxx.rows()) != state_->get_nx() || |
||
271 |
static_cast<std::size_t>(Lxx.cols()) != state_->get_nx()) { |
||
272 |
throw_pretty("Invalid argument: " |
||
273 |
<< "Lxx has wrong dimension (it should be " + |
||
274 |
std::to_string(state_->get_nx()) + "," + |
||
275 |
std::to_string(state_->get_nx()) + ")"); |
||
276 |
} |
||
277 |
Lxx_ = Lxx; |
||
278 |
} |
||
279 |
|||
280 |
template <typename Scalar> |
||
281 |
void DifferentialActionModelLQRTpl<Scalar>::set_Lxu(const MatrixXs& Lxu) { |
||
282 |
if (static_cast<std::size_t>(Lxu.rows()) != state_->get_nx() || |
||
283 |
static_cast<std::size_t>(Lxu.cols()) != nu_) { |
||
284 |
throw_pretty("Invalid argument: " |
||
285 |
<< "Lxu has wrong dimension (it should be " + |
||
286 |
std::to_string(state_->get_nx()) + "," + |
||
287 |
std::to_string(nu_) + ")"); |
||
288 |
} |
||
289 |
Lxu_ = Lxu; |
||
290 |
} |
||
291 |
|||
292 |
template <typename Scalar> |
||
293 |
void DifferentialActionModelLQRTpl<Scalar>::set_Luu(const MatrixXs& Luu) { |
||
294 |
if (static_cast<std::size_t>(Luu.rows()) != nu_ || |
||
295 |
static_cast<std::size_t>(Luu.cols()) != nu_) { |
||
296 |
throw_pretty("Invalid argument: " |
||
297 |
<< "Fq has wrong dimension (it should be " + |
||
298 |
std::to_string(nu_) + "," + std::to_string(nu_) + ")"); |
||
299 |
} |
||
300 |
Luu_ = Luu; |
||
301 |
} |
||
302 |
|||
303 |
} // namespace crocoddyl |
Generated by: GCOVR (Version 4.2) |