blob: 63156fe719fbc20c9c8e41bb4e8ffbddb8235a8f [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"
Philipp Schrader790cb542023-07-05 21:06:52 -07008
Austin Schuhf7c65202022-11-04 21:28:20 -07009#include "aos/containers/sized_array.h"
Austin Schuh941b46d2018-12-19 18:06:05 +110010#include "frc971/control_loops/drivetrain/spline.h"
James Kuszmaul75a18c52021-03-10 22:02:07 -080011#include "frc971/control_loops/drivetrain/trajectory_generated.h"
Austin Schuh941b46d2018-12-19 18:06:05 +110012#include "frc971/control_loops/fixed_quadrature.h"
13
14namespace frc971 {
15namespace control_loops {
16namespace drivetrain {
17
James Kuszmaul75a18c52021-03-10 22:02:07 -080018std::vector<Spline> FlatbufferToSplines(const MultiSpline *fb);
19
Austin Schuh941b46d2018-12-19 18:06:05 +110020// Class to hold a spline as a function of distance.
Austin Schuhf7c65202022-11-04 21:28:20 -070021class DistanceSplineBase {
Austin Schuh941b46d2018-12-19 18:06:05 +110022 public:
23 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
24
Austin Schuhf7c65202022-11-04 21:28:20 -070025 virtual ~DistanceSplineBase() {}
James Kuszmaul75a18c52021-03-10 22:02:07 -080026
27 flatbuffers::Offset<fb::DistanceSpline> Serialize(
28 flatbuffers::FlatBufferBuilder *fbb,
29 flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Constraint>>>
30 constraints) const;
Austin Schuh941b46d2018-12-19 18:06:05 +110031
32 // Returns a point on the spline as a function of distance.
33 ::Eigen::Matrix<double, 2, 1> XY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080034 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070035 return splines()[a.index].Point(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110036 }
37
38 // Returns the velocity as a function of distance.
39 ::Eigen::Matrix<double, 2, 1> DXY(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080040 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070041 return splines()[a.index].DPoint(a.alpha).normalized();
Austin Schuh941b46d2018-12-19 18:06:05 +110042 }
43
44 // Returns the acceleration as a function of distance.
45 ::Eigen::Matrix<double, 2, 1> DDXY(double distance) const;
46
47 // Returns the heading as a function of distance.
48 double Theta(double distance) const {
Austin Schuh280996e2019-01-19 17:43:37 -080049 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070050 return splines()[a.index].Theta(a.alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +110051 }
52
53 // Returns the angular velocity as a function of distance.
James Kuszmaulaa2499d2020-06-02 21:31:19 -070054 // This is also equivalent to the curvature at the given point.
Austin Schuh941b46d2018-12-19 18:06:05 +110055 double DTheta(double distance) const {
56 // TODO(austin): We are re-computing DPoint here!
Austin Schuh280996e2019-01-19 17:43:37 -080057 const AlphaAndIndex a = DistanceToAlpha(distance);
Austin Schuhf7c65202022-11-04 21:28:20 -070058 const Spline &spline = splines()[a.index];
Austin Schuh280996e2019-01-19 17:43:37 -080059 return spline.DTheta(a.alpha) / spline.DPoint(a.alpha).norm();
Austin Schuh941b46d2018-12-19 18:06:05 +110060 }
61
James Kuszmaulaa2499d2020-06-02 21:31:19 -070062 // Returns the derivative of heading with respect to time at a given
63 // distance along the spline, if we are travelling at the provided velocity.
Austin Schuhec7f06d2019-01-04 07:47:15 +110064 double DThetaDt(double distance, double velocity) const {
65 return DTheta(distance) * velocity;
66 }
67
Austin Schuh941b46d2018-12-19 18:06:05 +110068 // Returns the angular acceleration as a function of distance.
69 double DDTheta(double distance) const;
70
71 // Returns the length of the path in meters.
Austin Schuhf7c65202022-11-04 21:28:20 -070072 double length() const { return distances().back(); }
Austin Schuh941b46d2018-12-19 18:06:05 +110073
Austin Schuhf7c65202022-11-04 21:28:20 -070074 virtual const absl::Span<const float> distances() const = 0;
75 virtual const absl::Span<const Spline> splines() const = 0;
James Kuszmaul75a18c52021-03-10 22:02:07 -080076
Austin Schuh941b46d2018-12-19 18:06:05 +110077 private:
Austin Schuh280996e2019-01-19 17:43:37 -080078 struct AlphaAndIndex {
79 size_t index;
80 double alpha;
81 };
82
Austin Schuh941b46d2018-12-19 18:06:05 +110083 // Computes alpha for a distance
Austin Schuh280996e2019-01-19 17:43:37 -080084 AlphaAndIndex DistanceToAlpha(double distance) const;
Austin Schuhf7c65202022-11-04 21:28:20 -070085};
Austin Schuh280996e2019-01-19 17:43:37 -080086
Austin Schuhf7c65202022-11-04 21:28:20 -070087// Class which computes a DistanceSpline and stores it.
88class DistanceSpline final : public DistanceSplineBase {
89 public:
90 DistanceSpline(const Spline &spline, int num_alpha = 0);
91 DistanceSpline(::std::vector<Spline> &&splines, int num_alpha = 0);
92 DistanceSpline(const MultiSpline *fb, int num_alpha = 0);
93
94 const absl::Span<const float> distances() const override {
95 return distances_;
96 }
97 const absl::Span<const Spline> splines() const override { return splines_; }
98
99 private:
James Kuszmaul75a18c52021-03-10 22:02:07 -0800100 ::std::vector<float> BuildDistances(size_t num_alpha);
Austin Schuh941b46d2018-12-19 18:06:05 +1100101
102 // The spline we are converting to a distance.
Austin Schuh280996e2019-01-19 17:43:37 -0800103 const ::std::vector<Spline> splines_;
Austin Schuh941b46d2018-12-19 18:06:05 +1100104 // An interpolation table of distances evenly distributed in alpha.
James Kuszmaul75a18c52021-03-10 22:02:07 -0800105 const ::std::vector<float> distances_;
Austin Schuh941b46d2018-12-19 18:06:05 +1100106};
107
Austin Schuhf7c65202022-11-04 21:28:20 -0700108// Class exposing a finished DistanceSpline flatbuffer as a DistanceSpline.
109//
110// The lifetime of the provided fb::DistanceSpline needs to out-live this class.
111class FinishedDistanceSpline final : public DistanceSplineBase {
112 public:
113 static constexpr size_t kMaxSplines = 6;
114 FinishedDistanceSpline(const fb::DistanceSpline &fb);
115
116 const absl::Span<const float> distances() const override {
117 return distances_;
118 }
119 const absl::Span<const Spline> splines() const override { return splines_; }
120
121 private:
122 ::std::vector<float> BuildDistances(size_t num_alpha);
123
124 // The spline we are converting to a distance.
125 aos::SizedArray<Spline, kMaxSplines> splines_;
126 // An interpolation table of distances evenly distributed in alpha.
James Kuszmauldc534432023-02-05 14:51:11 -0800127 absl::Span<const float> distances_;
Austin Schuhf7c65202022-11-04 21:28:20 -0700128};
129
Austin Schuh941b46d2018-12-19 18:06:05 +1100130} // namespace drivetrain
131} // namespace control_loops
132} // namespace frc971
133
134#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_DISTANCE_SPLINE_H_