GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/residual-base.hpp
Date: 2025-01-16 08:47:40
Exec Total Coverage
Lines: 14 14 100.0%
Branches: 10 20 50.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2021-2023, University of Edinburgh, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifndef CROCODDYL_CORE_RESIDUAL_BASE_HPP_
10 #define CROCODDYL_CORE_RESIDUAL_BASE_HPP_
11
12 #include <boost/make_shared.hpp>
13 #include <boost/shared_ptr.hpp>
14
15 #include "crocoddyl/core/activation-base.hpp"
16 #include "crocoddyl/core/cost-base.hpp"
17 #include "crocoddyl/core/data-collector-base.hpp"
18 #include "crocoddyl/core/fwd.hpp"
19 #include "crocoddyl/core/state-base.hpp"
20
21 namespace crocoddyl {
22
23 /**
24 * @brief Abstract class for residual models
25 *
26 * A residual model defines a vector function \f$\mathbf{r}(\mathbf{x},
27 * \mathbf{u})\mathbb{R}^{nr}\f$ where `nr` describes its dimension in the
28 * Euclidean space. This function depends on the state point
29 * \f$\mathbf{x}\in\mathcal{X}\f$, which lies in the state manifold described
30 * with a `nq`-tuple, its velocity \f$\dot{\mathbf{x}}\in
31 * T_{\mathbf{x}}\mathcal{X}\f$ that belongs to the tangent space with `nv`
32 * dimension, and the control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$. The
33 * residual function can used across cost and constraint models.
34 *
35 * The main computations are carring out in `calc` and `calcDiff` routines.
36 * `calc` computes the residual vector and `calcDiff` computes the Jacobians of
37 * the residual function. Additionally, it is important to note that
38 * `calcDiff()` computes the Jacobians using the latest stored values by
39 * `calc()`. Thus, we need to first run `calc()`.
40 *
41 * \sa `StateAbstractTpl`, `calc()`, `calcDiff()`, `createData()`
42 */
43 template <typename _Scalar>
44 class ResidualModelAbstractTpl {
45 public:
46 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
47
48 typedef _Scalar Scalar;
49 typedef MathBaseTpl<Scalar> MathBase;
50 typedef ResidualDataAbstractTpl<Scalar> ResidualDataAbstract;
51 typedef CostDataAbstractTpl<Scalar> CostDataAbstract;
52 typedef ActivationDataAbstractTpl<Scalar> ActivationDataAbstract;
53 typedef StateAbstractTpl<Scalar> StateAbstract;
54 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
55 typedef typename MathBase::VectorXs VectorXs;
56 typedef typename MathBase::MatrixXs MatrixXs;
57 typedef typename MathBase::DiagonalMatrixXs DiagonalMatrixXs;
58
59 /**
60 * @brief Initialize the residual model
61 *
62 * @param[in] state State of the system
63 * @param[in] nr Dimension of residual vector
64 * @param[in] nu Dimension of control vector
65 * @param[in] q_dependent Define if the residual function depends on q
66 * (default true)
67 * @param[in] v_dependent Define if the residual function depends on v
68 * (default true)
69 * @param[in] u_dependent Define if the residual function depends on u
70 * (default true)
71 */
72 ResidualModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
73 const std::size_t nr, const std::size_t nu,
74 const bool q_dependent = true,
75 const bool v_dependent = true,
76 const bool u_dependent = true);
77
78 /**
79 * @copybrief ResidualModelAbstractTpl()
80 *
81 * The default `nu` value is obtained from `StateAbstractTpl::get_nv()`.
82 *
83 * @param[in] state State of the system
84 * @param[in] nr Dimension of residual vector
85 * @param[in] q_dependent Define if the residual function depends on q
86 * (default true)
87 * @param[in] v_dependent Define if the residual function depends on v
88 * (default true)
89 * @param[in] u_dependent Define if the residual function depends on u
90 * (default true)
91 */
92 ResidualModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
93 const std::size_t nr, const bool q_dependent = true,
94 const bool v_dependent = true,
95 const bool u_dependent = true);
96 virtual ~ResidualModelAbstractTpl();
97
98 /**
99 * @brief Compute the residual vector
100 *
101 * @param[in] data Residual data
102 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
103 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
104 */
105 virtual void calc(const boost::shared_ptr<ResidualDataAbstract>& data,
106 const Eigen::Ref<const VectorXs>& x,
107 const Eigen::Ref<const VectorXs>& u);
108
109 /**
110 * @brief Compute the residual vector for nodes that depends only on the state
111 *
112 * It updates the residual vector based on the state only. This function is
113 * used in the terminal nodes of an optimal control problem.
114 *
115 * @param[in] data Residual data
116 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
117 */
118 virtual void calc(const boost::shared_ptr<ResidualDataAbstract>& data,
119 const Eigen::Ref<const VectorXs>& x);
120
121 /**
122 * @brief Compute the Jacobian of the residual vector
123 *
124 * It computes the Jacobian the residual function. It assumes that `calc()`
125 * has been run first.
126 *
127 * @param[in] data Residual data
128 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
129 * @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
130 */
131 virtual void calcDiff(const boost::shared_ptr<ResidualDataAbstract>& data,
132 const Eigen::Ref<const VectorXs>& x,
133 const Eigen::Ref<const VectorXs>& u);
134
135 /**
136 * @brief Compute the Jacobian of the residual functions with respect to the
137 * state only
138 *
139 * It updates the Jacobian of the residual function based on the state only.
140 * This function is used in the terminal nodes of an optimal control problem.
141 *
142 * @param[in] data Residual data
143 * @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
144 */
145 virtual void calcDiff(const boost::shared_ptr<ResidualDataAbstract>& data,
146 const Eigen::Ref<const VectorXs>& x);
147
148 /**
149 * @brief Create the residual data
150 *
151 * The default data contains objects to store the values of the residual
152 * vector and their Jacobians. However, it is possible to specialize this
153 * function if we need to create additional data, for instance, to avoid
154 * dynamic memory allocation.
155 *
156 * @param data Data collector
157 * @return the residual data
158 */
159 virtual boost::shared_ptr<ResidualDataAbstract> createData(
160 DataCollectorAbstract* const data);
161
162 /**
163 * @brief Compute the derivative of the cost function
164 *
165 * This function assumes that the derivatives of the activation and residual
166 * are computed via calcDiff functions.
167 *
168 * @param cdata Cost data
169 * @param rdata Residual data
170 * @param adata Activation data
171 * @param update_u Update the derivative of the cost function w.r.t. to the
172 * control if True.
173 */
174 virtual void calcCostDiff(
175 const boost::shared_ptr<CostDataAbstract>& cdata,
176 const boost::shared_ptr<ResidualDataAbstract>& rdata,
177 const boost::shared_ptr<ActivationDataAbstract>& adata,
178 const bool update_u = true);
179
180 /**
181 * @brief Return the state
182 */
183 const boost::shared_ptr<StateAbstract>& get_state() const;
184
185 /**
186 * @brief Return the dimension of the residual vector
187 */
188 std::size_t get_nr() const;
189
190 /**
191 * @brief Return the dimension of the control input
192 */
193 std::size_t get_nu() const;
194
195 /**
196 * @brief Return true if the residual function depends on q
197 */
198 bool get_q_dependent() const;
199
200 /**
201 * @brief Return true if the residual function depends on v
202 */
203 bool get_v_dependent() const;
204
205 /**
206 * @brief Return true if the residual function depends on u
207 */
208 bool get_u_dependent() const;
209
210 /**
211 * @brief Print information on the residual model
212 */
213 template <class Scalar>
214 friend std::ostream& operator<<(
215 std::ostream& os, const ResidualModelAbstractTpl<Scalar>& model);
216
217 /**
218 * @brief Print relevant information of the residual model
219 *
220 * @param[out] os Output stream object
221 */
222 virtual void print(std::ostream& os) const;
223
224 protected:
225 boost::shared_ptr<StateAbstract> state_; //!< State description
226 std::size_t nr_; //!< Residual vector dimension
227 std::size_t nu_; //!< Control dimension
228 VectorXs unone_; //!< No control vector
229 bool q_dependent_; //!< Label that indicates if the residual function depends
230 //!< on q
231 bool v_dependent_; //!< Label that indicates if the residual function depends
232 //!< on v
233 bool u_dependent_; //!< Label that indicates if the residual function depends
234 //!< on u
235 };
236
237 template <typename _Scalar>
238 struct ResidualDataAbstractTpl {
239 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
240
241 typedef _Scalar Scalar;
242 typedef MathBaseTpl<Scalar> MathBase;
243 typedef DataCollectorAbstractTpl<Scalar> DataCollectorAbstract;
244 typedef typename MathBase::VectorXs VectorXs;
245 typedef typename MathBase::MatrixXs MatrixXs;
246
247 template <template <typename Scalar> class Model>
248 1454849 ResidualDataAbstractTpl(Model<Scalar>* const model,
249 DataCollectorAbstract* const data)
250 1454849 : shared(data),
251
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 r(model->get_nr()),
252
1/2
✓ Branch 5 taken 731867 times.
✗ Branch 6 not taken.
1454849 Rx(model->get_nr(), model->get_state()->get_ndx()),
253
1/2
✓ Branch 3 taken 731867 times.
✗ Branch 4 not taken.
1454849 Ru(model->get_nr(), model->get_nu()),
254
1/2
✓ Branch 5 taken 731867 times.
✗ Branch 6 not taken.
1454849 Arr_Rx(model->get_nr(), model->get_state()->get_ndx()),
255
1/2
✓ Branch 4 taken 731867 times.
✗ Branch 5 not taken.
2909698 Arr_Ru(model->get_nr(), model->get_nu()) {
256
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 r.setZero();
257
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 Rx.setZero();
258
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 Ru.setZero();
259
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 Arr_Rx.setZero();
260
1/2
✓ Branch 1 taken 731867 times.
✗ Branch 2 not taken.
1454849 Arr_Ru.setZero();
261 1454849 }
262 786101 virtual ~ResidualDataAbstractTpl() {}
263
264 DataCollectorAbstract* shared; //!< Shared data allocated by the action model
265 VectorXs r; //!< Residual vector
266 MatrixXs Rx; //!< Jacobian of the residual vector with respect the state
267 MatrixXs Ru; //!< Jacobian of the residual vector with respect the control
268 MatrixXs Arr_Rx;
269 MatrixXs Arr_Ru;
270 };
271
272 } // namespace crocoddyl
273
274 /* --- Details -------------------------------------------------------------- */
275 /* --- Details -------------------------------------------------------------- */
276 /* --- Details -------------------------------------------------------------- */
277 #include "crocoddyl/core/residual-base.hxx"
278
279 #endif // CROCODDYL_CORE_RESIDUAL_BASE_HPP_
280