GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/cost-base.hpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 19 28 67.9%
Branches: 24 54 44.4%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, 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_COST_BASE_HPP_
11 #define CROCODDYL_CORE_COST_BASE_HPP_
12
13 #include <memory>
14
15 #include "crocoddyl/core/activation-base.hpp"
16 #include "crocoddyl/core/activations/quadratic.hpp"
17 #include "crocoddyl/core/data-collector-base.hpp"
18 #include "crocoddyl/core/fwd.hpp"
19 #include "crocoddyl/core/residual-base.hpp"
20 #include "crocoddyl/core/state-base.hpp"
21 #include "crocoddyl/core/utils/deprecate.hpp"
22
23 namespace crocoddyl {
24
25 class CostModelBase {
26 public:
27 15384 virtual ~CostModelBase() = default;
28
29 CROCODDYL_BASE_CAST(CostModelBase, CostModelAbstractTpl)
30 };
31
32 /**
33 * @brief Abstract class for cost models
34 *
35 * A cost model is defined by the scalar activation function \f$a(\cdot)\f$ and
36 * by the residual function \f$\mathbf{r}(\cdot)\f$ as follows: \f[
37 * \ell(\mathbf{x},\mathbf{u}) = a(\mathbf{r}(\mathbf{x}, \mathbf{u})), \f]
38 * where the residual function depends on the state point
39 * \f$\mathbf{x}\in\mathcal{X}\f$, which lies in the state manifold described
40 * with a `nx`-tuple, its velocity \f$\dot{\mathbf{x}}\in
41 * T_{\mathbf{x}}\mathcal{X}\f$ that belongs to the tangent space with `ndx`
42 * dimension, and the control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$. The
43 * residual vector is defined by \f$\mathbf{r}\in\mathbb{R}^{nr}\f$ where `nr`
44 * describes its dimension in the Euclidean space. On the other hand, the
45 * activation function builds a cost value based on the definition of the
46 * residual vector. The residual vector has to be specialized in a derived
47 * classes.
48 *
49 * The main computations are carring out in `calc()` and `calcDiff()` routines.
50 * `calc()` computes the cost (and its residual) and `calcDiff()` computes the
51 * derivatives of the cost function (and its residual). Concretely speaking,
52 * `calcDiff()` builds a linear-quadratic approximation of the cost function
53 * with the form: \f$\mathbf{l_x}\in\mathbb{R}^{ndx}\f$,
54 * \f$\mathbf{l_u}\in\mathbb{R}^{nu}\f$,
55 * \f$\mathbf{l_{xx}}\in\mathbb{R}^{ndx\times ndx}\f$,
56 * \f$\mathbf{l_{xu}}\in\mathbb{R}^{ndx\times nu}\f$,
57 * \f$\mathbf{l_{uu}}\in\mathbb{R}^{nu\times nu}\f$ are the Jacobians and
58 * Hessians, respectively. Additionally, it is important to note that
59 * `calcDiff()` computes the derivatives using the latest stored values by
60 * `calc()`. Thus, we need to first run `calc()`.
61 *
62 * \sa `ActivationModelAbstractTpl`, `ResidualModelAbstractTpl` `calc()`,
63 * `calcDiff()`, `createData()`
64 */
65 template <typename _Scalar>
66 class CostModelAbstractTpl : public CostModelBase {
67 public:
68 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
69
70 typedef _Scalar Scalar;
71 typedef MathBaseTpl<Scalar> MathBase;
72 typedef CostDataAbstractTpl<Scalar> CostDataAbstract;
73 typedef StateAbstractTpl<Scalar> StateAbstract;
74 typedef ActivationModelAbstractTpl<Scalar> ActivationModelAbstract;
75 typedef ResidualModelAbstractTpl<Scalar> ResidualModelAbstract;
76 typedef ActivationModelQuadTpl<Scalar> ActivationModelQuad;
77 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
78 typedef typename MathBase::VectorXs VectorXs;
79 typedef typename MathBase::MatrixXs MatrixXs;
80
81 /**
82 * @brief Initialize the cost model
83 *
84 * @param[in] state State of the dynamical system
85 * @param[in] activation Activation model
86 * @param[in] residual Residual model
87 */
88 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
89 std::shared_ptr<ActivationModelAbstract> activation,
90 std::shared_ptr<ResidualModelAbstract> residual);
91
92 /**
93 * @brief Initialize the cost model
94 *
95 * @param[in] state State of the dynamical system
96 * @param[in] activation Activation model
97 * @param[in] nu Dimension of control vector
98 */
99 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
100 std::shared_ptr<ActivationModelAbstract> activation,
101 const std::size_t nu);
102
103 /**
104 * @copybrief CostModelAbstractTpl()
105 *
106 * The default `nu` value is obtained from `StateAbstractTpl::get_nv()`.
107 *
108 * @param[in] state State of the dynamical system
109 * @param[in] activation Activation model
110 */
111 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
112 std::shared_ptr<ActivationModelAbstract> activation);
113
114 /**
115 * @copybrief CostModelAbstractTpl()
116 *
117 * We use `ActivationModelQuadTpl` as a default activation model (i.e.,
118 * \f$a=\frac{1}{2}\|\mathbf{r}\|^2\f$)
119 *
120 * @param[in] state State of the dynamical system
121 * @param[in] residual Residual model
122 */
123 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
124 std::shared_ptr<ResidualModelAbstract> residual);
125
126 /**
127 * @copybrief CostModelAbstractTpl()
128 *
129 * We use `ActivationModelQuadTpl` as a default activation model (i.e.,
130 * \f$a=\frac{1}{2}\|\mathbf{r}\|^2\f$)
131 *
132 * @param[in] state State of the system
133 * @param[in] nr Dimension of residual vector
134 * @param[in] nu Dimension of control vector
135 */
136 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
137 const std::size_t nr, const std::size_t nu);
138
139 /**
140 * @copybrief CostModelAbstractTpl()
141 *
142 * We use `ActivationModelQuadTpl` as a default activation model (i.e.,
143 * \f$a=\frac{1}{2}\|\mathbf{r}\|^2\f$). Furthermore, the default `nu` value
144 * is obtained from `StateAbstractTpl::get_nv()`.
145 *
146 * @param[in] state State of the dynamical system
147 * @param[in] nr Dimension of residual vector
148 * @param[in] nu Dimension of control vector
149 */
150 CostModelAbstractTpl(std::shared_ptr<StateAbstract> state,
151 const std::size_t nr);
152 15384 virtual ~CostModelAbstractTpl() = default;
153
154 /**
155 * @brief Compute the cost value and its residual vector
156 *
157 * @param[in] data Cost data
158 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
159 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
160 */
161 virtual void calc(const std::shared_ptr<CostDataAbstract>& data,
162 const Eigen::Ref<const VectorXs>& x,
163 const Eigen::Ref<const VectorXs>& u) = 0;
164
165 /**
166 * @brief Compute the total cost value for nodes that depends only on the
167 * state
168 *
169 * It updates the total cost based on the state only. This function is used in
170 * the terminal nodes of an optimal control problem.
171 *
172 * @param[in] data Cost data
173 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
174 */
175 virtual void calc(const std::shared_ptr<CostDataAbstract>& data,
176 const Eigen::Ref<const VectorXs>& x);
177
178 /**
179 * @brief Compute the Jacobian and Hessian of cost and its residual vector
180 *
181 * It computes the Jacobian and Hessian of the cost function. It assumes that
182 * `calc()` has been run first.
183 *
184 * @param[in] data Cost data
185 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
186 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
187 */
188 virtual void calcDiff(const std::shared_ptr<CostDataAbstract>& data,
189 const Eigen::Ref<const VectorXs>& x,
190 const Eigen::Ref<const VectorXs>& u) = 0;
191
192 /**
193 * @brief Compute the Jacobian and Hessian of the cost functions with respect
194 * to the state only
195 *
196 * It updates the Jacobian and Hessian of the cost function based on the state
197 * only. This function is used in the terminal nodes of an optimal control
198 * problem.
199 *
200 * @param[in] data Cost data
201 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
202 */
203 virtual void calcDiff(const std::shared_ptr<CostDataAbstract>& data,
204 const Eigen::Ref<const VectorXs>& x);
205
206 /**
207 * @brief Create the cost data
208 *
209 * The default data contains objects to store the values of the cost, residual
210 * vector and their derivatives (first and second order derivatives). However,
211 * it is possible to specialize this function if we need to create additional
212 * data, for instance, to avoid dynamic memory allocation.
213 *
214 * @param data Data collector
215 * @return the cost data
216 */
217 virtual std::shared_ptr<CostDataAbstract> createData(
218 DataCollectorAbstract* const data);
219
220 /**
221 * @brief Return the state
222 */
223 const std::shared_ptr<StateAbstract>& get_state() const;
224
225 /**
226 * @brief Return the activation model
227 */
228 const std::shared_ptr<ActivationModelAbstract>& get_activation() const;
229
230 /**
231 * @brief Return the residual model
232 */
233 const std::shared_ptr<ResidualModelAbstract>& get_residual() const;
234
235 /**
236 * @brief Return the dimension of the control input
237 */
238 std::size_t get_nu() const;
239
240 /**
241 * @brief Print information on the cost model
242 */
243 template <class Scalar>
244 friend std::ostream& operator<<(std::ostream& os,
245 const CostModelAbstractTpl<Scalar>& model);
246
247 /**
248 * @brief Modify the cost reference
249 */
250 template <class ReferenceType>
251 void set_reference(ReferenceType ref);
252
253 /**
254 * @brief Return the cost reference
255 */
256 template <class ReferenceType>
257 ReferenceType get_reference();
258
259 /**
260 * @brief Print relevant information of the cost model
261 *
262 * @param[out] os Output stream object
263 */
264 virtual void print(std::ostream& os) const;
265
266 protected:
267 /**
268 * @copybrief set_reference()
269 */
270 virtual void set_referenceImpl(const std::type_info&, const void*);
271
272 /**
273 * @copybrief get_reference()
274 */
275 virtual void get_referenceImpl(const std::type_info&, void*);
276
277 std::shared_ptr<StateAbstract> state_; //!< State description
278 std::shared_ptr<ActivationModelAbstract> activation_; //!< Activation model
279 std::shared_ptr<ResidualModelAbstract> residual_; //!< Residual model
280 std::size_t nu_; //!< Control dimension
281 VectorXs unone_; //!< No control vector
282 CostModelAbstractTpl()
283 : state_(nullptr), activation_(nullptr), residual_(nullptr), nu_(0) {}
284 };
285
286 template <typename _Scalar>
287 struct CostDataAbstractTpl {
288 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
289
290 typedef _Scalar Scalar;
291 typedef MathBaseTpl<Scalar> MathBase;
292 typedef ActivationDataAbstractTpl<Scalar> ActivationDataAbstract;
293 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
294 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
295 typedef typename MathBase::VectorXs VectorXs;
296 typedef typename MathBase::MatrixXs MatrixXs;
297
298 template <template <typename Scalar> class Model>
299 478159 CostDataAbstractTpl(Model<Scalar>* const model,
300 DataCollectorAbstract* const data)
301 478159 : shared(data),
302 478159 activation(model->get_activation()->createData()),
303
2/4
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 476333 times.
✗ Branch 6 not taken.
478159 residual(model->get_residual()->createData(data)),
304 478159 cost(Scalar(0.)),
305
3/6
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 476333 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 476333 times.
✗ Branch 9 not taken.
478159 Lx(model->get_state()->get_ndx()),
306
2/4
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 476333 times.
✗ Branch 5 not taken.
478159 Lu(model->get_nu()),
307
5/10
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 476333 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 476333 times.
✗ Branch 9 not taken.
✓ Branch 12 taken 476333 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 476333 times.
✗ Branch 16 not taken.
478159 Lxx(model->get_state()->get_ndx(), model->get_state()->get_ndx()),
308
4/8
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 476333 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 476333 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 476333 times.
✗ Branch 12 not taken.
478159 Lxu(model->get_state()->get_ndx(), model->get_nu()),
309
3/6
✓ Branch 2 taken 476333 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 476333 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 476333 times.
✗ Branch 9 not taken.
956318 Luu(model->get_nu(), model->get_nu()) {
310
1/2
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
478159 Lx.setZero();
311
1/2
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
478159 Lu.setZero();
312
1/2
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
478159 Lxx.setZero();
313
1/2
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
478159 Lxu.setZero();
314
1/2
✓ Branch 1 taken 476333 times.
✗ Branch 2 not taken.
478159 Luu.setZero();
315 478159 }
316 950814 virtual ~CostDataAbstractTpl() = default;
317
318 DEPRECATED(
319 "Use residual.r", const VectorXs& get_r() const { return residual->r; };)
320 DEPRECATED(
321 "Use residual.Rx",
322 const MatrixXs& get_Rx() const { return residual->Rx; };)
323 DEPRECATED(
324 "Use residual.Ru",
325 const MatrixXs& get_Ru() const { return residual->Ru; };)
326 DEPRECATED(
327 "Use residual.r", void set_r(const VectorXs& r) { residual->r = r; };)
328 DEPRECATED(
329 "Use residual.Rx",
330 void set_Rx(const MatrixXs& Rx) { residual->Rx = Rx; };)
331 DEPRECATED(
332 "Use residual.Ru",
333 void set_Ru(const MatrixXs& Ru) { residual->Ru = Ru; };)
334
335 DataCollectorAbstract* shared;
336 std::shared_ptr<ActivationDataAbstract> activation;
337 std::shared_ptr<ResidualDataAbstract> residual;
338 Scalar cost;
339 VectorXs Lx;
340 VectorXs Lu;
341 MatrixXs Lxx;
342 MatrixXs Lxu;
343 MatrixXs Luu;
344 };
345
346 } // namespace crocoddyl
347
348 /* --- Details -------------------------------------------------------------- */
349 /* --- Details -------------------------------------------------------------- */
350 /* --- Details -------------------------------------------------------------- */
351 #include "crocoddyl/core/cost-base.hxx"
352
353 CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(crocoddyl::CostModelAbstractTpl)
354 CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(crocoddyl::CostDataAbstractTpl)
355
356 #endif // CROCODDYL_CORE_COST_BASE_HPP_
357