30 void casadi_hpipm_mproject(T1 factor,
const T1* x,
const casadi_int* sp_x,
31 T1* y,
const casadi_int* sp_y, T1* w) {
33 const casadi_int* colind_y;
36 casadi_project(x, sp_x, y, sp_y, w);
37 casadi_scal(colind_y[ncol_y], factor, y);
42 void casadi_hpipm_dense_transfer(
double factor,
const T1* x,
43 const casadi_int* sp_x, T1* y,
44 const casadi_int* sp_y, T1* w) {
45 casadi_sparsify(x, w, sp_x, 0);
46 casadi_int nrow_y = sp_y[0];
47 casadi_int ncol_y = sp_y[1];
48 const casadi_int *colind_y = sp_y+2, *row_y = sp_y + 2 + ncol_y+1;
51 for (i=0; i<ncol_y; ++i) {
52 for (el=colind_y[i]; el<colind_y[i+1]; ++el) y[nrow_y*i + row_y[el]] += factor*(*w++);
66 inline void casadi_hpipm_unpack_blocks(casadi_int N,
casadi_hpipm_block* blocks,
const casadi_int* packed) {
71 blocks[i].
rows = *packed++;
72 blocks[i].
cols = *packed++;
78 void casadi_hpipm_ptr_block(casadi_int N, T1** vs, T1* v,
const casadi_hpipm_block* blocks,
int eye) {
79 casadi_int k, offset = 0;
83 offset += blocks[k].
rows;
85 offset += blocks[k].
rows*blocks[k].
cols;
123 template<
typename T1>
139 template<
typename T1>
180 template<
typename T1>
181 void casadi_hpipm_work(
const casadi_hpipm_prob<T1>* p, casadi_int* sz_arg, casadi_int* sz_res, casadi_int* sz_iw, casadi_int* sz_w) {
182 casadi_qp_work(p->
qp, sz_arg, sz_res, sz_iw, sz_w);
185 *sz_w = casadi_max(*sz_w, 2*(p->
qp->nx+p->
qp->na));
220 *sz_w += casadi_sp_nnz(p->
Asp);
221 *sz_w += casadi_sp_nnz(p->
Bsp);
222 *sz_w += casadi_sp_nnz(p->
Csp);
223 *sz_w += casadi_sp_nnz(p->
Dsp);
224 *sz_w += casadi_sp_nnz(p->
Rsp);
225 *sz_w += casadi_sp_nnz(p->
Isp);
226 *sz_w += casadi_sp_nnz(p->
Ssp);
227 *sz_w += casadi_sp_nnz(p->
Qsp);
228 *sz_w += casadi_sp_nnz(p->
bsp);
229 *sz_w += casadi_sp_nnz(p->
bsp);
230 *sz_w += casadi_sp_nnz(p->
xsp);
231 *sz_w += casadi_sp_nnz(p->
xsp);
232 *sz_w += casadi_sp_nnz(p->
usp);
233 *sz_w += casadi_sp_nnz(p->
usp);
234 *sz_w += casadi_sp_nnz(p->
lugsp);
235 *sz_w += casadi_sp_nnz(p->
lugsp);
236 *sz_w += casadi_sp_nnz(p->
pisp);
249 template<
typename T1>
250 void casadi_hpipm_set_work(
casadi_hpipm_data<T1>* d,
const T1*** arg, T1*** res, casadi_int** iw, T1** w) {
252 casadi_int offset, i, k;
256 d->
hA = *res; *res += p->
N;
257 d->
hB = *res; *res += p->
N;
258 d->
hC = *res; *res += p->
N + 1;
259 d->
hD = *res; *res += p->
N + 1;
260 d->
hR = *res; *res += p->
N + 1;
261 d->
hI = *res; *res += p->
N;
262 d->
hS = *res; *res += p->
N + 1;
263 d->
hQ = *res; *res += p->
N + 1;
264 d->
hx = *res; *res += p->
N + 1;
265 d->
hq = *res; *res += p->
N + 1;
266 d->
hu = *res; *res += p->
N + 1;
267 d->
hr = *res; *res += p->
N + 1;
268 d->
hlg = *res; *res += p->
N + 1;
269 d->
hug = *res; *res += p->
N + 1;
270 d->
hb = *res; *res += p->
N;
271 d->
pis = *res; *res += p->
N;
272 d->
hlbx = *res; *res += p->
N+1;
273 d->
hubx = *res; *res += p->
N+1;
274 d->
hlbu = *res; *res += p->
N+1;
275 d->
hubu = *res; *res += p->
N+1;
276 d->
lams = *res; *res += p->
N+1;
277 d->
hidxbx =
reinterpret_cast<int**
>(*res); *res += p->
N+1;
278 d->
hidxbu =
reinterpret_cast<int**
>(*res); *res += p->
N+1;
279 d->
hidxs =
reinterpret_cast<int**
>(*res); *res += p->
N+1;
281 d->
hZl = *res; *res += p->
N+1;
282 d->
hZu = *res; *res += p->
N+1;
283 d->
hzl = *res; *res += p->
N+1;
284 d->
hzu = *res; *res += p->
N+1;
285 d->
hlls = *res; *res += p->
N+1;
286 d->
hlus = *res; *res += p->
N+1;
288 d->
A = *w; *w += casadi_sp_nnz(p->
Asp);
289 d->
B = *w; *w += casadi_sp_nnz(p->
Bsp);
290 d->
C = *w; *w += casadi_sp_nnz(p->
Csp);
291 d->
D = *w; *w += casadi_sp_nnz(p->
Dsp);
292 d->
R = *w; *w += casadi_sp_nnz(p->
Rsp);
293 d->
I = *w; *w += casadi_sp_nnz(p->
Isp);
294 d->
S = *w; *w += casadi_sp_nnz(p->
Ssp);
295 d->
Q = *w; *w += casadi_sp_nnz(p->
Qsp);
296 d->
b = *w; *w += casadi_sp_nnz(p->
bsp);
297 d->
b2 = *w; *w += casadi_sp_nnz(p->
bsp);
298 d->
x = *w; *w += casadi_sp_nnz(p->
xsp);
299 d->
q = *w; *w += casadi_sp_nnz(p->
xsp);
300 d->
u = *w; *w += casadi_sp_nnz(p->
usp);
301 d->
r = *w; *w += casadi_sp_nnz(p->
usp);
302 d->
lg = *w; *w += casadi_sp_nnz(p->
lugsp);
303 d->
ug = *w; *w += casadi_sp_nnz(p->
lugsp);
304 d->
pi = *w; *w += casadi_sp_nnz(p->
pisp);
317 casadi_hpipm_ptr_block(p->
N, d->
hA, d->
A, p->
A, 0);
318 casadi_hpipm_ptr_block(p->
N, d->
hB, d->
B, p->
B, 0);
319 casadi_hpipm_ptr_block(p->
N+1, d->
hC, d->
C, p->
C, 0);
320 casadi_hpipm_ptr_block(p->
N+1, d->
hD, d->
D, p->
D, 0);
321 casadi_hpipm_ptr_block(p->
N+1, d->
hR, d->
R, p->
R, 0);
322 casadi_hpipm_ptr_block(p->
N, d->
hI, d->
I, p->
I, 1);
323 casadi_hpipm_ptr_block(p->
N+1, d->
hS, d->
S, p->
S, 0);
324 casadi_hpipm_ptr_block(p->
N+1, d->
hQ, d->
Q, p->
Q, 0);
325 casadi_hpipm_ptr_block(p->
N+1, d->
hx, d->
x, p->
x, 0);
326 casadi_hpipm_ptr_block(p->
N+1, d->
hq, d->
q, p->
x, 0);
327 casadi_hpipm_ptr_block(p->
N+1, d->
hu, d->
u, p->
u, 0);
328 casadi_hpipm_ptr_block(p->
N+1, d->
hr, d->
r, p->
u, 0);
329 casadi_hpipm_ptr_block(p->
N+1, d->
hlg, d->
lg, p->
lug, 0);
330 casadi_hpipm_ptr_block(p->
N+1, d->
hug, d->
ug, p->
lug, 0);
331 casadi_hpipm_ptr_block(p->
N, d->
hb, d->
b, p->
b, 0);
334 for(i=0;i<p->
N+1;++i) d->
hZl[i] = 0;
335 for(i=0;i<p->N+1;++i) d->
hZu[i] = 0;
336 for(i=0;i<p->
N+1;++i) d->
hzl[i] = 0;
337 for(i=0;i<p->N+1;++i) d->
hzu[i] = 0;
338 for(i=0;i<p->
N+1;++i) d->
hlls[i] = 0;
339 for(i=0;i<p->N+1;++i) d->
hlus[i] = 0;
342 for (k=0;k<p->
N;++k) {
343 d->
pis[k] = d->
pi+offset;
344 offset += p->
nx[k+1];
348 for (k=0;k<p->
N+1;++k) {
354 for (k=0;k<p->
N+1;++k) {
360 for (k=0;k<p->
N+1;++k) {
362 for (i=0;i<p->
nbx[k];++i) d->
hidxbx[k][i] = i;
366 for (k=0;k<p->
N+1;++k) {
368 for (i=0;i<p->
nbu[k];++i) d->
hidxbu[k][i] = i;
376 template<
typename T1>
377 int casadi_hpipm_solve(
casadi_hpipm_data<T1>* d,
const double** arg,
double** res, casadi_int* iw,
double* w) {
378 casadi_int k, i, j, n_row, offset;
384 int dim_size = d_ocp_qp_dim_memsize(p->
N);
385 void *dim_mem = malloc(dim_size);
387 struct d_ocp_qp_dim dim;
388 d_ocp_qp_dim_create(p->
N, &dim, dim_mem);
390 d_ocp_qp_dim_set_all(
const_cast<int*
>(p->
nx),
const_cast<int*
>(p->
nu),
const_cast<int*
>(p->
nbx),
const_cast<int*
>(p->
nbu),
391 const_cast<int*
>(p->
ng),
const_cast<int*
>(p->
nsbx),
const_cast<int*
>(p->
nsbu),
const_cast<int*
>(p->
nsg), &dim);
393 int qp_size = d_ocp_qp_memsize(&dim);
394 void *qp_mem = malloc(qp_size);
397 d_ocp_qp_create(&dim, &qp, qp_mem);
400 casadi_project(d_qp->
a, p_qp->
sp_a, d->
A, p->
Asp, d->
pv);
401 casadi_project(d_qp->
a, p_qp->
sp_a, d->
B, p->
Bsp, d->
pv);
402 casadi_project(d_qp->
a, p_qp->
sp_a, d->
C, p->
Csp, d->
pv);
403 casadi_project(d_qp->
a, p_qp->
sp_a, d->
D, p->
Dsp, d->
pv);
404 casadi_project(d_qp->
a, p_qp->
sp_a, d->
I, p->
Isp, d->
pv);
407 casadi_hpipm_mproject(0.5, d_qp->
h, p_qp->
sp_h, d->
R, p->
Rsp, d->
pv);
408 casadi_hpipm_mproject(0.5, d_qp->
h, p_qp->
sp_h, d->
S, p->
Ssp, d->
pv);
409 casadi_hpipm_mproject(0.5, d_qp->
h, p_qp->
sp_h, d->
Q, p->
Qsp, d->
pv);
412 casadi_hpipm_mproject(-1.0, d_qp->
lba, p->
sp_ba, d->
b, p->
bsp, d->
pv);
413 casadi_hpipm_mproject(-1.0, d_qp->
uba, p->
sp_ba, d->
b2, p->
bsp, d->
pv);
430 casadi_hpipm_mproject(0.5, d_qp->
g, p->
sp_x, d->
r, p->
usp, d->
pv);
431 casadi_hpipm_mproject(0.5, d_qp->
g, p->
sp_x, d->
q, p->
xsp, d->
pv);
440 for (k=0;k<p->
N;++k) {
442 for (i=0;i<n_row;++i) {
445 for (j=0;j<p->
nx[k];++j) d->
hA[k][i+j*n_row]*=f;
446 for (j=0;j<p->
nu[k];++j) d->
hB[k][i+j*n_row]*=f;
463 casadi_fill(d->
pi, casadi_sp_nnz(p->
pisp), 0.0);
466 d_ocp_qp_set_all(d->
hA, d->
hB, d->
hb,
477 int qp_sol_size = d_ocp_qp_sol_memsize(&dim);
478 void *qp_sol_mem = malloc(qp_sol_size);
480 struct d_ocp_qp_sol qp_sol;
481 d_ocp_qp_sol_create(&dim, &qp_sol, qp_sol_mem);
483 int ipm_arg_size = d_ocp_qp_ipm_arg_memsize(&dim);
484 void *ipm_arg_mem = malloc(ipm_arg_size);
485 struct d_ocp_qp_ipm_arg myarg;
486 d_ocp_qp_ipm_arg_create(&dim, &myarg, ipm_arg_mem);
488 memcpy(&myarg, &p->
hpipm_options,
sizeof(
struct d_ocp_qp_ipm_arg));
490 int ipm_size = d_ocp_qp_ipm_ws_memsize(&dim, &myarg);
491 void *ipm_mem = malloc(ipm_size);
493 struct d_ocp_qp_ipm_ws workspace;
494 d_ocp_qp_ipm_ws_create(&dim, &myarg, &workspace, ipm_mem);
497 for (i=0; i<p->
N+1; i++) d_ocp_qp_sol_set_u(i, d->
hu[i], &qp_sol);
498 for (i=0; i<p->
N+1; i++) d_ocp_qp_sol_set_x(i, d->
hx[i], &qp_sol);
501 d_ocp_qp_print(&dim, &qp);
504 d_ocp_qp_ipm_solve(&qp, &qp_sol, &myarg, &workspace);
509 d_ocp_qp_ipm_get_iter(&workspace, &d->
iter_count);
510 d_ocp_qp_ipm_get_max_res_stat(&workspace, &d->
res_stat);
511 d_ocp_qp_ipm_get_max_res_eq(&workspace, &d->
res_eq);
512 d_ocp_qp_ipm_get_max_res_ineq(&workspace, &d->
res_ineq);
513 d_ocp_qp_ipm_get_max_res_comp(&workspace, &d->
res_comp);
516 d_ocp_qp_ipm_get_stat(&workspace, &stat);
517 printf(
"\nalpha_aff\tmu_aff\t\tsigma\t\talpha\t\tmu\n");
518 d_print_exp_tran_mat(5, d->
iter_count, stat, 5);
520 printf(
"\nHPIPM returned with flag %i.\n", d->
return_status);
523 printf(
"\n -> QP solved!\n");
527 printf(
"\n -> Solver failed! Maximum number of iterations reached\n");
531 printf(
"\n -> Solver failed! Minimum step lenght reached\n");
535 printf(
"\n -> Solver failed! NaN in computations\n");
539 printf(
"\n -> Solver failed! Unknown return flag\n");
544 for(i=0; i<p->
N+1; ++i) d_ocp_qp_sol_get_u(i, &qp_sol, d->
hu[i]);
545 for(i=0; i<p->
N+1; ++i) d_ocp_qp_sol_get_x(i, &qp_sol, d->
hx[i]);
546 for(i=0; i<p->
N; ++i) d_ocp_qp_sol_get_pi(i, &qp_sol, d->
pis[i]);
551 for (i=0; i<p->
N+1; ++i) {
552 double* lam_lb = d->
pv;
553 double* lam_ub = d->
pv+p->
nbx[i]+p->
nbu[i];
554 d_ocp_qp_sol_get_lam_lb(i, &qp_sol, lam_lb);
555 d_ocp_qp_sol_get_lam_ub(i, &qp_sol, lam_ub);
556 for (k=0;k<p->
nbx[i];++k) {
557 d_qp->
lam_x[offset+k] = (lam_ub[k+p->
nbu[i]]-lam_lb[k+p->
nbu[i]])*2;
560 for (k=0;k<p->
nbu[i];++k) {
561 d_qp->
lam_x[offset+k] = (lam_ub[k]-lam_lb[k])*2;
569 for (i=0; i<p->
N+1; ++i) {
570 double* lam_lg = d->
pv;
571 double* lam_ug = d->
pv+p->
ng[i];
572 d_ocp_qp_sol_get_lam_lg(i, &qp_sol, lam_lg);
573 d_ocp_qp_sol_get_lam_ug(i, &qp_sol, lam_ug);
574 for (k=0;k<p->
ng[i];++k) {
575 d_qp->
lam_a[offset+(i<p->
N ? p->
nx[i+1]: 0)+k] = (lam_ug[k]-lam_lg[k])*2;
577 offset += p->
ng[i]+(i<p->
N ? p->
nx[i+1]: 0);
586 for (k=0;k<p->
N;++k) {
588 for (i=0;i<n_row;++i) {
597 f = casadi_dot(p_qp->
nx, d_qp->
g, d_qp->
x);
598 f += 0.5*casadi_bilin(d_qp->
h, p_qp->
sp_h, d_qp->
x, d_qp->
x);
600 if (d_qp->
f) d_qp->
f[0] = f;
const casadi_hpipm_prob< T1 > * prob
casadi_qp_data< T1 > * qp
const casadi_int * theirs_Usp
casadi_hpipm_block * lam_xu
casadi_hpipm_block * lam_ul
casadi_hpipm_block * lam_uu
const casadi_int * theirs_xsp
const casadi_int * theirs_Xsp
const casadi_int * lamg_gapsp
casadi_hpipm_block * lam_cl
casadi_hpipm_block * lam_cu
const casadi_int * theirs_usp
struct d_ocp_qp_ipm_arg hpipm_options
casadi_hpipm_block * lam_xl
const casadi_qp_prob< T1 > * qp