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 template<typename T1>
67 void casadi_hpipm_unpack_blocks(casadi_int N, casadi_hpipm_block* blocks, const casadi_int* packed) {
68  casadi_int i;
69  for (i=0;i<N;++i) {
70  blocks[i].offset_r = *packed++;
71  blocks[i].offset_c = *packed++;
72  blocks[i].rows = *packed++;
73  blocks[i].cols = *packed++;
74  }
75 }
76 
77 // SYMBOL "hpipm_ptr_block"
78 template<typename T1>
79 void casadi_hpipm_ptr_block(casadi_int N, T1** vs, T1* v, const casadi_hpipm_block* blocks, int eye) {
80  casadi_int k, offset = 0;
81  for(k=0;k<N;++k) {
82  vs[k] = v+offset;
83  if (eye) {
84  offset += blocks[k].rows;
85  } else {
86  offset += blocks[k].rows*blocks[k].cols;
87  }
88  }
89 }
90 
91 template<typename T1>
94  const int *nx, *nu, *ng;
95  const int *nbx, *nbu, *ns;
96  const int *nsbx, *nsbu, *nsg;
97  // Sparsities
98  const casadi_int *sp_x, *sp_ba;
99  const casadi_int *Asp, *Bsp, *Csp, *Dsp;
100  const casadi_int *Rsp, *Isp, *Ssp, *Qsp;
101  const casadi_int *bsp;
102  const casadi_int *xsp, *usp;
103  const casadi_int *pisp;
104  const casadi_int *theirs_xsp, *theirs_usp, *theirs_Xsp, *theirs_Usp;
105  const casadi_int *lamg_gapsp, *lugsp;
106 
107  casadi_int N;
108  casadi_int nx_total, nu_total, ng_total;
114 
116  T1 inf;
117 
118  struct d_ocp_qp_ipm_arg hpipm_options;
119 
120 };
121 // C-REPLACE "casadi_hpipm_prob<T1>" "struct casadi_hpipm_prob"
122 
123 // SYMBOL "hpipm_setup"
124 template<typename T1>
125 void casadi_hpipm_setup(casadi_hpipm_prob<T1>* p) {
126  casadi_int i;
127 
128  p->nx_total = 0;
129  p->nu_total = 0;
130  p->ng_total = 0;
131  for (i=0;i<p->N+1;++i) p->nx_total+= p->nx[i];
132  for (i=0;i<p->N+1;++i) p->nu_total+= p->nu[i];
133  for (i=0;i<p->N+1;++i) p->ng_total+= p->ng[i];
134 
135 }
136 
137 
138 
139 // SYMBOL "hpipm_data"
140 template<typename T1>
142  // Problem structure
144  // Problem structure
146  T1 *A, *B, *C, *D;
147  T1 *R, *I, *Q, *S;
148  T1 *b, *b2;
149  T1 *x, *q;
150  T1 *u, *r;
151  T1 *lg, *ug;
152  T1 *pi;
153  T1 *lbx, *ubx, *lbu, *ubu, *lam;
154 
155  T1 **hA, **hB, **hC, **hD;
156  T1 **hR, **hI, **hQ, **hS;
157  T1 **hx, **hq;
158  T1 **hu, **hr;
159  T1 **hlg, **hug;
160  T1 **hb;
161 
162  T1 **hZl, **hZu, **hzl, **hzu, **hlls, **hlus;
163  T1 **pis, **hlbx, **hubx, **hlbu, **hubu, **lams;
164 
165  int *iidxbx, *iidxbu;
166  int **hidxbx, **hidxbu, **hidxs;
167 
171  T1 res_eq;
174 
175  T1 *pv;
176 };
177 // C-REPLACE "casadi_hpipm_data<T1>" "struct casadi_hpipm_data"
178 
179 
180 // SYMBOL "hpipm_work"
181 template<typename T1>
182 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) {
183  casadi_qp_work(p->qp, sz_arg, sz_res, sz_iw, sz_w);
184 
185  // Temporary work vectors
186  *sz_w = casadi_max(*sz_w, 2*(p->qp->nx+p->qp->na)); // pv
187  // Persistent work vectors
188  *sz_res += p->N; // hA
189  *sz_res += p->N; // hB
190  *sz_res += p->N+1; // hC
191  *sz_res += p->N+1; // hD
192  *sz_res += p->N+1; // hR
193  *sz_res += p->N; // hI
194  *sz_res += p->N+1; // hS
195  *sz_res += p->N+1; // hQ
196  *sz_res += p->N+1; // hx
197  *sz_res += p->N+1; // hq
198  *sz_res += p->N+1; // hu
199  *sz_res += p->N+1; // hr
200  *sz_res += p->N+1; // hlg
201  *sz_res += p->N+1; // hug
202  *sz_res += p->N; // hb
203 
204  *sz_res += p->N; // pis
205  *sz_res += p->N+1; // hlbx
206  *sz_res += p->N+1; // hubx
207  *sz_res += p->N+1; // hlbu
208  *sz_res += p->N+1; // hubu
209  *sz_res += p->N+1; // lams
210  *sz_res += p->N+1; // hidxbx
211  *sz_res += p->N+1; // hidxbu
212  *sz_res += p->N+1; // hidxs
213 
214  *sz_res += p->N+1; // hZl
215  *sz_res += p->N+1; // hZu
216  *sz_res += p->N+1; // hzl
217  *sz_res += p->N+1; // hzu
218  *sz_res += p->N+1; // hlls
219  *sz_res += p->N+1; // hlus
220 
221  *sz_w += casadi_sp_nnz(p->Asp); // A
222  *sz_w += casadi_sp_nnz(p->Bsp); // B
223  *sz_w += casadi_sp_nnz(p->Csp); // C
224  *sz_w += casadi_sp_nnz(p->Dsp); // D
225  *sz_w += casadi_sp_nnz(p->Rsp); // R
226  *sz_w += casadi_sp_nnz(p->Isp); // I
227  *sz_w += casadi_sp_nnz(p->Ssp); // S
228  *sz_w += casadi_sp_nnz(p->Qsp); // Q
229  *sz_w += casadi_sp_nnz(p->bsp); // b
230  *sz_w += casadi_sp_nnz(p->bsp); // b2
231  *sz_w += casadi_sp_nnz(p->xsp); // x
232  *sz_w += casadi_sp_nnz(p->xsp); // q
233  *sz_w += casadi_sp_nnz(p->usp); // u
234  *sz_w += casadi_sp_nnz(p->usp); // r
235  *sz_w += casadi_sp_nnz(p->lugsp); // lg
236  *sz_w += casadi_sp_nnz(p->lugsp); // ug
237  *sz_w += casadi_sp_nnz(p->pisp); // pi
238  *sz_w += p->nx_total; // lbx
239  *sz_w += p->nx_total; // ubx
240  *sz_w += p->nu_total; // lbu
241  *sz_w += p->nu_total; // ubu
242  *sz_w += p->nx_total+p->ng_total; // lam
243 
244  *sz_iw += p->nx_total; // iidxbx
245  *sz_iw += p->nu_total; // iidxbu
246 
247 }
248 
249 // SYMBOL "hpipm_set_work"
250 template<typename T1>
251 void casadi_hpipm_set_work(casadi_hpipm_data<T1>* d, const T1*** arg, T1*** res, casadi_int** iw, T1** w) {
252  // Local variables
253  casadi_int offset, i, k;
254 
255  const casadi_hpipm_prob<T1>* p = d->prob;
256 
257  d->hA = *res; *res += p->N;
258  d->hB = *res; *res += p->N;
259  d->hC = *res; *res += p->N + 1;
260  d->hD = *res; *res += p->N + 1;
261  d->hR = *res; *res += p->N + 1;
262  d->hI = *res; *res += p->N;
263  d->hS = *res; *res += p->N + 1;
264  d->hQ = *res; *res += p->N + 1;
265  d->hx = *res; *res += p->N + 1;
266  d->hq = *res; *res += p->N + 1;
267  d->hu = *res; *res += p->N + 1;
268  d->hr = *res; *res += p->N + 1;
269  d->hlg = *res; *res += p->N + 1;
270  d->hug = *res; *res += p->N + 1;
271  d->hb = *res; *res += p->N;
272  d->pis = *res; *res += p->N;
273  d->hlbx = *res; *res += p->N+1;
274  d->hubx = *res; *res += p->N+1;
275  d->hlbu = *res; *res += p->N+1;
276  d->hubu = *res; *res += p->N+1;
277  d->lams = *res; *res += p->N+1;
278  d->hidxbx = reinterpret_cast<int**>(*res); *res += p->N+1;
279  d->hidxbu = reinterpret_cast<int**>(*res); *res += p->N+1;
280  d->hidxs = reinterpret_cast<int**>(*res); *res += p->N+1;
281 
282  d->hZl = *res; *res += p->N+1;
283  d->hZu = *res; *res += p->N+1;
284  d->hzl = *res; *res += p->N+1;
285  d->hzu = *res; *res += p->N+1;
286  d->hlls = *res; *res += p->N+1;
287  d->hlus = *res; *res += p->N+1;
288 
289  d->A = *w; *w += casadi_sp_nnz(p->Asp);
290  d->B = *w; *w += casadi_sp_nnz(p->Bsp);
291  d->C = *w; *w += casadi_sp_nnz(p->Csp);
292  d->D = *w; *w += casadi_sp_nnz(p->Dsp);
293  d->R = *w; *w += casadi_sp_nnz(p->Rsp);
294  d->I = *w; *w += casadi_sp_nnz(p->Isp);
295  d->S = *w; *w += casadi_sp_nnz(p->Ssp);
296  d->Q = *w; *w += casadi_sp_nnz(p->Qsp);
297  d->b = *w; *w += casadi_sp_nnz(p->bsp);
298  d->b2 = *w; *w += casadi_sp_nnz(p->bsp);
299  d->x = *w; *w += casadi_sp_nnz(p->xsp);
300  d->q = *w; *w += casadi_sp_nnz(p->xsp);
301  d->u = *w; *w += casadi_sp_nnz(p->usp);
302  d->r = *w; *w += casadi_sp_nnz(p->usp);
303  d->lg = *w; *w += casadi_sp_nnz(p->lugsp);
304  d->ug = *w; *w += casadi_sp_nnz(p->lugsp);
305  d->pi = *w; *w += casadi_sp_nnz(p->pisp);
306 
307  d->lbx = *w; *w += p->nx_total;
308  d->ubx = *w; *w += p->nx_total;
309  d->lbu = *w; *w += p->nu_total;
310  d->ubu = *w; *w += p->nu_total;
311  d->lam = *w; *w += p->nx_total+p->ng_total;
312 
313  d->iidxbx = reinterpret_cast<int*>(*iw); *iw += p->nx_total;
314  d->iidxbu = reinterpret_cast<int*>(*iw); *iw += p->nu_total;
315 
316  d->pv = *w;
317 
318  casadi_hpipm_ptr_block(p->N, d->hA, d->A, p->A, 0);
319  casadi_hpipm_ptr_block(p->N, d->hB, d->B, p->B, 0);
320  casadi_hpipm_ptr_block(p->N+1, d->hC, d->C, p->C, 0);
321  casadi_hpipm_ptr_block(p->N+1, d->hD, d->D, p->D, 0);
322  casadi_hpipm_ptr_block(p->N+1, d->hR, d->R, p->R, 0);
323  casadi_hpipm_ptr_block(p->N, d->hI, d->I, p->I, 1);
324  casadi_hpipm_ptr_block(p->N+1, d->hS, d->S, p->S, 0);
325  casadi_hpipm_ptr_block(p->N+1, d->hQ, d->Q, p->Q, 0);
326  casadi_hpipm_ptr_block(p->N+1, d->hx, d->x, p->x, 0);
327  casadi_hpipm_ptr_block(p->N+1, d->hq, d->q, p->x, 0);
328  casadi_hpipm_ptr_block(p->N+1, d->hu, d->u, p->u, 0);
329  casadi_hpipm_ptr_block(p->N+1, d->hr, d->r, p->u, 0);
330  casadi_hpipm_ptr_block(p->N+1, d->hlg, d->lg, p->lug, 0);
331  casadi_hpipm_ptr_block(p->N+1, d->hug, d->ug, p->lug, 0);
332  casadi_hpipm_ptr_block(p->N, d->hb, d->b, p->b, 0);
333 
334  // Slack variables featues not currently interfaced
335  for(i=0;i<p->N+1;++i) d->hZl[i] = 0;
336  for(i=0;i<p->N+1;++i) d->hZu[i] = 0;
337  for(i=0;i<p->N+1;++i) d->hzl[i] = 0;
338  for(i=0;i<p->N+1;++i) d->hzu[i] = 0;
339  for(i=0;i<p->N+1;++i) d->hlls[i] = 0;
340  for(i=0;i<p->N+1;++i) d->hlus[i] = 0;
341 
342  offset = 0;
343  for (k=0;k<p->N;++k) {
344  d->pis[k] = d->pi+offset;
345  offset += p->nx[k+1];
346  }
347 
348  offset = 0;
349  for (k=0;k<p->N+1;++k) {
350  d->hlbx[k] = d->lbx+offset;
351  d->hubx[k] = d->ubx+offset;
352  offset += p->nx[k];
353  }
354  offset = 0;
355  for (k=0;k<p->N+1;++k) {
356  d->hlbu[k] = d->lbu+offset;
357  d->hubu[k] = d->ubu+offset;
358  offset += p->nu[k];
359  }
360  offset = 0;
361  for (k=0;k<p->N+1;++k) {
362  d->hidxbx[k] = d->iidxbx+offset;
363  for (i=0;i<p->nbx[k];++i) d->hidxbx[k][i] = i;
364  offset+= p->nbx[k];
365  }
366  offset = 0;
367  for (k=0;k<p->N+1;++k) {
368  d->hidxbu[k] = d->iidxbu+offset;
369  for (i=0;i<p->nbu[k];++i) d->hidxbu[k][i] = i;
370  offset+= p->nbu[k];
371  }
372 
373 }
374 
375 
376 // SYMBOL "hpipm_solve"
377 template<typename T1>
378 int casadi_hpipm_solve(casadi_hpipm_data<T1>* d, const double** arg, double** res, casadi_int* iw, double* w) {
379  casadi_int k, i, j, n_row, offset;
380  T1 f;
381  const casadi_hpipm_prob<T1>* p = d->prob;
382  const casadi_qp_prob<T1>* p_qp = p->qp;
383  casadi_qp_data<T1>* d_qp = d->qp;
384 
385  int dim_size = d_ocp_qp_dim_memsize(p->N);
386  void *dim_mem = malloc(dim_size);
387 
388  struct d_ocp_qp_dim dim;
389  d_ocp_qp_dim_create(p->N, &dim, dim_mem);
390 
391  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),
392  const_cast<int*>(p->ng), const_cast<int*>(p->nsbx), const_cast<int*>(p->nsbu), const_cast<int*>(p->nsg), &dim);
393 
394  int qp_size = d_ocp_qp_memsize(&dim);
395  void *qp_mem = malloc(qp_size);
396 
397  struct d_ocp_qp qp;
398  d_ocp_qp_create(&dim, &qp, qp_mem);
399 
400  // Dissect A matrix
401  casadi_project(d_qp->a, p_qp->sp_a, d->A, p->Asp, d->pv);
402  casadi_project(d_qp->a, p_qp->sp_a, d->B, p->Bsp, d->pv);
403  casadi_project(d_qp->a, p_qp->sp_a, d->C, p->Csp, d->pv);
404  casadi_project(d_qp->a, p_qp->sp_a, d->D, p->Dsp, d->pv);
405  casadi_project(d_qp->a, p_qp->sp_a, d->I, p->Isp, d->pv);
406 
407  // Dissect H matrix; definition of HPIPM lacks a factor 2
408  casadi_hpipm_mproject(0.5, d_qp->h, p_qp->sp_h, d->R, p->Rsp, d->pv);
409  casadi_hpipm_mproject(0.5, d_qp->h, p_qp->sp_h, d->S, p->Ssp, d->pv);
410  casadi_hpipm_mproject(0.5, d_qp->h, p_qp->sp_h, d->Q, p->Qsp, d->pv);
411 
412  // Dissect LBA/UBA
413  casadi_hpipm_mproject(-1.0, d_qp->lba, p->sp_ba, d->b, p->bsp, d->pv);
414  casadi_hpipm_mproject(-1.0, d_qp->uba, p->sp_ba, d->b2, p->bsp, d->pv);
415  //casadi_assert_dev(std::equal(m->b.begin(), m->b.end(), m->b2.begin()));
416  casadi_project(d_qp->lba, p->sp_ba, d->lg, p->lugsp, d->pv);
417  casadi_project(d_qp->uba, p->sp_ba, d->ug, p->lugsp, d->pv);
418 
419  // Dissect LBX/UBX input
420  casadi_fill(d->lbu, p->nu_total, 0.0);
421  casadi_fill(d->ubu, p->nu_total, 0.0);
422  casadi_fill(d->lbx, p->nx_total, 0.0);
423  casadi_fill(d->ubx, p->nx_total, 0.0);
424 
425  casadi_hpipm_dense_transfer(1.0, d_qp->lbx, p->xsp, d->lbx, p->theirs_Xsp, d->pv);
426  casadi_hpipm_dense_transfer(1.0, d_qp->ubx, p->xsp, d->ubx, p->theirs_Xsp, d->pv);
427  casadi_hpipm_dense_transfer(1.0, d_qp->lbx, p->usp, d->lbu, p->theirs_Usp, d->pv);
428  casadi_hpipm_dense_transfer(1.0, d_qp->ubx, p->usp, d->ubu, p->theirs_Usp, d->pv);
429 
430  // Dissect G
431  casadi_hpipm_mproject(0.5, d_qp->g, p->sp_x, d->r, p->usp, d->pv);
432  casadi_hpipm_mproject(0.5, d_qp->g, p->sp_x, d->q, p->xsp, d->pv);
433 
434  // Dissect X0
435  casadi_project(d_qp->x0, p->sp_x, d->u, p->usp, d->pv);
436  casadi_project(d_qp->x0, p->sp_x, d->x, p->xsp, d->pv);
437 
438  d->iter_count = -1;
439 
440  // Deal with non-unity I block
441  for (k=0;k<p->N;++k) {
442  n_row = p->nx[k+1];
443  for (i=0;i<n_row;++i) {
444  f = -1/d->hI[k][i];
445  d->hb[k][i]*=f;
446  for (j=0;j<p->nx[k];++j) d->hA[k][i+j*n_row]*=f;
447  for (j=0;j<p->nu[k];++j) d->hB[k][i+j*n_row]*=f;
448  }
449  }
450 
451  // replace infinities
452  casadi_clip_min(d->lbx, p->nx_total, -p->inf, 0);
453  casadi_clip_min(d->lbu, p->nu_total, -p->inf, 0);
454  casadi_clip_min(d->lg, p->ng_total, -p->inf, 0); // count?
455  casadi_clip_max(d->ubx, p->nx_total, p->inf, 0);
456  casadi_clip_max(d->ubu, p->nu_total, p->inf, 0);
457  casadi_clip_max(d->ug, p->ng_total, p->inf, 0); // count?
458 
459 
460  //m->fstats.at("preprocessing").toc();
461 
462 
463 
464  casadi_fill(d->pi, casadi_sp_nnz(p->pisp), 0.0);
465  casadi_fill(d->lam, p->nx_total+p->ng_total, 0.0);
466 
467  d_ocp_qp_set_all(d->hA, d->hB, d->hb,
468  d->hQ, d->hS, d->hR,
469  d->hq, d->hr,
470  d->hidxbx, d->hlbx, d->hubx,
471  d->hidxbu, d->hlbu, d->hubu,
472  d->hC, d->hD,
473  d->hlg, d->hug,
474  d->hZl, d->hZu, d->hzl,
475  d->hzu, d->hidxs,
476  d->hlls, d->hlus, &qp);
477 
478  int qp_sol_size = d_ocp_qp_sol_memsize(&dim);
479  void *qp_sol_mem = malloc(qp_sol_size);
480 
481  struct d_ocp_qp_sol qp_sol;
482  d_ocp_qp_sol_create(&dim, &qp_sol, qp_sol_mem);
483 
484  int ipm_arg_size = d_ocp_qp_ipm_arg_memsize(&dim);
485  void *ipm_arg_mem = malloc(ipm_arg_size);
486  struct d_ocp_qp_ipm_arg myarg;
487  d_ocp_qp_ipm_arg_create(&dim, &myarg, ipm_arg_mem);
488 
489  memcpy(&myarg, &p->hpipm_options, sizeof(struct d_ocp_qp_ipm_arg));
490 
491  int ipm_size = d_ocp_qp_ipm_ws_memsize(&dim, &myarg);
492  void *ipm_mem = malloc(ipm_size);
493 
494  struct d_ocp_qp_ipm_ws workspace;
495  d_ocp_qp_ipm_ws_create(&dim, &myarg, &workspace, ipm_mem);
496 
497  // solution guess
498  for (i=0; i<p->N+1; i++) d_ocp_qp_sol_set_u(i, d->hu[i], &qp_sol);
499  for (i=0; i<p->N+1; i++) d_ocp_qp_sol_set_x(i, d->hx[i], &qp_sol);
500 
501 
502  d_ocp_qp_print(&dim, &qp);
503  //m->fstats.at("solver").tic();
504  // call solver
505  d_ocp_qp_ipm_solve(&qp, &qp_sol, &myarg, &workspace);
506  d_ocp_qp_ipm_get_status(&workspace, &d->return_status);
507  //m->fstats.at("solver").toc();
508  //m->fstats.at("postprocessing").tic();
509 
510  d_ocp_qp_ipm_get_iter(&workspace, &d->iter_count);
511  d_ocp_qp_ipm_get_max_res_stat(&workspace, &d->res_stat);
512  d_ocp_qp_ipm_get_max_res_eq(&workspace, &d->res_eq);
513  d_ocp_qp_ipm_get_max_res_ineq(&workspace, &d->res_ineq);
514  d_ocp_qp_ipm_get_max_res_comp(&workspace, &d->res_comp);
515 
516  double *stat;
517  d_ocp_qp_ipm_get_stat(&workspace, &stat);
518  printf("\nalpha_aff\tmu_aff\t\tsigma\t\talpha\t\tmu\n");
519  d_print_exp_tran_mat(5, d->iter_count, stat, 5);
520 
521  printf("\nHPIPM returned with flag %i.\n", d->return_status);
522  if(d->return_status == 0)
523  {
524  printf("\n -> QP solved!\n");
525  }
526  else if(d->return_status==1)
527  {
528  printf("\n -> Solver failed! Maximum number of iterations reached\n");
529  }
530  else if(d->return_status==2)
531  {
532  printf("\n -> Solver failed! Minimum step lenght reached\n");
533  }
534  else if(d->return_status==2)
535  {
536  printf("\n -> Solver failed! NaN in computations\n");
537  }
538  else
539  {
540  printf("\n -> Solver failed! Unknown return flag\n");
541  }
542  printf("\n\n");
543 
544 
545  for(i=0; i<p->N+1; ++i) d_ocp_qp_sol_get_u(i, &qp_sol, d->hu[i]);
546  for(i=0; i<p->N+1; ++i) d_ocp_qp_sol_get_x(i, &qp_sol, d->hx[i]);
547  for(i=0; i<p->N; ++i) d_ocp_qp_sol_get_pi(i, &qp_sol, d->pis[i]);
548 
549 
550  if (d_qp->lam_x) {
551  offset = 0;
552  for (i=0; i<p->N+1; ++i) {
553  double* lam_lb = d->pv;
554  double* lam_ub = d->pv+p->nbx[i]+p->nbu[i];
555  d_ocp_qp_sol_get_lam_lb(i, &qp_sol, lam_lb);
556  d_ocp_qp_sol_get_lam_ub(i, &qp_sol, lam_ub);
557  for (k=0;k<p->nbx[i];++k) {
558  d_qp->lam_x[offset+k] = (lam_ub[k+p->nbu[i]]-lam_lb[k+p->nbu[i]])*2;
559  }
560  offset += p->nbx[i];
561  for (k=0;k<p->nbu[i];++k) {
562  d_qp->lam_x[offset+k] = (lam_ub[k]-lam_lb[k])*2;
563  }
564  offset += p->nbu[i];
565  }
566  }
567 
568  if (d_qp->lam_a) {
569  offset = 0;
570  for (i=0; i<p->N+1; ++i) {
571  double* lam_lg = d->pv;
572  double* lam_ug = d->pv+p->ng[i];
573  d_ocp_qp_sol_get_lam_lg(i, &qp_sol, lam_lg);
574  d_ocp_qp_sol_get_lam_ug(i, &qp_sol, lam_ug);
575  for (k=0;k<p->ng[i];++k) {
576  d_qp->lam_a[offset+(i<p->N ? p->nx[i+1]: 0)+k] = (lam_ug[k]-lam_lg[k])*2;
577  }
578  offset += p->ng[i]+(i<p->N ? p->nx[i+1]: 0);
579  }
580  }
581 
582  casadi_hpipm_dense_transfer(1.0, d->x, p->theirs_Xsp, d_qp->x, p->xsp, d->pv);
583  casadi_hpipm_dense_transfer(1.0, d->u, p->theirs_Usp, d_qp->x, p->usp, d->pv);
584 
585 
586  // Deal with non-unity I block
587  for (k=0;k<p->N;++k) {
588  n_row = p->nx[k+1];
589  for (i=0;i<n_row;++i) {
590  f = -1/d->hI[k][i];
591  d->pis[k][i]*=f;
592  }
593  }
594 
595  casadi_hpipm_dense_transfer(2.0, d->pi, p->pisp, d_qp->lam_a, p->lamg_gapsp, d->pv);
596 
597  // Construct f
598  f = casadi_dot(p_qp->nx, d_qp->g, d_qp->x);
599  f += 0.5*casadi_bilin(d_qp->h, p_qp->sp_h, d_qp->x, d_qp->x);
600 
601  if (d_qp->f) d_qp->f[0] = f;
602 
603  /*
604  m->fstats.at("postprocessing").toc();
605 
606  */
607 
608  return d->return_status==0;
609 }
void casadi_sparsify(const T1 *x, T2 *y, const casadi_int *sp_y, casadi_int tr)
Convert dense to sparse.
void casadi_scal(casadi_int n, T1 alpha, T1 *x)
SCAL: x <- alpha*x.
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