blob: ab88560ef554a7150ee5ba1811c0a4ebb4cec4b7 [file] [log] [blame]
Austin Schuh941b46d2018-12-19 18:06:05 +11001#ifndef FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_
2#define FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_
3
4#include <vector>
5
6#include "Eigen/Dense"
7#include "frc971/control_loops/drivetrain/spline.h"
8#include "frc971/control_loops/fixed_quadrature.h"
9
10namespace frc971 {
11namespace control_loops {
12namespace drivetrain {
13
14// Class to hold a spline as a function of distance.
15class DistanceSpline {
16 public:
17 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
18
Austin Schuh280996e2019-01-19 17:43:37 -080019 DistanceSpline(const Spline &spline, int num_alpha = 0);
20 DistanceSpline(::std::vector<Spline> &&splines, int num_alpha = 0);
Austin Schuh941b46d2018-12-19 18:06:05 +110021
22 // Returns a point on the spline as a function of distance.
23 ::Eigen::Matrix<double, 2, 1> XY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080024 const AlphaAndIndex a = DistanceToAlpha(distance);
25 return splines_[a.index].Point(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110026 }
27
28 // Returns the velocity as a function of distance.
29 ::Eigen::Matrix<double, 2, 1> DXY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080030 const AlphaAndIndex a = DistanceToAlpha(distance);
31 return splines_[a.index].DPoint(a.alpha).normalized();
Austin Schuh941b46d2018-12-19 18:06:05 +110032 }
33
34 // Returns the acceleration as a function of distance.
35 ::Eigen::Matrix<double, 2, 1> DDXY(double distance) const;
36
37 // Returns the heading as a function of distance.
38 double Theta(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080039 const AlphaAndIndex a = DistanceToAlpha(distance);
40 return splines_[a.index].Theta(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110041 }
42
43 // Returns the angular velocity as a function of distance.
James Kuszmaulaa2499d2020-06-02 21:31:19 -070044 // This is also equivalent to the curvature at the given point.
Austin Schuh941b46d2018-12-19 18:06:05 +110045 double DTheta(double distance) const {
46 // TODO(austin): We are re-computing DPoint here!
Austin Schuh280996e2019-01-19 17:43:37 -080047 const AlphaAndIndex a = DistanceToAlpha(distance);
48 const Spline &spline = splines_[a.index];
49 return spline.DTheta(a.alpha) / spline.DPoint(a.alpha).norm();
Austin Schuh941b46d2018-12-19 18:06:05 +110050 }
51
James Kuszmaulaa2499d2020-06-02 21:31:19 -070052 // Returns the derivative of heading with respect to time at a given
53 // distance along the spline, if we are travelling at the provided velocity.
Austin Schuhec7f06d2019-01-04 07:47:15 +110054 double DThetaDt(double distance, double velocity) const {
55 return DTheta(distance) * velocity;
56 }
57
Austin Schuh941b46d2018-12-19 18:06:05 +110058 // Returns the angular acceleration as a function of distance.
59 double DDTheta(double distance) const;
60
61 // Returns the length of the path in meters.
62 double length() const { return distances_.back(); }
63
64 private:
Austin Schuh280996e2019-01-19 17:43:37 -080065 struct AlphaAndIndex {
66 size_t index;
67 double alpha;
68 };
69
Austin Schuh941b46d2018-12-19 18:06:05 +110070 // Computes alpha for a distance
Austin Schuh280996e2019-01-19 17:43:37 -080071 AlphaAndIndex DistanceToAlpha(double distance) const;
72
73 ::std::vector<double> BuildDistances(size_t num_alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110074
75 // The spline we are converting to a distance.
Austin Schuh280996e2019-01-19 17:43:37 -080076 const ::std::vector<Spline> splines_;
Austin Schuh941b46d2018-12-19 18:06:05 +110077 // An interpolation table of distances evenly distributed in alpha.
Austin Schuh280996e2019-01-19 17:43:37 -080078 const ::std::vector<double> distances_;
Austin Schuh941b46d2018-12-19 18:06:05 +110079};
80
81} // namespace drivetrain
82} // namespace control_loops
83} // namespace frc971
84
85#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_