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