13 template <
int STATE_DIM,
int CONTROL_DIM>
14 HPIPMInterface<STATE_DIM, CONTROL_DIM>::HPIPMInterface() : N_(-1), settings_(NLOptConSettings())
22 template <
int STATE_DIM,
int CONTROL_DIM>
23 HPIPMInterface<STATE_DIM, CONTROL_DIM>::~HPIPMInterface()
28 template <
int STATE_DIM,
int CONTROL_DIM>
29 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::initializeAndAllocate()
33 std::cout <<
"HPIPM allocating memory for QP with time horizon: " <<
N_ << std::endl;
34 for (
int i = 0;
i <
N_ + 1;
i++)
36 std::cout <<
"HPIPM stage " <<
i <<
": (nx, nu, nbu, nbx, ng) : (" << nx_[
i] <<
", " << nu_[
i] <<
", " 37 << nbu_[
i] <<
", " << nbx_[
i] <<
", " << ng_[
i] <<
")" << std::endl;
42 dim_size_ = d_ocp_qp_dim_memsize(
N_);
43 dim_mem_ = malloc(dim_size_);
44 d_ocp_qp_dim_create(
N_, &dim_, dim_mem_);
46 nx_.data(), nu_.data(), nbx_.data(), nbu_.data(), ng_.data(), nsbx_.data(), nsbu_.data(), nsg_.data(), &dim_);
49 int qp_size = ::d_ocp_qp_memsize(&dim_);
50 qp_mem_ = malloc(qp_size);
51 ::d_ocp_qp_create(&dim_, &qp_, qp_mem_);
52 ::d_ocp_qp_set_all(hA_.data(), hB_.data(), hb_.data(), hQ_.data(), hS_.data(), hR_.data(), hq_.data(), hr_.data(),
53 hidxbx_.data(), hlbx_.data(), hubx_.data(), hidxbu_.data(), hlbu_.data(), hubu_.data(),
54 hC_.data(), hD_.data(), hlg_.data(), hug_.data(),
55 hZl_.data(), hZu_.data(), hzl_.data(), hzu_.data(), hidxs_.data(), hlls_.data(), hlus_.data(), &qp_);
58 int qp_sol_size = ::d_ocp_qp_sol_memsize(&dim_);
59 qp_sol_mem_ = malloc(qp_sol_size);
60 ::d_ocp_qp_sol_create(&dim_, &qp_sol_, qp_sol_mem_);
63 int ipm_arg_size = ::d_ocp_qp_ipm_arg_memsize(&dim_);
64 ipm_arg_mem_ = malloc(ipm_arg_size);
65 ::d_ocp_qp_ipm_arg_create(&dim_, &arg_, ipm_arg_mem_);
67 ::d_ocp_qp_ipm_arg_set_default(mode_, &arg_);
71 int ipm_size = ::d_ocp_qp_ipm_ws_memsize(&dim_, &arg_);
72 ipm_mem_ = malloc(ipm_size);
73 ::d_ocp_qp_ipm_ws_create(&dim_, &arg_, &workspace_, ipm_mem_);
78 std::cout <<
"HPIPM qp_size: " << qp_size << std::endl;
79 std::cout <<
"HPIPM qp_sol_size: " << qp_sol_size << std::endl;
80 std::cout <<
"HPIPM ipm_arg_size: " << ipm_arg_size << std::endl;
81 std::cout <<
"HPIPM ipm_size: " << ipm_size << std::endl;
86 template <
int STATE_DIM,
int CONTROL_DIM>
87 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::configure(
const NLOptConSettings& settings)
94 template <
int STATE_DIM,
int CONTROL_DIM>
95 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::solve()
98 #ifdef HPIPM_PRINT_MATRICES 99 for (
int i = 0;
i <
N_ + 1;
i++)
101 std::cout <<
"HPIPM matrix printout for stage " <<
i << std::endl;
105 d_print_mat(STATE_DIM, STATE_DIM, hA_[
i], STATE_DIM);
107 d_print_mat(STATE_DIM, CONTROL_DIM, hB_[
i], STATE_DIM);
109 d_print_mat(1, STATE_DIM, hb_[
i], 1);
113 d_print_mat(STATE_DIM, STATE_DIM, hQ_[
i], STATE_DIM);
115 d_print_mat(1, STATE_DIM, hq_[
i], 1);
121 d_print_mat(CONTROL_DIM, CONTROL_DIM, hR_[
i], CONTROL_DIM);
123 d_print_mat(CONTROL_DIM, STATE_DIM, hS_[
i], CONTROL_DIM);
125 d_print_mat(1, CONTROL_DIM, hr_[
i], 1);
129 std::cout << nbu_[
i] << std::endl;
131 d_print_mat(1, nbu_[
i], hlbu_[i], 1);
133 d_print_mat(1, nbu_[
i], hubu_[i], 1);
136 std::cout << nbx_[
i] << std::endl;
138 d_print_mat(1, nbx_[
i], hlbx_[i], 1);
140 d_print_mat(1, nbx_[
i], hubx_[i], 1);
143 std::cout << ng_[
i] << std::endl;
145 d_print_mat(ng_[
i], STATE_DIM, hC_[i], ng_[i]);
147 d_print_mat(ng_[
i], CONTROL_DIM, hD_[i], ng_[i]);
149 d_print_mat(1, ng_[
i], hlg_[i], 1);
151 d_print_mat(1, ng_[
i], hug_[i], 1);
154 #endif // HPIPM_PRINT_MATRICES 158 ::d_ocp_qp_ipm_solve(&qp_, &qp_sol_, &arg_, &workspace_);
159 ::d_ocp_qp_ipm_get_status(&workspace_, &hpipm_status_);
161 isLrInvComputed_ =
false;
166 printf(
"\nHPIPM returned with flag %i.\n", hpipm_status_);
167 if (hpipm_status_ == 0)
169 printf(
"\n -> QP solved!\n");
171 else if (hpipm_status_ == 1)
173 printf(
"\n -> Solver failed! Maximum number of iterations reached\n");
175 else if (hpipm_status_ == 2)
177 printf(
"\n -> Solver failed! Minimum step length reached\n");
179 else if (hpipm_status_ == 2)
181 printf(
"\n -> Solver failed! NaN in computations\n");
185 printf(
"\n -> Solver failed! Unknown return flag\n");
187 printf(
"\nipm iter = %d\n", workspace_.iter);
188 printf(
"\nalpha_aff\tmu_aff\t\tsigma\t\talpha\t\tmu\n");
189 d_print_e_tran_mat(5, workspace_.iter, workspace_.stat, 5);
193 template <
int STATE_DIM,
int CONTROL_DIM>
194 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::computeStatesAndControls()
197 for (
int ii = 0; ii <
N_; ii++)
199 Eigen::Matrix<double, CONTROL_DIM, 1> u_sol;
200 ::d_ocp_qp_sol_get_u(ii, &qp_sol_, this->
u_sol_[ii].
data());
202 for (
int ii = 0; ii <=
N_; ii++)
204 Eigen::Matrix<double, STATE_DIM, 1> x_sol;
205 ::d_ocp_qp_sol_get_x(ii, &qp_sol_, this->
x_sol_[ii].
data());
215 template <
int STATE_DIM,
int CONTROL_DIM>
216 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::computeLrInvArray()
219 Eigen::Matrix<double, control_dim, control_dim> Lr;
220 for (
int i = 0;
i <
N_;
i++)
222 ::d_ocp_qp_ipm_get_ric_Lr(
i, &workspace_, Lr.data());
223 Lr_inv_[
i] = (Lr.template triangularView<Eigen::Lower>())
224 .solve(Eigen::Matrix<double, control_dim, control_dim>::Identity());
226 isLrInvComputed_ =
true;
229 template <
int STATE_DIM,
int CONTROL_DIM>
230 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::computeFeedbackMatrices()
232 if (isLrInvComputed_ ==
false)
235 LQOCProblem<STATE_DIM, CONTROL_DIM>& p = *this->
lqocProblem_;
236 this->
L_.resize(p.getNumberOfStages());
239 Eigen::Matrix<double, state_dim, control_dim> Ls;
243 ::d_ocp_qp_ipm_get_ric_Ls(
i, &workspace_, Ls.data());
244 this->
L_[
i] = -(Ls * Lr_inv_[
i]).transpose();
249 Eigen::Matrix<double, state_dim, state_dim> S1;
250 ::d_ocp_qp_ipm_get_ric_P(1, &workspace_, S1.data());
253 Eigen::Matrix<double, control_dim, state_dim> G;
255 G.noalias() += p.B_[0].transpose() * S1 * p.A_[0];
258 this->L_[0] = (-Lr_inv_[0].transpose() * Lr_inv_[0] * G);
261 template <
int STATE_DIM,
int CONTROL_DIM>
262 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::compute_lv()
265 throw std::runtime_error(
266 "Retrieving lv is not compatible with constraints in HPIPM. Switch to different algorithm, e.g. GNMS, " 267 "which does not require lv");
269 if (isLrInvComputed_ ==
false)
272 Eigen::Matrix<double, control_dim, 1> lr;
275 ::d_ocp_qp_ipm_get_ric_lr(
i, &workspace_, lr.data());
276 this->
lv_[
i] = -Lr_inv_[
i].transpose() * lr;
280 template <
int STATE_DIM,
int CONTROL_DIM>
283 #ifdef HPIPM_PRINT_MATRICES 286 std::cout <<
"Solution for u: " << std::endl;
287 for (ii = 0; ii <
N_; ii++)
289 std::cout << this->
u_sol_[ii].transpose() << std::endl;
292 std::cout <<
"Solution for x: " << std::endl;
293 for (ii = 0; ii <=
N_; ii++)
295 std::cout << this->
x_sol_[ii].transpose() << std::endl;
297 #endif // HPIPM_PRINT_MATRICES 300 ::d_ocp_qp_ipm_get_iter(&workspace_, &iter);
301 printf(
"\nalpha_aff\tmu_aff\t\tsigma\t\talpha\t\tmu\n");
302 ::d_print_mat(5, iter, workspace_.stat, 5);
306 template <
int STATE_DIM,
int CONTROL_DIM>
307 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::setProblemImpl(
308 std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
311 bool dimsChanged = changeProblemSize(lqocProblem);
318 setupCostAndDynamics(lqocProblem->A_, lqocProblem->B_, lqocProblem->b_, lqocProblem->P_, lqocProblem->qv_,
319 lqocProblem->Q_, lqocProblem->rv_, lqocProblem->R_);
328 ::d_ocp_qp_set_all(hA_.data(), hB_.data(), hb_.data(), hQ_.data(), hS_.data(), hR_.data(), hq_.data(),
329 hr_.data(), hidxbx_.data(), hlbx_.data(), hubx_.data(), hidxbu_.data(), hlbu_.data(), hubu_.data(),
330 hC_.data(), hD_.data(), hlg_.data(), hug_.data(), hZl_.data(), hZu_.data(), hzl_.data(), hzu_.data(),
331 hidxs_.data(), hlls_.data(), hlus_.data(), &qp_);
336 template <
int STATE_DIM,
int CONTROL_DIM>
337 bool HPIPMInterface<STATE_DIM, CONTROL_DIM>::configureInputBoxConstraints(
338 std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
340 bool configChanged =
false;
342 const int N = lqocProblem->getNumberOfStages();
344 if ((
int)nbu_.size() != N + 1)
346 nbu_.resize(N + 1, 0);
347 hidxbu_.resize(N + 1);
350 configChanged =
true;
354 for (
int i = 0;
i < N;
i++)
356 if (nbu_[
i] != lqocProblem->nbu_[
i])
358 nbu_[
i] = lqocProblem->nbu_[
i];
361 hlbu_[
i] = lqocProblem->u_lb_[
i].data();
362 hubu_[
i] = lqocProblem->u_ub_[
i].data();
363 hidxbu_[
i] = lqocProblem->u_I_[
i].data();
365 configChanged =
true;
369 return configChanged;
373 template <
int STATE_DIM,
int CONTROL_DIM>
374 bool HPIPMInterface<STATE_DIM, CONTROL_DIM>::configureStateBoxConstraints(
375 std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
377 bool configChanged =
false;
379 const int N = lqocProblem->getNumberOfStages();
381 if ((
int)nbx_.size() != N + 1)
383 nbx_.resize(N + 1, 0);
384 hidxbx_.resize(N + 1);
387 configChanged =
true;
391 for (
int i = 0;
i < N + 1;
i++)
400 if (nbx_[
i] != lqocProblem->nbx_[
i])
402 nbx_[
i] = lqocProblem->nbx_[
i];
405 hlbx_[
i] = lqocProblem->x_lb_[
i].data();
406 hubx_[
i] = lqocProblem->x_ub_[
i].data();
407 hidxbx_[
i] = lqocProblem->x_I_[
i].data();
409 configChanged =
true;
413 return configChanged;
417 template <
int STATE_DIM,
int CONTROL_DIM>
418 bool HPIPMInterface<STATE_DIM, CONTROL_DIM>::configureGeneralConstraints(
419 std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
421 bool configChanged =
false;
423 const int N = lqocProblem->getNumberOfStages();
424 if ((
int)ng_.size() != N + 1)
426 ng_.resize(N + 1, 0);
427 hlg_.resize(N + 1, 0);
428 hug_.resize(N + 1, 0);
431 configChanged =
true;
436 hd_lg_0_Eigen_ = lqocProblem->d_lb_[0];
437 hd_ug_0_Eigen_ = lqocProblem->d_ub_[0];
439 for (
int i = 0;
i < N + 1;
i++)
442 if (ng_[
i] != lqocProblem->ng_[
i])
444 ng_[
i] = lqocProblem->ng_[
i];
445 configChanged =
true;
448 lqocProblem->C_[
i].resize(lqocProblem->ng_[
i], STATE_DIM);
449 lqocProblem->D_[
i].resize(lqocProblem->ng_[
i], CONTROL_DIM);
450 lqocProblem->d_lb_[
i].resize(lqocProblem->ng_[
i], 1);
451 lqocProblem->d_ub_[
i].resize(lqocProblem->ng_[
i], 1);
456 hlg_[
i] = hd_lg_0_Eigen_.data();
457 hug_[
i] = hd_ug_0_Eigen_.data();
461 hlg_[
i] = lqocProblem->d_lb_[
i].data();
462 hug_[
i] = lqocProblem->d_ub_[
i].data();
465 hC_[
i] = lqocProblem->C_[
i].data();
466 hD_[
i] = lqocProblem->D_[
i].data();
469 return configChanged;
473 template <
int STATE_DIM,
int CONTROL_DIM>
474 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::setupCostAndDynamics(
StateMatrixArray& A,
484 throw std::runtime_error(
"Time horizon not set, please set it first");
486 this->
x_sol_[0].setZero();
493 for (
int i = 0;
i <
N_;
i++)
495 hA_[
i] = A[
i].data();
496 hB_[
i] = B[
i].data();
499 hb_[
i] = b[
i].data();
502 for (
int i = 0;
i <
N_;
i++)
504 hQ_[
i] = Q[
i].data();
505 hS_[
i] = P[
i].data();
506 hR_[
i] = R[
i].data();
507 hq_[
i] = qv[
i].data();
510 hr_[
i] = rv[
i].data();
514 hQ_[
N_] = Q[
N_].data();
515 hq_[
N_] = qv[
N_].data();
519 template <
int STATE_DIM,
int CONTROL_DIM>
520 bool HPIPMInterface<STATE_DIM, CONTROL_DIM>::changeProblemSize(std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> p)
522 const int N = p->getNumberOfStages();
525 bool horizonChanged =
false;
528 horizonChanged =
true;
534 bool numConstraintsChanged =
false;
537 numConstraintsChanged =
true;
540 numConstraintsChanged =
true;
543 numConstraintsChanged =
true;
547 if (!horizonChanged && !numConstraintsChanged)
554 nu_.back() = CONTROL_DIM;
555 nu_.resize(N_ + 1, CONTROL_DIM);
558 nx_.resize(N_ + 1, STATE_DIM);
567 this->
x_sol_.resize(N_ + 1);
569 this->
lv_.resize(N_);
580 nsbx_.resize(N_ + 1, 0);
581 nsbu_.resize(N_ + 1, 0);
582 nsg_.resize(N_ + 1, 0);
584 hZl_.resize(N_ + 1, 0);
585 hZu_.resize(N_ + 1, 0);
586 hzl_.resize(N_ + 1, 0);
587 hzu_.resize(N_ + 1, 0);
589 hidxs_.resize(N_ + 1, 0);
591 hlls_.resize(N_ + 1, 0);
592 hlus_.resize(N_ + 1, 0);
597 hb_[0] = hb0_.data();
598 hr_[0] = hr0_.data();
607 template <
int STATE_DIM,
int CONTROL_DIM>
608 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::d_print_mat(
int m,
int n,
double* A,
int lda)
611 for (i = 0; i < m; i++)
613 for (j = 0; j < n; j++)
615 printf(
"%9.5f ", A[i + lda * j]);
623 template <
int STATE_DIM,
int CONTROL_DIM>
624 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::d_print_e_tran_mat(
int row,
int col,
double* A,
int lda)
627 for (j = 0; j < col; j++)
629 for (i = 0; i < row; i++)
631 printf(
"%e\t", A[i + lda * j]);
639 template <
int STATE_DIM,
int CONTROL_DIM>
643 throw std::runtime_error(
644 "Retrieving lv is not compatible with constraints in HPIPM. Switch to different algorithm, e.g. GNMS, " 645 "which does not require lv");
void printSolution(const ct::core::StateVectorArray< state_dim > &x, const ct::core::ControlVectorArray< control_dim > &u, const ct::core::FeedbackArray< state_dim, control_dim > &K)
Definition: ConstrainedLQOCSolverTest.h:16
virtual bool configureStateBoxConstraints(std::shared_ptr< LQOCProblem< STATE_DIM, CONTROL_DIM >> lqocProblem)
Definition: LQOCSolver.hpp:58
ct::core::FeedbackArray< STATE_DIM, CONTROL_DIM, SCALAR > L_
Definition: LQOCSolver.hpp:111
int num_lqoc_iterations
Definition: NLOptConSettings.hpp:160
DiscreteArray< StateMatrix< STATE_DIM, SCALAR > > StateMatrixArray
virtual bool configureGeneralConstraints(std::shared_ptr< LQOCProblem< STATE_DIM, CONTROL_DIM >> lqocProblem)
setup and configure the general (in)equality constraints
Definition: LQOCSolver.hpp:65
virtual void configure(const NLOptConSettings &settings) override
Definition: GNRiccatiSolver-impl.hpp:49
std::shared_ptr< LQOCProblem_t > lqocProblem_
Definition: LQOCSolver.hpp:107
DiscreteArray< ControlMatrix< CONTROL_DIM, SCALAR > > ControlMatrixArray
for i
Definition: mpc_unittest_plotting.m:14
core::ControlVectorArray< CONTROL_DIM, SCALAR > u_sol_
Definition: LQOCSolver.hpp:110
ct::core::ControlVectorArray< CONTROL_DIM, SCALAR > lv_
Definition: LQOCSolver.hpp:112
virtual bool configureInputBoxConstraints(std::shared_ptr< LQOCProblem< STATE_DIM, CONTROL_DIM >> lqocProblem)
setup and configure the box constraints
Definition: LQOCSolver.hpp:52
LQOCSolverSettings lqoc_solver_settings
the line search settings
Definition: NLOptConSettings.hpp:276
virtual void initializeAndAllocate() override
a method reserved for memory allocation (e.g. required for HPIPM)
Definition: GNRiccatiSolver-impl.hpp:286
int N_
Definition: GNRiccatiSolver.hpp:93
bool lqoc_debug_print
Definition: NLOptConSettings.hpp:159
DiscreteArray< StateControlMatrix< STATE_DIM, CONTROL_DIM, SCALAR > > StateControlMatrixArray
core::StateVectorArray< STATE_DIM, SCALAR > x_sol_
Definition: LQOCSolver.hpp:109
NLOptConSettings settings_
Definition: GNRiccatiSolver.hpp:80