blob: e135f2c39e1f1de4d79e0786587c00ca13b8c4f2 [file] [log] [blame]
Sabina Davis92d2efa2017-11-04 22:35:25 -07001#ifndef AOS_INPUT_DRIVETRAIN_INPUT_H_
2#define AOS_INPUT_DRIVETRAIN_INPUT_H_
3
Sabina Davis92d2efa2017-11-04 22:35:25 -07004#include <cmath>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07005#include <cstdio>
6#include <cstring>
Sabina Davis92d2efa2017-11-04 22:35:25 -07007#include <memory>
8
John Park33858a32018-09-28 23:05:48 -07009#include "aos/logging/logging.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "frc971/control_loops/control_loops_generated.h"
Sabina Davis82b19182017-11-10 09:30:25 -080011#include "frc971/control_loops/drivetrain/drivetrain_config.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070012#include "frc971/control_loops/drivetrain/drivetrain_goal_generated.h"
13#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
Nikolai Sohmers0991b1f2024-10-20 14:24:34 -070014#include "frc971/control_loops/swerve/swerve_drivetrain_goal_static.h"
15#include "frc971/control_loops/swerve/swerve_drivetrain_joystick_goal_static.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070016#include "frc971/input/driver_station_data.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070017
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080018namespace frc971::input {
Sabina Davis92d2efa2017-11-04 22:35:25 -070019
Maxwell Henderson24f89f32023-03-25 15:55:46 -070020using control_loops::drivetrain::PistolBottomButtonUse;
21using control_loops::drivetrain::PistolSecondButtonUse;
22using control_loops::drivetrain::PistolTopButtonUse;
23
Sabina Davis92d2efa2017-11-04 22:35:25 -070024// We have a couple different joystick configurations used to drive our skid
25// steer robots. These configurations don't change very often, and there are a
26// small, discrete, set of them. The interface to the drivetrain is the same
27// across all of our drivetrains, so we can abstract that away from our users.
28//
29// We want to be able to re-use that code across years, and switch joystick
30// types quickly and efficiently.
31//
32// DrivetrainInputReader is the abstract base class which provides a consistent
33// API to control drivetrains.
34//
35// To construct the appropriate DrivetrainInputReader, call
36// DrivetrainInputReader::Make with the input type enum.
37// To use it, call HandleDrivetrain(data) every time a joystick packet is
38// received.
39//
40// Base class for the interface to the drivetrain implemented by multiple
41// joystick types.
42class DrivetrainInputReader {
43 public:
James Kuszmaul8bad2412019-03-10 10:47:56 -070044 // What to use the turn1/2 buttons for.
45 enum class TurnButtonUse {
46 // Use the button to enable control loop driving.
47 kControlLoopDriving,
48 // Use the button to set line following mode.
49 kLineFollow,
50 };
Sabina Davis92d2efa2017-11-04 22:35:25 -070051 // Inputs driver station button and joystick locations
Austin Schuhbd0a40f2019-06-30 14:56:31 -070052 DrivetrainInputReader(::aos::EventLoop *event_loop,
53 driver_station::JoystickAxis wheel,
Austin Schuh2b1fce02018-03-02 20:05:20 -080054 driver_station::JoystickAxis throttle,
Sabina Davis82b19182017-11-10 09:30:25 -080055 driver_station::ButtonLocation quick_turn,
56 driver_station::ButtonLocation turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -070057 TurnButtonUse turn1_use,
58 driver_station::ButtonLocation turn2,
59 TurnButtonUse turn2_use)
Austin Schuh2b1fce02018-03-02 20:05:20 -080060 : wheel_(wheel),
61 throttle_(throttle),
Sabina Davis82b19182017-11-10 09:30:25 -080062 quick_turn_(quick_turn),
63 turn1_(turn1),
James Kuszmaul8bad2412019-03-10 10:47:56 -070064 turn1_use_(turn1_use),
65 turn2_(turn2),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070066 turn2_use_(turn2_use),
67 drivetrain_status_fetcher_(
68 event_loop
Alex Perrycb7da4b2019-08-28 19:35:56 -070069 ->MakeFetcher<::frc971::control_loops::drivetrain::Status>(
70 "/drivetrain")),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070071 drivetrain_goal_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070072 event_loop->MakeSender<::frc971::control_loops::drivetrain::Goal>(
73 "/drivetrain")) {}
Sabina Davis92d2efa2017-11-04 22:35:25 -070074
75 virtual ~DrivetrainInputReader() = default;
76
77 // List of driver joystick types.
78 enum class InputType {
79 kSteeringWheel,
80 kPistol,
81 kXbox,
82 };
83
84 // Constructs the appropriate DrivetrainInputReader.
Sabina Davis82b19182017-11-10 09:30:25 -080085 static std::unique_ptr<DrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -070086 ::aos::EventLoop *event_loop, InputType type,
Austin Schuhbcce26a2018-03-26 23:41:24 -070087 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
88 &dt_config);
Sabina Davis92d2efa2017-11-04 22:35:25 -070089
90 // Processes new joystick data and publishes drivetrain goal messages.
James Kuszmaul7077d342021-06-09 20:23:58 -070091 void HandleDrivetrain(const ::frc971::input::driver_station::Data &data);
Sabina Davis92d2efa2017-11-04 22:35:25 -070092
93 // Sets the scalar for the steering wheel for closed loop mode converting
94 // steering ratio to meters displacement on the two wheels.
95 void set_wheel_multiplier(double wheel_multiplier) {
96 wheel_multiplier_ = wheel_multiplier;
97 }
98
99 // Returns the current robot velocity in m/s.
100 double robot_velocity() const { return robot_velocity_; }
101
Austin Schuh0b00c862021-10-17 17:39:10 -0700102 // Returns the current drivetrain status.
103 const control_loops::drivetrain::Status *drivetrain_status() const {
104 return drivetrain_status_fetcher_.get();
105 }
106
Austin Schuha250b2d2019-05-27 16:14:02 -0700107 void set_vision_align_fn(
James Kuszmaul7077d342021-06-09 20:23:58 -0700108 ::std::function<bool(const ::frc971::input::driver_station::Data &data)>
Austin Schuha250b2d2019-05-27 16:14:02 -0700109 vision_align_fn) {
110 vision_align_fn_ = vision_align_fn;
111 }
112
Sabina Davis92d2efa2017-11-04 22:35:25 -0700113 protected:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800114 const driver_station::JoystickAxis wheel_;
115 const driver_station::JoystickAxis throttle_;
Sabina Davis82b19182017-11-10 09:30:25 -0800116 const driver_station::ButtonLocation quick_turn_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700117 // Button for enabling control loop driving.
Sabina Davis82b19182017-11-10 09:30:25 -0800118 const driver_station::ButtonLocation turn1_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700119 const TurnButtonUse turn1_use_;
120 // But for enabling line following.
Sabina Davis82b19182017-11-10 09:30:25 -0800121 const driver_station::ButtonLocation turn2_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700122 const TurnButtonUse turn2_use_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700123
Austin Schuh48d3a962019-03-17 18:12:32 -0700124 bool last_is_control_loop_driving_ = false;
125
Sabina Davis92d2efa2017-11-04 22:35:25 -0700126 // Structure containing the (potentially adjusted) steering and throttle
127 // values from the joysticks.
128 struct WheelAndThrottle {
129 double wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800130 double wheel_velocity;
131 double wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700132 double throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800133 double throttle_velocity;
134 double throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -0800135 bool high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700136 };
137
138 private:
139 // Computes the steering and throttle from the provided driverstation data.
140 virtual WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700141 const ::frc971::input::driver_station::Data &data) = 0;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700142
Alex Perrycb7da4b2019-08-28 19:35:56 -0700143 ::aos::Fetcher<::frc971::control_loops::drivetrain::Status>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700144 drivetrain_status_fetcher_;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700145 ::aos::Sender<::frc971::control_loops::drivetrain::Goal>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700146 drivetrain_goal_sender_;
147
Sabina Davis92d2efa2017-11-04 22:35:25 -0700148 double robot_velocity_ = 0.0;
149 // Goals to send to the drivetrain in closed loop mode.
150 double left_goal_ = 0.0;
151 double right_goal_ = 0.0;
152 // The scale for the joysticks for closed loop mode converting
153 // joysticks to meters displacement on the two wheels.
154 double wheel_multiplier_ = 0.5;
Austin Schuha250b2d2019-05-27 16:14:02 -0700155
James Kuszmaul7077d342021-06-09 20:23:58 -0700156 ::std::function<bool(const ::frc971::input::driver_station::Data &data)>
Austin Schuha250b2d2019-05-27 16:14:02 -0700157 vision_align_fn_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700158};
159
Nikolai Sohmers0991b1f2024-10-20 14:24:34 -0700160class SwerveDrivetrainInputReader {
161 SwerveDrivetrainInputReader(::aos::EventLoop *event_loop,
162 driver_station::JoystickAxis vx_axis,
163 driver_station::JoystickAxis vy_axis,
164 driver_station::JoystickAxis omega_axis)
165 : vx_axis_(vx_axis),
166 vy_axis_(vy_axis),
167 omega_axis_(omega_axis),
168 goal_sender_(event_loop->MakeSender<control_loops::swerve::GoalStatic>(
169 "/drivetrain")) {}
170
171 public:
172 virtual ~SwerveDrivetrainInputReader() = default;
173
174 // Constructs the appropriate DrivetrainInputReader.
175 static std::unique_ptr<SwerveDrivetrainInputReader> Make(
176 ::aos::EventLoop *event_loop);
177
178 // Processes new joystick data and publishes drivetrain goal messages.
179 void HandleDrivetrain(const ::frc971::input::driver_station::Data &data);
180
181 // Sets the scalar for the steering wheel for closed loop mode converting
182 // steering ratio to meters displacement on the two wheels.
183 void set_wheel_multiplier(double wheel_multiplier) {
184 wheel_multiplier_ = wheel_multiplier;
185 }
186
187 protected:
188 const driver_station::JoystickAxis vx_axis_;
189 const driver_station::JoystickAxis vy_axis_;
190 const driver_station::JoystickAxis omega_axis_;
191
192 // Structure containing the (potentially adjusted) steering and throttle
193 // values from the joysticks.
194 struct SwerveGoals {
195 double vx;
196 double vy;
197 double omega;
198 };
199
200 private:
201 // Computes the steering and throttle from the provided driverstation data.
202 SwerveGoals GetSwerveGoals(const ::frc971::input::driver_station::Data &data);
203
204 ::aos::Sender<control_loops::swerve::GoalStatic> goal_sender_;
205
206 // The scale for the joysticks for closed loop mode converting
207 // joysticks to meters displacement on the two wheels.
208 double wheel_multiplier_ = 0.5;
209};
210
Sabina Davis92d2efa2017-11-04 22:35:25 -0700211// Implements DrivetrainInputReader for the original steering wheel.
212class SteeringWheelDrivetrainInputReader : public DrivetrainInputReader {
213 public:
214 using DrivetrainInputReader::DrivetrainInputReader;
215
216 // Creates a DrivetrainInputReader with the corresponding joystick ports and
217 // axis for the big steering wheel and throttle stick.
Sabina Davis82b19182017-11-10 09:30:25 -0800218 static std::unique_ptr<SteeringWheelDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700219 ::aos::EventLoop *event_loop, bool default_high_gear);
Sabina Davis82b19182017-11-10 09:30:25 -0800220
221 // Sets the default shifter position
222 void set_default_high_gear(bool default_high_gear) {
223 high_gear_ = default_high_gear;
224 default_high_gear_ = default_high_gear;
225 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700226
227 private:
228 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700229 const ::frc971::input::driver_station::Data &data) override;
Sabina Davis82b19182017-11-10 09:30:25 -0800230 bool high_gear_;
231 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700232};
233
234class PistolDrivetrainInputReader : public DrivetrainInputReader {
235 public:
236 using DrivetrainInputReader::DrivetrainInputReader;
237
238 // Creates a DrivetrainInputReader with the corresponding joystick ports and
239 // axis for the (cheap) pistol grip controller.
James Kuszmaul8bad2412019-03-10 10:47:56 -0700240 static std::unique_ptr<PistolDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700241 ::aos::EventLoop *event_loop, bool default_high_gear,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700242 PistolTopButtonUse top_button_use,
243 PistolSecondButtonUse second_button_use,
244 PistolBottomButtonUse bottom_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700245
246 private:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800247 PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700248 ::aos::EventLoop *event_loop, driver_station::JoystickAxis wheel_high,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800249 driver_station::JoystickAxis wheel_low,
250 driver_station::JoystickAxis wheel_velocity_high,
251 driver_station::JoystickAxis wheel_velocity_low,
252 driver_station::JoystickAxis wheel_torque_high,
253 driver_station::JoystickAxis wheel_torque_low,
254 driver_station::JoystickAxis throttle_high,
255 driver_station::JoystickAxis throttle_low,
256 driver_station::JoystickAxis throttle_velocity_high,
257 driver_station::JoystickAxis throttle_velocity_low,
258 driver_station::JoystickAxis throttle_torque_high,
259 driver_station::JoystickAxis throttle_torque_low,
260 driver_station::ButtonLocation quick_turn,
261 driver_station::ButtonLocation shift_high,
262 driver_station::ButtonLocation shift_low,
263 driver_station::ButtonLocation turn1,
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700264 driver_station::ButtonLocation turn2,
265 driver_station::ButtonLocation slow_down)
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700266 : DrivetrainInputReader(event_loop, wheel_high, throttle_high, quick_turn,
267 turn1, TurnButtonUse::kLineFollow, turn2,
Austin Schuh48d3a962019-03-17 18:12:32 -0700268 TurnButtonUse::kControlLoopDriving),
Austin Schuh2b1fce02018-03-02 20:05:20 -0800269 wheel_low_(wheel_low),
270 wheel_velocity_high_(wheel_velocity_high),
271 wheel_velocity_low_(wheel_velocity_low),
272 wheel_torque_high_(wheel_torque_high),
273 wheel_torque_low_(wheel_torque_low),
274 throttle_low_(throttle_low),
275 throttle_velocity_high_(throttle_velocity_high),
276 throttle_velocity_low_(throttle_velocity_low),
277 throttle_torque_high_(throttle_torque_high),
278 throttle_torque_low_(throttle_torque_low),
279 shift_high_(shift_high),
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700280 shift_low_(shift_low),
281 slow_down_(slow_down) {}
Austin Schuh2b1fce02018-03-02 20:05:20 -0800282
Sabina Davis92d2efa2017-11-04 22:35:25 -0700283 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700284 const ::frc971::input::driver_station::Data &data) override;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800285
286 // Sets the default shifter position
287 void set_default_high_gear(bool default_high_gear) {
288 high_gear_ = default_high_gear;
289 default_high_gear_ = default_high_gear;
290 }
291
292 const driver_station::JoystickAxis wheel_low_;
293 const driver_station::JoystickAxis wheel_velocity_high_;
294 const driver_station::JoystickAxis wheel_velocity_low_;
295 const driver_station::JoystickAxis wheel_torque_high_;
296 const driver_station::JoystickAxis wheel_torque_low_;
297
298 const driver_station::JoystickAxis throttle_low_;
299 const driver_station::JoystickAxis throttle_velocity_high_;
300 const driver_station::JoystickAxis throttle_velocity_low_;
301 const driver_station::JoystickAxis throttle_torque_high_;
302 const driver_station::JoystickAxis throttle_torque_low_;
303
304 const driver_station::ButtonLocation shift_high_;
305 const driver_station::ButtonLocation shift_low_;
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700306 const driver_station::ButtonLocation slow_down_;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800307
308 bool high_gear_;
309 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700310};
311
312class XboxDrivetrainInputReader : public DrivetrainInputReader {
313 public:
314 using DrivetrainInputReader::DrivetrainInputReader;
315
316 // Creates a DrivetrainInputReader with the corresponding joystick ports and
317 // axis for the Xbox controller.
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700318 static std::unique_ptr<XboxDrivetrainInputReader> Make(
319 ::aos::EventLoop *event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700320
321 private:
322 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700323 const ::frc971::input::driver_station::Data &data) override;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700324};
325
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -0800326} // namespace frc971::input
Sabina Davis92d2efa2017-11-04 22:35:25 -0700327
328#endif // AOS_INPUT_DRIVETRAIN_INPUT_H_