GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/actions/lqr.hpp
Date: 2025-01-30 11:01:55
Exec Total Coverage
Lines: 16 24 66.7%
Branches: 17 34 50.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 #ifndef CROCODDYL_CORE_ACTIONS_LQR_HPP_
11 #define CROCODDYL_CORE_ACTIONS_LQR_HPP_
12
13 #include <stdexcept>
14
15 #include "crocoddyl/core/action-base.hpp"
16 #include "crocoddyl/core/fwd.hpp"
17 #include "crocoddyl/core/states/euclidean.hpp"
18
19 namespace crocoddyl {
20
21 /**
22 * @brief Linear-quadratic regulator (LQR) action model
23 *
24 * A linear-quadratic regulator (LQR) action has a transition model of the form
25 * \f[ \begin{equation}
26 * \mathbf{x}^' = \mathbf{A x + B u + f}.
27 * \end{equation} \f]
28 * Its cost function is quadratic of the form:
29 * \f[ \begin{equation}
30 * \ell(\mathbf{x},\mathbf{u}) = \begin{bmatrix}1
31 * \\ \mathbf{x} \\ \mathbf{u}\end{bmatrix}^T \begin{bmatrix}0 &
32 * \mathbf{q}^T & \mathbf{r}^T \\ \mathbf{q} & \mathbf{Q}
33 * &
34 * \mathbf{N}^T \\
35 * \mathbf{r} & \mathbf{N} & \mathbf{R}\end{bmatrix}
36 * \begin{bmatrix}1 \\ \mathbf{x} \\
37 * \mathbf{u}\end{bmatrix}
38 * \end{equation} \f]
39 * and the linear equality and inequality constraints has the form:
40 * \f[ \begin{aligned}
41 * \mathbf{g(x,u)} = \mathbf{G}\begin{bmatrix} \mathbf{x} \\ \mathbf{u}
42 * \end{bmatrix} [x,u] + \mathbf{g} \leq \mathbf{0}
43 * &\mathbf{h(x,u)} = \mathbf{H}\begin{bmatrix} \mathbf{x} \\ \mathbf{u}
44 * \end{bmatrix} [x,u] + \mathbf{h} \end{aligned} \f]
45 */
46 template <typename _Scalar>
47 class ActionModelLQRTpl : public ActionModelAbstractTpl<_Scalar> {
48 public:
49 typedef _Scalar Scalar;
50 typedef ActionDataAbstractTpl<Scalar> ActionDataAbstract;
51 typedef ActionModelAbstractTpl<Scalar> Base;
52 typedef ActionDataLQRTpl<Scalar> Data;
53 typedef StateVectorTpl<Scalar> StateVector;
54 typedef MathBaseTpl<Scalar> MathBase;
55 typedef typename MathBase::VectorXs VectorXs;
56 typedef typename MathBase::MatrixXs MatrixXs;
57
58 /**
59 * @brief Initialize the LQR action model
60 *
61 * @param[in] A State matrix
62 * @param[in] B Input matrix
63 * @param[in] Q State weight matrix
64 * @param[in] R Input weight matrix
65 * @param[in] N State-input weight matrix
66 */
67 ActionModelLQRTpl(const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q,
68 const MatrixXs& R, const MatrixXs& N);
69
70 /**
71 * @brief Initialize the LQR action model
72 *
73 * @param[in] A State matrix
74 * @param[in] B Input matrix
75 * @param[in] Q State weight matrix
76 * @param[in] R Input weight matrix
77 * @param[in] N State-input weight matrix
78 * @param[in] f Dynamics drift
79 * @param[in] q State weight vector
80 * @param[in] r Input weight vector
81 */
82 ActionModelLQRTpl(const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q,
83 const MatrixXs& R, const MatrixXs& N, const VectorXs& f,
84 const VectorXs& q, const VectorXs& r);
85
86 /**
87 * @brief Initialize the LQR action model
88 *
89 * @param[in] A State matrix
90 * @param[in] B Input matrix
91 * @param[in] Q State weight matrix
92 * @param[in] R Input weight matrix
93 * @param[in] N State-input weight matrix
94 * @param[in] G State-input inequality constraint matrix
95 * @param[in] H State-input equality constraint matrix
96 * @param[in] f Dynamics drift
97 * @param[in] q State weight vector
98 * @param[in] r Input weight vector
99 * @param[in] g State-input inequality constraint bias
100 * @param[in] h State-input equality constraint bias
101 */
102 ActionModelLQRTpl(const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q,
103 const MatrixXs& R, const MatrixXs& N, const MatrixXs& G,
104 const MatrixXs& H, const VectorXs& f, const VectorXs& q,
105 const VectorXs& r, const VectorXs& g, const VectorXs& h);
106
107 /**
108 * @brief Initialize the LQR action model
109 *
110 * @param[in] nx Dimension of state vector
111 * @param[in] nu Dimension of control vector
112 * @param[in] drif_free Enable / disable the bias term of the linear dynamics
113 * (default true)
114 */
115 ActionModelLQRTpl(const std::size_t nx, const std::size_t nu,
116 const bool drift_free = true);
117
118 /** @brief Copy constructor */
119 ActionModelLQRTpl(const ActionModelLQRTpl& copy);
120
121 virtual ~ActionModelLQRTpl();
122
123 virtual void calc(const std::shared_ptr<ActionDataAbstract>& data,
124 const Eigen::Ref<const VectorXs>& x,
125 const Eigen::Ref<const VectorXs>& u);
126 virtual void calc(const std::shared_ptr<ActionDataAbstract>& data,
127 const Eigen::Ref<const VectorXs>& x);
128 virtual void calcDiff(const std::shared_ptr<ActionDataAbstract>& data,
129 const Eigen::Ref<const VectorXs>& x,
130 const Eigen::Ref<const VectorXs>& u);
131 virtual void calcDiff(const std::shared_ptr<ActionDataAbstract>& data,
132 const Eigen::Ref<const VectorXs>& x);
133 virtual std::shared_ptr<ActionDataAbstract> createData();
134 virtual bool checkData(const std::shared_ptr<ActionDataAbstract>& data);
135
136 /**
137 * @brief Create a random LQR model
138 *
139 * @param[in] nx State dimension
140 * @param[in] nu Control dimension
141 * @param[in] ng Inequality constraint dimension (default 0)
142 * @param[in] nh Equality constraint dimension (defaul 0)
143 */
144 static ActionModelLQRTpl Random(const std::size_t nx, const std::size_t nu,
145 const std::size_t ng = 0,
146 const std::size_t nh = 0);
147
148 /** @brief Return the state matrix */
149 const MatrixXs& get_A() const;
150
151 /** @brief Return the input matrix */
152 const MatrixXs& get_B() const;
153
154 /** @brief Return the dynamics drift */
155 const VectorXs& get_f() const;
156
157 /** @brief Return the state weight matrix */
158 const MatrixXs& get_Q() const;
159
160 /** @brief Return the input weight matrix */
161 const MatrixXs& get_R() const;
162
163 /** @brief Return the state-input weight matrix */
164 const MatrixXs& get_N() const;
165
166 /** @brief Return the state-input inequality constraint matrix */
167 const MatrixXs& get_G() const;
168
169 /** @brief Return the state-input equality constraint matrix */
170 const MatrixXs& get_H() const;
171
172 /** @brief Return the state weight vector */
173 const VectorXs& get_q() const;
174
175 /** @brief Return the input weight vector */
176 const VectorXs& get_r() const;
177
178 /** @brief Return the state-input inequality constraint bias */
179 const VectorXs& get_g() const;
180
181 /** @brief Return the state-input equality constraint bias */
182 const VectorXs& get_h() const;
183
184 /**
185 * @brief Modify the LQR action model
186 *
187 * @param[in] A State matrix
188 * @param[in] B Input matrix
189 * @param[in] Q State weight matrix
190 * @param[in] R Input weight matrix
191 * @param[in] N State-input weight matrix
192 * @param[in] G State-input inequality constraint matrix
193 * @param[in] H State-input equality constraint matrix
194 * @param[in] f Dynamics drift
195 * @param[in] q State weight vector
196 * @param[in] r Input weight vector
197 * @param[in] g State-input inequality constraint bias
198 * @param[in] h State-input equality constraint bias
199 */
200 void set_LQR(const MatrixXs& A, const MatrixXs& B, const MatrixXs& Q,
201 const MatrixXs& R, const MatrixXs& N, const MatrixXs& G,
202 const MatrixXs& H, const VectorXs& f, const VectorXs& q,
203 const VectorXs& r, const VectorXs& g, const VectorXs& h);
204
205 DEPRECATED("Use get_A", const MatrixXs& get_Fx() const { return get_A(); })
206 DEPRECATED("Use get_B", const MatrixXs& get_Fu() const { return get_B(); })
207 DEPRECATED("Use get_f", const VectorXs& get_f0() const { return get_f(); })
208 DEPRECATED("Use get_q", const VectorXs& get_lx() const { return get_q(); })
209 DEPRECATED("Use get_r", const VectorXs& get_lu() const { return get_r(); })
210 DEPRECATED("Use get_Q", const MatrixXs& get_Lxx() const { return get_Q(); })
211 DEPRECATED("Use get_R", const MatrixXs& get_Lxu() const { return get_R(); })
212 DEPRECATED("Use get_N", const MatrixXs& get_Luu() const { return get_N(); })
213 DEPRECATED(
214 "Use set_LQR", void set_Fx(const MatrixXs& A) {
215 set_LQR(A, B_, Q_, R_, N_, G_, H_, f_, q_, r_, g_, h_);
216 })
217 DEPRECATED(
218 "Use set_LQR", void set_Fu(const MatrixXs& B) {
219 set_LQR(A_, B, Q_, R_, N_, G_, H_, f_, q_, r_, g_, h_);
220 })
221 DEPRECATED(
222 "Use set_LQR", void set_f0(const VectorXs& f) {
223 set_LQR(A_, B_, Q_, R_, N_, G_, H_, f, q_, r_, g_, h_);
224 })
225 DEPRECATED(
226 "Use set_LQR", void set_lx(const VectorXs& q) {
227 set_LQR(A_, B_, Q_, R_, N_, G_, H_, f_, q, r_, g_, h_);
228 })
229 DEPRECATED(
230 "Use set_LQR", void set_lu(const VectorXs& r) {
231 set_LQR(A_, B_, Q_, R_, N_, G_, H_, f_, q_, r, g_, h_);
232 })
233 DEPRECATED(
234 "Use set_LQR", void set_Lxx(const MatrixXs& Q) {
235 set_LQR(A_, B_, Q, R_, N_, G_, H_, f_, q_, r_, g_, h_);
236 })
237 DEPRECATED(
238 "Use set_LQR", void set_Luu(const MatrixXs& R) {
239 set_LQR(A_, B_, Q_, R, N_, G_, H_, f_, q_, r_, g_, h_);
240 })
241 DEPRECATED(
242 "Use set_LQR", void set_Lxu(const MatrixXs& N) {
243 set_LQR(A_, B_, Q_, R_, N, G_, H_, f_, q_, r_, g_, h_);
244 })
245
246 /**
247 * @brief Print relevant information of the LQR model
248 *
249 * @param[out] os Output stream object
250 */
251 virtual void print(std::ostream& os) const;
252
253 protected:
254 using Base::ng_; //!< Equality constraint dimension
255 using Base::nh_; //!< Inequality constraint dimension
256 using Base::nu_; //!< Control dimension
257 using Base::state_; //!< Model of the state
258
259 private:
260 MatrixXs A_;
261 MatrixXs B_;
262 MatrixXs Q_;
263 MatrixXs R_;
264 MatrixXs N_;
265 MatrixXs G_;
266 MatrixXs H_;
267 VectorXs f_;
268 VectorXs q_;
269 VectorXs r_;
270 VectorXs g_;
271 VectorXs h_;
272 MatrixXs L_;
273 bool drift_free_;
274 bool updated_lqr_;
275 };
276
277 template <typename _Scalar>
278 struct ActionDataLQRTpl : public ActionDataAbstractTpl<_Scalar> {
279 typedef _Scalar Scalar;
280 typedef MathBaseTpl<Scalar> MathBase;
281 typedef ActionDataAbstractTpl<Scalar> Base;
282 typedef typename MathBase::VectorXs VectorXs;
283
284 template <template <typename Scalar> class Model>
285 1617 explicit ActionDataLQRTpl(Model<Scalar>* const model)
286 : Base(model),
287
2/4
✓ Branch 1 taken 1617 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1617 times.
✗ Branch 5 not taken.
1617 R_u_tmp(VectorXs::Zero(static_cast<Eigen::Index>(model->get_nu()))),
288
2/4
✓ Branch 1 taken 1617 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1617 times.
✗ Branch 5 not taken.
1617 Q_x_tmp(VectorXs::Zero(
289 3234 static_cast<Eigen::Index>(model->get_state()->get_ndx()))) {
290 // Setting the linear model and quadratic cost as they are constant
291 1617 const std::size_t nq = model->get_state()->get_nq();
292 1617 const std::size_t nu = model->get_nu();
293
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 Fx = model->get_A();
294
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 Fu = model->get_B();
295
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 Lxx = model->get_Q();
296
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 Luu = model->get_R();
297
1/2
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
1617 Lxu = model->get_N();
298
2/4
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1617 times.
✗ Branch 6 not taken.
1617 Gx = model->get_G().leftCols(2 * nq);
299
2/4
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1617 times.
✗ Branch 6 not taken.
1617 Gu = model->get_G().rightCols(nu);
300
2/4
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1617 times.
✗ Branch 6 not taken.
1617 Hx = model->get_H().leftCols(2 * nq);
301
2/4
✓ Branch 2 taken 1617 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1617 times.
✗ Branch 6 not taken.
1617 Hu = model->get_H().rightCols(nu);
302 1617 }
303
304 using Base::cost;
305 using Base::Fu;
306 using Base::Fx;
307 using Base::Gu;
308 using Base::Gx;
309 using Base::Hu;
310 using Base::Hx;
311 using Base::Lu;
312 using Base::Luu;
313 using Base::Lx;
314 using Base::Lxu;
315 using Base::Lxx;
316 using Base::r;
317 using Base::xnext;
318
319 VectorXs R_u_tmp; // Temporary variable for storing Hessian-vector product
320 // (size: nu)
321 VectorXs Q_x_tmp; // Temporary variable for storing Hessian-vector product
322 // (size: nx)
323 };
324
325 } // namespace crocoddyl
326
327 /* --- Details -------------------------------------------------------------- */
328 /* --- Details -------------------------------------------------------------- */
329 /* --- Details -------------------------------------------------------------- */
330 #include "crocoddyl/core/actions/lqr.hxx"
331
332 #endif // CROCODDYL_CORE_ACTIONS_LQR_HPP_
333