GCC Code Coverage Report


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