GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/state-base.hpp
Date: 2025-03-26 19:23:43
Exec Total Coverage
Lines: 4 4 100.0%
Branches: 7 10 70.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2025, LAAS-CNRS, University of Edinburgh, INRIA,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifndef CROCODDYL_CORE_STATE_BASE_HPP_
11 #define CROCODDYL_CORE_STATE_BASE_HPP_
12
13 #include <stdexcept>
14 #include <string>
15 #include <vector>
16
17 #include "crocoddyl/core/fwd.hpp"
18 #include "crocoddyl/core/mathbase.hpp"
19
20 namespace crocoddyl {
21
22 enum Jcomponent { both = 0, first = 1, second = 2 };
23
24 60713 inline bool is_a_Jcomponent(Jcomponent firstsecond) {
25
5/6
✓ Branch 0 taken 45553 times.
✓ Branch 1 taken 15160 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 45111 times.
✓ Branch 4 taken 442 times.
✗ Branch 5 not taken.
60713 return (firstsecond == first || firstsecond == second || firstsecond == both);
26 }
27
28 class StateBase {
29 public:
30 23442 virtual ~StateBase() = default;
31
32
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
✓ Branch 5 taken 102 times.
✗ Branch 6 not taken.
408 CROCODDYL_BASE_CAST(StateBase, StateAbstractTpl)
33 };
34
35 /**
36 * @brief Abstract class for the state representation
37 *
38 * A state is represented by its operators: difference, integrates, transport
39 * and their derivatives. The difference operator returns the value of
40 * \f$\mathbf{x}_{1}\ominus\mathbf{x}_{0}\f$ operation. Instead the integrate
41 * operator returns the value of \f$\mathbf{x}\oplus\delta\mathbf{x}\f$. These
42 * operators are used to compared two points on the state manifold
43 * \f$\mathcal{M}\f$ or to advance the state given a tangential velocity
44 * (\f$T_\mathbf{x} \mathcal{M}\f$). Therefore the points \f$\mathbf{x}\f$,
45 * \f$\mathbf{x}_{0}\f$ and \f$\mathbf{x}_{1}\f$ belong to the manifold
46 * \f$\mathcal{M}\f$; and \f$\delta\mathbf{x}\f$ or
47 * \f$\mathbf{x}_{1}\ominus\mathbf{x}_{0}\f$ lie on its tangential space.
48 *
49 * \sa `diff()`, `integrate()`, `Jdiff()`, `Jintegrate()` and
50 * `JintegrateTransport()`
51 */
52 template <typename _Scalar>
53 class StateAbstractTpl : public StateBase {
54 public:
55 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
56
57 typedef _Scalar Scalar;
58 typedef MathBaseTpl<Scalar> MathBase;
59 typedef typename MathBase::VectorXs VectorXs;
60 typedef typename MathBase::MatrixXs MatrixXs;
61
62 /**
63 * @brief Initialize the state dimensions
64 *
65 * @param[in] nx Dimension of state configuration tuple
66 * @param[in] ndx Dimension of state tangent vector
67 */
68 StateAbstractTpl(const std::size_t nx, const std::size_t ndx);
69 StateAbstractTpl();
70 virtual ~StateAbstractTpl();
71
72 /**
73 * @brief Generate a zero state
74 */
75 virtual VectorXs zero() const = 0;
76
77 /**
78 * @brief Generate a random state
79 */
80 virtual VectorXs rand() const = 0;
81
82 /**
83 * @brief Compute the state manifold differentiation.
84 *
85 * The state differentiation is defined as:
86 * \f{equation*}{
87 * \delta\mathbf{x} = \mathbf{x}_{1} \ominus \mathbf{x}_{0},
88 * \f}
89 * where \f$\mathbf{x}_{1}\f$, \f$\mathbf{x}_{0}\f$ are the current and
90 * previous state which lie in a manifold \f$\mathcal{M}\f$, and
91 * \f$\delta\mathbf{x} \in T_\mathbf{x} \mathcal{M}\f$ is the rate of change
92 * in the state in the tangent space of the manifold.
93 *
94 * @param[in] x0 Previous state point (size `nx`)
95 * @param[in] x1 Current state point (size `nx`)
96 * @param[out] dxout Difference between the current and previous state points
97 * (size `ndx`)
98 */
99 virtual void diff(const Eigen::Ref<const VectorXs>& x0,
100 const Eigen::Ref<const VectorXs>& x1,
101 Eigen::Ref<VectorXs> dxout) const = 0;
102
103 /**
104 * @brief Compute the state manifold integration.
105 *
106 * The state integration is defined as:
107 * \f{equation*}{
108 * \mathbf{x}_{next} = \mathbf{x} \oplus \delta\mathbf{x},
109 * \f}
110 * where \f$\mathbf{x}\f$, \f$\mathbf{x}_{next}\f$ are the current and next
111 * state which lie in a manifold \f$\mathcal{M}\f$, and \f$\delta\mathbf{x}
112 * \in T_\mathbf{x} \mathcal{M}\f$ is the rate of change in the state in the
113 * tangent space of the manifold.
114 *
115 * @param[in] x State point (size `nx`)
116 * @param[in] dx Velocity vector (size `ndx`)
117 * @param[out] xout Next state point (size `nx`)
118 */
119 virtual void integrate(const Eigen::Ref<const VectorXs>& x,
120 const Eigen::Ref<const VectorXs>& dx,
121 Eigen::Ref<VectorXs> xout) const = 0;
122
123 /**
124 * @brief Compute the Jacobian of the state manifold differentiation.
125 *
126 * The state differentiation is defined as:
127 * \f{equation*}{
128 * \delta\mathbf{x} = \mathbf{x}_{1} \ominus \mathbf{x}_{0},
129 * \f}
130 * where \f$\mathbf{x}_{1}\f$, \f$\mathbf{x}_{0}\f$ are the current and
131 * previous state which lie in a manifold \f$\mathcal{M}\f$, and
132 * \f$\delta\mathbf{x} \in T_\mathbf{x} \mathcal{M}\f$ is the rate of change
133 * in the state in the tangent space of the manifold.
134 *
135 * The Jacobians lie in the tangent space of manifold, i.e.
136 * \f$\mathbb{R}^{\textrm{ndx}\times\textrm{ndx}}\f$. Note that the state is
137 * represented as a tuple of `nx` values and its dimension is `ndx`. Calling
138 * \f$\boldsymbol{\Delta}(\mathbf{x}_{0}, \mathbf{x}_{1}) \f$, the difference
139 * function, these Jacobians satisfy the following relationships:
140 * -
141 * \f$\boldsymbol{\Delta}(\mathbf{x}_{0},\mathbf{x}_{0}\oplus\delta\mathbf{y})
142 * - \boldsymbol{\Delta}(\mathbf{x}_{0},\mathbf{x}_{1}) =
143 * \mathbf{J}_{\mathbf{x}_{1}}\delta\mathbf{y} +
144 * \mathbf{o}(\mathbf{x}_{0})\f$.
145 * -
146 * \f$\boldsymbol{\Delta}(\mathbf{x}_{0}\oplus\delta\mathbf{y},\mathbf{x}_{1})
147 * - \boldsymbol{\Delta}(\mathbf{x}_{0},\mathbf{x}_{1}) =
148 * \mathbf{J}_{\mathbf{x}_{0}}\delta\mathbf{y} +
149 * \mathbf{o}(\mathbf{x}_{0})\f$,
150 *
151 * where \f$\mathbf{J}_{\mathbf{x}_{1}}\f$ and
152 * \f$\mathbf{J}_{\mathbf{x}_{0}}\f$ are the Jacobian with respect to the
153 * current and previous state, respectively.
154 *
155 * @param[in] x0 Previous state point (size `nx`)
156 * @param[in] x1 Current state point (size `nx`)
157 * @param[out] Jfirst Jacobian of the difference operation relative to
158 * the previous state point (size `ndx`\f$\times\f$`ndx`)
159 * @param[out] Jsecond Jacobian of the difference operation relative to
160 * the current state point (size `ndx`\f$\times\f$`ndx`)
161 * @param[in] firstsecond Argument (either x0 and / or x1) with respect to
162 * which the differentiation is performed.
163 */
164 virtual void Jdiff(const Eigen::Ref<const VectorXs>& x0,
165 const Eigen::Ref<const VectorXs>& x1,
166 Eigen::Ref<MatrixXs> Jfirst, Eigen::Ref<MatrixXs> Jsecond,
167 const Jcomponent firstsecond = both) const = 0;
168
169 /**
170 * @brief Compute the Jacobian of the state manifold integration.
171 *
172 * The state integration is defined as:
173 * \f{equation*}{
174 * \mathbf{x}_{next} = \mathbf{x} \oplus \delta\mathbf{x},
175 * \f}
176 * where \f$\mathbf{x}\f$, \f$\mathbf{x}_{next}\f$ are the current and next
177 * state which lie in a manifold \f$\mathcal{M}\f$, and \f$\delta\mathbf{x}
178 * \in T_\mathbf{x} \mathcal{M}\f$ is the rate of change in the state in the
179 * tangent space of the manifold.
180 *
181 * The Jacobians lie in the tangent space of manifold, i.e.
182 * \f$\mathbb{R}^{\textrm{ndx}\times\textrm{ndx}}\f$. Note that the state is
183 * represented as a tuple of `nx` values and its dimension is `ndx`. Calling
184 * \f$ \mathbf{f}(\mathbf{x}, \delta\mathbf{x}) \f$, the integrate function,
185 * these Jacobians satisfy the following relationships:
186 * -
187 * \f$\mathbf{f}(\mathbf{x}\oplus\delta\mathbf{y},\delta\mathbf{x})\ominus\mathbf{f}(\mathbf{x},\delta\mathbf{x})
188 * = \mathbf{J}_\mathbf{x}\delta\mathbf{y} + \mathbf{o}(\delta\mathbf{x})\f$.
189 * -
190 * \f$\mathbf{f}(\mathbf{x},\delta\mathbf{x}+\delta\mathbf{y})\ominus\mathbf{f}(\mathbf{x},\delta\mathbf{x})
191 * = \mathbf{J}_{\delta\mathbf{x}}\delta\mathbf{y} +
192 * \mathbf{o}(\delta\mathbf{x})\f$,
193 *
194 * where \f$\mathbf{J}_{\delta\mathbf{x}}\f$ and \f$\mathbf{J}_{\mathbf{x}}\f$
195 * are the Jacobian with respect to the state and velocity, respectively.
196 *
197 * @param[in] x State point (size `nx`)
198 * @param[in] dx Velocity vector (size `ndx`)
199 * @param[out] Jfirst Jacobian of the integration operation relative to
200 * the state point (size `ndx`\f$\times\f$`ndx`)
201 * @param[out] Jsecond Jacobian of the integration operation relative to
202 * the velocity vector (size `ndx`\f$\times\f$`ndx`)
203 * @param[in] firstsecond Argument (either x and / or dx) with respect to
204 * which the differentiation is performed
205 * @param[in] op Assignment operator which sets, adds, or removes
206 * the given Jacobian matrix
207 */
208 virtual void Jintegrate(const Eigen::Ref<const VectorXs>& x,
209 const Eigen::Ref<const VectorXs>& dx,
210 Eigen::Ref<MatrixXs> Jfirst,
211 Eigen::Ref<MatrixXs> Jsecond,
212 const Jcomponent firstsecond = both,
213 const AssignmentOp op = setto) const = 0;
214
215 /**
216 * @brief Parallel transport from integrate(x, dx) to x.
217 *
218 * This function performs the parallel transportation of an input matrix whose
219 * columns are expressed in the tangent space at
220 * \f$\mathbf{x}\oplus\delta\mathbf{x}\f$ to the tangent space at
221 * \f$\mathbf{x}\f$ point.
222 *
223 * @param[in] x State point (size `nx`).
224 * @param[in] dx Velocity vector (size `ndx`)
225 * @param[out] Jin Input matrix (number of rows = `nv`).
226 * @param[in] firstsecond Argument (either x or dx) with respect to which the
227 * differentiation of Jintegrate is performed.
228 */
229 virtual void JintegrateTransport(const Eigen::Ref<const VectorXs>& x,
230 const Eigen::Ref<const VectorXs>& dx,
231 Eigen::Ref<MatrixXs> Jin,
232 const Jcomponent firstsecond) const = 0;
233
234 /**
235 * @copybrief diff()
236 *
237 * @param[in] x0 Previous state point (size `nx`)
238 * @param[in] x1 Current state point (size `nx`)
239 * @return Difference between the current and previous state points (size
240 * `ndx`)
241 */
242 VectorXs diff_dx(const Eigen::Ref<const VectorXs>& x0,
243 const Eigen::Ref<const VectorXs>& x1);
244
245 /**
246 * @copybrief integrate()
247 *
248 * @param[in] x State point (size `nx`)
249 * @param[in] dx Velocity vector (size `ndx`)
250 * @return Next state point (size `nx`)
251 */
252 VectorXs integrate_x(const Eigen::Ref<const VectorXs>& x,
253 const Eigen::Ref<const VectorXs>& dx);
254
255 /**
256 * @copybrief jdiff()
257 *
258 * @param[in] x0 Previous state point (size `nx`)
259 * @param[in] x1 Current state point (size `nx`)
260 * @return Jacobians
261 */
262 std::vector<MatrixXs> Jdiff_Js(const Eigen::Ref<const VectorXs>& x0,
263 const Eigen::Ref<const VectorXs>& x1,
264 const Jcomponent firstsecond = both);
265
266 /**
267 * @copybrief Jintegrate()
268 *
269 * @param[in] x State point (size `nx`)
270 * @param[in] dx Velocity vector (size `ndx`)
271 * @return Jacobians
272 */
273 std::vector<MatrixXs> Jintegrate_Js(const Eigen::Ref<const VectorXs>& x,
274 const Eigen::Ref<const VectorXs>& dx,
275 const Jcomponent firstsecond = both);
276
277 /**
278 * @brief Print information on the state model
279 */
280 template <class Scalar>
281 friend std::ostream& operator<<(std::ostream& os,
282 const ActionModelAbstractTpl<Scalar>& model);
283
284 /**
285 * @brief Print relevant information of the state model
286 *
287 * @param[out] os Output stream object
288 */
289 virtual void print(std::ostream& os) const;
290
291 /**
292 * @brief Return the dimension of the state tuple
293 */
294 std::size_t get_nx() const;
295
296 /**
297 * @brief Return the dimension of the tangent space of the state manifold
298 */
299 std::size_t get_ndx() const;
300
301 /**
302 * @brief Return the dimension of the configuration tuple
303 */
304 std::size_t get_nq() const;
305
306 /**
307 * @brief Return the dimension of tangent space of the configuration manifold
308 */
309 std::size_t get_nv() const;
310
311 /**
312 * @brief Return the state lower bound
313 */
314 const VectorXs& get_lb() const;
315
316 /**
317 * @brief Return the state upper bound
318 */
319 const VectorXs& get_ub() const;
320
321 /**
322 * @brief Indicate if the state has defined limits
323 */
324 bool get_has_limits() const;
325
326 /**
327 * @brief Modify the state lower bound
328 */
329 void set_lb(const VectorXs& lb);
330
331 /**
332 * @brief Modify the state upper bound
333 */
334 void set_ub(const VectorXs& ub);
335
336 protected:
337 void update_has_limits();
338
339 std::size_t nx_; //!< State dimension
340 std::size_t ndx_; //!< State rate dimension
341 std::size_t nq_; //!< Configuration dimension
342 std::size_t nv_; //!< Velocity dimension
343 VectorXs lb_; //!< Lower state limits
344 VectorXs ub_; //!< Upper state limits
345 bool has_limits_; //!< Indicates whether any of the state limits is finite
346 };
347
348 } // namespace crocoddyl
349
350 /* --- Details -------------------------------------------------------------- */
351 /* --- Details -------------------------------------------------------------- */
352 /* --- Details -------------------------------------------------------------- */
353 #include "crocoddyl/core/state-base.hxx"
354
355 CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(crocoddyl::StateAbstractTpl)
356
357 #endif // CROCODDYL_CORE_STATE_BASE_HPP_
358