blob: c92b7d70393e1acd1f4547564454d6ce96135b19 [file] [log] [blame]
Comran Morshed5323ecb2015-12-26 20:50:55 +00001#ifndef FRC971_CONTROL_LOOPS_DRIVETRAIN_H_
2#define FRC971_CONTROL_LOOPS_DRIVETRAIN_H_
3
4#include "Eigen/Dense"
Philipp Schrader790cb542023-07-05 21:06:52 -07005
John Park33858a32018-09-28 23:05:48 -07006#include "aos/util/log_interval.h"
milind1f1dca32021-07-03 13:50:07 -07007#include "frc971/control_loops/control_loop.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -07008#include "frc971/control_loops/control_loops_generated.h"
Austin Schuh093535c2016-03-05 23:21:00 -08009#include "frc971/control_loops/drivetrain/drivetrain_config.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "frc971/control_loops/drivetrain/drivetrain_goal_generated.h"
11#include "frc971/control_loops/drivetrain/drivetrain_output_generated.h"
12#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
Austin Schuh95771d92021-01-23 14:42:25 -080013#include "frc971/control_loops/drivetrain/drivetrain_states.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070014#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
Austin Schuh093535c2016-03-05 23:21:00 -080015#include "frc971/control_loops/drivetrain/gear.h"
James Kuszmaul3e1bb272020-01-17 18:38:19 -080016#include "frc971/control_loops/drivetrain/improved_down_estimator.h"
James Kuszmaule39cbcf2019-02-27 20:48:34 -080017#include "frc971/control_loops/drivetrain/line_follow_drivetrain.h"
Austin Schuh73b6e3b2019-05-27 16:37:15 -070018#include "frc971/control_loops/drivetrain/localizer.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070019#include "frc971/control_loops/drivetrain/localizer_generated.h"
Austin Schuh73b6e3b2019-05-27 16:37:15 -070020#include "frc971/control_loops/drivetrain/polydrivetrain.h"
Alex Perry731b4602019-02-02 22:13:01 -080021#include "frc971/control_loops/drivetrain/splinedrivetrain.h"
Austin Schuh73b6e3b2019-05-27 16:37:15 -070022#include "frc971/control_loops/drivetrain/ssdrivetrain.h"
milind1f1dca32021-07-03 13:50:07 -070023#include "frc971/control_loops/polytope.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070024#include "frc971/queues/gyro_generated.h"
Austin Schuhac17fba2020-03-28 15:55:33 -070025#include "frc971/wpilib/imu_batch_generated.h"
James Kuszmaul3e1bb272020-01-17 18:38:19 -080026#include "frc971/zeroing/imu_zeroer.h"
Comran Morshed5323ecb2015-12-26 20:50:55 +000027
28namespace frc971 {
29namespace control_loops {
30namespace drivetrain {
31
Austin Schuhfb0f35c2021-02-14 21:25:29 -080032namespace chrono = std::chrono;
33
34// A class to hold all the estimators in use in the drivetrain. This lets us
35// run them on a log file without running the controllers, making them easier to
36// tune.
37class DrivetrainFilters {
38 public:
39 DrivetrainFilters(const DrivetrainConfig<double> &dt_config,
40 ::aos::EventLoop *event_loop,
41 LocalizerInterface *localizer);
42
43 double localizer_theta() const { return localizer_->theta(); }
44 double x() const { return localizer_->x(); }
45 double y() const { return localizer_->y(); }
46
47 // Returns the current gear for both sides.
48 Gear left_gear() const { return left_gear_; }
49 Gear right_gear() const { return right_gear_; }
50
51 // Tracks the shift requests for each side.
52 void set_left_high_requested(bool value) { left_high_requested_ = value; }
53 void set_right_high_requested(bool value) { right_high_requested_ = value; }
54
55 // Returns a pointer to the drivetrain kalman filter.
56 StateFeedbackLoop<7, 2, 4> *kf() { return &kf_; }
57
58 // Populates the various state flatbuffers used for diagnostics.
59 flatbuffers::Offset<LocalizerState> PopulateLocalizerState(
60 flatbuffers::FlatBufferBuilder *fbb);
61 flatbuffers::Offset<ImuZeroerState> PopulateImuZeroerState(
62 flatbuffers::FlatBufferBuilder *fbb);
63 flatbuffers::Offset<DownEstimatorState> PopulateDownEstimatorState(
64 flatbuffers::FlatBufferBuilder *fbb,
65 aos::monotonic_clock::time_point monotonic_now);
66 flatbuffers::Offset<GearLogging> CreateGearLogging(
67 flatbuffers::FlatBufferBuilder *fbb) const;
68
69 // Returns the current localizer state.
70 Eigen::Matrix<double, 5, 1> trajectory_state() {
James Kuszmaul49c93202023-03-23 20:44:03 -070071 // Use the regular kalman filter's left/right velocity because they are
72 // generally smoother.
Austin Schuhfb0f35c2021-02-14 21:25:29 -080073 return (Eigen::Matrix<double, 5, 1>() << localizer_->x(), localizer_->y(),
James Kuszmaul49c93202023-03-23 20:44:03 -070074 localizer_->theta(), DrivetrainXHat()(1), DrivetrainXHat()(3))
Austin Schuhfb0f35c2021-02-14 21:25:29 -080075 .finished();
76 }
77
78 // Resets all filters when wpilib_interface resets.
79 void Reset(aos::monotonic_clock::time_point monotonic_now,
80 const drivetrain::Position *position);
81
82 // Corrects all the filters.
83 void Correct(aos::monotonic_clock::time_point monotonic_now,
84 const drivetrain::Position *position);
85 // Runs the predict step for all filters. Should be called with the undelayed
86 // U.
87 void UpdateObserver(Eigen::Matrix<double, 2, 1> U);
88
89 // Returns the negative of the voltage error from the drivetrain controller.
90 // This can be used for integral control.
91 Eigen::Matrix<double, 2, 1> VoltageError() const;
92
93 // Returns the current drivetrain state.
94 Eigen::Matrix<double, 7, 1> DrivetrainXHat() const { return kf_.X_hat(); }
95 double DrivetrainXHat(int index) const { return kf_.X_hat(index); }
96
97 // Returns the current uncapped voltage from the kalman filter.
98 double DrivetrainUUncapped(int index) const { return kf_.U_uncapped(index); }
99
James Kuszmaulddc69702021-03-24 21:55:03 -0700100 bool Ready() const { return ready_; }
101
Austin Schuhfb0f35c2021-02-14 21:25:29 -0800102 private:
103 // Returns the current controller index for the current gear.
104 int ControllerIndexFromGears() const;
105
106 // Computes which gear a shifter is in.
107 Gear ComputeGear(double shifter_position,
108 const constants::ShifterHallEffect &shifter_config,
109 bool high_requested) const;
110
111 const DrivetrainConfig<double> dt_config_;
112
113 aos::Fetcher<LocalizerControl> localizer_control_fetcher_;
114 aos::Fetcher<frc971::IMUValuesBatch> imu_values_fetcher_;
115 aos::Fetcher<frc971::sensors::GyroReading> gyro_reading_fetcher_;
116
117 zeroing::ImuZeroer imu_zeroer_;
118 DrivetrainUkf down_estimator_;
119 aos::monotonic_clock::time_point last_imu_update_ =
120 aos::monotonic_clock::min_time;
121 LocalizerInterface *localizer_;
122 StateFeedbackLoop<7, 2, 4> kf_;
123
124 // Current gears for each drive side.
125 Gear left_gear_;
126 Gear right_gear_;
127
128 // Shift request.
129 bool left_high_requested_;
130 bool right_high_requested_;
131
132 // Last acceleration and yaw rate.
133 aos::monotonic_clock::time_point last_gyro_time_ =
134 aos::monotonic_clock::min_time;
135 double last_accel_ = 0.0;
136 double last_gyro_rate_ = 0.0;
137
James Kuszmaulddc69702021-03-24 21:55:03 -0700138 bool ready_ = false;
139
Austin Schuhfb0f35c2021-02-14 21:25:29 -0800140 // Last applied voltage.
141 Eigen::Matrix<double, 2, 1> last_voltage_;
142 Eigen::Matrix<double, 2, 1> last_last_voltage_;
James Kuszmaulc53de4a2022-03-12 21:32:06 -0800143
144 std::optional<double> yaw_gyro_zero_;
145 zeroing::Averager<double, 200> yaw_gyro_zeroer_;
Austin Schuhfb0f35c2021-02-14 21:25:29 -0800146};
147
Alex Perrycb7da4b2019-08-28 19:35:56 -0700148class DrivetrainLoop
James Kuszmaul61750662021-06-21 21:32:33 -0700149 : public frc971::controls::ControlLoop<Goal, Position, Status, Output> {
Comran Morshed5323ecb2015-12-26 20:50:55 +0000150 public:
James Kuszmauldc534432023-02-05 14:51:11 -0800151 // Note that we only actually store N - 1 splines consistently, since we need
152 // to keep one fetcher free to check whether there are any new splines.
153 static constexpr size_t kNumSplineFetchers =
154 SplineDrivetrain::kMaxTrajectories;
James Kuszmaul75a18c52021-03-10 22:02:07 -0800155
Comran Morshed5323ecb2015-12-26 20:50:55 +0000156 // Constructs a control loop which can take a Drivetrain or defaults to the
157 // drivetrain at frc971::control_loops::drivetrain
Alex Perrycb7da4b2019-08-28 19:35:56 -0700158 explicit DrivetrainLoop(const DrivetrainConfig<double> &dt_config,
159 ::aos::EventLoop *event_loop,
160 LocalizerInterface *localizer,
161 const ::std::string &name = "/drivetrain");
Comran Morshed5323ecb2015-12-26 20:50:55 +0000162
James Kuszmaul531609d2020-02-18 17:12:23 -0800163 virtual ~DrivetrainLoop() {}
164
Comran Morshed5323ecb2015-12-26 20:50:55 +0000165 protected:
James Kuszmaul75a18c52021-03-10 22:02:07 -0800166 struct TrajectoryFetcherState {
167 aos::Fetcher<fb::Trajectory> fetcher;
168 bool in_use = false;
169 };
170
Comran Morshed5323ecb2015-12-26 20:50:55 +0000171 // Executes one cycle of the control loop.
Adam Snaiderbc918b62016-02-27 21:03:39 -0800172 void RunIteration(
Alex Perrycb7da4b2019-08-28 19:35:56 -0700173 const ::frc971::control_loops::drivetrain::Goal *goal,
174 const ::frc971::control_loops::drivetrain::Position *position,
175 aos::Sender<::frc971::control_loops::drivetrain::Output>::Builder *output,
176 aos::Sender<::frc971::control_loops::drivetrain::Status>::Builder *status)
177 override;
Adam Snaiderbc918b62016-02-27 21:03:39 -0800178
Alex Perrycb7da4b2019-08-28 19:35:56 -0700179 flatbuffers::Offset<drivetrain::Output> Zero(
180 aos::Sender<drivetrain::Output>::Builder *builder) override;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000181
James Kuszmaul75a18c52021-03-10 22:02:07 -0800182 void UpdateTrajectoryFetchers();
183
Austin Schuhbcce26a2018-03-26 23:41:24 -0700184 const DrivetrainConfig<double> dt_config_;
Austin Schuhfb0f35c2021-02-14 21:25:29 -0800185 DrivetrainFilters filters_;
James Kuszmaul75a18c52021-03-10 22:02:07 -0800186 std::array<TrajectoryFetcherState, kNumSplineFetchers> trajectory_fetchers_;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000187
Austin Schuhbcce26a2018-03-26 23:41:24 -0700188 PolyDrivetrain<double> dt_openloop_;
Austin Schuh41565602016-02-28 20:10:49 -0800189 DrivetrainMotorsSS dt_closedloop_;
Alex Perry731b4602019-02-02 22:13:01 -0800190 SplineDrivetrain dt_spline_;
James Kuszmaule39cbcf2019-02-27 20:48:34 -0800191 LineFollowDrivetrain dt_line_follow_;
Austin Schuh5900d142016-04-03 21:35:12 -0700192
193 bool has_been_enabled_ = false;
milind1f1dca32021-07-03 13:50:07 -0700194
195 aos::SendFailureCounter status_failure_counter_;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000196};
197
198} // namespace drivetrain
199} // namespace control_loops
200} // namespace frc971
201
202#endif // FRC971_CONTROL_LOOPS_DRIVETRAIN_H_