11 #ifdef CROCODDYL_WITH_MULTITHREADING
15 #include "crocoddyl/core/solvers/ipopt/ipopt-iface.hpp"
21 const std::size_t T = problem_->get_T();
29 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
30 problem_->get_runningModels();
31 for (std::size_t t = 0; t < T; ++t) {
32 const std::size_t nxi = models[t]->get_state()->get_nx();
33 const std::size_t ndxi = models[t]->get_state()->get_ndx();
34 const std::size_t nui = models[t]->get_nu();
36 xs_[t] = models[t]->get_state()->zero();
37 us_[t] = Eigen::VectorXd::Zero(nui);
38 datas_[t] = createData(nxi, ndxi, nui);
46 nconst_ += models[0]->get_state()->get_ndx();
48 const std::shared_ptr<ActionModelAbstract>& model =
49 problem_->get_terminalModel();
50 const std::size_t nxi = model->get_state()->get_nx();
51 const std::size_t ndxi = model->get_state()->get_ndx();
53 xs_[T] = model->get_state()->zero();
54 datas_[T] = createData(nxi, ndxi, 0);
57 void IpoptInterface::resizeData() {
58 const std::size_t T = problem_->get_T();
60 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
61 problem_->get_runningModels();
62 for (std::size_t t = 0; t < T; ++t) {
63 const std::size_t nxi = models[t]->get_state()->get_nx();
64 const std::size_t ndxi = models[t]->get_state()->get_ndx();
65 const std::size_t nui = models[t]->get_nu();
67 xs_[t].conservativeResize(nxi);
68 us_[t].conservativeResize(nui);
69 datas_[t]->resize(nxi, ndxi, nui);
77 nconst_ += models[0]->get_state()->get_ndx();
79 const std::shared_ptr<ActionModelAbstract>& model =
80 problem_->get_terminalModel();
81 const std::size_t nxi = model->get_state()->get_nx();
82 const std::size_t ndxi = model->get_state()->get_ndx();
84 xs_[T].conservativeResize(nxi);
85 datas_[T]->resize(nxi, ndxi, 0);
88 IpoptInterface::~IpoptInterface() {}
90 bool IpoptInterface::get_nlp_info(Ipopt::Index& n, Ipopt::Index& m,
91 Ipopt::Index& nnz_jac_g,
92 Ipopt::Index& nnz_h_lag,
93 IndexStyleEnum& index_style) {
94 n =
static_cast<Ipopt::Index
>(nvar_);
95 m =
static_cast<Ipopt::Index
>(nconst_);
99 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
100 problem_->get_runningModels();
101 const std::size_t T = problem_->get_T();
102 for (std::size_t t = 0; t < T; ++t) {
103 const std::size_t ndxi = models[t]->get_state()->get_ndx();
104 const std::size_t ndxi_next =
105 t + 1 == T ? problem_->get_terminalModel()->get_state()->get_ndx()
106 : models[t + 1]->get_state()->get_ndx();
107 const std::size_t nui = models[t]->get_nu();
108 nnz_jac_g += ndxi * (ndxi + ndxi_next + nui);
111 std::size_t nonzero = 0;
112 for (std::size_t i = 1; i <= (ndxi + nui); ++i) {
115 nnz_h_lag += nonzero;
120 models[0]->get_state()->get_ndx() * models[0]->get_state()->get_ndx();
123 const std::size_t ndxi =
124 problem_->get_terminalModel()->get_state()->get_ndx();
125 std::size_t nonzero = 0;
126 for (std::size_t i = 1; i <= ndxi; ++i) {
129 nnz_h_lag += nonzero;
132 index_style = Ipopt::TNLP::C_STYLE;
138 bool IpoptInterface::get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l,
139 Ipopt::Number* x_u, Ipopt::Index m,
140 Ipopt::Number* g_l, Ipopt::Number* g_u) {
142 bool IpoptInterface::get_bounds_info(Ipopt::Index, Ipopt::Number* x_l,
143 Ipopt::Number* x_u, Ipopt::Index,
144 Ipopt::Number* g_l, Ipopt::Number* g_u) {
146 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
147 "Inconsistent number of decision variables");
148 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
149 "Inconsistent number of constraints");
152 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
153 problem_->get_runningModels();
154 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
156 const std::size_t ndxi = models[t]->get_state()->get_ndx();
157 const std::size_t nui = models[t]->get_nu();
159 for (std::size_t j = 0; j < ndxi; ++j) {
160 x_l[ixu_[t] + j] = std::numeric_limits<double>::lowest();
161 x_u[ixu_[t] + j] = std::numeric_limits<double>::max();
163 for (std::size_t j = 0; j < nui; ++j) {
164 x_l[ixu_[t] + ndxi + j] = models[t]->get_has_control_limits()
165 ? models[t]->get_u_lb()(j)
166 : std::numeric_limits<double>::lowest();
167 x_u[ixu_[t] + ndxi + j] = models[t]->get_has_control_limits()
168 ? models[t]->get_u_ub()(j)
169 : std::numeric_limits<double>::max();
174 const std::size_t ndxi =
175 problem_->get_terminalModel()->get_state()->get_ndx();
176 for (std::size_t j = 0; j < ndxi; j++) {
177 x_l[ixu_.back() + j] = std::numeric_limits<double>::lowest();
178 x_u[ixu_.back() + j] = std::numeric_limits<double>::max();
182 for (Ipopt::Index i = 0; i < static_cast<Ipopt::Index>(nconst_); ++i) {
191 bool IpoptInterface::get_starting_point(Ipopt::Index n,
bool init_x,
192 Ipopt::Number* x,
bool init_z,
194 Ipopt::Number* , Ipopt::Index m,
198 bool IpoptInterface::get_starting_point(Ipopt::Index,
bool ,
199 Ipopt::Number* x,
bool, Ipopt::Number*,
200 Ipopt::Number*, Ipopt::Index,
bool,
203 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
204 "Inconsistent number of decision variables");
205 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
206 "Inconsistent number of constraints");
207 assert_pretty(init_x ==
true,
208 "Make sure to provide initial value for primal variables");
209 assert_pretty(init_z ==
false,
210 "Cannot provide initial value for bound multipliers");
211 assert_pretty(init_lambda ==
false,
212 "Cannot provide initial value for constraint multipliers");
217 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
218 problem_->get_runningModels();
219 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
220 const std::size_t ndxi = models[t]->get_state()->get_ndx();
221 const std::size_t nui = models[t]->get_nu();
222 for (std::size_t j = 0; j < ndxi; ++j) {
225 for (std::size_t j = 0; j < nui; ++j) {
226 x[ixu_[t] + ndxi + j] = us_[t](j);
229 const std::size_t ndxi =
230 problem_->get_terminalModel()->get_state()->get_ndx();
231 for (std::size_t j = 0; j < ndxi; j++) {
232 x[ixu_.back() + j] = 0;
239 bool IpoptInterface::eval_f(Ipopt::Index n,
const Ipopt::Number* x,
240 bool , Ipopt::Number& obj_value) {
242 bool IpoptInterface::eval_f(Ipopt::Index,
const Ipopt::Number* x,
bool,
243 Ipopt::Number& obj_value) {
245 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
246 "Inconsistent number of decision variables");
249 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
250 problem_->get_runningModels();
251 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
252 problem_->get_runningDatas();
253 const std::size_t T = problem_->get_T();
254 #ifdef CROCODDYL_WITH_MULTITHREADING
255 #pragma omp parallel for num_threads(problem_->get_nthreads())
257 for (std::size_t t = 0; t < T; ++t) {
258 const std::shared_ptr<ActionModelAbstract>& model = models[t];
259 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
260 const std::size_t ndxi = model->get_state()->get_ndx();
261 const std::size_t nui = model->get_nu();
263 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
264 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
265 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
266 model->calc(data, datas_[t]->x, datas_[t]->u);
269 #ifdef CROCODDYL_WITH_MULTITHREADING
270 #pragma omp simd reduction(+ : obj_value)
272 for (std::size_t t = 0; t < T; ++t) {
273 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
274 obj_value += data->cost;
278 const std::shared_ptr<ActionModelAbstract>& model =
279 problem_->get_terminalModel();
280 const std::shared_ptr<ActionDataAbstract>& data =
281 problem_->get_terminalData();
282 const std::size_t ndxi = model->get_state()->get_ndx();
284 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
285 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
286 model->calc(data, datas_[T]->x);
287 obj_value += data->cost;
293 bool IpoptInterface::eval_grad_f(Ipopt::Index n,
const Ipopt::Number* x,
294 bool , Ipopt::Number* grad_f) {
296 bool IpoptInterface::eval_grad_f(Ipopt::Index,
const Ipopt::Number* x,
bool,
297 Ipopt::Number* grad_f) {
299 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
300 "Inconsistent number of decision variables");
302 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
303 problem_->get_runningModels();
304 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
305 problem_->get_runningDatas();
306 const std::size_t T = problem_->get_T();
307 #ifdef CROCODDYL_WITH_MULTITHREADING
308 #pragma omp parallel for num_threads(problem_->get_nthreads())
310 for (std::size_t t = 0; t < T; ++t) {
311 const std::shared_ptr<ActionModelAbstract>& model = models[t];
312 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
313 const std::size_t ndxi = model->get_state()->get_ndx();
314 const std::size_t nui = model->get_nu();
316 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
317 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
318 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
319 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
320 datas_[t]->Jint_dx, second, setto);
321 model->calc(data, datas_[t]->x, datas_[t]->u);
322 model->calcDiff(data, datas_[t]->x, datas_[t]->u);
323 datas_[t]->Ldx.noalias() = datas_[t]->Jint_dx.transpose() * data->Lx;
325 for (std::size_t t = 0; t < T; ++t) {
326 const std::shared_ptr<ActionModelAbstract>& model = models[t];
327 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
328 const std::size_t ndxi = model->get_state()->get_ndx();
329 const std::size_t nui = model->get_nu();
330 for (std::size_t j = 0; j < ndxi; ++j) {
331 grad_f[ixu_[t] + j] = datas_[t]->Ldx(j);
333 for (std::size_t j = 0; j < nui; ++j) {
334 grad_f[ixu_[t] + ndxi + j] = data->Lu(j);
339 const std::shared_ptr<ActionModelAbstract>& model =
340 problem_->get_terminalModel();
341 const std::shared_ptr<ActionDataAbstract>& data =
342 problem_->get_terminalData();
343 const std::size_t ndxi = model->get_state()->get_ndx();
345 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
346 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
347 model->get_state()->Jintegrate(xs_[T], datas_[T]->dx, datas_[T]->Jint_dx,
348 datas_[T]->Jint_dx, second, setto);
349 model->calc(data, datas_[T]->x);
350 model->calcDiff(data, datas_[T]->x);
351 datas_[T]->Ldx.noalias() = datas_[T]->Jint_dx.transpose() * data->Lx;
352 for (std::size_t j = 0; j < ndxi; ++j) {
353 grad_f[ixu_.back() + j] = datas_[T]->Ldx(j);
360 bool IpoptInterface::eval_g(Ipopt::Index n,
const Ipopt::Number* x,
361 bool , Ipopt::Index m, Ipopt::Number* g) {
363 bool IpoptInterface::eval_g(Ipopt::Index,
const Ipopt::Number* x,
364 bool , Ipopt::Index, Ipopt::Number* g) {
366 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
367 "Inconsistent number of decision variables");
368 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
369 "Inconsistent number of constraints");
372 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
373 problem_->get_runningModels();
374 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
375 problem_->get_runningDatas();
376 const std::size_t T = problem_->get_T();
377 #ifdef CROCODDYL_WITH_MULTITHREADING
378 #pragma omp parallel for num_threads(problem_->get_nthreads())
380 for (std::size_t t = 0; t < T; ++t) {
381 const std::shared_ptr<ActionModelAbstract>& model = models[t];
382 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
383 const std::size_t ndxi = model->get_state()->get_ndx();
384 const std::size_t nui = model->get_nu();
385 const std::shared_ptr<ActionModelAbstract>& model_next =
386 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
387 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
389 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
390 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
392 Eigen::VectorXd::Map(x + ixu_[t] + ndxi + nui, ndxi_next);
393 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
394 model_next->get_state()->integrate(xs_[t + 1], datas_[t]->dxnext,
396 model->calc(data, datas_[t]->x, datas_[t]->u);
397 model->get_state()->diff(data->xnext, datas_[t]->xnext, datas_[t]->x_diff);
401 for (std::size_t t = 0; t < T; ++t) {
402 const std::shared_ptr<ActionModelAbstract>& model = models[t];
403 const std::size_t ndxi = model->get_state()->get_ndx();
404 for (std::size_t j = 0; j < ndxi; ++j) {
405 g[ix + j] = datas_[t]->x_diff[j];
411 const std::shared_ptr<ActionModelAbstract>& model = models[0];
412 const std::size_t ndxi = model->get_state()->get_ndx();
413 datas_[0]->dx = Eigen::VectorXd::Map(x, ndxi);
414 model->get_state()->integrate(xs_[0], datas_[0]->dx, datas_[0]->x);
415 model->get_state()->diff(datas_[0]->x, problem_->get_x0(),
417 for (std::size_t j = 0; j < ndxi; j++) {
418 g[ix + j] = datas_[0]->x_diff[j];
425 bool IpoptInterface::eval_jac_g(Ipopt::Index n,
const Ipopt::Number* x,
426 bool , Ipopt::Index m,
427 Ipopt::Index nele_jac, Ipopt::Index* iRow,
428 Ipopt::Index* jCol, Ipopt::Number* values) {
430 bool IpoptInterface::eval_jac_g(Ipopt::Index,
const Ipopt::Number* x,
bool,
431 Ipopt::Index, Ipopt::Index, Ipopt::Index* iRow,
432 Ipopt::Index* jCol, Ipopt::Number* values) {
434 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
435 "Inconsistent number of decision variables");
436 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
437 "Inconsistent number of constraints");
439 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
440 problem_->get_runningModels();
441 if (values == NULL) {
445 const std::size_t T = problem_->get_T();
446 for (std::size_t t = 0; t < T; ++t) {
447 const std::shared_ptr<ActionModelAbstract>& model = models[t];
448 const std::size_t ndxi = model->get_state()->get_ndx();
449 const std::size_t nui = model->get_nu();
450 const std::size_t ndxi_next =
451 t + 1 == T ? problem_->get_terminalModel()->get_state()->get_ndx()
452 : models[t + 1]->get_state()->get_ndx();
453 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
454 for (std::size_t idx_col = 0; idx_col < (ndxi + nui + ndxi_next);
456 iRow[idx] =
static_cast<Ipopt::Index
>(ix + idx_row);
457 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_col);
465 const std::size_t ndxi = models[0]->get_state()->get_ndx();
466 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
467 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
468 iRow[idx] =
static_cast<Ipopt::Index
>(ix + idx_row);
469 jCol[idx] =
static_cast<Ipopt::Index
>(idx_col);
474 assert_pretty(nele_jac ==
static_cast<Ipopt::Index
>(idx),
475 "Number of jacobian elements set does not coincide with the "
476 "total non-zero Jacobian values");
478 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
479 problem_->get_runningDatas();
481 const std::size_t T = problem_->get_T();
482 #ifdef CROCODDYL_WITH_MULTITHREADING
483 #pragma omp parallel for num_threads(problem_->get_nthreads())
485 for (std::size_t t = 0; t < T; ++t) {
486 const std::shared_ptr<ActionModelAbstract>& model = models[t];
487 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
488 const std::shared_ptr<ActionModelAbstract>& model_next =
489 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
490 const std::size_t ndxi = model->get_state()->get_ndx();
491 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
492 const std::size_t nui = model->get_nu();
493 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
494 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
496 Eigen::VectorXd::Map(x + ixu_[t] + ndxi + nui, ndxi_next);
498 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
499 model_next->get_state()->integrate(xs_[t + 1], datas_[t]->dxnext,
501 model->calcDiff(data, datas_[t]->x, datas_[t]->u);
502 model_next->get_state()->Jintegrate(
503 xs_[t + 1], datas_[t]->dxnext, datas_[t]->Jint_dxnext,
504 datas_[t]->Jint_dxnext, second,
506 model->get_state()->Jdiff(
507 data->xnext, datas_[t]->xnext, datas_[t]->Jdiff_x,
508 datas_[t]->Jdiff_xnext,
510 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
511 datas_[t]->Jint_dx, second,
513 datas_[t]->Jg_dxnext.noalias() =
514 datas_[t]->Jdiff_xnext * datas_[t]->Jint_dxnext;
515 datas_[t]->FxJint_dx.noalias() = data->Fx * datas_[t]->Jint_dx;
516 datas_[t]->Jg_dx.noalias() = datas_[t]->Jdiff_x * datas_[t]->FxJint_dx;
517 datas_[t]->Jg_u.noalias() = datas_[t]->Jdiff_x * data->Fu;
520 for (std::size_t t = 0; t < T; ++t) {
521 const std::shared_ptr<ActionModelAbstract>& model = models[t];
522 const std::shared_ptr<ActionModelAbstract>& model_next =
523 t + 1 == T ? problem_->get_terminalModel() : models[t + 1];
524 const std::size_t ndxi = model->get_state()->get_ndx();
525 const std::size_t nui = model->get_nu();
526 const std::size_t ndxi_next = model_next->get_state()->get_ndx();
527 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
528 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
529 values[idx] = datas_[t]->Jg_dx(idx_row, idx_col);
532 for (std::size_t idx_col = 0; idx_col < nui; ++idx_col) {
533 values[idx] = datas_[t]->Jg_u(idx_row, idx_col);
537 for (std::size_t idx_col = 0; idx_col < ndxi_next; ++idx_col) {
538 values[idx] = datas_[t]->Jg_dxnext(idx_row, idx_col);
545 const std::shared_ptr<ActionModelAbstract>& model = models[0];
546 const std::size_t ndxi = model->get_state()->get_ndx();
547 datas_[0]->dx = Eigen::VectorXd::Map(x, ndxi);
549 model->get_state()->integrate(xs_[0], datas_[0]->dx, datas_[0]->x);
550 model->get_state()->Jdiff(datas_[0]->x, problem_->get_x0(),
551 datas_[0]->Jdiff_x, datas_[0]->Jdiff_x, first);
552 model->get_state()->Jintegrate(xs_[0], datas_[0]->dx, datas_[0]->Jint_dx,
553 datas_[0]->Jint_dx, second, setto);
554 datas_[0]->Jg_ic.noalias() = datas_[0]->Jdiff_x * datas_[0]->Jint_dx;
555 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
556 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
557 values[idx] = datas_[0]->Jg_ic(idx_row, idx_col);
567 bool IpoptInterface::eval_h(Ipopt::Index n,
const Ipopt::Number* x,
568 bool , Ipopt::Number obj_factor,
569 Ipopt::Index m,
const Ipopt::Number* ,
570 bool , Ipopt::Index nele_hess,
571 Ipopt::Index* iRow, Ipopt::Index* jCol,
572 Ipopt::Number* values) {
574 bool IpoptInterface::eval_h(Ipopt::Index,
const Ipopt::Number* x,
bool,
575 Ipopt::Number obj_factor, Ipopt::Index,
576 const Ipopt::Number*,
bool, Ipopt::Index,
577 Ipopt::Index* iRow, Ipopt::Index* jCol,
578 Ipopt::Number* values) {
580 assert_pretty(n ==
static_cast<Ipopt::Index
>(nvar_),
581 "Inconsistent number of decision variables");
582 assert_pretty(m ==
static_cast<Ipopt::Index
>(nconst_),
583 "Inconsistent number of constraints");
585 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
586 problem_->get_runningModels();
587 const std::size_t T = problem_->get_T();
588 if (values == NULL) {
594 for (std::size_t t = 0; t < problem_->get_T(); ++t) {
595 const std::shared_ptr<ActionModelAbstract> model = models[t];
596 const std::size_t ndxi = model->get_state()->get_ndx();
597 const std::size_t nui = model->get_nu();
598 for (std::size_t idx_row = 0; idx_row < ndxi + nui; ++idx_row) {
599 for (std::size_t idx_col = 0; idx_col < ndxi + nui; ++idx_col) {
601 if (idx_col > idx_row) {
604 iRow[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_row);
605 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_[t] + idx_col);
612 const std::size_t ndxi =
613 problem_->get_terminalModel()->get_state()->get_ndx();
614 for (std::size_t idx_row = 0; idx_row < ndxi; idx_row++) {
615 for (std::size_t idx_col = 0; idx_col < ndxi; idx_col++) {
617 if (idx_col > idx_row) {
620 iRow[idx] =
static_cast<Ipopt::Index
>(ixu_.back() + idx_row);
621 jCol[idx] =
static_cast<Ipopt::Index
>(ixu_.back() + idx_col);
626 assert_pretty(nele_hess ==
static_cast<Ipopt::Index
>(idx),
627 "Number of Hessian elements set does not coincide with the "
628 "total non-zero Hessian values");
633 const std::vector<std::shared_ptr<ActionDataAbstract> >& datas =
634 problem_->get_runningDatas();
635 #ifdef CROCODDYL_WITH_MULTITHREADING
636 #pragma omp parallel for num_threads(problem_->get_nthreads())
638 for (std::size_t t = 0; t < T; ++t) {
639 const std::shared_ptr<ActionModelAbstract>& model = models[t];
640 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
641 const std::size_t ndxi = model->get_state()->get_ndx();
642 const std::size_t nui = model->get_nu();
643 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
644 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
646 model->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
647 model->calcDiff(data, datas_[t]->x,
649 model->get_state()->Jintegrate(xs_[t], datas_[t]->dx, datas_[t]->Jint_dx,
650 datas_[t]->Jint_dx, second, setto);
651 datas_[t]->Ldxdx.noalias() =
652 datas_[t]->Jint_dx.transpose() * data->Lxx * datas_[t]->Jint_dx;
653 datas_[t]->Ldxu.noalias() = datas_[t]->Jint_dx.transpose() * data->Lxu;
657 for (std::size_t t = 0; t < T; ++t) {
658 const std::shared_ptr<ActionModelAbstract>& model = models[t];
659 const std::shared_ptr<ActionDataAbstract>& data = datas[t];
660 const std::size_t ndxi = model->get_state()->get_ndx();
661 const std::size_t nui = model->get_nu();
662 for (std::size_t idx_row = 0; idx_row < ndxi; ++idx_row) {
663 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
665 if (idx_col > idx_row) {
668 values[idx] = obj_factor * datas_[t]->Ldxdx(idx_row, idx_col);
672 for (std::size_t idx_row = 0; idx_row < nui; ++idx_row) {
673 for (std::size_t idx_col = 0; idx_col < ndxi; ++idx_col) {
674 values[idx] = obj_factor * datas_[t]->Ldxu(idx_col, idx_row);
677 for (std::size_t idx_col = 0; idx_col < nui; ++idx_col) {
678 if (idx_col > idx_row) {
681 values[idx] = obj_factor * data->Luu(idx_row, idx_col);
688 const std::shared_ptr<ActionModelAbstract>& model =
689 problem_->get_terminalModel();
690 const std::shared_ptr<ActionDataAbstract>& data =
691 problem_->get_terminalData();
692 const std::size_t ndxi = model->get_state()->get_ndx();
693 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
695 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
696 model->calc(data, datas_[T]->x);
697 model->calcDiff(data, datas_[T]->x);
698 model->get_state()->Jintegrate(xs_[T], datas_[T]->dx, datas_[T]->Jint_dx,
699 datas_[T]->Jint_dx, second, setto);
700 datas_[T]->Ldxdx.noalias() =
701 datas_[T]->Jint_dx.transpose() * data->Lxx * datas_[T]->Jint_dx;
702 for (std::size_t idx_row = 0; idx_row < ndxi; idx_row++) {
703 for (std::size_t idx_col = 0; idx_col < ndxi; idx_col++) {
705 if (idx_col > idx_row) {
708 values[idx] = datas_[T]->Ldxdx(idx_row, idx_col);
717 void IpoptInterface::finalize_solution(
718 Ipopt::SolverReturn , Ipopt::Index ,
const Ipopt::Number* x,
719 const Ipopt::Number* ,
const Ipopt::Number* ,
720 Ipopt::Index ,
const Ipopt::Number* ,
721 const Ipopt::Number* , Ipopt::Number obj_value,
722 const Ipopt::IpoptData* ,
723 Ipopt::IpoptCalculatedQuantities* ) {
725 const std::vector<std::shared_ptr<ActionModelAbstract> >& models =
726 problem_->get_runningModels();
727 const std::size_t T = problem_->get_T();
728 for (std::size_t t = 0; t < T; ++t) {
729 const std::size_t ndxi = models[t]->get_state()->get_ndx();
730 const std::size_t nui = models[t]->get_nu();
731 datas_[t]->dx = Eigen::VectorXd::Map(x + ixu_[t], ndxi);
732 datas_[t]->u = Eigen::VectorXd::Map(x + ixu_[t] + ndxi, nui);
734 models[t]->get_state()->integrate(xs_[t], datas_[t]->dx, datas_[t]->x);
735 xs_[t] = datas_[t]->x;
736 us_[t] = datas_[t]->u;
739 const std::shared_ptr<ActionModelAbstract>& model =
740 problem_->get_terminalModel();
741 const std::size_t ndxi = model->get_state()->get_ndx();
742 datas_[T]->dx = Eigen::VectorXd::Map(x + ixu_.back(), ndxi);
743 model->get_state()->integrate(xs_[T], datas_[T]->dx, datas_[T]->x);
744 xs_[T] = datas_[T]->x;
749 bool IpoptInterface::intermediate_callback(
750 Ipopt::AlgorithmMode , Ipopt::Index ,
751 Ipopt::Number , Ipopt::Number ,
752 Ipopt::Number , Ipopt::Number , Ipopt::Number ,
753 Ipopt::Number , Ipopt::Number ,
754 Ipopt::Number , Ipopt::Index ,
755 const Ipopt::IpoptData* ,
756 Ipopt::IpoptCalculatedQuantities* ) {
760 std::shared_ptr<IpoptInterfaceData> IpoptInterface::createData(
761 const std::size_t nx,
const std::size_t ndx,
const std::size_t nu) {
762 return std::allocate_shared<IpoptInterfaceData>(
763 Eigen::aligned_allocator<IpoptInterfaceData>(), nx, ndx, nu);
766 void IpoptInterface::set_xs(
const std::vector<Eigen::VectorXd>& xs) {
770 void IpoptInterface::set_us(
const std::vector<Eigen::VectorXd>& us) {
774 std::size_t IpoptInterface::get_nvar()
const {
return nvar_; }
776 std::size_t IpoptInterface::get_nconst()
const {
return nconst_; }
778 const std::vector<Eigen::VectorXd>& IpoptInterface::get_xs()
const {
782 const std::vector<Eigen::VectorXd>& IpoptInterface::get_us()
const {
786 const std::shared_ptr<ShootingProblem>& IpoptInterface::get_problem()
const {
790 double IpoptInterface::get_cost()
const {
return cost_; }
EIGEN_MAKE_ALIGNED_OPERATOR_NEW IpoptInterface(const std::shared_ptr< crocoddyl::ShootingProblem > &problem)
Initialize the Ipopt interface.