GCC Code Coverage Report


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