9 #include "crocoddyl/core/solvers/ipopt/ipopt-iface.hpp"
17 const std::size_t T = problem_->get_T();
25 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
26 problem_->get_runningModels();
27 for (std::size_t t = 0; t < T; ++t) {
28 const std::size_t nxi = models[t]->get_state()->get_nx();
29 const std::size_t ndxi = models[t]->get_state()->get_ndx();
30 const std::size_t nui = models[t]->get_nu();
32 xs_[t] = models[t]->get_state()->zero();
33 us_[t] = Eigen::VectorXd::Zero(nui);
34 datas_[t] = createData(nxi, ndxi, nui);
42 nconst_ += models[0]->get_state()->get_ndx();
44 const std::shared_ptr<ActionModelAbstract>& model =
45 problem_->get_terminalModel();
46 const std::size_t nxi = model->get_state()->get_nx();
47 const std::size_t ndxi = model->get_state()->get_ndx();
49 xs_[T] = model->get_state()->zero();
50 datas_[T] = createData(nxi, ndxi, 0);
53 void IpoptInterface::resizeData() {
54 const std::size_t T = problem_->get_T();
56 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
57 problem_->get_runningModels();
58 for (std::size_t t = 0; t < T; ++t) {
59 const std::size_t nxi = models[t]->get_state()->get_nx();
60 const std::size_t ndxi = models[t]->get_state()->get_ndx();
61 const std::size_t nui = models[t]->get_nu();
63 xs_[t].conservativeResize(nxi);
64 us_[t].conservativeResize(nui);
65 datas_[t]->resize(nxi, ndxi, nui);
73 nconst_ += models[0]->get_state()->get_ndx();
75 const std::shared_ptr<ActionModelAbstract>& model =
76 problem_->get_terminalModel();
77 const std::size_t nxi = model->get_state()->get_nx();
78 const std::size_t ndxi = model->get_state()->get_ndx();
80 xs_[T].conservativeResize(nxi);
81 datas_[T]->resize(nxi, ndxi, 0);
84 IpoptInterface::~IpoptInterface() {}
86 bool IpoptInterface::get_nlp_info(Ipopt::Index& n, Ipopt::Index& m,
87 Ipopt::Index& nnz_jac_g,
88 Ipopt::Index& nnz_h_lag,
89 IndexStyleEnum& index_style) {
90 n =
static_cast<Ipopt::Index
>(nvar_);
91 m =
static_cast<Ipopt::Index
>(nconst_);
95 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
96 problem_->get_runningModels();
97 const std::size_t T = problem_->get_T();
98 for (std::size_t t = 0; t < T; ++t) {
99 const std::size_t ndxi = models[t]->get_state()->get_ndx();
100 const std::size_t ndxi_next =
101 t + 1 == T ? problem_->get_terminalModel()->get_state()->get_ndx()
102 : models[t + 1]->get_state()->get_ndx();
103 const std::size_t nui = models[t]->get_nu();
104 nnz_jac_g += ndxi * (ndxi + ndxi_next + nui);
107 std::size_t nonzero = 0;
108 for (std::size_t i = 1; i <= (ndxi + nui); ++i) {
111 nnz_h_lag += nonzero;
116 models[0]->get_state()->get_ndx() * models[0]->get_state()->get_ndx();
119 const std::size_t ndxi =
120 problem_->get_terminalModel()->get_state()->get_ndx();
121 std::size_t nonzero = 0;
122 for (std::size_t i = 1; i <= ndxi; ++i) {
125 nnz_h_lag += nonzero;
128 index_style = Ipopt::TNLP::C_STYLE;
134 bool IpoptInterface::get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l,
135 Ipopt::Number* x_u, Ipopt::Index m,
136 Ipopt::Number* g_l, Ipopt::Number* g_u) {
138 bool IpoptInterface::get_bounds_info(Ipopt::Index, Ipopt::Number* x_l,
139 Ipopt::Number* x_u, Ipopt::Index,
140 Ipopt::Number* g_l, Ipopt::Number* g_u) {
142 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
143 "Inconsistent number of decision variables");
144 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
145 "Inconsistent number of constraints");
148 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
149 problem_->get_runningModels();
150 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
152 const std::size_t ndxi = models[t]->get_state()->get_ndx();
153 const std::size_t nui = models[t]->get_nu();
155 for (std::size_t j = 0; j < ndxi; ++j) {
156 x_l[ixu_[t] + j] = std::numeric_limits<double>::lowest();
157 x_u[ixu_[t] + j] = std::numeric_limits<double>::max();
159 for (std::size_t j = 0; j < nui; ++j) {
160 x_l[ixu_[t] + ndxi + j] = models[t]->get_has_control_limits()
161 ? models[t]->get_u_lb()(j)
162 : std::numeric_limits<double>::lowest();
163 x_u[ixu_[t] + ndxi + j] = models[t]->get_has_control_limits()
164 ? models[t]->get_u_ub()(j)
165 : std::numeric_limits<double>::max();
170 const std::size_t ndxi =
171 problem_->get_terminalModel()->get_state()->get_ndx();
172 for (std::size_t j = 0; j < ndxi; j++) {
173 x_l[ixu_.back() + j] = std::numeric_limits<double>::lowest();
174 x_u[ixu_.back() + j] = std::numeric_limits<double>::max();
178 for (Ipopt::Index i = 0; i < static_cast<Ipopt::Index>(nconst_); ++i) {
187 bool IpoptInterface::get_starting_point(Ipopt::Index n,
bool init_x,
188 Ipopt::Number* x,
bool init_z,
190 Ipopt::Number* , Ipopt::Index m,
194 bool IpoptInterface::get_starting_point(Ipopt::Index,
bool ,
195 Ipopt::Number* x,
bool, Ipopt::Number*,
196 Ipopt::Number*, Ipopt::Index,
bool,
199 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
200 "Inconsistent number of decision variables");
201 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
202 "Inconsistent number of constraints");
203 assert_pretty(init_x ==
true,
204 "Make sure to provide initial value for primal variables");
205 assert_pretty(init_z ==
false,
206 "Cannot provide initial value for bound multipliers");
207 assert_pretty(init_lambda ==
false,
208 "Cannot provide initial value for constraint multipliers");
213 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
214 problem_->get_runningModels();
215 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
216 const std::size_t ndxi = models[t]->get_state()->get_ndx();
217 const std::size_t nui = models[t]->get_nu();
218 for (std::size_t j = 0; j < ndxi; ++j) {
221 for (std::size_t j = 0; j < nui; ++j) {
222 x[ixu_[t] + ndxi + j] = us_[t](j);
225 const std::size_t ndxi =
226 problem_->get_terminalModel()->get_state()->get_ndx();
227 for (std::size_t j = 0; j < ndxi; j++) {
228 x[ixu_.back() + j] = 0;
235 bool IpoptInterface::eval_f(Ipopt::Index n,
const Ipopt::Number* x,
236 bool , Ipopt::Number& obj_value) {
238 bool IpoptInterface::eval_f(Ipopt::Index,
const Ipopt::Number* x,
bool,
239 Ipopt::Number& obj_value) {
241 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
242 "Inconsistent number of decision variables");
245 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
246 problem_->get_runningModels();
247 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
248 problem_->get_runningDatas();
249 const std::size_t T = problem_->get_T();
250 #ifdef CROCODDYL_WITH_MULTITHREADING
251 #pragma omp parallel for num_threads(problem_->get_nthreads())
253 for (std::size_t t = 0; t < T; ++t) {
254 const std::shared_ptr<ActionModelAbstract>& model = models[t];
255 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
256 const std::size_t ndxi = model->get_state()->get_ndx();
257 const std::size_t nui = model->get_nu();
259 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
260 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
261 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
262 model->calc(data, datas_[t]->x, datas_[t]->u);
265 #ifdef CROCODDYL_WITH_MULTITHREADING
266 #pragma omp simd reduction(+ : obj_value)
268 for (std::size_t t = 0; t < T; ++t) {
269 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
270 obj_value += data->cost;
274 const std::shared_ptr<ActionModelAbstract>& model =
275 problem_->get_terminalModel();
276 const std::shared_ptr<ActionDataAbstract>& data =
277 problem_->get_terminalData();
278 const std::size_t ndxi = model->get_state()->get_ndx();
280 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
281 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
282 model->calc(data, datas_[T]->x);
283 obj_value += data->cost;
289 bool IpoptInterface::eval_grad_f(Ipopt::Index n,
const Ipopt::Number* x,
290 bool , Ipopt::Number* grad_f) {
292 bool IpoptInterface::eval_grad_f(Ipopt::Index,
const Ipopt::Number* x,
bool,
293 Ipopt::Number* grad_f) {
295 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
296 "Inconsistent number of decision variables");
298 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
299 problem_->get_runningModels();
300 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
301 problem_->get_runningDatas();
302 const std::size_t T = problem_->get_T();
303 #ifdef CROCODDYL_WITH_MULTITHREADING
304 #pragma omp parallel for num_threads(problem_->get_nthreads())
306 for (std::size_t t = 0; t < T; ++t) {
307 const std::shared_ptr<ActionModelAbstract>& model = models[t];
308 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
309 const std::size_t ndxi = model->get_state()->get_ndx();
310 const std::size_t nui = model->get_nu();
312 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
313 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
314 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
315 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
316 datas_[t]->Jint_dx, second, setto);
317 model->calc(data, datas_[t]->x, datas_[t]->u);
318 model->calcDiff(data, datas_[t]->x, datas_[t]->u);
319 datas_[t]->Ldx.noalias() = datas_[t]->Jint_dx.transpose() * data->Lx;
321 for (std::size_t t = 0; t < T; ++t) {
322 const std::shared_ptr<ActionModelAbstract>& model = models[t];
323 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
324 const std::size_t ndxi = model->get_state()->get_ndx();
325 const std::size_t nui = model->get_nu();
326 for (std::size_t j = 0; j < ndxi; ++j) {
327 grad_f[ixu_[t] + j] = datas_[t]->Ldx(j);
329 for (std::size_t j = 0; j < nui; ++j) {
330 grad_f[ixu_[t] + ndxi + j] = data->Lu(j);
335 const std::shared_ptr<ActionModelAbstract>& model =
336 problem_->get_terminalModel();
337 const std::shared_ptr<ActionDataAbstract>& data =
338 problem_->get_terminalData();
339 const std::size_t ndxi = model->get_state()->get_ndx();
341 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
342 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
343 model->get_state()->Jintegrate(xs_[T], datas_[T]->dx, datas_[T]->Jint_dx,
344 datas_[T]->Jint_dx, second, setto);
345 model->calc(data, datas_[T]->x);
346 model->calcDiff(data, datas_[T]->x);
347 datas_[T]->Ldx.noalias() = datas_[T]->Jint_dx.transpose() * data->Lx;
348 for (std::size_t j = 0; j < ndxi; ++j) {
349 grad_f[ixu_.back() + j] = datas_[T]->Ldx(j);
356 bool IpoptInterface::eval_g(Ipopt::Index n,
const Ipopt::Number* x,
357 bool , Ipopt::Index m, Ipopt::Number* g) {
359 bool IpoptInterface::eval_g(Ipopt::Index,
const Ipopt::Number* x,
360 bool , Ipopt::Index, Ipopt::Number* g) {
362 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
363 "Inconsistent number of decision variables");
364 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
365 "Inconsistent number of constraints");
368 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
369 problem_->get_runningModels();
370 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
371 problem_->get_runningDatas();
372 const std::size_t T = problem_->get_T();
373 #ifdef CROCODDYL_WITH_MULTITHREADING
374 #pragma omp parallel for num_threads(problem_->get_nthreads())
376 for (std::size_t t = 0; t < T; ++t) {
377 const std::shared_ptr<ActionModelAbstract>& model = models[t];
378 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
379 const std::size_t ndxi = model->get_state()->get_ndx();
380 const std::size_t nui = model->get_nu();
381 const std::shared_ptr<ActionModelAbstract>& model_next =
382 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
383 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
385 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
386 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
388 Eigen::VectorXd::Map(x + ixu_[t] + ndxi + nui, ndxi_next);
389 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
390 model_next->get_state()->integrate(xs_[t + 1], datas_[t]->dxnext,
392 model->calc(data, datas_[t]->x, datas_[t]->u);
393 model->get_state()->diff(data->xnext, datas_[t]->xnext, datas_[t]->x_diff);
397 for (std::size_t t = 0; t < T; ++t) {
398 const std::shared_ptr<ActionModelAbstract>& model = models[t];
399 const std::size_t ndxi = model->get_state()->get_ndx();
400 for (std::size_t j = 0; j < ndxi; ++j) {
401 g[ix + j] = datas_[t]->x_diff[j];
407 const std::shared_ptr<ActionModelAbstract>& model = models[0];
408 const std::size_t ndxi = model->get_state()->get_ndx();
409 datas_[0]->dx = Eigen::VectorXd::Map(x, ndxi);
410 model->get_state()->integrate(xs_[0], datas_[0]->dx, datas_[0]->x);
411 model->get_state()->diff(datas_[0]->x, problem_->get_x0(),
413 for (std::size_t j = 0; j < ndxi; j++) {
414 g[ix + j] = datas_[0]->x_diff[j];
421 bool IpoptInterface::eval_jac_g(Ipopt::Index n,
const Ipopt::Number* x,
422 bool , Ipopt::Index m,
423 Ipopt::Index nele_jac, Ipopt::Index* iRow,
424 Ipopt::Index* jCol, Ipopt::Number* values) {
426 bool IpoptInterface::eval_jac_g(Ipopt::Index,
const Ipopt::Number* x,
bool,
427 Ipopt::Index, Ipopt::Index, Ipopt::Index* iRow,
428 Ipopt::Index* jCol, Ipopt::Number* values) {
430 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
431 "Inconsistent number of decision variables");
432 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
433 "Inconsistent number of constraints");
435 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
436 problem_->get_runningModels();
437 if (values == NULL) {
441 const std::size_t T = problem_->get_T();
442 for (std::size_t t = 0; t < T; ++t) {
443 const std::shared_ptr<ActionModelAbstract>& model = models[t];
444 const std::size_t ndxi = model->get_state()->get_ndx();
445 const std::size_t nui = model->get_nu();
446 const std::size_t ndxi_next =
447 t + 1 == T ? problem_->get_terminalModel()->get_state()->get_ndx()
448 : models[t + 1]->get_state()->get_ndx();
449 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
450 for (std::size_t idx_col = 0; idx_col < (ndxi + nui + ndxi_next);
452 iRow[idx] =
static_cast<Ipopt::Index
>(ix + idx_row);
453 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_col);
461 const std::size_t ndxi = models[0]->get_state()->get_ndx();
462 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
463 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
464 iRow[idx] =
static_cast<Ipopt::Index
>(ix + idx_row);
465 jCol[idx] =
static_cast<Ipopt::Index
>(idx_col);
470 assert_pretty(nele_jac ==
static_cast<Ipopt::Index
>(idx),
471 "Number of jacobian elements set does not coincide with the "
472 "total non-zero Jacobian values");
474 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
475 problem_->get_runningDatas();
477 const std::size_t T = problem_->get_T();
478 #ifdef CROCODDYL_WITH_MULTITHREADING
479 #pragma omp parallel for num_threads(problem_->get_nthreads())
481 for (std::size_t t = 0; t < T; ++t) {
482 const std::shared_ptr<ActionModelAbstract>& model = models[t];
483 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
484 const std::shared_ptr<ActionModelAbstract>& model_next =
485 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
486 const std::size_t ndxi = model->get_state()->get_ndx();
487 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
488 const std::size_t nui = model->get_nu();
489 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
490 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
492 Eigen::VectorXd::Map(x + ixu_[t] + ndxi + nui, ndxi_next);
494 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
495 model_next->get_state()->integrate(xs_[t + 1], datas_[t]->dxnext,
497 model->calcDiff(data, datas_[t]->x, datas_[t]->u);
498 model_next->get_state()->Jintegrate(
499 xs_[t + 1], datas_[t]->dxnext, datas_[t]->Jint_dxnext,
500 datas_[t]->Jint_dxnext, second,
502 model->get_state()->Jdiff(
503 data->xnext, datas_[t]->xnext, datas_[t]->Jdiff_x,
504 datas_[t]->Jdiff_xnext,
506 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
507 datas_[t]->Jint_dx, second,
509 datas_[t]->Jg_dxnext.noalias() =
510 datas_[t]->Jdiff_xnext * datas_[t]->Jint_dxnext;
511 datas_[t]->FxJint_dx.noalias() = data->Fx * datas_[t]->Jint_dx;
512 datas_[t]->Jg_dx.noalias() = datas_[t]->Jdiff_x * datas_[t]->FxJint_dx;
513 datas_[t]->Jg_u.noalias() = datas_[t]->Jdiff_x * data->Fu;
516 for (std::size_t t = 0; t < T; ++t) {
517 const std::shared_ptr<ActionModelAbstract>& model = models[t];
518 const std::shared_ptr<ActionModelAbstract>& model_next =
519 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
520 const std::size_t ndxi = model->get_state()->get_ndx();
521 const std::size_t nui = model->get_nu();
522 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
523 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
524 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
525 values[idx] = datas_[t]->Jg_dx(idx_row, idx_col);
528 for (std::size_t idx_col = 0; idx_col < nui; ++idx_col) {
529 values[idx] = datas_[t]->Jg_u(idx_row, idx_col);
533 for (std::size_t idx_col = 0; idx_col < ndxi_next; ++idx_col) {
534 values[idx] = datas_[t]->Jg_dxnext(idx_row, idx_col);
541 const std::shared_ptr<ActionModelAbstract>& model = models[0];
542 const std::size_t ndxi = model->get_state()->get_ndx();
543 datas_[0]->dx = Eigen::VectorXd::Map(x, ndxi);
545 model->get_state()->integrate(xs_[0], datas_[0]->dx, datas_[0]->x);
546 model->get_state()->Jdiff(datas_[0]->x, problem_->get_x0(),
547 datas_[0]->Jdiff_x, datas_[0]->Jdiff_x, first);
548 model->get_state()->Jintegrate(xs_[0], datas_[0]->dx, datas_[0]->Jint_dx,
549 datas_[0]->Jint_dx, second, setto);
550 datas_[0]->Jg_ic.noalias() = datas_[0]->Jdiff_x * datas_[0]->Jint_dx;
551 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
552 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
553 values[idx] = datas_[0]->Jg_ic(idx_row, idx_col);
563 bool IpoptInterface::eval_h(Ipopt::Index n,
const Ipopt::Number* x,
564 bool , Ipopt::Number obj_factor,
565 Ipopt::Index m,
const Ipopt::Number* ,
566 bool , Ipopt::Index nele_hess,
567 Ipopt::Index* iRow, Ipopt::Index* jCol,
568 Ipopt::Number* values) {
570 bool IpoptInterface::eval_h(Ipopt::Index,
const Ipopt::Number* x,
bool,
571 Ipopt::Number obj_factor, Ipopt::Index,
572 const Ipopt::Number*,
bool, Ipopt::Index,
573 Ipopt::Index* iRow, Ipopt::Index* jCol,
574 Ipopt::Number* values) {
576 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
577 "Inconsistent number of decision variables");
578 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
579 "Inconsistent number of constraints");
581 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
582 problem_->get_runningModels();
583 const std::size_t T = problem_->get_T();
584 if (values == NULL) {
590 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
591 const std::shared_ptr<ActionModelAbstract> model = models[t];
592 const std::size_t ndxi = model->get_state()->get_ndx();
593 const std::size_t nui = model->get_nu();
594 for (std::size_t idx_row = 0; idx_row < ndxi + nui; ++idx_row) {
595 for (std::size_t idx_col = 0; idx_col < ndxi + nui; ++idx_col) {
597 if (idx_col > idx_row) {
600 iRow[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_row);
601 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_col);
608 const std::size_t ndxi =
609 problem_->get_terminalModel()->get_state()->get_ndx();
610 for (std::size_t idx_row = 0; idx_row < ndxi; idx_row++) {
611 for (std::size_t idx_col = 0; idx_col < ndxi; idx_col++) {
613 if (idx_col > idx_row) {
616 iRow[idx] =
static_cast<Ipopt::Index
>(ixu_.back() + idx_row);
617 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_.back() + idx_col);
622 assert_pretty(nele_hess ==
static_cast<Ipopt::Index
>(idx),
623 "Number of Hessian elements set does not coincide with the "
624 "total non-zero Hessian values");
629 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
630 problem_->get_runningDatas();
631 #ifdef CROCODDYL_WITH_MULTITHREADING
632 #pragma omp parallel for num_threads(problem_->get_nthreads())
634 for (std::size_t t = 0; t < T; ++t) {
635 const std::shared_ptr<ActionModelAbstract>& model = models[t];
636 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
637 const std::size_t ndxi = model->get_state()->get_ndx();
638 const std::size_t nui = model->get_nu();
639 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
640 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
642 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
643 model->calcDiff(data, datas_[t]->x,
645 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
646 datas_[t]->Jint_dx, second, setto);
647 datas_[t]->Ldxdx.noalias() =
648 datas_[t]->Jint_dx.transpose() * data->Lxx * datas_[t]->Jint_dx;
649 datas_[t]->Ldxu.noalias() = datas_[t]->Jint_dx.transpose() * data->Lxu;
653 for (std::size_t t = 0; t < T; ++t) {
654 const std::shared_ptr<ActionModelAbstract>& model = models[t];
655 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
656 const std::size_t ndxi = model->get_state()->get_ndx();
657 const std::size_t nui = model->get_nu();
658 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
659 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
661 if (idx_col > idx_row) {
664 values[idx] = obj_factor * datas_[t]->Ldxdx(idx_row, idx_col);
668 for (std::size_t idx_row = 0; idx_row < nui; ++idx_row) {
669 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
670 values[idx] = obj_factor * datas_[t]->Ldxu(idx_col, idx_row);
673 for (std::size_t idx_col = 0; idx_col < nui; ++idx_col) {
674 if (idx_col > idx_row) {
677 values[idx] = obj_factor * data->Luu(idx_row, idx_col);
684 const std::shared_ptr<ActionModelAbstract>& model =
685 problem_->get_terminalModel();
686 const std::shared_ptr<ActionDataAbstract>& data =
687 problem_->get_terminalData();
688 const std::size_t ndxi = model->get_state()->get_ndx();
689 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
691 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
692 model->calc(data, datas_[T]->x);
693 model->calcDiff(data, datas_[T]->x);
694 model->get_state()->Jintegrate(xs_[T], datas_[T]->dx, datas_[T]->Jint_dx,
695 datas_[T]->Jint_dx, second, setto);
696 datas_[T]->Ldxdx.noalias() =
697 datas_[T]->Jint_dx.transpose() * data->Lxx * datas_[T]->Jint_dx;
698 for (std::size_t idx_row = 0; idx_row < ndxi; idx_row++) {
699 for (std::size_t idx_col = 0; idx_col < ndxi; idx_col++) {
701 if (idx_col > idx_row) {
704 values[idx] = datas_[T]->Ldxdx(idx_row, idx_col);
713 void IpoptInterface::finalize_solution(
714 Ipopt::SolverReturn , Ipopt::Index ,
const Ipopt::Number* x,
715 const Ipopt::Number* ,
const Ipopt::Number* ,
716 Ipopt::Index ,
const Ipopt::Number* ,
717 const Ipopt::Number* , Ipopt::Number obj_value,
718 const Ipopt::IpoptData* ,
719 Ipopt::IpoptCalculatedQuantities* ) {
721 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
722 problem_->get_runningModels();
723 const std::size_t T = problem_->get_T();
724 for (std::size_t t = 0; t < T; ++t) {
725 const std::size_t ndxi = models[t]->get_state()->get_ndx();
726 const std::size_t nui = models[t]->get_nu();
727 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
728 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
730 models[t]->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
731 xs_[t] = datas_[t]->x;
732 us_[t] = datas_[t]->u;
735 const std::shared_ptr<ActionModelAbstract>& model =
736 problem_->get_terminalModel();
737 const std::size_t ndxi = model->get_state()->get_ndx();
738 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
739 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
740 xs_[T] = datas_[T]->x;
745 bool IpoptInterface::intermediate_callback(
746 Ipopt::AlgorithmMode , Ipopt::Index ,
747 Ipopt::Number , Ipopt::Number ,
748 Ipopt::Number , Ipopt::Number , Ipopt::Number ,
749 Ipopt::Number , Ipopt::Number ,
750 Ipopt::Number , Ipopt::Index ,
751 const Ipopt::IpoptData* ,
752 Ipopt::IpoptCalculatedQuantities* ) {
756 std::shared_ptr<IpoptInterfaceData> IpoptInterface::createData(
757 const std::size_t nx,
const std::size_t ndx,
const std::size_t nu) {
758 return std::allocate_shared<IpoptInterfaceData>(
759 Eigen::aligned_allocator<IpoptInterfaceData>(), nx, ndx, nu);
762 void IpoptInterface::set_xs(
const std::vector<Eigen::VectorXd>& xs) {
766 void IpoptInterface::set_us(
const std::vector<Eigen::VectorXd>& us) {
770 std::size_t IpoptInterface::get_nvar()
const {
return nvar_; }
772 std::size_t IpoptInterface::get_nconst()
const {
return nconst_; }
774 const std::vector<Eigen::VectorXd>& IpoptInterface::get_xs()
const {
778 const std::vector<Eigen::VectorXd>& IpoptInterface::get_us()
const {
782 const std::shared_ptr<ShootingProblem>& IpoptInterface::get_problem()
const {
786 double IpoptInterface::get_cost()
const {
return cost_; }
EIGEN_MAKE_ALIGNED_OPERATOR_NEW IpoptInterface(const std::shared_ptr< crocoddyl::ShootingProblem > &problem)
Initialize the Ipopt interface.