// // Created by xtkuang on 2025/7/7. // #ifndef QP_SOLVER_H #define QP_SOLVER_H #pragma once #include #include #include #include #include namespace cmvr::math { class QPSolverException : public std::exception { public: static constexpr unsigned int kStatusOffset = 100; explicit QPSolverException(int error_code); const char* what() const noexcept override; int code() const noexcept; static std::string GenerateMessage(int code); private: int error_code_; std::string message_; }; class QPSolverImpl { public: QPSolverImpl() = default; ~QPSolverImpl() = default; void SetupImpl(int n_var, int n_const, double time_limit); void InitFunctionImpl(); void AddCostFunctionImpl(const Eigen::MatrixXd &A, const Eigen::VectorXd &b); void SetCostFunctionImpl(const Eigen::MatrixXd &A, const Eigen::VectorXd &b); void SetConstraintsFunctionImpl(const Eigen::MatrixXd &A, const Eigen::VectorXd &lb, const Eigen::VectorXd &ub); void SetPrimalVariableImpl(const Eigen::VectorXd &pv); void ResetIsFirstImpl(); Eigen::VectorXd SolveImpl(); Eigen::MatrixXd GetACostImpl() const; Eigen::VectorXd GetBCostImpl() const; Eigen::MatrixXd GetAConstImpl() const; Eigen::VectorXd GetLowerBoundImpl() const; Eigen::VectorXd GetUpperBoundImpl() const; private: OsqpEigen::Solver solver_; int n_var_{}; int n_const_{}; int err_code_{}; int is_first_{}; int n_hessian_element_{}; Eigen::Matrix A_cost_; Eigen::Matrix b_cost_; Eigen::Matrix A_const_; Eigen::Matrix lb_; Eigen::Matrix ub_; Eigen::SparseMatrix hessian_; Eigen::Matrix gradient_; Eigen::SparseMatrix linearMatrix_; Eigen::Matrix lowerBound_; Eigen::Matrix upperBound_; Eigen::Matrix primal_variable_for_warmstart_; }; class QPSolver { public: QPSolver(); ~QPSolver(); void Setup(int n_var, int n_const, double time_limit = 2e-3); void InitFunction(); void AddCostFunction(const Eigen::MatrixXd& A, const Eigen::VectorXd& b); void SetCostFunction(const Eigen::MatrixXd& A, const Eigen::VectorXd& b); void SetConstraintsFunction(const Eigen::MatrixXd& A, const Eigen::VectorXd& lb, const Eigen::VectorXd& ub); void SetPrimalVariable(const Eigen::VectorXd& pv); void ResetIsFirst(); /** * Solve the QP problem * @return Solution * @throw QPSolverException */ Eigen::VectorXd Solve(); Eigen::MatrixXd GetACost() const; // NOLINT Eigen::VectorXd GetBCost() const; // NOLINT Eigen::MatrixXd GetAConst() const; // NOLINT Eigen::VectorXd GetLowerBound() const; // NOLINT Eigen::VectorXd GetUpperBound() const; // NOLINT private: std::unique_ptr impl_; }; } #endif //QP_SOLVER_H