blob: 2b7d73d93c8ae518dbd43b7d2d423d1fda4cff50 [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>
7#include <cmath>
8#include <memory>
9
John Park33858a32018-09-28 23:05:48 -070010#include "aos/input/driver_station_data.h"
11#include "aos/logging/logging.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070012#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Sabina Davis82b19182017-11-10 09:30:25 -080013#include "frc971/control_loops/drivetrain/drivetrain_config.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070014
15namespace aos {
16namespace input {
17
18// We have a couple different joystick configurations used to drive our skid
19// steer robots. These configurations don't change very often, and there are a
20// small, discrete, set of them. The interface to the drivetrain is the same
21// across all of our drivetrains, so we can abstract that away from our users.
22//
23// We want to be able to re-use that code across years, and switch joystick
24// types quickly and efficiently.
25//
26// DrivetrainInputReader is the abstract base class which provides a consistent
27// API to control drivetrains.
28//
29// To construct the appropriate DrivetrainInputReader, call
30// DrivetrainInputReader::Make with the input type enum.
31// To use it, call HandleDrivetrain(data) every time a joystick packet is
32// received.
33//
34// Base class for the interface to the drivetrain implemented by multiple
35// joystick types.
36class DrivetrainInputReader {
37 public:
James Kuszmaul8bad2412019-03-10 10:47:56 -070038 // What to use the turn1/2 buttons for.
39 enum class TurnButtonUse {
40 // Use the button to enable control loop driving.
41 kControlLoopDriving,
42 // Use the button to set line following mode.
43 kLineFollow,
44 };
Sabina Davis92d2efa2017-11-04 22:35:25 -070045 // Inputs driver station button and joystick locations
Austin Schuh2b1fce02018-03-02 20:05:20 -080046 DrivetrainInputReader(driver_station::JoystickAxis wheel,
47 driver_station::JoystickAxis throttle,
Sabina Davis82b19182017-11-10 09:30:25 -080048 driver_station::ButtonLocation quick_turn,
49 driver_station::ButtonLocation turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -070050 TurnButtonUse turn1_use,
51 driver_station::ButtonLocation turn2,
52 TurnButtonUse turn2_use)
Austin Schuh2b1fce02018-03-02 20:05:20 -080053 : wheel_(wheel),
54 throttle_(throttle),
Sabina Davis82b19182017-11-10 09:30:25 -080055 quick_turn_(quick_turn),
56 turn1_(turn1),
James Kuszmaul8bad2412019-03-10 10:47:56 -070057 turn1_use_(turn1_use),
58 turn2_(turn2),
59 turn2_use_(turn2_use) {}
Sabina Davis92d2efa2017-11-04 22:35:25 -070060
61 virtual ~DrivetrainInputReader() = default;
62
63 // List of driver joystick types.
64 enum class InputType {
65 kSteeringWheel,
66 kPistol,
67 kXbox,
68 };
69
70 // Constructs the appropriate DrivetrainInputReader.
Sabina Davis82b19182017-11-10 09:30:25 -080071 static std::unique_ptr<DrivetrainInputReader> Make(
72 InputType type,
Austin Schuhbcce26a2018-03-26 23:41:24 -070073 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
74 &dt_config);
Sabina Davis92d2efa2017-11-04 22:35:25 -070075
76 // Processes new joystick data and publishes drivetrain goal messages.
77 void HandleDrivetrain(const ::aos::input::driver_station::Data &data);
78
79 // Sets the scalar for the steering wheel for closed loop mode converting
80 // steering ratio to meters displacement on the two wheels.
81 void set_wheel_multiplier(double wheel_multiplier) {
82 wheel_multiplier_ = wheel_multiplier;
83 }
84
85 // Returns the current robot velocity in m/s.
86 double robot_velocity() const { return robot_velocity_; }
87
Austin Schuha250b2d2019-05-27 16:14:02 -070088 void set_vision_align_fn(
89 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
90 vision_align_fn) {
91 vision_align_fn_ = vision_align_fn;
92 }
93
Sabina Davis92d2efa2017-11-04 22:35:25 -070094 protected:
Austin Schuh2b1fce02018-03-02 20:05:20 -080095 const driver_station::JoystickAxis wheel_;
96 const driver_station::JoystickAxis throttle_;
Sabina Davis82b19182017-11-10 09:30:25 -080097 const driver_station::ButtonLocation quick_turn_;
James Kuszmaul8bad2412019-03-10 10:47:56 -070098 // Button for enabling control loop driving.
Sabina Davis82b19182017-11-10 09:30:25 -080099 const driver_station::ButtonLocation turn1_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700100 const TurnButtonUse turn1_use_;
101 // But for enabling line following.
Sabina Davis82b19182017-11-10 09:30:25 -0800102 const driver_station::ButtonLocation turn2_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700103 const TurnButtonUse turn2_use_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700104
Austin Schuh48d3a962019-03-17 18:12:32 -0700105 bool last_is_control_loop_driving_ = false;
106
Sabina Davis92d2efa2017-11-04 22:35:25 -0700107 // Structure containing the (potentially adjusted) steering and throttle
108 // values from the joysticks.
109 struct WheelAndThrottle {
110 double wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800111 double wheel_velocity;
112 double wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700113 double throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800114 double throttle_velocity;
115 double throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -0800116 bool high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700117 };
118
119 private:
120 // Computes the steering and throttle from the provided driverstation data.
121 virtual WheelAndThrottle GetWheelAndThrottle(
122 const ::aos::input::driver_station::Data &data) = 0;
123
124 double robot_velocity_ = 0.0;
125 // Goals to send to the drivetrain in closed loop mode.
126 double left_goal_ = 0.0;
127 double right_goal_ = 0.0;
128 // The scale for the joysticks for closed loop mode converting
129 // joysticks to meters displacement on the two wheels.
130 double wheel_multiplier_ = 0.5;
Austin Schuha250b2d2019-05-27 16:14:02 -0700131
132 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
133 vision_align_fn_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700134};
135
136// Implements DrivetrainInputReader for the original steering wheel.
137class SteeringWheelDrivetrainInputReader : public DrivetrainInputReader {
138 public:
139 using DrivetrainInputReader::DrivetrainInputReader;
140
141 // Creates a DrivetrainInputReader with the corresponding joystick ports and
142 // axis for the big steering wheel and throttle stick.
Sabina Davis82b19182017-11-10 09:30:25 -0800143 static std::unique_ptr<SteeringWheelDrivetrainInputReader> Make(
144 bool default_high_gear);
145
146 // Sets the default shifter position
147 void set_default_high_gear(bool default_high_gear) {
148 high_gear_ = default_high_gear;
149 default_high_gear_ = default_high_gear;
150 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700151
152 private:
153 WheelAndThrottle GetWheelAndThrottle(
154 const ::aos::input::driver_station::Data &data) override;
Sabina Davis82b19182017-11-10 09:30:25 -0800155 bool high_gear_;
156 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700157};
158
159class PistolDrivetrainInputReader : public DrivetrainInputReader {
160 public:
161 using DrivetrainInputReader::DrivetrainInputReader;
162
James Kuszmaul8bad2412019-03-10 10:47:56 -0700163 // What to use the top two buttons for on the pistol grip.
164 enum class TopButtonUse {
165 // Normal shifting.
166 kShift,
167 // Line following (currently just uses top button).
168 kLineFollow,
169 };
170
Sabina Davis92d2efa2017-11-04 22:35:25 -0700171 // Creates a DrivetrainInputReader with the corresponding joystick ports and
172 // axis for the (cheap) pistol grip controller.
James Kuszmaul8bad2412019-03-10 10:47:56 -0700173 static std::unique_ptr<PistolDrivetrainInputReader> Make(
174 bool default_high_gear, TopButtonUse top_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700175
176 private:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800177 PistolDrivetrainInputReader(
178 driver_station::JoystickAxis wheel_high,
179 driver_station::JoystickAxis wheel_low,
180 driver_station::JoystickAxis wheel_velocity_high,
181 driver_station::JoystickAxis wheel_velocity_low,
182 driver_station::JoystickAxis wheel_torque_high,
183 driver_station::JoystickAxis wheel_torque_low,
184 driver_station::JoystickAxis throttle_high,
185 driver_station::JoystickAxis throttle_low,
186 driver_station::JoystickAxis throttle_velocity_high,
187 driver_station::JoystickAxis throttle_velocity_low,
188 driver_station::JoystickAxis throttle_torque_high,
189 driver_station::JoystickAxis throttle_torque_low,
190 driver_station::ButtonLocation quick_turn,
191 driver_station::ButtonLocation shift_high,
192 driver_station::ButtonLocation shift_low,
193 driver_station::ButtonLocation turn1,
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700194 driver_station::ButtonLocation turn2,
195 driver_station::ButtonLocation slow_down)
Austin Schuh2b1fce02018-03-02 20:05:20 -0800196 : DrivetrainInputReader(wheel_high, throttle_high, quick_turn, turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700197 TurnButtonUse::kLineFollow, turn2,
Austin Schuh48d3a962019-03-17 18:12:32 -0700198 TurnButtonUse::kControlLoopDriving),
Austin Schuh2b1fce02018-03-02 20:05:20 -0800199 wheel_low_(wheel_low),
200 wheel_velocity_high_(wheel_velocity_high),
201 wheel_velocity_low_(wheel_velocity_low),
202 wheel_torque_high_(wheel_torque_high),
203 wheel_torque_low_(wheel_torque_low),
204 throttle_low_(throttle_low),
205 throttle_velocity_high_(throttle_velocity_high),
206 throttle_velocity_low_(throttle_velocity_low),
207 throttle_torque_high_(throttle_torque_high),
208 throttle_torque_low_(throttle_torque_low),
209 shift_high_(shift_high),
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700210 shift_low_(shift_low),
211 slow_down_(slow_down) {}
Austin Schuh2b1fce02018-03-02 20:05:20 -0800212
Sabina Davis92d2efa2017-11-04 22:35:25 -0700213 WheelAndThrottle GetWheelAndThrottle(
214 const ::aos::input::driver_station::Data &data) override;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800215
216 // Sets the default shifter position
217 void set_default_high_gear(bool default_high_gear) {
218 high_gear_ = default_high_gear;
219 default_high_gear_ = default_high_gear;
220 }
221
222 const driver_station::JoystickAxis wheel_low_;
223 const driver_station::JoystickAxis wheel_velocity_high_;
224 const driver_station::JoystickAxis wheel_velocity_low_;
225 const driver_station::JoystickAxis wheel_torque_high_;
226 const driver_station::JoystickAxis wheel_torque_low_;
227
228 const driver_station::JoystickAxis throttle_low_;
229 const driver_station::JoystickAxis throttle_velocity_high_;
230 const driver_station::JoystickAxis throttle_velocity_low_;
231 const driver_station::JoystickAxis throttle_torque_high_;
232 const driver_station::JoystickAxis throttle_torque_low_;
233
234 const driver_station::ButtonLocation shift_high_;
235 const driver_station::ButtonLocation shift_low_;
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700236 const driver_station::ButtonLocation slow_down_;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800237
238 bool high_gear_;
239 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700240};
241
242class XboxDrivetrainInputReader : public DrivetrainInputReader {
243 public:
244 using DrivetrainInputReader::DrivetrainInputReader;
245
246 // Creates a DrivetrainInputReader with the corresponding joystick ports and
247 // axis for the Xbox controller.
248 static std::unique_ptr<XboxDrivetrainInputReader> Make();
249
250 private:
251 WheelAndThrottle GetWheelAndThrottle(
252 const ::aos::input::driver_station::Data &data) override;
253};
254
255} // namespace input
256} // namespace aos
257
258#endif // AOS_INPUT_DRIVETRAIN_INPUT_H_