blob: 1c9f37ded6f1ab25622f6fb8c34173f654c4a723 [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.
44 double DTheta(double distance) const {
45 // TODO(austin): We are re-computing DPoint here!
Austin Schuh280996e2019-01-19 17:43:37 -080046 const AlphaAndIndex a = DistanceToAlpha(distance);
47 const Spline &spline = splines_[a.index];
48 return spline.DTheta(a.alpha) / spline.DPoint(a.alpha).norm();
Austin Schuh941b46d2018-12-19 18:06:05 +110049 }
50
Austin Schuhec7f06d2019-01-04 07:47:15 +110051 double DThetaDt(double distance, double velocity) const {
52 return DTheta(distance) * velocity;
53 }
54
Austin Schuh941b46d2018-12-19 18:06:05 +110055 // Returns the angular acceleration as a function of distance.
56 double DDTheta(double distance) const;
57
58 // Returns the length of the path in meters.
59 double length() const { return distances_.back(); }
60
61 private:
Austin Schuh280996e2019-01-19 17:43:37 -080062 struct AlphaAndIndex {
63 size_t index;
64 double alpha;
65 };
66
Austin Schuh941b46d2018-12-19 18:06:05 +110067 // Computes alpha for a distance
Austin Schuh280996e2019-01-19 17:43:37 -080068 AlphaAndIndex DistanceToAlpha(double distance) const;
69
70 ::std::vector<double> BuildDistances(size_t num_alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110071
72 // The spline we are converting to a distance.
Austin Schuh280996e2019-01-19 17:43:37 -080073 const ::std::vector<Spline> splines_;
Austin Schuh941b46d2018-12-19 18:06:05 +110074 // An interpolation table of distances evenly distributed in alpha.
Austin Schuh280996e2019-01-19 17:43:37 -080075 const ::std::vector<double> distances_;
Austin Schuh941b46d2018-12-19 18:06:05 +110076};
77
78} // namespace drivetrain
79} // namespace control_loops
80} // namespace frc971
81
82#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_