blob: 9e450d5b340198bf62dde0131c3110c4a52ada0f [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
4#include <math.h>
5#include <stdio.h>
6#include <string.h>
James Kuszmaul7077d342021-06-09 20:23:58 -07007
Sabina Davis92d2efa2017-11-04 22:35:25 -07008#include <cmath>
9#include <memory>
10
John Park33858a32018-09-28 23:05:48 -070011#include "aos/logging/logging.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070012#include "frc971/control_loops/control_loops_generated.h"
Sabina Davis82b19182017-11-10 09:30:25 -080013#include "frc971/control_loops/drivetrain/drivetrain_config.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070014#include "frc971/control_loops/drivetrain/drivetrain_goal_generated.h"
15#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070016#include "frc971/input/driver_station_data.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070017
James Kuszmaul7077d342021-06-09 20:23:58 -070018namespace frc971 {
Sabina Davis92d2efa2017-11-04 22:35:25 -070019namespace input {
20
21// We have a couple different joystick configurations used to drive our skid
22// steer robots. These configurations don't change very often, and there are a
23// small, discrete, set of them. The interface to the drivetrain is the same
24// across all of our drivetrains, so we can abstract that away from our users.
25//
26// We want to be able to re-use that code across years, and switch joystick
27// types quickly and efficiently.
28//
29// DrivetrainInputReader is the abstract base class which provides a consistent
30// API to control drivetrains.
31//
32// To construct the appropriate DrivetrainInputReader, call
33// DrivetrainInputReader::Make with the input type enum.
34// To use it, call HandleDrivetrain(data) every time a joystick packet is
35// received.
36//
37// Base class for the interface to the drivetrain implemented by multiple
38// joystick types.
39class DrivetrainInputReader {
40 public:
James Kuszmaul8bad2412019-03-10 10:47:56 -070041 // What to use the turn1/2 buttons for.
42 enum class TurnButtonUse {
43 // Use the button to enable control loop driving.
44 kControlLoopDriving,
45 // Use the button to set line following mode.
46 kLineFollow,
47 };
Sabina Davis92d2efa2017-11-04 22:35:25 -070048 // Inputs driver station button and joystick locations
Austin Schuhbd0a40f2019-06-30 14:56:31 -070049 DrivetrainInputReader(::aos::EventLoop *event_loop,
50 driver_station::JoystickAxis wheel,
Austin Schuh2b1fce02018-03-02 20:05:20 -080051 driver_station::JoystickAxis throttle,
Sabina Davis82b19182017-11-10 09:30:25 -080052 driver_station::ButtonLocation quick_turn,
53 driver_station::ButtonLocation turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -070054 TurnButtonUse turn1_use,
55 driver_station::ButtonLocation turn2,
56 TurnButtonUse turn2_use)
Austin Schuh2b1fce02018-03-02 20:05:20 -080057 : wheel_(wheel),
58 throttle_(throttle),
Sabina Davis82b19182017-11-10 09:30:25 -080059 quick_turn_(quick_turn),
60 turn1_(turn1),
James Kuszmaul8bad2412019-03-10 10:47:56 -070061 turn1_use_(turn1_use),
62 turn2_(turn2),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070063 turn2_use_(turn2_use),
64 drivetrain_status_fetcher_(
65 event_loop
Alex Perrycb7da4b2019-08-28 19:35:56 -070066 ->MakeFetcher<::frc971::control_loops::drivetrain::Status>(
67 "/drivetrain")),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070068 drivetrain_goal_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070069 event_loop->MakeSender<::frc971::control_loops::drivetrain::Goal>(
70 "/drivetrain")) {}
Sabina Davis92d2efa2017-11-04 22:35:25 -070071
72 virtual ~DrivetrainInputReader() = default;
73
74 // List of driver joystick types.
75 enum class InputType {
76 kSteeringWheel,
77 kPistol,
78 kXbox,
79 };
80
81 // Constructs the appropriate DrivetrainInputReader.
Sabina Davis82b19182017-11-10 09:30:25 -080082 static std::unique_ptr<DrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -070083 ::aos::EventLoop *event_loop, InputType type,
Austin Schuhbcce26a2018-03-26 23:41:24 -070084 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
85 &dt_config);
Sabina Davis92d2efa2017-11-04 22:35:25 -070086
87 // Processes new joystick data and publishes drivetrain goal messages.
James Kuszmaul7077d342021-06-09 20:23:58 -070088 void HandleDrivetrain(const ::frc971::input::driver_station::Data &data);
Sabina Davis92d2efa2017-11-04 22:35:25 -070089
90 // Sets the scalar for the steering wheel for closed loop mode converting
91 // steering ratio to meters displacement on the two wheels.
92 void set_wheel_multiplier(double wheel_multiplier) {
93 wheel_multiplier_ = wheel_multiplier;
94 }
95
96 // Returns the current robot velocity in m/s.
97 double robot_velocity() const { return robot_velocity_; }
98
Austin Schuha250b2d2019-05-27 16:14:02 -070099 void set_vision_align_fn(
James Kuszmaul7077d342021-06-09 20:23:58 -0700100 ::std::function<bool(const ::frc971::input::driver_station::Data &data)>
Austin Schuha250b2d2019-05-27 16:14:02 -0700101 vision_align_fn) {
102 vision_align_fn_ = vision_align_fn;
103 }
104
Sabina Davis92d2efa2017-11-04 22:35:25 -0700105 protected:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800106 const driver_station::JoystickAxis wheel_;
107 const driver_station::JoystickAxis throttle_;
Sabina Davis82b19182017-11-10 09:30:25 -0800108 const driver_station::ButtonLocation quick_turn_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700109 // Button for enabling control loop driving.
Sabina Davis82b19182017-11-10 09:30:25 -0800110 const driver_station::ButtonLocation turn1_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700111 const TurnButtonUse turn1_use_;
112 // But for enabling line following.
Sabina Davis82b19182017-11-10 09:30:25 -0800113 const driver_station::ButtonLocation turn2_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700114 const TurnButtonUse turn2_use_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700115
Austin Schuh48d3a962019-03-17 18:12:32 -0700116 bool last_is_control_loop_driving_ = false;
117
Sabina Davis92d2efa2017-11-04 22:35:25 -0700118 // Structure containing the (potentially adjusted) steering and throttle
119 // values from the joysticks.
120 struct WheelAndThrottle {
121 double wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800122 double wheel_velocity;
123 double wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700124 double throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800125 double throttle_velocity;
126 double throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -0800127 bool high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700128 };
129
130 private:
131 // Computes the steering and throttle from the provided driverstation data.
132 virtual WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700133 const ::frc971::input::driver_station::Data &data) = 0;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700134
Alex Perrycb7da4b2019-08-28 19:35:56 -0700135 ::aos::Fetcher<::frc971::control_loops::drivetrain::Status>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700136 drivetrain_status_fetcher_;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700137 ::aos::Sender<::frc971::control_loops::drivetrain::Goal>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700138 drivetrain_goal_sender_;
139
Sabina Davis92d2efa2017-11-04 22:35:25 -0700140 double robot_velocity_ = 0.0;
141 // Goals to send to the drivetrain in closed loop mode.
142 double left_goal_ = 0.0;
143 double right_goal_ = 0.0;
144 // The scale for the joysticks for closed loop mode converting
145 // joysticks to meters displacement on the two wheels.
146 double wheel_multiplier_ = 0.5;
Austin Schuha250b2d2019-05-27 16:14:02 -0700147
James Kuszmaul7077d342021-06-09 20:23:58 -0700148 ::std::function<bool(const ::frc971::input::driver_station::Data &data)>
Austin Schuha250b2d2019-05-27 16:14:02 -0700149 vision_align_fn_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700150};
151
152// Implements DrivetrainInputReader for the original steering wheel.
153class SteeringWheelDrivetrainInputReader : public DrivetrainInputReader {
154 public:
155 using DrivetrainInputReader::DrivetrainInputReader;
156
157 // Creates a DrivetrainInputReader with the corresponding joystick ports and
158 // axis for the big steering wheel and throttle stick.
Sabina Davis82b19182017-11-10 09:30:25 -0800159 static std::unique_ptr<SteeringWheelDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700160 ::aos::EventLoop *event_loop, bool default_high_gear);
Sabina Davis82b19182017-11-10 09:30:25 -0800161
162 // Sets the default shifter position
163 void set_default_high_gear(bool default_high_gear) {
164 high_gear_ = default_high_gear;
165 default_high_gear_ = default_high_gear;
166 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700167
168 private:
169 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700170 const ::frc971::input::driver_station::Data &data) override;
Sabina Davis82b19182017-11-10 09:30:25 -0800171 bool high_gear_;
172 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700173};
174
175class PistolDrivetrainInputReader : public DrivetrainInputReader {
176 public:
177 using DrivetrainInputReader::DrivetrainInputReader;
178
James Kuszmaul8bad2412019-03-10 10:47:56 -0700179 // What to use the top two buttons for on the pistol grip.
180 enum class TopButtonUse {
181 // Normal shifting.
182 kShift,
183 // Line following (currently just uses top button).
184 kLineFollow,
185 };
186
Sabina Davis92d2efa2017-11-04 22:35:25 -0700187 // Creates a DrivetrainInputReader with the corresponding joystick ports and
188 // axis for the (cheap) pistol grip controller.
James Kuszmaul8bad2412019-03-10 10:47:56 -0700189 static std::unique_ptr<PistolDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700190 ::aos::EventLoop *event_loop, bool default_high_gear,
191 TopButtonUse top_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700192
193 private:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800194 PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700195 ::aos::EventLoop *event_loop, driver_station::JoystickAxis wheel_high,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800196 driver_station::JoystickAxis wheel_low,
197 driver_station::JoystickAxis wheel_velocity_high,
198 driver_station::JoystickAxis wheel_velocity_low,
199 driver_station::JoystickAxis wheel_torque_high,
200 driver_station::JoystickAxis wheel_torque_low,
201 driver_station::JoystickAxis throttle_high,
202 driver_station::JoystickAxis throttle_low,
203 driver_station::JoystickAxis throttle_velocity_high,
204 driver_station::JoystickAxis throttle_velocity_low,
205 driver_station::JoystickAxis throttle_torque_high,
206 driver_station::JoystickAxis throttle_torque_low,
207 driver_station::ButtonLocation quick_turn,
208 driver_station::ButtonLocation shift_high,
209 driver_station::ButtonLocation shift_low,
210 driver_station::ButtonLocation turn1,
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700211 driver_station::ButtonLocation turn2,
212 driver_station::ButtonLocation slow_down)
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700213 : DrivetrainInputReader(event_loop, wheel_high, throttle_high, quick_turn,
214 turn1, TurnButtonUse::kLineFollow, turn2,
Austin Schuh48d3a962019-03-17 18:12:32 -0700215 TurnButtonUse::kControlLoopDriving),
Austin Schuh2b1fce02018-03-02 20:05:20 -0800216 wheel_low_(wheel_low),
217 wheel_velocity_high_(wheel_velocity_high),
218 wheel_velocity_low_(wheel_velocity_low),
219 wheel_torque_high_(wheel_torque_high),
220 wheel_torque_low_(wheel_torque_low),
221 throttle_low_(throttle_low),
222 throttle_velocity_high_(throttle_velocity_high),
223 throttle_velocity_low_(throttle_velocity_low),
224 throttle_torque_high_(throttle_torque_high),
225 throttle_torque_low_(throttle_torque_low),
226 shift_high_(shift_high),
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700227 shift_low_(shift_low),
228 slow_down_(slow_down) {}
Austin Schuh2b1fce02018-03-02 20:05:20 -0800229
Sabina Davis92d2efa2017-11-04 22:35:25 -0700230 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700231 const ::frc971::input::driver_station::Data &data) override;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800232
233 // Sets the default shifter position
234 void set_default_high_gear(bool default_high_gear) {
235 high_gear_ = default_high_gear;
236 default_high_gear_ = default_high_gear;
237 }
238
239 const driver_station::JoystickAxis wheel_low_;
240 const driver_station::JoystickAxis wheel_velocity_high_;
241 const driver_station::JoystickAxis wheel_velocity_low_;
242 const driver_station::JoystickAxis wheel_torque_high_;
243 const driver_station::JoystickAxis wheel_torque_low_;
244
245 const driver_station::JoystickAxis throttle_low_;
246 const driver_station::JoystickAxis throttle_velocity_high_;
247 const driver_station::JoystickAxis throttle_velocity_low_;
248 const driver_station::JoystickAxis throttle_torque_high_;
249 const driver_station::JoystickAxis throttle_torque_low_;
250
251 const driver_station::ButtonLocation shift_high_;
252 const driver_station::ButtonLocation shift_low_;
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700253 const driver_station::ButtonLocation slow_down_;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800254
255 bool high_gear_;
256 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700257};
258
259class XboxDrivetrainInputReader : public DrivetrainInputReader {
260 public:
261 using DrivetrainInputReader::DrivetrainInputReader;
262
263 // Creates a DrivetrainInputReader with the corresponding joystick ports and
264 // axis for the Xbox controller.
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700265 static std::unique_ptr<XboxDrivetrainInputReader> Make(
266 ::aos::EventLoop *event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700267
268 private:
269 WheelAndThrottle GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700270 const ::frc971::input::driver_station::Data &data) override;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700271};
272
273} // namespace input
James Kuszmaul7077d342021-06-09 20:23:58 -0700274} // namespace frc971
Sabina Davis92d2efa2017-11-04 22:35:25 -0700275
276#endif // AOS_INPUT_DRIVETRAIN_INPUT_H_