hpipm_runtime.hpp
1 //
2 // MIT No Attribution
3 //
4 // Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl, KU Leuven.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of this
7 // software and associated documentation files (the "Software"), to deal in the Software
8 // without restriction, including without limitation the rights to use, copy, modify,
9 // merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
14 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
16 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
17 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 //
19 
20 // C-REPLACE "casadi_qp_prob<T1>" "struct casadi_qp_prob"
21 // C-REPLACE "casadi_qp_data<T1>" "struct casadi_qp_data"
22 
23 // C-REPLACE "reinterpret_cast<int**>" "(int**) "
24 // C-REPLACE "reinterpret_cast<int*>" "(int*) "
25 // C-REPLACE "const_cast<int*>" "(int*) "
26 
27 
28 // SYMBOL "hpipm_mproject"
29 template<typename T1>
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) {
32  casadi_int ncol_y;
33  const casadi_int* colind_y;
34  ncol_y = sp_y[1];
35  colind_y = sp_y+2;
36  casadi_project(x, sp_x, y, sp_y, w);
37  casadi_scal(colind_y[ncol_y], factor, y);
38 }
39 
40 // SYMBOL "hpipm_dense_transfer"
41 template<typename T1>
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;
49  /* Loop over columns of y */
50  casadi_int i, el;
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++);
53  }
54 }
55 
56 // SYMBOL "hpipm_block"
58  casadi_int offset_r;
59  casadi_int offset_c;
60  casadi_int rows;
61  casadi_int cols;
62 };
63 // C-REPLACE "casadi_hpipm_block" "struct casadi_hpipm_block"
64 
65 // SYMBOL "hpipm_unpack_blocks"
66 inline void casadi_hpipm_unpack_blocks(casadi_int N, casadi_hpipm_block* blocks, const casadi_int* packed) {
67  casadi_int i;
68  for (i=0;i<N;++i) {
69  blocks[i].offset_r = *packed++;
70  blocks[i].offset_c = *packed++;
71  blocks[i].rows = *packed++;
72  blocks[i].cols = *packed++;
73  }
74 }
75 
76 // SYMBOL "hpipm_ptr_block"
77 template<typename T1>
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;
80  for(k=0;k<N;++k) {
81  vs[k] = v+offset;
82  if (eye) {
83  offset += blocks[k].rows;
84  } else {
85  offset += blocks[k].rows*blocks[k].cols;
86  }
87  }
88 }
89 
90 template<typename T1>
93  const int *nx, *nu, *ng;
94  const int *nbx, *nbu, *ns;
95  const int *nsbx, *nsbu, *nsg;
96  // Sparsities
97  const casadi_int *sp_x, *sp_ba;
98  const casadi_int *Asp, *Bsp, *Csp, *Dsp;
99  const casadi_int *Rsp, *Isp, *Ssp, *Qsp;
100  const casadi_int *bsp;
101  const casadi_int *xsp, *usp;
102  const casadi_int *pisp;
103  const casadi_int *theirs_xsp, *theirs_usp, *theirs_Xsp, *theirs_Usp;
104  const casadi_int *lamg_gapsp, *lugsp;
105 
106  casadi_int N;
107  casadi_int nx_total, nu_total, ng_total;
113 
115  T1 inf;
116 
117  struct d_ocp_qp_ipm_arg hpipm_options;
118 
119 };
120 // C-REPLACE "casadi_hpipm_prob<T1>" "struct casadi_hpipm_prob"
121 
122 // SYMBOL "hpipm_setup"
123 template<typename T1>
124 void casadi_hpipm_setup(casadi_hpipm_prob<T1>* p) {
125  casadi_int i;
126 
127  p->nx_total = 0;
128  p->nu_total = 0;
129  p->ng_total = 0;
130  for (i=0;i<p->N+1;++i) p->nx_total+= p->nx[i];
131  for (i=0;i<p->N+1;++i) p->nu_total+= p->nu[i];
132  for (i=0;i<p->N+1;++i) p->ng_total+= p->ng[i];
133 
134 }
135 
136 
137 
138 // SYMBOL "hpipm_data"
139 template<typename T1>
141  // Problem structure
143  // Problem structure
145  T1 *A, *B, *C, *D;
146  T1 *R, *I, *Q, *S;
147  T1 *b, *b2;
148  T1 *x, *q;
149  T1 *u, *r;
150  T1 *lg, *ug;
151  T1 *pi;
152  T1 *lbx, *ubx, *lbu, *ubu, *lam;
153 
154  T1 **hA, **hB, **hC, **hD;
155  T1 **hR, **hI, **hQ, **hS;
156  T1 **hx, **hq;
157  T1 **hu, **hr;
158  T1 **hlg, **hug;
159  T1 **hb;
160 
161  T1 **hZl, **hZu, **hzl, **hzu, **hlls, **hlus;
162  T1 **pis, **hlbx, **hubx, **hlbu, **hubu, **lams;
163 
164  int *iidxbx, *iidxbu;
165  int **hidxbx, **hidxbu, **hidxs;
166 
170  T1 res_eq;
173 
174  T1 *pv;
175 };
176 // C-REPLACE "casadi_hpipm_data<T1>" "struct casadi_hpipm_data"
177 
178 
179 // SYMBOL "hpipm_work"
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);
183 
184  // Temporary work vectors
185  *sz_w = casadi_max(*sz_w, 2*(p->qp->nx+p->qp->na)); // pv
186  // Persistent work vectors
187  *sz_res += p->N; // hA
188  *sz_res += p->N; // hB
189  *sz_res += p->N+1; // hC
190  *sz_res += p->N+1; // hD
191  *sz_res += p->N+1; // hR
192  *sz_res += p->N; // hI
193  *sz_res += p->N+1; // hS
194  *sz_res += p->N+1; // hQ
195  *sz_res += p->N+1; // hx
196  *sz_res += p->N+1; // hq
197  *sz_res += p->N+1; // hu
198  *sz_res += p->N+1; // hr
199  *sz_res += p->N+1; // hlg
200  *sz_res += p->N+1; // hug
201  *sz_res += p->N; // hb
202 
203  *sz_res += p->N; // pis
204  *sz_res += p->N+1; // hlbx
205  *sz_res += p->N+1; // hubx
206  *sz_res += p->N+1; // hlbu
207  *sz_res += p->N+1; // hubu
208  *sz_res += p->N+1; // lams
209  *sz_res += p->N+1; // hidxbx
210  *sz_res += p->N+1; // hidxbu
211  *sz_res += p->N+1; // hidxs
212 
213  *sz_res += p->N+1; // hZl
214  *sz_res += p->N+1; // hZu
215  *sz_res += p->N+1; // hzl
216  *sz_res += p->N+1; // hzu
217  *sz_res += p->N+1; // hlls
218  *sz_res += p->N+1; // hlus
219 
220  *sz_w += casadi_sp_nnz(p->Asp); // A
221  *sz_w += casadi_sp_nnz(p->Bsp); // B
222  *sz_w += casadi_sp_nnz(p->Csp); // C
223  *sz_w += casadi_sp_nnz(p->Dsp); // D
224  *sz_w += casadi_sp_nnz(p->Rsp); // R
225  *sz_w += casadi_sp_nnz(p->Isp); // I
226  *sz_w += casadi_sp_nnz(p->Ssp); // S
227  *sz_w += casadi_sp_nnz(p->Qsp); // Q
228  *sz_w += casadi_sp_nnz(p->bsp); // b
229  *sz_w += casadi_sp_nnz(p->bsp); // b2
230  *sz_w += casadi_sp_nnz(p->xsp); // x
231  *sz_w += casadi_sp_nnz(p->xsp); // q
232  *sz_w += casadi_sp_nnz(p->usp); // u
233  *sz_w += casadi_sp_nnz(p->usp); // r
234  *sz_w += casadi_sp_nnz(p->lugsp); // lg
235  *sz_w += casadi_sp_nnz(p->lugsp); // ug
236  *sz_w += casadi_sp_nnz(p->pisp); // pi
237  *sz_w += p->nx_total; // lbx
238  *sz_w += p->nx_total; // ubx
239  *sz_w += p->nu_total; // lbu
240  *sz_w += p->nu_total; // ubu
241  *sz_w += p->nx_total+p->ng_total; // lam
242 
243  *sz_iw += p->nx_total; // iidxbx
244  *sz_iw += p->nu_total; // iidxbu
245 
246 }
247 
248 // SYMBOL "hpipm_set_work"
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) {
251  // Local variables
252  casadi_int offset, i, k;
253 
254  const casadi_hpipm_prob<T1>* p = d->prob;
255 
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;
280 
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;
287 
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);
305 
306  d->lbx = *w; *w += p->nx_total;
307  d->ubx = *w; *w += p->nx_total;
308  d->lbu = *w; *w += p->nu_total;
309  d->ubu = *w; *w += p->nu_total;
310  d->lam = *w; *w += p->nx_total+p->ng_total;
311 
312  d->iidxbx = reinterpret_cast<int*>(*iw); *iw += p->nx_total;
313  d->iidxbu = reinterpret_cast<int*>(*iw); *iw += p->nu_total;
314 
315  d->pv = *w;
316 
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);
332 
333  // Slack variables featues not currently interfaced
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;
340 
341  offset = 0;
342  for (k=0;k<p->N;++k) {
343  d->pis[k] = d->pi+offset;
344  offset += p->nx[k+1];
345  }
346 
347  offset = 0;
348  for (k=0;k<p->N+1;++k) {
349  d->hlbx[k] = d->lbx+offset;
350  d->hubx[k] = d->ubx+offset;
351  offset += p->nx[k];
352  }
353  offset = 0;
354  for (k=0;k<p->N+1;++k) {
355  d->hlbu[k] = d->lbu+offset;
356  d->hubu[k] = d->ubu+offset;
357  offset += p->nu[k];
358  }
359  offset = 0;
360  for (k=0;k<p->N+1;++k) {
361  d->hidxbx[k] = d->iidxbx+offset;
362  for (i=0;i<p->nbx[k];++i) d->hidxbx[k][i] = i;
363  offset+= p->nbx[k];
364  }
365  offset = 0;
366  for (k=0;k<p->N+1;++k) {
367  d->hidxbu[k] = d->iidxbu+offset;
368  for (i=0;i<p->nbu[k];++i) d->hidxbu[k][i] = i;
369  offset+= p->nbu[k];
370  }
371 
372 }
373 
374 
375 // SYMBOL "hpipm_solve"
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;
379  T1 f;
380  const casadi_hpipm_prob<T1>* p = d->prob;
381  const casadi_qp_prob<T1>* p_qp = p->qp;
382  casadi_qp_data<T1>* d_qp = d->qp;
383 
384  int dim_size = d_ocp_qp_dim_memsize(p->N);
385  void *dim_mem = malloc(dim_size);
386 
387  struct d_ocp_qp_dim dim;
388  d_ocp_qp_dim_create(p->N, &dim, dim_mem);
389 
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);
392 
393  int qp_size = d_ocp_qp_memsize(&dim);
394  void *qp_mem = malloc(qp_size);
395 
396  struct d_ocp_qp qp;
397  d_ocp_qp_create(&dim, &qp, qp_mem);
398 
399  // Dissect A matrix
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);
405 
406  // Dissect H matrix; definition of HPIPM lacks a factor 2
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);
410 
411  // Dissect LBA/UBA
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);
414  //casadi_assert_dev(std::equal(m->b.begin(), m->b.end(), m->b2.begin()));
415  casadi_project(d_qp->lba, p->sp_ba, d->lg, p->lugsp, d->pv);
416  casadi_project(d_qp->uba, p->sp_ba, d->ug, p->lugsp, d->pv);
417 
418  // Dissect LBX/UBX input
419  casadi_fill(d->lbu, p->nu_total, 0.0);
420  casadi_fill(d->ubu, p->nu_total, 0.0);
421  casadi_fill(d->lbx, p->nx_total, 0.0);
422  casadi_fill(d->ubx, p->nx_total, 0.0);
423 
424  casadi_hpipm_dense_transfer(1.0, d_qp->lbx, p->xsp, d->lbx, p->theirs_Xsp, d->pv);
425  casadi_hpipm_dense_transfer(1.0, d_qp->ubx, p->xsp, d->ubx, p->theirs_Xsp, d->pv);
426  casadi_hpipm_dense_transfer(1.0, d_qp->lbx, p->usp, d->lbu, p->theirs_Usp, d->pv);
427  casadi_hpipm_dense_transfer(1.0, d_qp->ubx, p->usp, d->ubu, p->theirs_Usp, d->pv);
428 
429  // Dissect G
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);
432 
433  // Dissect X0
434  casadi_project(d_qp->x0, p->sp_x, d->u, p->usp, d->pv);
435  casadi_project(d_qp->x0, p->sp_x, d->x, p->xsp, d->pv);
436 
437  d->iter_count = -1;
438 
439  // Deal with non-unity I block
440  for (k=0;k<p->N;++k) {
441  n_row = p->nx[k+1];
442  for (i=0;i<n_row;++i) {
443  f = -1/d->hI[k][i];
444  d->hb[k][i]*=f;
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;
447  }
448  }
449 
450  // replace infinities
451  casadi_clip_min(d->lbx, p->nx_total, -p->inf, 0);
452  casadi_clip_min(d->lbu, p->nu_total, -p->inf, 0);
453  casadi_clip_min(d->lg, p->ng_total, -p->inf, 0); // count?
454  casadi_clip_max(d->ubx, p->nx_total, p->inf, 0);
455  casadi_clip_max(d->ubu, p->nu_total, p->inf, 0);
456  casadi_clip_max(d->ug, p->ng_total, p->inf, 0); // count?
457 
458 
459  //m->fstats.at("preprocessing").toc();
460 
461 
462 
463  casadi_fill(d->pi, casadi_sp_nnz(p->pisp), 0.0);
464  casadi_fill(d->lam, p->nx_total+p->ng_total, 0.0);
465 
466  d_ocp_qp_set_all(d->hA, d->hB, d->hb,
467  d->hQ, d->hS, d->hR,
468  d->hq, d->hr,
469  d->hidxbx, d->hlbx, d->hubx,
470  d->hidxbu, d->hlbu, d->hubu,
471  d->hC, d->hD,
472  d->hlg, d->hug,
473  d->hZl, d->hZu, d->hzl,
474  d->hzu, d->hidxs,
475  d->hlls, d->hlus, &qp);
476 
477  int qp_sol_size = d_ocp_qp_sol_memsize(&dim);
478  void *qp_sol_mem = malloc(qp_sol_size);
479 
480  struct d_ocp_qp_sol qp_sol;
481  d_ocp_qp_sol_create(&dim, &qp_sol, qp_sol_mem);
482 
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);
487 
488  memcpy(&myarg, &p->hpipm_options, sizeof(struct d_ocp_qp_ipm_arg));
489 
490  int ipm_size = d_ocp_qp_ipm_ws_memsize(&dim, &myarg);
491  void *ipm_mem = malloc(ipm_size);
492 
493  struct d_ocp_qp_ipm_ws workspace;
494  d_ocp_qp_ipm_ws_create(&dim, &myarg, &workspace, ipm_mem);
495 
496  // solution guess
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);
499 
500 
501  d_ocp_qp_print(&dim, &qp);
502  //m->fstats.at("solver").tic();
503  // call solver
504  d_ocp_qp_ipm_solve(&qp, &qp_sol, &myarg, &workspace);
505  d_ocp_qp_ipm_get_status(&workspace, &d->return_status);
506  //m->fstats.at("solver").toc();
507  //m->fstats.at("postprocessing").tic();
508 
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);
514 
515  double *stat;
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);
519 
520  printf("\nHPIPM returned with flag %i.\n", d->return_status);
521  if(d->return_status == 0)
522  {
523  printf("\n -> QP solved!\n");
524  }
525  else if(d->return_status==1)
526  {
527  printf("\n -> Solver failed! Maximum number of iterations reached\n");
528  }
529  else if(d->return_status==2)
530  {
531  printf("\n -> Solver failed! Minimum step lenght reached\n");
532  }
533  else if(d->return_status==2)
534  {
535  printf("\n -> Solver failed! NaN in computations\n");
536  }
537  else
538  {
539  printf("\n -> Solver failed! Unknown return flag\n");
540  }
541  printf("\n\n");
542 
543 
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]);
547 
548 
549  if (d_qp->lam_x) {
550  offset = 0;
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;
558  }
559  offset += p->nbx[i];
560  for (k=0;k<p->nbu[i];++k) {
561  d_qp->lam_x[offset+k] = (lam_ub[k]-lam_lb[k])*2;
562  }
563  offset += p->nbu[i];
564  }
565  }
566 
567  if (d_qp->lam_a) {
568  offset = 0;
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;
576  }
577  offset += p->ng[i]+(i<p->N ? p->nx[i+1]: 0);
578  }
579  }
580 
581  casadi_hpipm_dense_transfer(1.0, d->x, p->theirs_Xsp, d_qp->x, p->xsp, d->pv);
582  casadi_hpipm_dense_transfer(1.0, d->u, p->theirs_Usp, d_qp->x, p->usp, d->pv);
583 
584 
585  // Deal with non-unity I block
586  for (k=0;k<p->N;++k) {
587  n_row = p->nx[k+1];
588  for (i=0;i<n_row;++i) {
589  f = -1/d->hI[k][i];
590  d->pis[k][i]*=f;
591  }
592  }
593 
594  casadi_hpipm_dense_transfer(2.0, d->pi, p->pisp, d_qp->lam_a, p->lamg_gapsp, d->pv);
595 
596  // Construct f
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);
599 
600  if (d_qp->f) d_qp->f[0] = f;
601 
602  /*
603  m->fstats.at("postprocessing").toc();
604 
605  */
606 
607  return d->return_status==0;
608 }
const casadi_hpipm_prob< T1 > * prob
casadi_qp_data< T1 > * qp
const casadi_int * Csp
const casadi_int * theirs_Usp
casadi_hpipm_block * lam_xu
casadi_hpipm_block * lam_ul
casadi_hpipm_block * lam_uu
const casadi_int * pisp
casadi_hpipm_block * C
const casadi_int * lugsp
const casadi_int * usp
casadi_hpipm_block * S
casadi_hpipm_block * Q
casadi_hpipm_block * I
const casadi_int * Asp
const casadi_int * theirs_xsp
const casadi_int * Ssp
const casadi_int * theirs_Xsp
const casadi_int * lamg_gapsp
const casadi_int * Bsp
const casadi_int * Rsp
const casadi_int * xsp
casadi_hpipm_block * lug
casadi_hpipm_block * D
const casadi_int * Dsp
const casadi_int * bsp
casadi_hpipm_block * R
casadi_hpipm_block * lam_cl
casadi_hpipm_block * B
casadi_hpipm_block * u
casadi_hpipm_block * lam_cu
const casadi_int * Qsp
const casadi_int * theirs_usp
const casadi_int * sp_ba
casadi_hpipm_block * A
casadi_hpipm_block * b
const casadi_int * sp_x
struct d_ocp_qp_ipm_arg hpipm_options
const casadi_int * Isp
casadi_hpipm_block * lam_xl
casadi_hpipm_block * x
const casadi_qp_prob< T1 > * qp
const T1 * h
Definition: casadi_qp.hpp:64
const T1 * lba
Definition: casadi_qp.hpp:64
const T1 * lbx
Definition: casadi_qp.hpp:64
const T1 * uba
Definition: casadi_qp.hpp:64
const T1 * ubx
Definition: casadi_qp.hpp:64
const T1 * x0
Definition: casadi_qp.hpp:64
const T1 * g
Definition: casadi_qp.hpp:64
const T1 * a
Definition: casadi_qp.hpp:64
const casadi_int * sp_h
Definition: casadi_qp.hpp:31
casadi_int nx
Definition: casadi_qp.hpp:33
const casadi_int * sp_a
Definition: casadi_qp.hpp:31