Skip to content

Commit 73c9f0e

Browse files
Create a new qp solver based on sdqp (#52)
* Create a new qp solver based on sdqp * remove sdqp dependency
1 parent 76a628e commit 73c9f0e

File tree

12 files changed

+643
-823
lines changed

12 files changed

+643
-823
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ set(cddp_core_srcs
176176
src/cddp_core/constraint.cpp
177177
src/cddp_core/helper.cpp
178178
src/cddp_core/boxqp.cpp
179+
src/cddp_core/qp_solver.cpp
179180
src/cddp_core/cddp_core.cpp
180181
src/cddp_core/clddp_core.cpp
181182
src/cddp_core/logddp_core.cpp

include/cddp-cpp/cddp.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "cddp_core/cddp_core.hpp"
2929
#include "cddp_core/helper.hpp"
3030
#include "cddp_core/boxqp.hpp"
31+
#include "cddp_core/qp_solver.hpp"
3132

3233
#include "cddp_core/torch_dynamical_system.hpp"
3334

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
Copyright 2024 Tomo Sasaki
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#ifndef CDDP_QP_SOLVER_HPP
18+
#define CDDP_QP_SOLVER_HPP
19+
20+
#include <Eigen/Dense>
21+
#include <memory>
22+
#include <vector>
23+
#include <random>
24+
25+
namespace cddp {
26+
27+
/**
28+
* @brief Solver status codes
29+
*/
30+
enum class QPStatus {
31+
OPTIMAL = 0, ///< Optimal solution found
32+
INFEASIBLE = 1, ///< Problem is infeasible
33+
MAX_ITER = 2, ///< Maximum iterations reached
34+
NUMERICAL_ERROR = 3 ///< Numerical issues encountered
35+
};
36+
37+
/**
38+
* @brief Configuration parameters for QP solver
39+
*/
40+
struct QPSolverOptions {
41+
double eps = 1e-6; ///< Numerical tolerance
42+
int max_iterations = 1000; ///< Maximum iterations
43+
bool warm_start = false; ///< Use warm start if available
44+
bool verbose = false; ///< Print debug info
45+
int random_seed = 42; ///< Random seed for initialization
46+
};
47+
48+
/**
49+
* @brief Result structure containing solution and status information
50+
*/
51+
struct QPResult {
52+
Eigen::VectorXd x; ///< Optimal solution
53+
double objective_value; ///< Optimal objective value
54+
QPStatus status; ///< Solution status
55+
int iterations; ///< Number of iterations used
56+
double solve_time; ///< Solution time in seconds
57+
};
58+
59+
/**
60+
* @brief Quadratic Programming Solver using SDQP algorithm
61+
*
62+
* Solves problems of the form:
63+
* minimize 1/2 x'Qx + c'x
64+
* subject to Ax <= b
65+
*/
66+
class QPSolver {
67+
public:
68+
/**
69+
* @brief Constructor
70+
* @param options Solver configuration options
71+
*/
72+
explicit QPSolver(const QPSolverOptions& options = QPSolverOptions());
73+
74+
/**
75+
* @brief Set problem dimensions
76+
* @param num_vars Number of variables
77+
* @param num_constraints Number of constraints
78+
*/
79+
void setDimensions(int num_vars, int num_constraints);
80+
81+
/**
82+
* @brief Set the quadratic cost matrix Q
83+
* @param Q Quadratic cost matrix (must be positive definite)
84+
*/
85+
void setHessian(const Eigen::MatrixXd& Q);
86+
87+
/**
88+
* @brief Set the linear cost vector c
89+
* @param c Linear cost vector
90+
*/
91+
void setGradient(const Eigen::VectorXd& c);
92+
93+
/**
94+
* @brief Set the constraint matrix A and vector b
95+
* @param A Constraint matrix
96+
* @param b Constraint vector
97+
*/
98+
void setConstraints(const Eigen::MatrixXd& A, const Eigen::VectorXd& b);
99+
100+
/**
101+
* @brief Solve the QP problem
102+
* @return QPResult containing solution and status
103+
*/
104+
QPResult solve();
105+
106+
private:
107+
QPSolverOptions options_;
108+
int num_vars_;
109+
int num_constraints_;
110+
111+
Eigen::MatrixXd Q_; // Quadratic cost matrix
112+
Eigen::VectorXd c_; // Linear cost vector
113+
Eigen::MatrixXd A_; // Constraint matrix
114+
Eigen::VectorXd b_; // Constraint vector
115+
116+
// Work matrices/vectors
117+
Eigen::MatrixXd halves_;
118+
std::vector<Eigen::VectorXd> work_vectors_;
119+
std::vector<int> work_indices_;
120+
121+
/**
122+
* @brief Solve minimum norm problem (internal)
123+
* @param x Solution vector
124+
* @return QPStatus solution status
125+
*/
126+
QPStatus solveMinNorm(Eigen::VectorXd& x);
127+
128+
/**
129+
* @brief Generate random permutation (internal)
130+
* @param n Size of permutation
131+
* @param perm Output permutation vector
132+
*/
133+
void generateRandomPermutation(int n, Eigen::VectorXi& perm);
134+
135+
/**
136+
* @brief Move element to front of linked list (internal)
137+
* @param i Index to move
138+
* @param next Next pointers
139+
* @param prev Previous pointers
140+
* @return Previous index
141+
*/
142+
static int moveToFront(int i, Eigen::VectorXi& next, Eigen::VectorXi& prev);
143+
144+
// Random number generator
145+
std::mt19937 rng_;
146+
};
147+
148+
} // namespace cddp
149+
150+
#endif // CDDP_QP_SOLVER_HPP

0 commit comments

Comments
 (0)