#pragma once #include #include #include /** * osqp interface: * minimize 0.5 x' P x + q' x * subject to l <= A x <= u **/ namespace osqp { class IOSQP { public: IOSQP() : UNBOUNDED_VAL(OSQP_INFTY), pWork(nullptr), pSettings(nullptr), pData(nullptr) { pSettings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings)); pData = (OSQPData *)c_malloc(sizeof(OSQPData)); if (pSettings) osqp_set_default_settings(pSettings); } ~IOSQP() { if (pWork) osqp_cleanup(pWork); if (pSettings) c_free(pSettings); if (pData) c_free(pData); } const double UNBOUNDED_VAL; inline c_int setMats(Eigen::SparseMatrix &P, Eigen::VectorXd &q, Eigen::SparseMatrix &A, Eigen::VectorXd &l, Eigen::VectorXd &u, const double &eps_abs = 1e-3, const double &eps_rel = 1e-3) { if (pWork) osqp_cleanup(pWork); P = P.triangularView(); P.makeCompressed(); A.makeCompressed(); pData->n = P.rows(); pData->m = A.rows(); Eigen::Map iIdxP(P.innerIndexPtr(), P.nonZeros()); Eigen::Map oIdxP(P.outerIndexPtr(), P.cols() + 1); Eigen::Matrix innerIdxP = iIdxP.cast(); Eigen::Matrix outerIdxP = oIdxP.cast(); pData->P = csc_matrix(pData->n, pData->n, P.nonZeros(), P.valuePtr(), innerIdxP.data(), outerIdxP.data()); Eigen::Map iIdxA(A.innerIndexPtr(), A.nonZeros()); Eigen::Map oIdxA(A.outerIndexPtr(), A.cols() + 1); Eigen::Matrix innerIdxA = iIdxA.cast(); Eigen::Matrix outerIdxA = oIdxA.cast(); pData->A = csc_matrix(pData->m, pData->n, A.nonZeros(), A.valuePtr(), innerIdxA.data(), outerIdxA.data()); Eigen::Matrix pDqVec = q.cast(); pData->q = pDqVec.data(); Eigen::Matrix pDlVec = l.cast(); pData->l = pDlVec.data(); Eigen::Matrix pDuVec = u.cast(); pData->u = pDuVec.data(); pSettings->eps_abs = eps_abs; pSettings->eps_rel = eps_rel; c_int exitflag = osqp_setup(&pWork, pData, pSettings); if (pData->A) c_free(pData->A); if (pData->P) c_free(pData->P); return exitflag; } inline c_int solve() const { return osqp_solve(pWork); } inline c_int getStatus() const { return pWork->info->status_val; } inline Eigen::VectorXd getPrimalSol() const { return Eigen::Map(pWork->solution->x, pWork->data->n); } private: OSQPWorkspace *pWork; OSQPSettings *pSettings; OSQPData *pData; }; } // namespace osqp