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