blob: 26dfe95bceb5c2b39aed80dcf7fe371bb4643e6f [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 Schuhbd0a40f2019-06-30 14:56:31 -070046 DrivetrainInputReader(::aos::EventLoop *event_loop,
47 driver_station::JoystickAxis wheel,
Austin Schuh2b1fce02018-03-02 20:05:20 -080048 driver_station::JoystickAxis throttle,
Sabina Davis82b19182017-11-10 09:30:25 -080049 driver_station::ButtonLocation quick_turn,
50 driver_station::ButtonLocation turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -070051 TurnButtonUse turn1_use,
52 driver_station::ButtonLocation turn2,
53 TurnButtonUse turn2_use)
Austin Schuh2b1fce02018-03-02 20:05:20 -080054 : wheel_(wheel),
55 throttle_(throttle),
Sabina Davis82b19182017-11-10 09:30:25 -080056 quick_turn_(quick_turn),
57 turn1_(turn1),
James Kuszmaul8bad2412019-03-10 10:47:56 -070058 turn1_use_(turn1_use),
59 turn2_(turn2),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070060 turn2_use_(turn2_use),
61 drivetrain_status_fetcher_(
62 event_loop
63 ->MakeFetcher<::frc971::control_loops::DrivetrainQueue::Status>(
64 ".frc971.control_loops.drivetrain_queue.status")),
65 drivetrain_goal_sender_(
66 event_loop
67 ->MakeSender<::frc971::control_loops::DrivetrainQueue::Goal>(
68 ".frc971.control_loops.drivetrain_queue.goal")) {}
Sabina Davis92d2efa2017-11-04 22:35:25 -070069
70 virtual ~DrivetrainInputReader() = default;
71
72 // List of driver joystick types.
73 enum class InputType {
74 kSteeringWheel,
75 kPistol,
76 kXbox,
77 };
78
79 // Constructs the appropriate DrivetrainInputReader.
Sabina Davis82b19182017-11-10 09:30:25 -080080 static std::unique_ptr<DrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -070081 ::aos::EventLoop *event_loop, InputType type,
Austin Schuhbcce26a2018-03-26 23:41:24 -070082 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
83 &dt_config);
Sabina Davis92d2efa2017-11-04 22:35:25 -070084
85 // Processes new joystick data and publishes drivetrain goal messages.
86 void HandleDrivetrain(const ::aos::input::driver_station::Data &data);
87
88 // Sets the scalar for the steering wheel for closed loop mode converting
89 // steering ratio to meters displacement on the two wheels.
90 void set_wheel_multiplier(double wheel_multiplier) {
91 wheel_multiplier_ = wheel_multiplier;
92 }
93
94 // Returns the current robot velocity in m/s.
95 double robot_velocity() const { return robot_velocity_; }
96
Austin Schuha250b2d2019-05-27 16:14:02 -070097 void set_vision_align_fn(
98 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
99 vision_align_fn) {
100 vision_align_fn_ = vision_align_fn;
101 }
102
Sabina Davis92d2efa2017-11-04 22:35:25 -0700103 protected:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800104 const driver_station::JoystickAxis wheel_;
105 const driver_station::JoystickAxis throttle_;
Sabina Davis82b19182017-11-10 09:30:25 -0800106 const driver_station::ButtonLocation quick_turn_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700107 // Button for enabling control loop driving.
Sabina Davis82b19182017-11-10 09:30:25 -0800108 const driver_station::ButtonLocation turn1_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700109 const TurnButtonUse turn1_use_;
110 // But for enabling line following.
Sabina Davis82b19182017-11-10 09:30:25 -0800111 const driver_station::ButtonLocation turn2_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700112 const TurnButtonUse turn2_use_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700113
Austin Schuh48d3a962019-03-17 18:12:32 -0700114 bool last_is_control_loop_driving_ = false;
115
Sabina Davis92d2efa2017-11-04 22:35:25 -0700116 // Structure containing the (potentially adjusted) steering and throttle
117 // values from the joysticks.
118 struct WheelAndThrottle {
119 double wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800120 double wheel_velocity;
121 double wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700122 double throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800123 double throttle_velocity;
124 double throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -0800125 bool high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700126 };
127
128 private:
129 // Computes the steering and throttle from the provided driverstation data.
130 virtual WheelAndThrottle GetWheelAndThrottle(
131 const ::aos::input::driver_station::Data &data) = 0;
132
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700133 ::aos::Fetcher<::frc971::control_loops::DrivetrainQueue::Status>
134 drivetrain_status_fetcher_;
135 ::aos::Sender<::frc971::control_loops::DrivetrainQueue::Goal>
136 drivetrain_goal_sender_;
137
Sabina Davis92d2efa2017-11-04 22:35:25 -0700138 double robot_velocity_ = 0.0;
139 // Goals to send to the drivetrain in closed loop mode.
140 double left_goal_ = 0.0;
141 double right_goal_ = 0.0;
142 // The scale for the joysticks for closed loop mode converting
143 // joysticks to meters displacement on the two wheels.
144 double wheel_multiplier_ = 0.5;
Austin Schuha250b2d2019-05-27 16:14:02 -0700145
146 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
147 vision_align_fn_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700148};
149
150// Implements DrivetrainInputReader for the original steering wheel.
151class SteeringWheelDrivetrainInputReader : public DrivetrainInputReader {
152 public:
153 using DrivetrainInputReader::DrivetrainInputReader;
154
155 // Creates a DrivetrainInputReader with the corresponding joystick ports and
156 // axis for the big steering wheel and throttle stick.
Sabina Davis82b19182017-11-10 09:30:25 -0800157 static std::unique_ptr<SteeringWheelDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700158 ::aos::EventLoop *event_loop, bool default_high_gear);
Sabina Davis82b19182017-11-10 09:30:25 -0800159
160 // Sets the default shifter position
161 void set_default_high_gear(bool default_high_gear) {
162 high_gear_ = default_high_gear;
163 default_high_gear_ = default_high_gear;
164 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700165
166 private:
167 WheelAndThrottle GetWheelAndThrottle(
168 const ::aos::input::driver_station::Data &data) override;
Sabina Davis82b19182017-11-10 09:30:25 -0800169 bool high_gear_;
170 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700171};
172
173class PistolDrivetrainInputReader : public DrivetrainInputReader {
174 public:
175 using DrivetrainInputReader::DrivetrainInputReader;
176
James Kuszmaul8bad2412019-03-10 10:47:56 -0700177 // What to use the top two buttons for on the pistol grip.
178 enum class TopButtonUse {
179 // Normal shifting.
180 kShift,
181 // Line following (currently just uses top button).
182 kLineFollow,
183 };
184
Sabina Davis92d2efa2017-11-04 22:35:25 -0700185 // Creates a DrivetrainInputReader with the corresponding joystick ports and
186 // axis for the (cheap) pistol grip controller.
James Kuszmaul8bad2412019-03-10 10:47:56 -0700187 static std::unique_ptr<PistolDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700188 ::aos::EventLoop *event_loop, bool default_high_gear,
189 TopButtonUse top_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700190
191 private:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800192 PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700193 ::aos::EventLoop *event_loop, driver_station::JoystickAxis wheel_high,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800194 driver_station::JoystickAxis wheel_low,
195 driver_station::JoystickAxis wheel_velocity_high,
196 driver_station::JoystickAxis wheel_velocity_low,
197 driver_station::JoystickAxis wheel_torque_high,
198 driver_station::JoystickAxis wheel_torque_low,
199 driver_station::JoystickAxis throttle_high,
200 driver_station::JoystickAxis throttle_low,
201 driver_station::JoystickAxis throttle_velocity_high,
202 driver_station::JoystickAxis throttle_velocity_low,
203 driver_station::JoystickAxis throttle_torque_high,
204 driver_station::JoystickAxis throttle_torque_low,
205 driver_station::ButtonLocation quick_turn,
206 driver_station::ButtonLocation shift_high,
207 driver_station::ButtonLocation shift_low,
208 driver_station::ButtonLocation turn1,
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700209 driver_station::ButtonLocation turn2,
210 driver_station::ButtonLocation slow_down)
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700211 : DrivetrainInputReader(event_loop, wheel_high, throttle_high, quick_turn,
212 turn1, TurnButtonUse::kLineFollow, turn2,
Austin Schuh48d3a962019-03-17 18:12:32 -0700213 TurnButtonUse::kControlLoopDriving),
Austin Schuh2b1fce02018-03-02 20:05:20 -0800214 wheel_low_(wheel_low),
215 wheel_velocity_high_(wheel_velocity_high),
216 wheel_velocity_low_(wheel_velocity_low),
217 wheel_torque_high_(wheel_torque_high),
218 wheel_torque_low_(wheel_torque_low),
219 throttle_low_(throttle_low),
220 throttle_velocity_high_(throttle_velocity_high),
221 throttle_velocity_low_(throttle_velocity_low),
222 throttle_torque_high_(throttle_torque_high),
223 throttle_torque_low_(throttle_torque_low),
224 shift_high_(shift_high),
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700225 shift_low_(shift_low),
226 slow_down_(slow_down) {}
Austin Schuh2b1fce02018-03-02 20:05:20 -0800227
Sabina Davis92d2efa2017-11-04 22:35:25 -0700228 WheelAndThrottle GetWheelAndThrottle(
229 const ::aos::input::driver_station::Data &data) override;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800230
231 // Sets the default shifter position
232 void set_default_high_gear(bool default_high_gear) {
233 high_gear_ = default_high_gear;
234 default_high_gear_ = default_high_gear;
235 }
236
237 const driver_station::JoystickAxis wheel_low_;
238 const driver_station::JoystickAxis wheel_velocity_high_;
239 const driver_station::JoystickAxis wheel_velocity_low_;
240 const driver_station::JoystickAxis wheel_torque_high_;
241 const driver_station::JoystickAxis wheel_torque_low_;
242
243 const driver_station::JoystickAxis throttle_low_;
244 const driver_station::JoystickAxis throttle_velocity_high_;
245 const driver_station::JoystickAxis throttle_velocity_low_;
246 const driver_station::JoystickAxis throttle_torque_high_;
247 const driver_station::JoystickAxis throttle_torque_low_;
248
249 const driver_station::ButtonLocation shift_high_;
250 const driver_station::ButtonLocation shift_low_;
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700251 const driver_station::ButtonLocation slow_down_;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800252
253 bool high_gear_;
254 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700255};
256
257class XboxDrivetrainInputReader : public DrivetrainInputReader {
258 public:
259 using DrivetrainInputReader::DrivetrainInputReader;
260
261 // Creates a DrivetrainInputReader with the corresponding joystick ports and
262 // axis for the Xbox controller.
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700263 static std::unique_ptr<XboxDrivetrainInputReader> Make(
264 ::aos::EventLoop *event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700265
266 private:
267 WheelAndThrottle GetWheelAndThrottle(
268 const ::aos::input::driver_station::Data &data) override;
269};
270
271} // namespace input
272} // namespace aos
273
274#endif // AOS_INPUT_DRIVETRAIN_INPUT_H_