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