GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/core/solvers/ipopt/ipopt-iface.hpp
Date: 2025-05-13 10:30:51
Exec Total Coverage
Lines: 0 56 0.0%
Branches: 0 70 0.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2022-2023, IRI: CSIC-UPC, Heriot-Watt University
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
7 ///////////////////////////////////////////////////////////////////////////////
8
9 #ifndef __CROCODDYL_CORE_SOLVERS_IPOPT_IPOPT_IFACE_HPP__
10 #define __CROCODDYL_CORE_SOLVERS_IPOPT_IPOPT_IFACE_HPP__
11
12 #define HAVE_CSTDDEF
13 #include <IpTNLP.hpp>
14 #undef HAVE_CSTDDEF
15
16 #include "crocoddyl/core/optctrl/shooting.hpp"
17
18 namespace crocoddyl {
19
20 struct IpoptInterfaceData;
21
22 /**
23 * @brief Class for interfacing a crocoddyl::ShootingProblem with IPOPT
24 *
25 * This class implements the pure virtual functions from Ipopt::TNLP to solve
26 * the optimal control problem in `problem_` using a multiple shooting approach.
27 *
28 * Ipopt considers its decision variables `x` to belong to the Euclidean space.
29 * However, Crocoddyl states could lie in a manifold. To ensure that the
30 * solution of Ipopt lies in the manifold of the state, we perform the
31 * optimization in the tangent space of a given initial state. Finally we
32 * retract the Ipopt solution to the manifold. That is:
33 * * \f[
34 * \begin{aligned}
35 * \mathbf{x}^* = \mathbf{x}^0 \oplus \mathbf{\Delta x}^*
36 * \end{aligned}
37 * \f]
38 *
39 * where \f$\mathbf{x}^*\f$ is the final solution, \f$\mathbf{x}^0\f$ is the
40 * initial guess and \f$\mathbf{\Delta x}^*\f$ is the Ipopt solution in the
41 * tangent space of \f$\mathbf{x}_0\f$. Due to this procedure, the computation
42 * of the cost function, the dynamic constraint as well as their corresponding
43 * derivatives should be properly modified.
44 *
45 * The Ipopt decision vector is built as follows: \f$x = [ \mathbf{\Delta
46 * x}_0^\top, \mathbf{u}_0^\top, \mathbf{\Delta x}_1^\top, \mathbf{u}_1^\top,
47 * \dots, \mathbf{\Delta x}_N^\top ]\f$
48 *
49 * Dynamic constraints are posed as: \f$(\mathbf{x}^0_{k+1} \oplus
50 * \mathbf{\Delta x}_{k+1}) \ominus \mathbf{f}(\mathbf{x}_{k}^0 \oplus
51 * \mathbf{\Delta x}_{k}, \mathbf{u}_k) = \mathbf{0}\f$
52 *
53 * Initial condition: \f$ \mathbf{x}(0) \ominus (\mathbf{x}_{k}^0 \oplus
54 * \mathbf{\Delta x}_{k}) = \mathbf{0}\f$
55 *
56 * Documentation of the methods has been extracted from Ipopt::TNLP.hpp file
57 *
58 * \sa `get_nlp_info()`, `get_bounds_info()`, `eval_f()`, `eval_g()`,
59 * `eval_grad_f()`, `eval_jac_g()`, `eval_h()`
60 */
61
62 class IpoptInterface : public Ipopt::TNLP {
63 public:
64 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
65
66 /**
67 * @brief Initialize the Ipopt interface
68 *
69 * @param[in] problem Crocoddyl shooting problem
70 */
71 IpoptInterface(const std::shared_ptr<crocoddyl::ShootingProblem>& problem);
72
73 virtual ~IpoptInterface();
74
75 /**
76 * @brief Methods to gather information about the NLP
77 *
78 * %Ipopt uses this information when allocating the arrays that it will later
79 * ask you to fill with values. Be careful in this method since incorrect
80 * values will cause memory bugs which may be very difficult to find.
81 * @param[out] n Storage for the number of variables \f$x\f$
82 * @param[out] m Storage for the number of constraints \f$g(x)\f$
83 * @param[out] nnz_jac_g Storage for the number of nonzero entries in the
84 * Jacobian
85 * @param[out] nnz_h_lag Storage for the number of nonzero entries in the
86 * Hessian
87 * @param[out] index_style Storage for the index style the numbering style
88 * used for row/col entries in the sparse matrix format
89 */
90 virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m,
91 Ipopt::Index& nnz_jac_g, Ipopt::Index& nnz_h_lag,
92 IndexStyleEnum& index_style);
93
94 /**
95 * @brief Method to request bounds on the variables and constraints.
96 T
97 * @param[in] n Number of variables \f$x\f$ in the problem
98 * @param[out] x_l Lower bounds \f$x^L\f$ for the variables \f$x\f$
99 * @param[out] x_u Upper bounds \f$x^U\f$ for the variables \f$x\f$
100 * @param[in] m Number of constraints \f$g(x)\f$ in the problem
101 * @param[out] g_l Lower bounds \f$g^L\f$ for the constraints \f$g(x)\f$
102 * @param[out] g_u Upper bounds \f$g^U\f$ for the constraints \f$g(x)\f$
103 *
104 * @return true if success, false otherwise.
105 *
106 * The values of `n` and `m` that were specified in
107 IpoptInterface::get_nlp_info are passed
108 * here for debug checking. Setting a lower bound to a value less than or
109 * equal to the value of the option \ref OPT_nlp_lower_bound_inf
110 "nlp_lower_bound_inf"
111 * will cause %Ipopt to assume no lower bound. Likewise, specifying the upper
112 bound above or
113 * equal to the value of the option \ref OPT_nlp_upper_bound_inf
114 "nlp_upper_bound_inf"
115 * will cause %Ipopt to assume no upper bound. These options are set to
116 -10<sup>19</sup> and
117 * 10<sup>19</sup>, respectively, by default, but may be modified by changing
118 these
119 * options.
120 */
121 virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l,
122 Ipopt::Number* x_u, Ipopt::Index m,
123 Ipopt::Number* g_l, Ipopt::Number* g_u);
124
125 /**
126 * \brief Method to request the starting point before iterating.
127 *
128 * @param[in] n Number of variables \f$x\f$ in the problem; it
129 * will have the same value that was specified in
130 * `IpoptInterface::get_nlp_info`
131 * @param[in] init_x If true, this method must provide an initial value
132 * for \f$x\f$
133 * @param[out] x Initial values for the primal variables \f$x\f$
134 * @param[in] init_z If true, this method must provide an initial value
135 * for the bound multipliers \f$z^L\f$ and \f$z^U\f$
136 * @param[out] z_L Initial values for the bound multipliers \f$z^L\f$
137 * @param[out] z_U Initial values for the bound multipliers \f$z^U\f$
138 * @param[in] m Number of constraints \f$g(x)\f$ in the problem;
139 * it will have the same value that was specified in
140 * `IpoptInterface::get_nlp_info`
141 * @param[in] init_lambda If true, this method must provide an initial value
142 * for the constraint multipliers \f$\lambda\f$
143 * @param[out] lambda Initial values for the constraint multipliers,
144 * \f$\lambda\f$
145 *
146 * @return true if success, false otherwise.
147 *
148 * The boolean variables indicate whether the algorithm requires to have x,
149 * z_L/z_u, and lambda initialized, respectively. If, for some reason, the
150 * algorithm requires initializations that cannot be provided, false should be
151 * returned and %Ipopt will stop. The default options only require initial
152 * values for the primal variables \f$x\f$.
153 *
154 * Note, that the initial values for bound multiplier components for absent
155 * bounds (\f$x^L_i=-\infty\f$ or \f$x^U_i=\infty\f$) are ignored.
156 */
157 // [TNLP_get_starting_point]
158 virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x,
159 bool init_z, Ipopt::Number* z_L,
160 Ipopt::Number* z_U, Ipopt::Index m,
161 bool init_lambda, Ipopt::Number* lambda);
162
163 /**
164 * @brief Method to request the value of the objective function.
165 *
166 * @param[in] n Number of variables \f$x\f$ in the problem; it will
167 * have the same value that was specified in `IpoptInterface::get_nlp_info`
168 * @param[in] x Values for the primal variables \f$x\f$ at which the
169 * objective function \f$f(x)\f$ is to be evaluated
170 * @param[in] new_x False if any evaluation method (`eval_*`) was
171 * previously called with the same values in x, true otherwise. This can be
172 * helpful when users have efficient implementations that calculate multiple
173 * outputs at once. %Ipopt internally caches results from the TNLP and
174 * generally, this flag can be ignored.
175 * @param[out] obj_value Storage for the value of the objective function
176 * \f$f(x)\f$
177 *
178 * @return true if success, false otherwise.
179 */
180 virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
181 Ipopt::Number& obj_value);
182
183 /**
184 * @brief Method to request the gradient of the objective function.
185 *
186 * @param[in] n Number of variables \f$x\f$ in the problem; it will
187 * have the same value that was specified in `IpoptInterface::get_nlp_info`
188 * @param[in] x Values for the primal variables \f$x\f$ at which the
189 * gradient \f$\nabla f(x)\f$ is to be evaluated
190 * @param[in] new_x False if any evaluation method (`eval_*`) was
191 * previously called with the same values in x, true otherwise; see also
192 * `IpoptInterface::eval_f`
193 * @param[out] grad_f Array to store values of the gradient of the objective
194 * function \f$\nabla f(x)\f$. The gradient array is in the same order as the
195 * \f$x\f$ variables (i.e., the gradient of the objective with respect to
196 * `x[2]` should be put in `grad_f[2]`).
197 *
198 * @return true if success, false otherwise.
199 */
200 virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
201 Ipopt::Number* grad_f);
202
203 /**
204 * @brief Method to request the constraint values.
205 *
206 * @param[in] n Number of variables \f$x\f$ in the problem; it will have
207 * the same value that was specified in `IpoptInterface::get_nlp_info`
208 * @param[in] x Values for the primal variables \f$x\f$ at which the
209 * constraint functions \f$g(x)\f$ are to be evaluated
210 * @param[in] new_x False if any evaluation method (`eval_*`) was previously
211 * called with the same values in x, true otherwise; see also
212 * `IpoptInterface::eval_f`
213 * @param[in] m Number of constraints \f$g(x)\f$ in the problem; it will
214 * have the same value that was specified in `IpoptInterface::get_nlp_info`
215 * @param[out] g Array to store constraint function values \f$g(x)\f$, do
216 * not add or subtract the bound values \f$g^L\f$ or \f$g^U\f$.
217 *
218 * @return true if success, false otherwise.
219 */
220 virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
221 Ipopt::Index m, Ipopt::Number* g);
222
223 /**
224 * @brief Method to request either the sparsity structure or the values of the
225 * Jacobian of the constraints.
226 *
227 * The Jacobian is the matrix of derivatives where the derivative of
228 * constraint function \f$g_i\f$ with respect to variable \f$x_j\f$ is placed
229 * in row \f$i\f$ and column \f$j\f$. See \ref TRIPLET for a discussion of the
230 * sparse matrix format used in this method.
231 *
232 * @param[in] n Number of variables \f$x\f$ in the problem; it will
233 * have the same value that was specified in `IpoptInterface::get_nlp_info`
234 * @param[in] x First call: NULL; later calls: the values for the
235 * primal variables \f$x\f$ at which the constraint Jacobian \f$\nabla
236 * g(x)^T\f$ is to be evaluated
237 * @param[in] new_x False if any evaluation method (`eval_*`) was
238 * previously called with the same values in x, true otherwise; see also
239 * `IpoptInterface::eval_f`
240 * @param[in] m Number of constraints \f$g(x)\f$ in the problem; it
241 * will have the same value that was specified in
242 * `IpoptInterface::get_nlp_info`
243 * @param[in] nele_jac Number of nonzero elements in the Jacobian; it will
244 * have the same value that was specified in `IpoptInterface::get_nlp_info`
245 * @param[out] iRow First call: array of length `nele_jac` to store the
246 * row indices of entries in the Jacobian f the constraints; later calls: NULL
247 * @param[out] jCol First call: array of length `nele_jac` to store the
248 * column indices of entries in the acobian of the constraints; later calls:
249 * NULL
250 * @param[out] values First call: NULL; later calls: array of length
251 * nele_jac to store the values of the entries in the Jacobian of the
252 * constraints
253 *
254 * @return true if success, false otherwise.
255 *
256 * @note The arrays iRow and jCol only need to be filled once. If the iRow and
257 * jCol arguments are not NULL (first call to this function), then %Ipopt
258 * expects that the sparsity structure of the Jacobian (the row and column
259 * indices only) are written into iRow and jCol. At this call, the arguments
260 * `x` and `values` will be NULL. If the arguments `x` and `values` are not
261 * NULL, then %Ipopt expects that the value of the Jacobian as calculated from
262 * array `x` is stored in array `values` (using the same order as used when
263 * specifying the sparsity structure). At this call, the arguments `iRow` and
264 * `jCol` will be NULL.
265 */
266 virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
267 Ipopt::Index m, Ipopt::Index nele_jac,
268 Ipopt::Index* iRow, Ipopt::Index* jCol,
269 Ipopt::Number* values);
270
271 /**
272 * @brief Method to request either the sparsity structure or the values of the
273 * Hessian of the Lagrangian.
274 *
275 * The Hessian matrix that %Ipopt uses is
276 * \f[ \sigma_f \nabla^2 f(x_k) + \sum_{i=1}^m\lambda_i\nabla^2 g_i(x_k) \f]
277 * for the given values for \f$x\f$, \f$\sigma_f\f$, and \f$\lambda\f$.
278 * See \ref TRIPLET for a discussion of the sparse matrix format used in this
279 * method.
280 *
281 * @param[in] n Number of variables \f$x\f$ in the problem; it will
282 * have the same value that was specified in `IpoptInterface::get_nlp_info`
283 * @param[in] x First call: NULL; later calls: the values for the
284 * primal variables \f$x\f$ at which the Hessian is to be evaluated
285 * @param[in] new_x False if any evaluation method (`eval_*`) was
286 * previously called with the same values in x, true otherwise; see also
287 * IpoptInterface::eval_f
288 * @param[in] obj_factor Factor \f$\sigma_f\f$ in front of the objective term
289 * in the Hessian
290 * @param[in] m Number of constraints \f$g(x)\f$ in the problem; it
291 * will have the same value that was specified in
292 * `IpoptInterface::get_nlp_info`
293 * @param[in] lambda Values for the constraint multipliers \f$\lambda\f$
294 * at which the Hessian is to be evaluated
295 * @param[in] new_lambda False if any evaluation method was previously called
296 * with the same values in lambda, true otherwise
297 * @param[in] nele_hess Number of nonzero elements in the Hessian; it will
298 * have the same value that was specified in `IpoptInterface::get_nlp_info`
299 * @param[out] iRow First call: array of length nele_hess to store the
300 * row indices of entries in the Hessian; later calls: NULL
301 * @param[out] jCol First call: array of length nele_hess to store the
302 * column indices of entries in the Hessian; later calls: NULL
303 * @param[out] values First call: NULL; later calls: array of length
304 * nele_hess to store the values of the entries in the Hessian
305 *
306 * @return true if success, false otherwise.
307 *
308 * @note The arrays iRow and jCol only need to be filled once. If the iRow and
309 * jCol arguments are not NULL (first call to this function), then %Ipopt
310 * expects that the sparsity structure of the Hessian (the row and column
311 * indices only) are written into iRow and jCol. At this call, the arguments
312 * `x`, `lambda`, and `values` will be NULL. If the arguments `x`, `lambda`,
313 * and `values` are not NULL, then %Ipopt expects that the value of the
314 * Hessian as calculated from arrays `x` and `lambda` are stored in array
315 * `values` (using the same order as used when specifying the sparsity
316 * structure). At this call, the arguments `iRow` and `jCol` will be NULL.
317 *
318 * @attention As this matrix is symmetric, %Ipopt expects that only the lower
319 * diagonal entries are specified.
320 *
321 * A default implementation is provided, in case the user wants to set
322 * quasi-Newton approximations to estimate the second derivatives and doesn't
323 * not need to implement this method.
324 */
325 virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
326 Ipopt::Number obj_factor, Ipopt::Index m,
327 const Ipopt::Number* lambda, bool new_lambda,
328 Ipopt::Index nele_hess, Ipopt::Index* iRow,
329 Ipopt::Index* jCol, Ipopt::Number* values);
330
331 /**
332 * @brief This method is called when the algorithm has finished (successfully
333 * or not) so the TNLP can digest the outcome, e.g., store/write the solution,
334 * if any.
335 *
336 * @param[in] status @parblock gives the status of the algorithm
337 * - SUCCESS: Algorithm terminated successfully at a locally optimal
338 * point, satisfying the convergence tolerances (can be specified
339 * by options).
340 * - MAXITER_EXCEEDED: Maximum number of iterations exceeded (can be
341 * specified by an option).
342 * - CPUTIME_EXCEEDED: Maximum number of CPU seconds exceeded (can be
343 * specified by an option).
344 * - STOP_AT_TINY_STEP: Algorithm proceeds with very little progress.
345 * - STOP_AT_ACCEPTABLE_POINT: Algorithm stopped at a point that was
346 * converged, not to "desired" tolerances, but to "acceptable" tolerances (see
347 * the acceptable-... options).
348 * - LOCAL_INFEASIBILITY: Algorithm converged to a point of local
349 * infeasibility. Problem may be infeasible.
350 * - USER_REQUESTED_STOP: The user call-back function
351 * IpoptInterface::intermediate_callback returned false, i.e., the user code
352 * requested a premature termination of the optimization.
353 * - DIVERGING_ITERATES: It seems that the iterates diverge.
354 * - RESTORATION_FAILURE: Restoration phase failed, algorithm doesn't know
355 * how to proceed.
356 * - ERROR_IN_STEP_COMPUTATION: An unrecoverable error occurred while %Ipopt
357 * tried to compute the search direction.
358 * - INVALID_NUMBER_DETECTED: Algorithm received an invalid number (such as
359 * NaN or Inf) from the NLP; see also option check_derivatives_for_nan_inf).
360 * - INTERNAL_ERROR: An unknown internal error occurred.
361 * @endparblock
362 * @param[in] n Number of variables \f$x\f$ in the problem; it will
363 * have the same value that was specified in `IpoptInterface::get_nlp_info`
364 * @param[in] x Final values for the primal variables
365 * @param[in] z_L Final values for the lower bound multipliers
366 * @param[in] z_U Final values for the upper bound multipliers
367 * @param[in] m Number of constraints \f$g(x)\f$ in the problem; it
368 * will have the same value that was specified in
369 * `IpoptInterface::get_nlp_info`
370 * @param[in] g Final values of the constraint functions
371 * @param[in] lambda Final values of the constraint multipliers
372 * @param[in] obj_value Final value of the objective function
373 * @param[in] ip_data Provided for expert users
374 * @param[in] ip_cq Provided for expert users
375 */
376 virtual void finalize_solution(
377 Ipopt::SolverReturn status, Ipopt::Index n, const Ipopt::Number* x,
378 const Ipopt::Number* z_L, const Ipopt::Number* z_U, Ipopt::Index m,
379 const Ipopt::Number* g, const Ipopt::Number* lambda,
380 Ipopt::Number obj_value, const Ipopt::IpoptData* ip_data,
381 Ipopt::IpoptCalculatedQuantities* ip_cq);
382
383 /**
384 * @brief Intermediate Callback method for the user.
385 *
386 * This method is called once per iteration (during the convergence check),
387 * and can be used to obtain information about the optimization status while
388 * %Ipopt solves the problem, and also to request a premature termination.
389 *
390 * The information provided by the entities in the argument list correspond to
391 * what %Ipopt prints in the iteration summary (see also \ref OUTPUT). Further
392 * information can be obtained from the ip_data and ip_cq objects. The current
393 * iterate and violations of feasibility and optimality can be accessed via
394 * the methods IpoptInterface::get_curr_iterate() and
395 * IpoptInterface::get_curr_violations(). These methods translate values for
396 * the *internal representation* of the problem from `ip_data` and `ip_cq`
397 * objects into the TNLP representation.
398 *
399 * @return If this method returns false, %Ipopt will terminate with the
400 * User_Requested_Stop status.
401 *
402 * It is not required to implement (overload) this method. The default
403 * implementation always returns true.
404 */
405 bool intermediate_callback(
406 Ipopt::AlgorithmMode mode, Ipopt::Index iter, Ipopt::Number obj_value,
407 Ipopt::Number inf_pr, Ipopt::Number inf_du, Ipopt::Number mu,
408 Ipopt::Number d_norm, Ipopt::Number regularization_size,
409 Ipopt::Number alpha_du, Ipopt::Number alpha_pr, Ipopt::Index ls_trials,
410 const Ipopt::IpoptData* ip_data, Ipopt::IpoptCalculatedQuantities* ip_cq);
411
412 /**
413 * @brief Create the data structure to store temporary computations
414 *
415 * @return the IpoptInterface Data
416 */
417 std::shared_ptr<IpoptInterfaceData> createData(const std::size_t nx,
418 const std::size_t ndx,
419 const std::size_t nu);
420
421 void resizeData();
422
423 /**
424 * @brief Return the total number of optimization variables (states and
425 * controls)
426 */
427 std::size_t get_nvar() const;
428
429 /**
430 * @brief Return the total number of constraints in the NLP
431 */
432 std::size_t get_nconst() const;
433
434 /**
435 * @brief Return the state vector
436 */
437 const std::vector<Eigen::VectorXd>& get_xs() const;
438
439 /**
440 * @brief Return the control vector
441 */
442 const std::vector<Eigen::VectorXd>& get_us() const;
443
444 /**
445 * @brief Return the crocoddyl::ShootingProblem to be solved
446 */
447 const std::shared_ptr<crocoddyl::ShootingProblem>& get_problem() const;
448
449 double get_cost() const;
450
451 /**
452 * @brief Modify the state vector
453 */
454 void set_xs(const std::vector<Eigen::VectorXd>& xs);
455
456 /**
457 * @brief Modify the control vector
458 */
459 void set_us(const std::vector<Eigen::VectorXd>& us);
460
461 private:
462 std::shared_ptr<crocoddyl::ShootingProblem>
463 problem_; //!< Optimal control problem
464 std::vector<Eigen::VectorXd> xs_; //!< Vector of states
465 std::vector<Eigen::VectorXd> us_; //!< Vector of controls
466 std::vector<std::size_t> ixu_; //!< Index of at node i
467 std::size_t nvar_; //!< Number of NLP variables
468 std::size_t nconst_; //!< Number of the NLP constraints
469 std::vector<std::shared_ptr<IpoptInterfaceData>> datas_; //!< Vector of Datas
470 double cost_; //!< Total cost
471
472 IpoptInterface(const IpoptInterface&);
473
474 IpoptInterface& operator=(const IpoptInterface&);
475 };
476
477 struct IpoptInterfaceData {
478 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
479
480 IpoptInterfaceData(const std::size_t nx, const std::size_t ndx,
481 const std::size_t nu)
482 : x(nx),
483 xnext(nx),
484 dx(ndx),
485 dxnext(ndx),
486 x_diff(ndx),
487 u(nu),
488 Jint_dx(ndx, ndx),
489 Jint_dxnext(ndx, ndx),
490 Jdiff_x(ndx, ndx),
491 Jdiff_xnext(ndx, ndx),
492 Jg_dx(ndx, ndx),
493 Jg_dxnext(ndx, ndx),
494 Jg_u(ndx, ndx),
495 Jg_ic(ndx, ndx),
496 FxJint_dx(ndx, ndx),
497 Ldx(ndx),
498 Ldxdx(ndx, ndx),
499 Ldxu(ndx, nu) {
500 x.setZero();
501 xnext.setZero();
502 dx.setZero();
503 dxnext.setZero();
504 x_diff.setZero();
505 u.setZero();
506 Jint_dx.setZero();
507 Jint_dxnext.setZero();
508 Jdiff_x.setZero();
509 Jdiff_xnext.setZero();
510 Jg_dx.setZero();
511 Jg_dxnext.setZero();
512 Jg_u.setZero();
513 Jg_ic.setZero();
514 FxJint_dx.setZero();
515 Ldx.setZero();
516 Ldxdx.setZero();
517 Ldxu.setZero();
518 }
519
520 void resize(const std::size_t nx, const std::size_t ndx,
521 const std::size_t nu) {
522 x.conservativeResize(nx);
523 xnext.conservativeResize(nx);
524 dx.conservativeResize(ndx);
525 dxnext.conservativeResize(ndx);
526 x_diff.conservativeResize(ndx);
527 u.conservativeResize(nu);
528 Jint_dx.conservativeResize(ndx, ndx);
529 Jint_dxnext.conservativeResize(ndx, ndx);
530 Jdiff_x.conservativeResize(ndx, ndx);
531 Jdiff_xnext.conservativeResize(ndx, ndx);
532 Jg_dx.conservativeResize(ndx, ndx);
533 Jg_dxnext.conservativeResize(ndx, ndx);
534 Jg_u.conservativeResize(ndx, ndx);
535 Jg_ic.conservativeResize(ndx, ndx);
536 FxJint_dx.conservativeResize(ndx, ndx);
537 Ldx.conservativeResize(ndx);
538 Ldxdx.conservativeResize(ndx, ndx);
539 Ldxu.conservativeResize(ndx, nu);
540 }
541
542 Eigen::VectorXd x; //!< Integrated state
543 Eigen::VectorXd xnext; //!< Integrated state at next node
544 Eigen::VectorXd dx; //!< Increment in the tangent space
545 Eigen::VectorXd dxnext; //!< Increment in the tangent space at next node
546 Eigen::VectorXd x_diff; //!< State difference
547 Eigen::VectorXd u; //!< Control
548 Eigen::MatrixXd Jint_dx; //!< Jacobian of the sum operation w.r.t dx
549 Eigen::MatrixXd
550 Jint_dxnext; //!< Jacobian of the sum operation w.r.t dx at next node
551 Eigen::MatrixXd
552 Jdiff_x; //!< Jacobian of the diff operation w.r.t the first element
553 Eigen::MatrixXd Jdiff_xnext; //!< Jacobian of the diff operation w.r.t the
554 //!< first element at the next node
555 Eigen::MatrixXd Jg_dx; //!< Jacobian of the dynamic constraint w.r.t dx
556 Eigen::MatrixXd
557 Jg_dxnext; //!< Jacobian of the dynamic constraint w.r.t dxnext
558 Eigen::MatrixXd Jg_u; //!< Jacobian of the dynamic constraint w.r.t u
559 Eigen::MatrixXd
560 Jg_ic; //!< Jacobian of the initial condition constraint w.r.t dx
561 Eigen::MatrixXd FxJint_dx; //!< Intermediate computation needed for Jg_ic
562 Eigen::VectorXd Ldx; //!< Jacobian of the cost w.r.t dx
563 Eigen::MatrixXd Ldxdx; //!< Hessian of the cost w.r.t dxdx
564 Eigen::MatrixXd Ldxu; //!< Hessian of the cost w.r.t dxu
565 };
566
567 } // namespace crocoddyl
568
569 #endif
570