blob: f445fa4a1722fe16d589f7dd494b4bcec61af4af [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"
Austin Schuhf7c65202022-11-04 21:28:20 -07007#include "absl/types/span.h"
8#include "aos/containers/sized_array.h"
Austin Schuh941b46d2018-12-19 18:06:05 +11009#include "frc971/control_loops/drivetrain/spline.h"
James Kuszmaul75a18c52021-03-10 22:02:07 -080010#include "frc971/control_loops/drivetrain/trajectory_generated.h"
Austin Schuh941b46d2018-12-19 18:06:05 +110011#include "frc971/control_loops/fixed_quadrature.h"
12
13namespace frc971 {
14namespace control_loops {
15namespace drivetrain {
16
James Kuszmaul75a18c52021-03-10 22:02:07 -080017std::vector<Spline> FlatbufferToSplines(const MultiSpline *fb);
18
Austin Schuh941b46d2018-12-19 18:06:05 +110019// Class to hold a spline as a function of distance.
Austin Schuhf7c65202022-11-04 21:28:20 -070020class DistanceSplineBase {
Austin Schuh941b46d2018-12-19 18:06:05 +110021 public:
22 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
23
Austin Schuhf7c65202022-11-04 21:28:20 -070024 virtual ~DistanceSplineBase() {}
James Kuszmaul75a18c52021-03-10 22:02:07 -080025
26 flatbuffers::Offset<fb::DistanceSpline> Serialize(
27 flatbuffers::FlatBufferBuilder *fbb,
28 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Constraint>>>
29 constraints) const;
Austin Schuh941b46d2018-12-19 18:06:05 +110030
31 // Returns a point on the spline as a function of distance.
32 ::Eigen::Matrix<double, 2, 1> XY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080033 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070034 return splines()[a.index].Point(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110035 }
36
37 // Returns the velocity as a function of distance.
38 ::Eigen::Matrix<double, 2, 1> DXY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080039 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070040 return splines()[a.index].DPoint(a.alpha).normalized();
Austin Schuh941b46d2018-12-19 18:06:05 +110041 }
42
43 // Returns the acceleration as a function of distance.
44 ::Eigen::Matrix<double, 2, 1> DDXY(double distance) const;
45
46 // Returns the heading as a function of distance.
47 double Theta(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080048 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070049 return splines()[a.index].Theta(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110050 }
51
52 // Returns the angular velocity as a function of distance.
James Kuszmaulaa2499d2020-06-02 21:31:19 -070053 // This is also equivalent to the curvature at the given point.
Austin Schuh941b46d2018-12-19 18:06:05 +110054 double DTheta(double distance) const {
55 // TODO(austin): We are re-computing DPoint here!
Austin Schuh280996e2019-01-19 17:43:37 -080056 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070057 const Spline &spline = splines()[a.index];
Austin Schuh280996e2019-01-19 17:43:37 -080058 return spline.DTheta(a.alpha) / spline.DPoint(a.alpha).norm();
Austin Schuh941b46d2018-12-19 18:06:05 +110059 }
60
James Kuszmaulaa2499d2020-06-02 21:31:19 -070061 // Returns the derivative of heading with respect to time at a given
62 // distance along the spline, if we are travelling at the provided velocity.
Austin Schuhec7f06d2019-01-04 07:47:15 +110063 double DThetaDt(double distance, double velocity) const {
64 return DTheta(distance) * velocity;
65 }
66
Austin Schuh941b46d2018-12-19 18:06:05 +110067 // Returns the angular acceleration as a function of distance.
68 double DDTheta(double distance) const;
69
70 // Returns the length of the path in meters.
Austin Schuhf7c65202022-11-04 21:28:20 -070071 double length() const { return distances().back(); }
Austin Schuh941b46d2018-12-19 18:06:05 +110072
Austin Schuhf7c65202022-11-04 21:28:20 -070073 virtual const absl::Span<const float> distances() const = 0;
74 virtual const absl::Span<const Spline> splines() const = 0;
James Kuszmaul75a18c52021-03-10 22:02:07 -080075
Austin Schuh941b46d2018-12-19 18:06:05 +110076 private:
Austin Schuh280996e2019-01-19 17:43:37 -080077 struct AlphaAndIndex {
78 size_t index;
79 double alpha;
80 };
81
Austin Schuh941b46d2018-12-19 18:06:05 +110082 // Computes alpha for a distance
Austin Schuh280996e2019-01-19 17:43:37 -080083 AlphaAndIndex DistanceToAlpha(double distance) const;
Austin Schuhf7c65202022-11-04 21:28:20 -070084};
Austin Schuh280996e2019-01-19 17:43:37 -080085
Austin Schuhf7c65202022-11-04 21:28:20 -070086// Class which computes a DistanceSpline and stores it.
87class DistanceSpline final : public DistanceSplineBase {
88 public:
89 DistanceSpline(const Spline &spline, int num_alpha = 0);
90 DistanceSpline(::std::vector<Spline> &&splines, int num_alpha = 0);
91 DistanceSpline(const MultiSpline *fb, int num_alpha = 0);
92
93 const absl::Span<const float> distances() const override {
94 return distances_;
95 }
96 const absl::Span<const Spline> splines() const override { return splines_; }
97
98 private:
James Kuszmaul75a18c52021-03-10 22:02:07 -080099 ::std::vector<float> BuildDistances(size_t num_alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +1100100
101 // The spline we are converting to a distance.
Austin Schuh280996e2019-01-19 17:43:37 -0800102 const ::std::vector<Spline> splines_;
Austin Schuh941b46d2018-12-19 18:06:05 +1100103 // An interpolation table of distances evenly distributed in alpha.
James Kuszmaul75a18c52021-03-10 22:02:07 -0800104 const ::std::vector<float> distances_;
Austin Schuh941b46d2018-12-19 18:06:05 +1100105};
106
Austin Schuhf7c65202022-11-04 21:28:20 -0700107// Class exposing a finished DistanceSpline flatbuffer as a DistanceSpline.
108//
109// The lifetime of the provided fb::DistanceSpline needs to out-live this class.
110class FinishedDistanceSpline final : public DistanceSplineBase {
111 public:
112 static constexpr size_t kMaxSplines = 6;
113 FinishedDistanceSpline(const fb::DistanceSpline &fb);
114
115 const absl::Span<const float> distances() const override {
116 return distances_;
117 }
118 const absl::Span<const Spline> splines() const override { return splines_; }
119
120 private:
121 ::std::vector<float> BuildDistances(size_t num_alpha);
122
123 // The spline we are converting to a distance.
124 aos::SizedArray<Spline, kMaxSplines> splines_;
125 // An interpolation table of distances evenly distributed in alpha.
James Kuszmauldc534432023-02-05 14:51:11 -0800126 absl::Span<const float> distances_;
Austin Schuhf7c65202022-11-04 21:28:20 -0700127};
128
Austin Schuh941b46d2018-12-19 18:06:05 +1100129} // namespace drivetrain
130} // namespace control_loops
131} // namespace frc971
132
133#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_