-
Notifications
You must be signed in to change notification settings - Fork 157
/
diff-action-base.hpp
436 lines (396 loc) · 16.7 KB
/
diff-action-base.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
///////////////////////////////////////////////////////////////////////////////
// BSD 3-Clause License
//
// Copyright (C) 2019-2022, LAAS-CNRS, University of Edinburgh,
// University of Oxford, Heriot-Watt University
// Copyright note valid unless otherwise stated in individual files.
// All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#ifndef CROCODDYL_CORE_DIFF_ACTION_BASE_HPP_
#define CROCODDYL_CORE_DIFF_ACTION_BASE_HPP_
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include "crocoddyl/core/fwd.hpp"
#include "crocoddyl/core/state-base.hpp"
#include "crocoddyl/core/utils/math.hpp"
namespace crocoddyl {
/**
* @brief Abstract class for differential action model
*
* A differential action model combines dynamics, cost and constraints models.
* We can use it in each node of our optimal control problem thanks to dedicated
* integration rules (e.g., `IntegratedActionModelEulerTpl` or
* `IntegratedActionModelRK4Tpl`). These integrated action models produce action
* models (`ActionModelAbstractTpl`). Thus, every time that we want to describe
* a problem, we need to provide ways of computing the dynamics, cost,
* constraints functions and their derivatives. All these are described inside
* the differential action model.
*
* Concretely speaking, the differential action model is the time-continuous
* version of an action model, i.e., \f[ \begin{aligned}
* &\dot{\mathbf{v}} = \mathbf{f}(\mathbf{q}, \mathbf{v}, \mathbf{u}),
* &\textrm{(dynamics)}\\
* &\ell(\mathbf{q}, \mathbf{v},\mathbf{u}) = \int_0^{\delta t}
* a(\mathbf{r}(\mathbf{q}, \mathbf{v},\mathbf{u}))\,dt,
* &\textrm{(cost)}\\
* &\mathbf{g}(\mathbf{q}, \mathbf{v},\mathbf{u})<\mathbf{0},
* &\textrm{(inequality constraint)}\\
* &\mathbf{h}(\mathbf{q}, \mathbf{v},\mathbf{u})=\mathbf{0}, &\textrm{(equality
* constraint)} \end{aligned} \f] where
* - the configuration \f$\mathbf{q}\in\mathcal{Q}\f$ lies in the configuration
* manifold described with a `nq`-tuple,
* - the velocity \f$\mathbf{v}\in T_{\mathbf{q}}\mathcal{Q}\f$ is the tangent
* vector to the configuration manifold with `nv` dimension,
* - the control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$ is an Euclidean
* vector,
* - \f$\mathbf{r}(\cdot)\f$ and \f$a(\cdot)\f$ are the residual and activation
* functions (see `ResidualModelAbstractTpl` and `ActivationModelAbstractTpl`,
* respectively),
* - \f$\mathbf{g}(\cdot)\in\mathbb{R}^{ng}\f$ and
* \f$\mathbf{h}(\cdot)\in\mathbb{R}^{nh}\f$ are the inequality and equality
* vector functions, respectively.
*
* Both configuration and velocity describe the system space
* \f$\mathbf{x}=(\mathbf{q}, \mathbf{v})\in\mathcal{X}\f$ which lies in the
* state manifold. Note that the acceleration \f$\dot{\mathbf{v}}\in
* T_{\mathbf{q}}\mathcal{Q}\f$ lies also in the tangent space of the
* configuration manifold. The computation of these equations are carried out
* inside `calc()` function. In short, this function computes the system
* acceleration, cost and constraints values (also called constraints
* violations). This procedure is equivalent to running a forward pass of the
* action model.
*
* However, during numerical optimization, we also need to run backward passes
* of the differential action model. These calculations are performed by
* `calcDiff()`. In short, this function builds a linear-quadratic approximation
* of the differential action model, i.e., \f[ \begin{aligned}
* &\delta\dot{\mathbf{v}} =
* \mathbf{f_{q}}\delta\mathbf{q}+\mathbf{f_{v}}\delta\mathbf{v}+\mathbf{f_{u}}\delta\mathbf{u},
* &\textrm{(dynamics)}\\
* &\ell(\delta\mathbf{q},\delta\mathbf{v},\delta\mathbf{u}) = \begin{bmatrix}1
* \\ \delta\mathbf{q} \\ \delta\mathbf{v}
* \\ \delta\mathbf{u}\end{bmatrix}^T \begin{bmatrix}0 & \mathbf{\ell_q}^T &
* \mathbf{\ell_v}^T & \mathbf{\ell_u}^T \\ \mathbf{\ell_q} & \mathbf{\ell_{qq}}
* &
* \mathbf{\ell_{qv}} & \mathbf{\ell_{uq}}^T \\
* \mathbf{\ell_v} & \mathbf{\ell_{vq}} & \mathbf{\ell_{vv}} &
* \mathbf{\ell_{uv}}^T \\
* \mathbf{\ell_u} & \mathbf{\ell_{uq}} & \mathbf{\ell_{uv}} &
* \mathbf{\ell_{uu}}\end{bmatrix} \begin{bmatrix}1 \\ \delta\mathbf{q}
* \\ \delta\mathbf{v} \\
* \delta\mathbf{u}\end{bmatrix}, &\textrm{(cost)}\\
* &\mathbf{g_q}\delta\mathbf{q}+\mathbf{g_v}\delta\mathbf{v}+\mathbf{g_u}\delta\mathbf{u}\leq\mathbf{0},
* &\textrm{(inequality constraints)}\\
* &\mathbf{h_q}\delta\mathbf{q}+\mathbf{h_v}\delta\mathbf{v}+\mathbf{h_u}\delta\mathbf{u}=\mathbf{0},
* &\textrm{(equality constraints)} \end{aligned} \f] where
* - \f$\mathbf{f_x}=(\mathbf{f_q};\,\, \mathbf{f_v})\in\mathbb{R}^{nv\times
* ndx}\f$ and \f$\mathbf{f_u}\in\mathbb{R}^{nv\times nu}\f$ are the Jacobians
* of the dynamics,
* - \f$\mathbf{\ell_x}=(\mathbf{\ell_q};\,\,
* \mathbf{\ell_v})\in\mathbb{R}^{ndx}\f$ and
* \f$\mathbf{\ell_u}\in\mathbb{R}^{nu}\f$ are the Jacobians of the cost
* function,
* - \f$\mathbf{\ell_{xx}}=(\mathbf{\ell_{qq}}\,\, \mathbf{\ell_{qv}};\,\,
* \mathbf{\ell_{vq}}\, \mathbf{\ell_{vv}})\in\mathbb{R}^{ndx\times ndx}\f$,
* \f$\mathbf{\ell_{xu}}=(\mathbf{\ell_q};\,\,
* \mathbf{\ell_v})\in\mathbb{R}^{ndx\times nu}\f$ and
* \f$\mathbf{\ell_{uu}}\in\mathbb{R}^{nu\times nu}\f$ are the Hessians of the
* cost function,
* - \f$\mathbf{g_x}=(\mathbf{g_q};\,\, \mathbf{g_v})\in\mathbb{R}^{ng\times
* ndx}\f$ and \f$\mathbf{g_u}\in\mathbb{R}^{ng\times nu}\f$ are the Jacobians
* of the inequality constraints, and
* - \f$\mathbf{h_x}=(\mathbf{h_q};\,\, \mathbf{h_v})\in\mathbb{R}^{nh\times
* ndx}\f$ and \f$\mathbf{h_u}\in\mathbb{R}^{nh\times nu}\f$ are the Jacobians
* of the equality constraints.
*
* Additionally, it is important to note that `calcDiff()` computes the
* derivatives using the latest stored values by `calc()`. Thus, we need to
* first run `calc()`.
*
* \sa `ActionModelAbstractTpl`, `calc()`, `calcDiff()`, `createData()`
*/
template <typename _Scalar>
class DifferentialActionModelAbstractTpl {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
typedef _Scalar Scalar;
typedef MathBaseTpl<Scalar> MathBase;
typedef DifferentialActionDataAbstractTpl<Scalar>
DifferentialActionDataAbstract;
typedef StateAbstractTpl<Scalar> StateAbstract;
typedef typename MathBase::VectorXs VectorXs;
typedef typename MathBase::MatrixXs MatrixXs;
/**
* @brief Initialize the differential action model
*
* @param[in] state State description
* @param[in] nu Dimension of control vector
* @param[in] nr Dimension of cost-residual vector
* @param[in] ng Number of inequality constraints
* @param[in] nh Number of equality constraints
*/
DifferentialActionModelAbstractTpl(boost::shared_ptr<StateAbstract> state,
const std::size_t nu,
const std::size_t nr = 0,
const std::size_t ng = 0,
const std::size_t nh = 0);
virtual ~DifferentialActionModelAbstractTpl();
/**
* @brief Compute the system acceleration and cost value
*
* @param[in] data Differential action data
* @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
* @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
*/
virtual void calc(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
const Eigen::Ref<const VectorXs>& x,
const Eigen::Ref<const VectorXs>& u) = 0;
/**
* @brief Compute the total cost value for nodes that depends only on the
* state
*
* It updates the total cost and the system acceleration is not updated as the
* control input is undefined. This function is used in the terminal nodes of
* an optimal control problem.
*
* @param[in] data Differential action data
* @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
*/
virtual void calc(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
const Eigen::Ref<const VectorXs>& x);
/**
* @brief Compute the derivatives of the dynamics and cost functions
*
* It computes the partial derivatives of the dynamical system and the cost
* function. It assumes that `calc()` has been run first. This function builds
* a quadratic approximation of the time-continuous action model (i.e.
* dynamical system and cost function).
*
* @param[in] data Differential action data
* @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
* @param[in] u Control input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
*/
virtual void calcDiff(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
const Eigen::Ref<const VectorXs>& x,
const Eigen::Ref<const VectorXs>& u) = 0;
/**
* @brief Compute the derivatives of the cost functions with respect to the
* state only
*
* It updates the derivatives of the cost function with respect to the state
* only. This function is used in the terminal nodes of an optimal control
* problem.
*
* @param[in] data Differential action data
* @param[in] x State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
*/
virtual void calcDiff(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
const Eigen::Ref<const VectorXs>& x);
/**
* @brief Create the differential action data
*
* @return the differential action data
*/
virtual boost::shared_ptr<DifferentialActionDataAbstract> createData();
/**
* @brief Checks that a specific data belongs to this model
*/
virtual bool checkData(
const boost::shared_ptr<DifferentialActionDataAbstract>& data);
/**
* @brief Computes the quasic static commands
*
* The quasic static commands are the ones produced for a the reference
* posture as an equilibrium point, i.e. for
* \f$\mathbf{f}(\mathbf{q},\mathbf{v}=\mathbf{0},\mathbf{u})=\mathbf{0}\f$
*
* @param[in] data Differential action data
* @param[out] u Quasic static commands
* @param[in] x State point (velocity has to be zero)
* @param[in] maxiter Maximum allowed number of iterations
* @param[in] tol Tolerance
*/
virtual void quasiStatic(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
Eigen::Ref<VectorXs> u, const Eigen::Ref<const VectorXs>& x,
const std::size_t maxiter = 100, const Scalar tol = Scalar(1e-9));
/**
* @copybrief quasicStatic()
*
* @copydetails quasicStatic()
*
* @param[in] data Differential action data
* @param[in] x State point (velocity has to be zero)
* @param[in] maxiter Maximum allowed number of iterations
* @param[in] tol Tolerance
* @return Quasic static commands
*/
VectorXs quasiStatic_x(
const boost::shared_ptr<DifferentialActionDataAbstract>& data,
const VectorXs& x, const std::size_t maxiter = 100,
const Scalar tol = Scalar(1e-9));
/**
* @brief Return the dimension of the control input
*/
std::size_t get_nu() const;
/**
* @brief Return the dimension of the cost-residual vector
*/
std::size_t get_nr() const;
/**
* @brief Return the number of inequality constraints
*/
virtual std::size_t get_ng() const;
/**
* @brief Return the number of equality constraints
*/
virtual std::size_t get_nh() const;
/**
* @brief Return the state
*/
const boost::shared_ptr<StateAbstract>& get_state() const;
/**
* @brief Return the lower bound of the inequality constraints
*/
virtual const VectorXs& get_g_lb() const;
/**
* @brief Return the upper bound of the inequality constraints
*/
virtual const VectorXs& get_g_ub() const;
/**
* @brief Return the control lower bound
*/
const VectorXs& get_u_lb() const;
/**
* @brief Return the control upper bound
*/
const VectorXs& get_u_ub() const;
/**
* @brief Indicates if there are defined control limits
*/
bool get_has_control_limits() const;
/**
* @brief Modify the control lower bounds
*/
void set_u_lb(const VectorXs& u_lb);
/**
* @brief Modify the control upper bounds
*/
void set_u_ub(const VectorXs& u_ub);
/**
* @brief Print information on the differential action model
*/
template <class Scalar>
friend std::ostream& operator<<(
std::ostream& os,
const DifferentialActionModelAbstractTpl<Scalar>& model);
/**
* @brief Print relevant information of the differential action model
*
* @param[out] os Output stream object
*/
virtual void print(std::ostream& os) const;
private:
std::size_t ng_internal_; //!< Internal object for storing the number of
//!< inequality constraints
std::size_t nh_internal_; //!< Internal object for storing the number of
//!< equality constraints
protected:
std::size_t nu_; //!< Control dimension
std::size_t nr_; //!< Dimension of the cost residual
std::size_t ng_; //!< Number of inequality constraints
std::size_t nh_; //!< Number of equality constraints
boost::shared_ptr<StateAbstract> state_; //!< Model of the state
VectorXs unone_; //!< Neutral state
VectorXs g_lb_; //!< Lower bound of the inequality constraints
VectorXs g_ub_; //!< Lower bound of the inequality constraints
VectorXs u_lb_; //!< Lower control limits
VectorXs u_ub_; //!< Upper control limits
bool has_control_limits_; //!< Indicates whether any of the control limits is
//!< finite
/**
* @brief Update the status of the control limits (i.e. if there are defined
* limits)
*/
void update_has_control_limits();
template <class Scalar>
friend class IntegratedActionModelAbstractTpl;
template <class Scalar>
friend class ConstraintModelManagerTpl;
};
template <typename _Scalar>
struct DifferentialActionDataAbstractTpl {
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
typedef _Scalar Scalar;
typedef MathBaseTpl<Scalar> MathBase;
typedef typename MathBase::VectorXs VectorXs;
typedef typename MathBase::MatrixXs MatrixXs;
template <template <typename Scalar> class Model>
explicit DifferentialActionDataAbstractTpl(Model<Scalar>* const model)
: cost(Scalar(0.)),
xout(model->get_state()->get_nv()),
Fx(model->get_state()->get_nv(), model->get_state()->get_ndx()),
Fu(model->get_state()->get_nv(), model->get_nu()),
r(model->get_nr()),
Lx(model->get_state()->get_ndx()),
Lu(model->get_nu()),
Lxx(model->get_state()->get_ndx(), model->get_state()->get_ndx()),
Lxu(model->get_state()->get_ndx(), model->get_nu()),
Luu(model->get_nu(), model->get_nu()),
g(model->get_ng()),
Gx(model->get_ng(), model->get_state()->get_ndx()),
Gu(model->get_ng(), model->get_nu()),
h(model->get_nh()),
Hx(model->get_nh(), model->get_state()->get_ndx()),
Hu(model->get_nh(), model->get_nu()) {
xout.setZero();
Fx.setZero();
Fu.setZero();
r.setZero();
Lx.setZero();
Lu.setZero();
Lxx.setZero();
Lxu.setZero();
Luu.setZero();
g.setZero();
Gx.setZero();
Gu.setZero();
h.setZero();
Hx.setZero();
Hu.setZero();
}
virtual ~DifferentialActionDataAbstractTpl() {}
Scalar cost; //!< cost value
VectorXs xout; //!< evolution state
MatrixXs Fx; //!< Jacobian of the dynamics w.r.t. the state \f$\mathbf{x}\f$
MatrixXs
Fu; //!< Jacobian of the dynamics w.r.t. the control \f$\mathbf{u}\f$
VectorXs r; //!< Cost residual
VectorXs Lx; //!< Jacobian of the cost w.r.t. the state \f$\mathbf{x}\f$
VectorXs Lu; //!< Jacobian of the cost w.r.t. the control \f$\mathbf{u}\f$
MatrixXs Lxx; //!< Hessian of the cost w.r.t. the state \f$\mathbf{x}\f$
MatrixXs Lxu; //!< Hessian of the cost w.r.t. the state \f$\mathbf{x}\f$ and
//!< control u
MatrixXs Luu; //!< Hessian of the cost w.r.t. the control \f$\mathbf{u}\f$
VectorXs g; //!< Inequality constraint values
MatrixXs Gx; //!< Jacobian of the inequality constraint w.r.t. the state
//!< \f$\mathbf{x}\f$
MatrixXs Gu; //!< Jacobian of the inequality constraint w.r.t. the control
//!< \f$\mathbf{u}\f$
VectorXs h; //!< Equality constraint values
MatrixXs Hx; //!< Jacobian of the equality constraint w.r.t. the state
//!< \f$\mathbf{x}\f$
MatrixXs Hu; //!< Jacobian of the equality constraint w.r.t the control
//!< \f$\mathbf{u}\f$
};
} // namespace crocoddyl
/* --- Details -------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------- */
/* --- Details -------------------------------------------------------------- */
#include "crocoddyl/core/diff-action-base.hxx"
#endif // CROCODDYL_CORE_DIFF_ACTION_BASE_HPP_