GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/actions/lqr.hxx
Date: 2025-01-30 11:01:55
Exec Total Coverage
Lines: 190 234 81.2%
Branches: 197 822 24.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2024, 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 "crocoddyl/core/utils/exception.hpp"
11
12 namespace crocoddyl {
13
14 template <typename Scalar>
15 ActionModelLQRTpl<Scalar>::ActionModelLQRTpl(const MatrixXs& A,
16 const MatrixXs& B,
17 const MatrixXs& Q,
18 const MatrixXs& R,
19 const MatrixXs& N)
20 : Base(std::make_shared<StateVector>(A.cols()), B.cols(), 0),
21 drift_free_(true),
22 updated_lqr_(false) {
23 const std::size_t nx = state_->get_nx();
24 MatrixXs G = MatrixXs::Zero(ng_, nx + nu_);
25 MatrixXs H = MatrixXs::Zero(nh_, nx + nu_);
26 VectorXs f = VectorXs::Zero(nx);
27 VectorXs q = VectorXs::Zero(nx);
28 VectorXs r = VectorXs::Zero(nu_);
29 VectorXs g = VectorXs::Zero(ng_);
30 VectorXs h = VectorXs::Zero(nh_);
31 set_LQR(A, B, Q, R, N, G, H, f, q, r, g, h);
32 }
33
34 template <typename Scalar>
35 ActionModelLQRTpl<Scalar>::ActionModelLQRTpl(
36 const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q, const MatrixXs& R,
37 const MatrixXs& N, const VectorXs& f, const VectorXs& q, const VectorXs& r)
38 : Base(std::make_shared<StateVector>(A.cols()), B.cols(), 0),
39 drift_free_(false),
40 updated_lqr_(false) {
41 const std::size_t nx = state_->get_nx();
42 MatrixXs G = MatrixXs::Zero(ng_, nx + nu_);
43 MatrixXs H = MatrixXs::Zero(ng_, nx + nu_);
44 VectorXs g = VectorXs::Zero(ng_);
45 VectorXs h = VectorXs::Zero(nh_);
46 set_LQR(A, B, Q, R, N, G, H, f, q, r, g, h);
47 }
48
49 template <typename Scalar>
50 57 ActionModelLQRTpl<Scalar>::ActionModelLQRTpl(
51 const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q, const MatrixXs& R,
52 const MatrixXs& N, const MatrixXs& G, const MatrixXs& H, const VectorXs& f,
53 const VectorXs& q, const VectorXs& r, const VectorXs& g, const VectorXs& h)
54 : Base(std::make_shared<StateVector>(A.cols()), B.cols(), 0, G.rows(),
55 171 H.rows(), G.rows(), H.rows()),
56 57 drift_free_(false),
57
15/30
✓ Branch 7 taken 57 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 57 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 57 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 57 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 57 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 57 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 57 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 57 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 57 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 57 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 57 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 57 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 57 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 57 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 57 times.
✗ Branch 53 not taken.
57 updated_lqr_(false) {
58
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 set_LQR(A, B, Q, R, N, G, H, f, q, r, g, h);
59 57 }
60
61 template <typename Scalar>
62 94 ActionModelLQRTpl<Scalar>::ActionModelLQRTpl(const std::size_t nx,
63 const std::size_t nu,
64 const bool drift_free)
65 : Base(std::make_shared<StateVector>(nx), nu, 0),
66
1/2
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
94 A_(MatrixXs::Identity(nx, nx)),
67
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 B_(MatrixXs::Identity(nx, nu)),
68
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 Q_(MatrixXs::Identity(nx, nx)),
69
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 R_(MatrixXs::Identity(nu, nu)),
70
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 N_(MatrixXs::Zero(nx, nu)),
71
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 G_(MatrixXs::Zero(0, nx + nu)),
72
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 H_(MatrixXs::Zero(0, nx + nu)),
73
5/8
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 56 times.
✓ Branch 3 taken 38 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 56 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 94 times.
✗ Branch 10 not taken.
94 f_(drift_free ? VectorXs::Zero(nx) : VectorXs::Ones(nx)),
74
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 q_(VectorXs::Ones(nx)),
75
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 r_(VectorXs::Ones(nu)),
76
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 g_(VectorXs::Zero(0)),
77
2/4
✓ Branch 1 taken 94 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 94 times.
✗ Branch 5 not taken.
94 h_(VectorXs::Zero(0)),
78
3/6
✓ Branch 3 taken 94 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 94 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 94 times.
✗ Branch 12 not taken.
188 drift_free_(drift_free) {}
79
80 template <typename Scalar>
81 59 ActionModelLQRTpl<Scalar>::ActionModelLQRTpl(const ActionModelLQRTpl& copy)
82 59 : Base(std::make_shared<StateVector>(copy.get_A().cols()),
83 177 copy.get_B().cols(), 0, copy.get_G().rows(), copy.get_H().rows(),
84 118 copy.get_G().rows(), copy.get_H().rows()),
85 59 drift_free_(false),
86
15/30
✓ Branch 7 taken 59 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 59 times.
✗ Branch 12 not taken.
✓ Branch 16 taken 59 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 59 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 59 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 59 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 59 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 59 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 59 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 59 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 59 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 59 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 59 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 59 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 59 times.
✗ Branch 53 not taken.
413 updated_lqr_(false) {
87
1/2
✓ Branch 6 taken 59 times.
✗ Branch 7 not taken.
59 set_LQR(copy.get_A(), copy.get_B(), copy.get_Q(), copy.get_R(), copy.get_N(),
88 59 copy.get_G(), copy.get_H(), copy.get_f(), copy.get_q(), copy.get_r(),
89 59 copy.get_g(), copy.get_h());
90 59 }
91
92 template <typename Scalar>
93 420 ActionModelLQRTpl<Scalar>::~ActionModelLQRTpl() {}
94
95 template <typename Scalar>
96 2856 void ActionModelLQRTpl<Scalar>::calc(
97 const std::shared_ptr<ActionDataAbstract>& data,
98 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
99
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 2856 times.
2856 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
100 throw_pretty(
101 "Invalid argument: " << "x has wrong dimension (it should be " +
102 std::to_string(state_->get_nx()) + ")");
103 }
104
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2856 times.
2856 if (static_cast<std::size_t>(u.size()) != nu_) {
105 throw_pretty(
106 "Invalid argument: " << "u has wrong dimension (it should be " +
107 std::to_string(nu_) + ")");
108 }
109 2856 Data* d = static_cast<Data*>(data.get());
110
111
2/4
✓ Branch 3 taken 2856 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
2856 data->xnext.noalias() = A_ * x;
112
2/4
✓ Branch 3 taken 2856 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
2856 data->xnext.noalias() += B_ * u;
113 2856 data->xnext += f_;
114
115 // cost = 0.5 * x^T * Q * x + 0.5 * u^T * R * u + x^T * N * u + q^T * x + r^T
116 // * u
117
2/4
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2856 times.
✗ Branch 6 not taken.
2856 d->Q_x_tmp.noalias() = Q_ * x;
118 2856 data->cost = Scalar(0.5) * x.dot(d->Q_x_tmp);
119
2/4
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2856 times.
✗ Branch 6 not taken.
2856 d->R_u_tmp.noalias() = R_ * u;
120 2856 data->cost += Scalar(0.5) * u.dot(d->R_u_tmp);
121
2/4
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2856 times.
✗ Branch 6 not taken.
2856 d->Q_x_tmp.noalias() = N_ * u;
122 2856 data->cost += x.dot(d->Q_x_tmp);
123 2856 data->cost += q_.dot(x);
124 2856 data->cost += r_.dot(u);
125
126 // constraints
127 2856 const std::size_t nx = state_->get_nx();
128
3/6
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2856 times.
✗ Branch 10 not taken.
2856 data->g.noalias() = G_.leftCols(nx) * x;
129
3/6
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2856 times.
✗ Branch 10 not taken.
2856 data->g.noalias() += G_.rightCols(nu_) * u;
130 2856 data->g += g_;
131
3/6
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2856 times.
✗ Branch 10 not taken.
2856 data->h.noalias() = H_.leftCols(nx) * x;
132
3/6
✓ Branch 2 taken 2856 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2856 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2856 times.
✗ Branch 10 not taken.
2856 data->h.noalias() += H_.rightCols(nu_) * u;
133 2856 data->h += h_;
134 2856 }
135
136 template <typename Scalar>
137 232 void ActionModelLQRTpl<Scalar>::calc(
138 const std::shared_ptr<ActionDataAbstract>& data,
139 const Eigen::Ref<const VectorXs>& x) {
140
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 232 times.
232 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
141 throw_pretty(
142 "Invalid argument: " << "x has wrong dimension (it should be " +
143 std::to_string(state_->get_nx()) + ")");
144 }
145 232 Data* d = static_cast<Data*>(data.get());
146
147 232 d->xnext = x;
148
149 // cost = 0.5 * x^T * Q * x + q^T * x
150
2/4
✓ Branch 2 taken 232 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 232 times.
✗ Branch 6 not taken.
232 d->Q_x_tmp.noalias() = Q_ * x;
151 232 data->cost = Scalar(0.5) * x.dot(d->Q_x_tmp);
152 232 data->cost += q_.dot(x);
153
154 // constraints
155 232 const std::size_t nx = state_->get_nx();
156
3/6
✓ Branch 2 taken 232 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 232 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 232 times.
✗ Branch 10 not taken.
232 data->g.noalias() = G_.leftCols(nx) * x;
157 232 data->g += g_;
158
3/6
✓ Branch 2 taken 232 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 232 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 232 times.
✗ Branch 10 not taken.
232 data->h.noalias() = H_.leftCols(nx) * x;
159 232 data->h += h_;
160 232 }
161
162 template <typename Scalar>
163 1846 void ActionModelLQRTpl<Scalar>::calcDiff(
164 const std::shared_ptr<ActionDataAbstract>& data,
165 const Eigen::Ref<const VectorXs>& x, const Eigen::Ref<const VectorXs>& u) {
166
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1846 times.
1846 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
167 throw_pretty(
168 "Invalid argument: " << "x has wrong dimension (it should be " +
169 std::to_string(state_->get_nx()) + ")");
170 }
171
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1846 times.
1846 if (static_cast<std::size_t>(u.size()) != nu_) {
172 throw_pretty(
173 "Invalid argument: " << "u has wrong dimension (it should be " +
174 std::to_string(nu_) + ")");
175 }
176
177 1846 const std::size_t nx = state_->get_nx();
178
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 1809 times.
1846 if (!updated_lqr_) {
179 37 data->Fx = A_;
180 37 data->Fu = B_;
181 37 data->Lxx = Q_;
182 37 data->Luu = R_;
183 37 data->Lxu = N_;
184
1/2
✓ Branch 3 taken 37 times.
✗ Branch 4 not taken.
37 data->Gx = G_.leftCols(nx);
185
1/2
✓ Branch 3 taken 37 times.
✗ Branch 4 not taken.
37 data->Gu = G_.rightCols(nu_);
186
1/2
✓ Branch 3 taken 37 times.
✗ Branch 4 not taken.
37 data->Hx = H_.leftCols(nx);
187
1/2
✓ Branch 3 taken 37 times.
✗ Branch 4 not taken.
37 data->Hu = H_.rightCols(nu_);
188 37 updated_lqr_ = true;
189 }
190 1846 data->Lx = q_;
191
2/4
✓ Branch 3 taken 1846 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1846 times.
✗ Branch 7 not taken.
1846 data->Lx.noalias() += Q_ * x;
192
2/4
✓ Branch 3 taken 1846 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1846 times.
✗ Branch 7 not taken.
1846 data->Lx.noalias() += N_ * u;
193 1846 data->Lu = r_;
194
3/6
✓ Branch 2 taken 1846 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1846 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1846 times.
✗ Branch 10 not taken.
1846 data->Lu.noalias() += N_.transpose() * x;
195
2/4
✓ Branch 3 taken 1846 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1846 times.
✗ Branch 7 not taken.
1846 data->Lu.noalias() += R_ * u;
196 1846 }
197
198 template <typename Scalar>
199 110 void ActionModelLQRTpl<Scalar>::calcDiff(
200 const std::shared_ptr<ActionDataAbstract>& data,
201 const Eigen::Ref<const VectorXs>& x) {
202
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 110 times.
110 if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
203 throw_pretty(
204 "Invalid argument: " << "x has wrong dimension (it should be " +
205 std::to_string(state_->get_nx()) + ")");
206 }
207
208 110 const std::size_t nx = state_->get_nx();
209
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 97 times.
110 if (!updated_lqr_) {
210 13 data->Lxx = Q_;
211
1/2
✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
13 data->Gx = G_.leftCols(nx);
212
1/2
✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
13 data->Hx = H_.leftCols(nx);
213 13 updated_lqr_ = true;
214 }
215 110 data->Lx = q_;
216
2/4
✓ Branch 3 taken 110 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 110 times.
✗ Branch 7 not taken.
110 data->Lx.noalias() += Q_ * x;
217 110 }
218
219 template <typename Scalar>
220 std::shared_ptr<ActionDataAbstractTpl<Scalar>>
221 1617 ActionModelLQRTpl<Scalar>::createData() {
222
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
223 }
224
225 template <typename Scalar>
226 256 bool ActionModelLQRTpl<Scalar>::checkData(
227 const std::shared_ptr<ActionDataAbstract>& data) {
228 256 std::shared_ptr<Data> d = std::dynamic_pointer_cast<Data>(data);
229
1/2
✓ Branch 1 taken 256 times.
✗ Branch 2 not taken.
256 if (d != NULL) {
230 256 return true;
231 } else {
232 return false;
233 }
234 256 }
235
236 template <typename Scalar>
237 57 ActionModelLQRTpl<Scalar> ActionModelLQRTpl<Scalar>::Random(
238 const std::size_t nx, const std::size_t nu, const std::size_t ng,
239 const std::size_t nh) {
240
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 MatrixXs A = MatrixXs::Random(nx, nx);
241
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 MatrixXs B = MatrixXs::Random(nx, nu);
242
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 MatrixXs L_tmp = MatrixXs::Random(nx + nu, nx + nu);
243
3/6
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 57 times.
✗ Branch 8 not taken.
57 MatrixXs L = L_tmp.transpose() * L_tmp;
244
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 const Eigen::Block<MatrixXs> Q = L.topLeftCorner(nx, nx);
245
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 const Eigen::Block<MatrixXs> R = L.bottomRightCorner(nu, nu);
246
1/2
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
57 const Eigen::Block<MatrixXs> N = L.topRightCorner(nx, nu);
247
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 MatrixXs G = MatrixXs::Random(ng, nx + nu);
248
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 MatrixXs H = MatrixXs::Random(nh, nx + nu);
249
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 VectorXs f = VectorXs::Random(nx);
250
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 VectorXs q = VectorXs::Random(nx);
251
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 VectorXs r = VectorXs::Random(nu);
252
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 VectorXs g = VectorXs::Random(ng);
253
2/4
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
57 VectorXs h = VectorXs::Random(nh);
254
4/8
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 57 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 57 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 57 times.
✗ Branch 11 not taken.
114 return ActionModelLQRTpl<Scalar>(A, B, Q, R, N, G, H, f, q, r, g, h);
255 57 }
256
257 template <typename Scalar>
258 88 void ActionModelLQRTpl<Scalar>::print(std::ostream& os) const {
259 88 os << "ActionModelLQR {nx=" << state_->get_nx() << ", nu=" << nu_
260 88 << ", ng=" << ng_ << ", nh=" << nh_ << ", drift_free=" << drift_free_
261 88 << "}";
262 88 }
263
264 template <typename Scalar>
265 1736 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_A()
266 const {
267 1736 return A_;
268 }
269
270 template <typename Scalar>
271 1736 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_B()
272 const {
273 1736 return B_;
274 }
275
276 template <typename Scalar>
277 60 const typename MathBaseTpl<Scalar>::VectorXs& ActionModelLQRTpl<Scalar>::get_f()
278 const {
279 60 return f_;
280 }
281
282 template <typename Scalar>
283 1677 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_Q()
284 const {
285 1677 return Q_;
286 }
287
288 template <typename Scalar>
289 1677 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_R()
290 const {
291 1677 return R_;
292 }
293
294 template <typename Scalar>
295 1677 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_N()
296 const {
297 1677 return N_;
298 }
299
300 template <typename Scalar>
301 3411 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_G()
302 const {
303 3411 return G_;
304 }
305
306 template <typename Scalar>
307 3411 const typename MathBaseTpl<Scalar>::MatrixXs& ActionModelLQRTpl<Scalar>::get_H()
308 const {
309 3411 return H_;
310 }
311
312 template <typename Scalar>
313 60 const typename MathBaseTpl<Scalar>::VectorXs& ActionModelLQRTpl<Scalar>::get_q()
314 const {
315 60 return q_;
316 }
317
318 template <typename Scalar>
319 60 const typename MathBaseTpl<Scalar>::VectorXs& ActionModelLQRTpl<Scalar>::get_r()
320 const {
321 60 return r_;
322 }
323
324 template <typename Scalar>
325 59 const typename MathBaseTpl<Scalar>::VectorXs& ActionModelLQRTpl<Scalar>::get_g()
326 const {
327 59 return g_;
328 }
329
330 template <typename Scalar>
331 59 const typename MathBaseTpl<Scalar>::VectorXs& ActionModelLQRTpl<Scalar>::get_h()
332 const {
333 59 return h_;
334 }
335
336 template <typename Scalar>
337 116 void ActionModelLQRTpl<Scalar>::set_LQR(const MatrixXs& A, const MatrixXs& B,
338 const MatrixXs& Q, const MatrixXs& R,
339 const MatrixXs& N, const MatrixXs& G,
340 const MatrixXs& H, const VectorXs& f,
341 const VectorXs& q, const VectorXs& r,
342 const VectorXs& g, const VectorXs& h) {
343 116 const std::size_t nx = state_->get_nx();
344
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(A.rows()) != nx) {
345 throw_pretty(
346 "Invalid argument: " << "A should be a squared matrix with size " +
347 std::to_string(nx));
348 }
349
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(B.rows()) != nx) {
350 throw_pretty(
351 "Invalid argument: " << "B has wrong dimension (it should have " +
352 std::to_string(nx) + " rows)");
353 }
354
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
232 if (static_cast<std::size_t>(Q.rows()) != nx ||
355
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 static_cast<std::size_t>(Q.cols()) != nx) {
356 throw_pretty("Invalid argument: "
357 << "Q has wrong dimension (it should be " +
358 std::to_string(nx) + " x " + std::to_string(nx) + ")");
359 }
360
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
232 if (static_cast<std::size_t>(R.rows()) != nu_ ||
361
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 static_cast<std::size_t>(R.cols()) != nu_) {
362 throw_pretty(
363 "Invalid argument: " << "R has wrong dimension (it should be " +
364 std::to_string(nu_) + " x " +
365 std::to_string(nu_) + ")");
366 }
367
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
232 if (static_cast<std::size_t>(N.rows()) != nx ||
368
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 static_cast<std::size_t>(N.cols()) != nu_) {
369 throw_pretty("Invalid argument: "
370 << "N has wrong dimension (it should be " +
371 std::to_string(nx) + " x " + std::to_string(nu_) + ")");
372 }
373
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
232 if (static_cast<std::size_t>(G.rows()) != ng_ ||
374
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 static_cast<std::size_t>(G.cols()) != nx + nu_) {
375 throw_pretty(
376 "Invalid argument: " << "G has wrong dimension (it should be " +
377 std::to_string(ng_) + " x " +
378 std::to_string(nx + nu_) + ")");
379 }
380
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
232 if (static_cast<std::size_t>(H.rows()) != nh_ ||
381
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 static_cast<std::size_t>(H.cols()) != nx + nu_) {
382 throw_pretty(
383 "Invalid argument: " << "H has wrong dimension (it should be " +
384 std::to_string(nh_) + " x " +
385 std::to_string(nx + nu_) + ")");
386 }
387
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(f.size()) != nx) {
388 throw_pretty(
389 "Invalid argument: " << "f has wrong dimension (it should be " +
390 std::to_string(nx) + ")");
391 }
392
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(q.size()) != nx) {
393 throw_pretty(
394 "Invalid argument: " << "q has wrong dimension (it should be " +
395 std::to_string(nx) + ")");
396 }
397
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(r.size()) != nu_) {
398 throw_pretty(
399 "Invalid argument: " << "r has wrong dimension (it should be " +
400 std::to_string(nu_) + ")");
401 }
402
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(g.size()) != ng_) {
403 throw_pretty(
404 "Invalid argument: " << "g has wrong dimension (it should be " +
405 std::to_string(ng_) + ")");
406 }
407
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 116 times.
116 if (static_cast<std::size_t>(h.size()) != nh_) {
408 throw_pretty(
409 "Invalid argument: " << "h has wrong dimension (it should be " +
410 std::to_string(nh_) + ")");
411 }
412
2/4
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116 times.
✗ Branch 5 not taken.
116 L_ = MatrixXs::Zero(nx + nu_, nx + nu_);
413
5/10
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 116 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 116 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 116 times.
✗ Branch 14 not taken.
116 L_ << Q, N, N.transpose(), R;
414
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 Eigen::LLT<MatrixXs> L_llt(H_);
415
5/10
✓ Branch 2 taken 116 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 116 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 116 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 116 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 116 times.
116 if (!L_.isApprox(L_.transpose()) || L_llt.info() == Eigen::NumericalIssue) {
416 throw_pretty("Invalid argument "
417 << "[Q, N; N.T, R] is not semi-positive definite");
418 }
419
420
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 A_ = A;
421
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 B_ = B;
422
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 f_ = f;
423
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 Q_ = Q;
424
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 R_ = R;
425
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 N_ = N;
426
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 G_ = G;
427
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 H_ = H;
428
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 q_ = q;
429
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 r_ = r;
430
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 g_ = g;
431
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 h_ = h;
432 116 updated_lqr_ = false;
433 116 }
434
435 } // namespace crocoddyl
436