blob: 96954318fb5c316037b9281fbb033df5ca11ebe0 [file] [log] [blame]
Austin Schuh29441032023-05-31 19:32:24 -07001#ifndef FRC971_SOLVERS_SPARSE_CONVEX_H_
2#define FRC971_SOLVERS_SPARSE_CONVEX_H_
3
4#include <sys/types.h>
5#include <unistd.h>
6
Austin Schuh29441032023-05-31 19:32:24 -07007#include <iomanip>
8
9#include "glog/logging.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070010#include <Eigen/Sparse>
Austin Schuh29441032023-05-31 19:32:24 -070011
12namespace frc971 {
13namespace solvers {
14
15// TODO(austin): Steal JET from Ceres to generate the derivatives easily and
16// quickly?
17//
18// States is the number of inputs to the optimization problem.
19// M is the number of inequality constraints.
20// N is the number of equality constraints.
21class SparseConvexProblem {
22 public:
23 size_t states() const { return states_; }
24 size_t inequality_constraints() const { return inequality_constraints_; }
25 size_t equality_constraints() const { return equality_constraints_; }
26
27 // Returns the function to minimize and it's derivatives.
28 virtual double f0(Eigen::Ref<const Eigen::VectorXd> X) const = 0;
29 // TODO(austin): Should the jacobian be sparse?
30 virtual Eigen::SparseMatrix<double> df0(
31 Eigen::Ref<const Eigen::VectorXd> X) const = 0;
32 virtual Eigen::SparseMatrix<double> ddf0(
33 Eigen::Ref<const Eigen::VectorXd> X) const = 0;
34
35 // Returns the constraints f(X) < 0, and their derivative.
36 virtual Eigen::VectorXd f(Eigen::Ref<const Eigen::VectorXd> X) const = 0;
37 virtual Eigen::SparseMatrix<double> df(
38 Eigen::Ref<const Eigen::VectorXd> X) const = 0;
39
40 // Returns the equality constraints of the form A x = b
41 virtual Eigen::SparseMatrix<double> A() const = 0;
42 virtual Eigen::VectorXd b() const = 0;
43
44 protected:
45 SparseConvexProblem(size_t states, size_t inequality_constraints,
46 size_t equality_constraints)
47 : states_(states),
48 inequality_constraints_(inequality_constraints),
49 equality_constraints_(equality_constraints) {}
50
51 private:
52 size_t states_;
53 size_t inequality_constraints_;
54 size_t equality_constraints_;
55};
56
57// Implements a Primal-Dual Interior point method convex solver.
58// See 11.7 of https://web.stanford.edu/~boyd/cvxbook/bv_cvxbook.pdf
59//
60// States is the number of inputs to the optimization problem.
61// M is the number of inequality constraints.
62// N is the number of equality constraints.
63class SparseSolver {
64 public:
65 // Ratio to require the cost to decrease when line searching.
66 static constexpr double kAlpha = 0.05;
67 // Line search step parameter.
68 static constexpr double kBeta = 0.5;
69 static constexpr double kMu = 2.0;
70 // Terminal condition for the primal problem (equality constraints) and dual
71 // (gradient + inequality constraints).
72 static constexpr double kEpsilonF = 1e-6;
73 // Terminal condition for nu, the surrogate duality gap.
74 static constexpr double kEpsilon = 1e-6;
75
76 // Solves the problem given a feasible initial solution.
77 Eigen::VectorXd Solve(const SparseConvexProblem &problem,
78 Eigen::Ref<const Eigen::VectorXd> X_initial);
79
80 private:
81 // Class to hold all the derivataves and function evaluations.
82 struct Derivatives {
83 size_t states() const { return hessian.rows(); }
84 size_t inequality_constraints() const { return f.rows(); }
85 size_t equality_constraints() const { return Axmb.rows(); }
86
87 Eigen::SparseMatrix<double> gradient;
88 Eigen::SparseMatrix<double> hessian;
89
90 // Inequality function f
91 Eigen::VectorXd f;
92 // df
93 Eigen::SparseMatrix<double> df;
94
95 // ddf is assumed to be 0 because for the linear constraint distance
96 // function we are using, it is actually 0, and by assuming it is zero
97 // rather than passing it through as 0 to the solver, we can save enough CPU
98 // to make it worth it.
99
100 // A
101 Eigen::SparseMatrix<double> A;
102 // Ax - b
103 Eigen::VectorXd Axmb;
104 };
105
106 // Computes all the values for the given problem at the given state.
Philipp Schrader790cb542023-07-05 21:06:52 -0700107 Derivatives ComputeDerivative(const SparseConvexProblem &problem,
108 const Eigen::Ref<const Eigen::VectorXd> y);
Austin Schuh29441032023-05-31 19:32:24 -0700109
110 // Computes Rt at the given state and with the given t_inverse. See 11.53 of
111 // cvxbook.pdf.
Philipp Schrader790cb542023-07-05 21:06:52 -0700112 Eigen::VectorXd Rt(const Derivatives &derivatives, Eigen::VectorXd y,
113 double t_inverse);
Austin Schuh29441032023-05-31 19:32:24 -0700114
115 // Prints out all the derivatives with VLOG at the provided verbosity.
Philipp Schrader790cb542023-07-05 21:06:52 -0700116 void PrintDerivatives(const Derivatives &derivatives,
117 const Eigen::Ref<const Eigen::VectorXd> y,
118 std::string_view prefix, int verbosity);
Austin Schuh29441032023-05-31 19:32:24 -0700119};
120
121} // namespace solvers
122} // namespace frc971
123
124#endif // FRC971_SOLVERS_SPARSE_CONVEX_H_