blob: 4d8533fcdf1c68047be56083f0df15062433ecc9 [file] [log] [blame]
Austin Schuhc2b08772018-12-19 18:05:06 +11001#ifndef FRC971_CONTROL_LOOPS_DRIVETRAIN_SPLINE_H_
2#define FRC971_CONTROL_LOOPS_DRIVETRAIN_SPLINE_H_
3
4#include "Eigen/Dense"
5
6namespace frc971 {
7namespace control_loops {
8namespace drivetrain {
9
10// Class to hold a spline as a function of alpha. Alpha can only range between
11// 0.0 and 1.0.
12// TODO(austin): Need to be able to represent splines which have more than 2
13// control points at some point. Or splines chained together. This is close
14// enough for now.
15class Spline {
16 public:
17 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
18
19 // Constructs a spline. control_points is a matrix of start, control1,
20 // control2, end.
21 Spline(::Eigen::Matrix<double, 2, 4> control_points)
22 : control_points_(control_points) {}
23
24 // Returns the xy coordiate of the spline for a given alpha.
25 ::Eigen::Matrix<double, 2, 1> Point(double alpha) const {
26 return control_points_ *
27 (::Eigen::Matrix<double, 4, 1>() << ::std::pow((1.0 - alpha), 3),
28 3.0 * ::std::pow((1.0 - alpha), 2) * alpha,
29 3.0 * (1.0 - alpha) * ::std::pow(alpha, 2), ::std::pow(alpha, 3))
30 .finished();
31 }
32
33 // Returns the dspline/dalpha for a given alpha.
34 ::Eigen::Matrix<double, 2, 1> DPoint(double alpha) const {
35 return control_points_ *
36 (::Eigen::Matrix<double, 4, 1>()
37 << -3.0 * ::std::pow((1.0 - alpha), 2),
38 3.0 * ::std::pow((1.0 - alpha), 2) +
39 -2.0 * 3.0 * (1.0 - alpha) * alpha,
40 -3.0 * ::std::pow(alpha, 2) + 2.0 * 3.0 * (1.0 - alpha) * alpha,
41 3.0 * ::std::pow(alpha, 2))
42 .finished();
43 }
44
45 // Returns the d^2spline/dalpha^2 for a given alpha.
46 ::Eigen::Matrix<double, 2, 1> DDPoint(double alpha) const {
47 return control_points_ *
48 (::Eigen::Matrix<double, 4, 1>() << 2.0 * 3.0 * (1.0 - alpha),
49 -2.0 * 3.0 * (1.0 - alpha) + -2.0 * 3.0 * (1.0 - alpha) +
50 2.0 * 3.0 * alpha,
51 -2.0 * 3.0 * alpha + 2.0 * 3.0 * (1.0 - alpha) - 2.0 * 3.0 * alpha,
52 2.0 * 3.0 * alpha)
53 .finished();
54 }
55
56 // Returns the d^3spline/dalpha^3 for a given alpha.
57 ::Eigen::Matrix<double, 2, 1> DDDPoint(double /*alpha*/) const {
58 return control_points_ *
59 (::Eigen::Matrix<double, 4, 1>() << -2.0 * 3.0,
60 2.0 * 3.0 + 2.0 * 3.0 + 2.0 * 3.0,
61 -2.0 * 3.0 - 2.0 * 3.0 - 2.0 * 3.0, 2.0 * 3.0)
62 .finished();
63 }
64
65 // Returns theta for a given alpha.
66 double Theta(double alpha) const;
67
68 // Returns dtheta/dalpha for a given alpha.
69 double DTheta(double alpha) const;
70
71 // Returns d^2 theta/dalpha^2 for a given alpha.
72 double DDTheta(double alpha) const;
73
74 private:
75 ::Eigen::Matrix<double, 2, 4> control_points_;
76};
77
78} // namespace drivetrain
79} // namespace control_loops
80} // namespace frc971
81
82#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_SPLINE_H_