33 SolverOsqp::SolverOsqp()
36 _settings = std::unique_ptr<OSQPSettings>(
new OSQPSettings);
39 osqp_set_default_settings(_settings.get());
42 _settings->verbose = 0;
45 SolverOsqp::~SolverOsqp()
48 if (_work) osqp_cleanup(_work);
53 if (_initialized)
return true;
63 bool zero_x_warmstart)
65 PRINT_ERROR(
"This method is currently not implemented.");
71 bool update_A,
bool update_bounds)
82 if (!P.isCompressed()) P.makeCompressed();
83 if (!A.isCompressed()) A.makeCompressed();
85 csc* P_csc = csc_matrix(P.rows(), P.cols(), P.nonZeros(), P.valuePtr(), P.innerIndexPtr(), P.outerIndexPtr());
86 csc* A_csc = csc_matrix(A.rows(), A.cols(), A.nonZeros(), A.valuePtr(), A.innerIndexPtr(), A.outerIndexPtr());
89 std::unique_ptr<OSQPData> data;
90 if (new_structure || _force_new_structure || !_settings->warm_start || !_work)
93 if (_work) osqp_cleanup(_work);
97 data = std::unique_ptr<OSQPData>(
new OSQPData);
103 data->l = lbA.data();
104 data->u = ubA.data();
107 c_int exitflag = osqp_setup(&_work, data.get(), _settings.get());
109 if (!_work || exitflag != 0)
115 _force_new_structure =
false;
125 if (zero_x_warmstart)
127 if (_zero.size() != _work->data->n) _zero.setZero(_work->data->n);
131 int dim_constr = _work->data->m;
133 if (update_P && update_A && dim_constr > 0)
135 if (osqp_update_P_A(_work, P.valuePtr(), OSQP_NULL, P.nonZeros(), A.valuePtr(), OSQP_NULL, A.nonZeros()) != 0)
137 PRINT_ERROR(
"SolverOSQP: Cannot update P and A due to dimensions mismatch. Maybe a new sparsity pattern?");
143 if (osqp_update_P(_work, P.valuePtr(), OSQP_NULL, P.nonZeros()) != 0)
145 PRINT_ERROR(
"SolverOSQP: Cannot update P due to dimensions mismatch. Maybe a new sparsity pattern?");
149 else if (update_A && dim_constr > 0)
151 if (osqp_update_A(_work, A.valuePtr(), OSQP_NULL, A.nonZeros()) != 0)
153 PRINT_ERROR_NAMED(
"SolverOSQP: Cannot update A due to dimensions mismatch. Maybe a new sparsity pattern?");
160 if (osqp_update_lin_cost(_work, q.data()) != 0)
167 if (update_bounds && dim_constr > 0)
169 if (osqp_update_bounds(_work, lbA.data(), ubA.data()) != 0)
192 if (data->P) c_free(data->P);
193 if (data->A) c_free(data->A);
200 return convertOsqpExitFlagToSolverStatus(_work->info->status_val);
219 PRINT_ERROR_NAMED(
"No previous workspace found. Cannot update primal solution...");
222 if (x.size() == _work->data->n)
223 osqp_warm_start_x(_work, x.data());
231 PRINT_ERROR_NAMED(
"No previous workspace found. Cannot update dual solution...");
234 if (y.size() == _work->data->m)
236 if (y.size() > 0) osqp_warm_start_y(_work, y.data());
242 SolverStatus SolverOsqp::convertOsqpExitFlagToSolverStatus(c_int status)
const 247 case OSQP_SOLVED_INACCURATE:
251 case OSQP_MAX_ITER_REACHED:
252 case OSQP_TIME_LIMIT_REACHED:
257 case OSQP_PRIMAL_INFEASIBLE:
258 case OSQP_DUAL_INFEASIBLE:
283 _force_new_structure =
true;
284 _initialized =
false;
287 #ifdef MESSAGE_SUPPORT 288 void SolverOsqp::toMessage(corbo::messages::SolverOsqp& message)
const 290 message.set_max_iter(_settings->max_iter);
291 message.set_eps_abs(_settings->eps_abs);
292 message.set_eps_rel(_settings->eps_rel);
293 message.set_eps_prim_inf(_settings->eps_prim_inf);
294 message.set_eps_dual_inf(_settings->eps_dual_inf);
295 message.set_alpha(_settings->alpha);
296 message.set_verbose(_settings->verbose);
297 message.set_scaled_termination(_settings->scaled_termination);
298 message.set_check_termination(_settings->check_termination);
299 message.set_warm_start(_settings->warm_start);
300 message.set_time_limit(_settings->time_limit);
302 message.set_rho(_settings->rho);
303 message.set_sigma(_settings->sigma);
304 message.set_scaling(_settings->scaling);
305 message.set_adaptive_rho(_settings->adaptive_rho);
307 message.set_delta(_settings->delta);
308 message.set_polish(_settings->polish);
309 message.set_polish_refine_iter(_settings->polish_refine_iter);
311 switch (_settings->linsys_solver)
315 message.set_linear_solver(messages::SolverOsqp_LinearSolver_QDLDL);
318 case MKL_PARDISO_SOLVER:
320 message.set_linear_solver(messages::SolverOsqp_LinearSolver_MKL_PARADISO);
326 void SolverOsqp::fromMessage(
const corbo::messages::SolverOsqp& message, std::stringstream* issues)
328 _settings->max_iter = message.max_iter();
329 _settings->eps_abs = message.eps_abs();
330 _settings->eps_rel = message.eps_rel();
331 _settings->eps_prim_inf = message.eps_prim_inf();
332 _settings->eps_dual_inf = message.eps_dual_inf();
333 _settings->alpha = message.alpha();
334 _settings->verbose = message.verbose();
335 _settings->scaled_termination = message.scaled_termination();
336 _settings->check_termination = message.check_termination();
337 _settings->warm_start = message.warm_start();
338 _settings->time_limit = message.time_limit();
340 _settings->rho = message.rho();
341 _settings->sigma = message.sigma();
342 _settings->scaling = message.scaling();
343 _settings->adaptive_rho = message.adaptive_rho();
345 _settings->delta = message.delta();
346 _settings->polish = message.polish();
347 _settings->polish_refine_iter = message.polish_refine_iter();
349 switch (message.linear_solver())
351 case messages::SolverOsqp_LinearSolver_QDLDL:
353 _settings->linsys_solver = QDLDL_SOLVER;
356 case messages::SolverOsqp_LinearSolver_MKL_PARADISO:
358 _settings->linsys_solver = MKL_PARDISO_SOLVER;
#define PRINT_ERROR_NAMED(msg)
SolverStatus solve(SparseMatrix &P, Eigen::Ref< Eigen::VectorXd > q, SparseMatrix &A, Eigen::Ref< Eigen::VectorXd > lbA, Eigen::Ref< Eigen::VectorXd > ubA, Eigen::Ref< Eigen::VectorXd > lb, Eigen::Ref< Eigen::VectorXd > ub, bool new_structure=true, bool zero_x_warmstart=false) override
Solve full QP.
void clear() override
clear internal caches
void updatePrimalSolutionWarmStart(const Eigen::Ref< const Eigen::VectorXd > &x) override
Eigen::SparseMatrix< double, Eigen::ColMajor, long long > SparseMatrix
A matrix or vector expression mapping an existing array of data.
MatrixType A(a, *n, *n, *lda)
Eigen::Ref< Eigen::VectorXd > getDualSolution() override
virtual bool initialize()
Initialize the qp solver.
constexpr const double CORBO_INF_DBL
Representation for infinity (double version)
EIGEN_DEVICE_FUNC const Scalar & q
Eigen::Ref< Eigen::VectorXd > getPrimalSolution() override
A matrix or vector expression mapping an existing expression.
void updateDualSolutionWarmStart(const Eigen::Ref< const Eigen::VectorXd > &y) override
#define PRINT_ERROR(msg)
Print msg-stream as error msg.