blob: 0c43d99afb629f17a6be1a575ab33fedee9782dd [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"
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"
Sabina Davis92d2efa2017-11-04 22:35:25 -070016
17namespace aos {
18namespace input {
19
20// We have a couple different joystick configurations used to drive our skid
21// steer robots. These configurations don't change very often, and there are a
22// small, discrete, set of them. The interface to the drivetrain is the same
23// across all of our drivetrains, so we can abstract that away from our users.
24//
25// We want to be able to re-use that code across years, and switch joystick
26// types quickly and efficiently.
27//
28// DrivetrainInputReader is the abstract base class which provides a consistent
29// API to control drivetrains.
30//
31// To construct the appropriate DrivetrainInputReader, call
32// DrivetrainInputReader::Make with the input type enum.
33// To use it, call HandleDrivetrain(data) every time a joystick packet is
34// received.
35//
36// Base class for the interface to the drivetrain implemented by multiple
37// joystick types.
38class DrivetrainInputReader {
39 public:
James Kuszmaul8bad2412019-03-10 10:47:56 -070040 // What to use the turn1/2 buttons for.
41 enum class TurnButtonUse {
42 // Use the button to enable control loop driving.
43 kControlLoopDriving,
44 // Use the button to set line following mode.
45 kLineFollow,
46 };
Sabina Davis92d2efa2017-11-04 22:35:25 -070047 // Inputs driver station button and joystick locations
Austin Schuhbd0a40f2019-06-30 14:56:31 -070048 DrivetrainInputReader(::aos::EventLoop *event_loop,
49 driver_station::JoystickAxis wheel,
Austin Schuh2b1fce02018-03-02 20:05:20 -080050 driver_station::JoystickAxis throttle,
Sabina Davis82b19182017-11-10 09:30:25 -080051 driver_station::ButtonLocation quick_turn,
52 driver_station::ButtonLocation turn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -070053 TurnButtonUse turn1_use,
54 driver_station::ButtonLocation turn2,
55 TurnButtonUse turn2_use)
Austin Schuh2b1fce02018-03-02 20:05:20 -080056 : wheel_(wheel),
57 throttle_(throttle),
Sabina Davis82b19182017-11-10 09:30:25 -080058 quick_turn_(quick_turn),
59 turn1_(turn1),
James Kuszmaul8bad2412019-03-10 10:47:56 -070060 turn1_use_(turn1_use),
61 turn2_(turn2),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070062 turn2_use_(turn2_use),
63 drivetrain_status_fetcher_(
64 event_loop
Alex Perrycb7da4b2019-08-28 19:35:56 -070065 ->MakeFetcher<::frc971::control_loops::drivetrain::Status>(
66 "/drivetrain")),
Austin Schuhbd0a40f2019-06-30 14:56:31 -070067 drivetrain_goal_sender_(
Alex Perrycb7da4b2019-08-28 19:35:56 -070068 event_loop->MakeSender<::frc971::control_loops::drivetrain::Goal>(
69 "/drivetrain")) {}
Sabina Davis92d2efa2017-11-04 22:35:25 -070070
71 virtual ~DrivetrainInputReader() = default;
72
73 // List of driver joystick types.
74 enum class InputType {
75 kSteeringWheel,
76 kPistol,
77 kXbox,
78 };
79
80 // Constructs the appropriate DrivetrainInputReader.
Sabina Davis82b19182017-11-10 09:30:25 -080081 static std::unique_ptr<DrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -070082 ::aos::EventLoop *event_loop, InputType type,
Austin Schuhbcce26a2018-03-26 23:41:24 -070083 const ::frc971::control_loops::drivetrain::DrivetrainConfig<double>
84 &dt_config);
Sabina Davis92d2efa2017-11-04 22:35:25 -070085
86 // Processes new joystick data and publishes drivetrain goal messages.
87 void HandleDrivetrain(const ::aos::input::driver_station::Data &data);
88
89 // Sets the scalar for the steering wheel for closed loop mode converting
90 // steering ratio to meters displacement on the two wheels.
91 void set_wheel_multiplier(double wheel_multiplier) {
92 wheel_multiplier_ = wheel_multiplier;
93 }
94
95 // Returns the current robot velocity in m/s.
96 double robot_velocity() const { return robot_velocity_; }
97
Austin Schuha250b2d2019-05-27 16:14:02 -070098 void set_vision_align_fn(
99 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
100 vision_align_fn) {
101 vision_align_fn_ = vision_align_fn;
102 }
103
Sabina Davis92d2efa2017-11-04 22:35:25 -0700104 protected:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800105 const driver_station::JoystickAxis wheel_;
106 const driver_station::JoystickAxis throttle_;
Sabina Davis82b19182017-11-10 09:30:25 -0800107 const driver_station::ButtonLocation quick_turn_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700108 // Button for enabling control loop driving.
Sabina Davis82b19182017-11-10 09:30:25 -0800109 const driver_station::ButtonLocation turn1_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700110 const TurnButtonUse turn1_use_;
111 // But for enabling line following.
Sabina Davis82b19182017-11-10 09:30:25 -0800112 const driver_station::ButtonLocation turn2_;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700113 const TurnButtonUse turn2_use_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700114
Austin Schuh48d3a962019-03-17 18:12:32 -0700115 bool last_is_control_loop_driving_ = false;
116
Sabina Davis92d2efa2017-11-04 22:35:25 -0700117 // Structure containing the (potentially adjusted) steering and throttle
118 // values from the joysticks.
119 struct WheelAndThrottle {
120 double wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800121 double wheel_velocity;
122 double wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700123 double throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800124 double throttle_velocity;
125 double throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -0800126 bool high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700127 };
128
129 private:
130 // Computes the steering and throttle from the provided driverstation data.
131 virtual WheelAndThrottle GetWheelAndThrottle(
132 const ::aos::input::driver_station::Data &data) = 0;
133
Alex Perrycb7da4b2019-08-28 19:35:56 -0700134 ::aos::Fetcher<::frc971::control_loops::drivetrain::Status>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700135 drivetrain_status_fetcher_;
Alex Perrycb7da4b2019-08-28 19:35:56 -0700136 ::aos::Sender<::frc971::control_loops::drivetrain::Goal>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700137 drivetrain_goal_sender_;
138
Sabina Davis92d2efa2017-11-04 22:35:25 -0700139 double robot_velocity_ = 0.0;
140 // Goals to send to the drivetrain in closed loop mode.
141 double left_goal_ = 0.0;
142 double right_goal_ = 0.0;
143 // The scale for the joysticks for closed loop mode converting
144 // joysticks to meters displacement on the two wheels.
145 double wheel_multiplier_ = 0.5;
Austin Schuha250b2d2019-05-27 16:14:02 -0700146
147 ::std::function<bool(const ::aos::input::driver_station::Data &data)>
148 vision_align_fn_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700149};
150
151// Implements DrivetrainInputReader for the original steering wheel.
152class SteeringWheelDrivetrainInputReader : public DrivetrainInputReader {
153 public:
154 using DrivetrainInputReader::DrivetrainInputReader;
155
156 // Creates a DrivetrainInputReader with the corresponding joystick ports and
157 // axis for the big steering wheel and throttle stick.
Sabina Davis82b19182017-11-10 09:30:25 -0800158 static std::unique_ptr<SteeringWheelDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700159 ::aos::EventLoop *event_loop, bool default_high_gear);
Sabina Davis82b19182017-11-10 09:30:25 -0800160
161 // Sets the default shifter position
162 void set_default_high_gear(bool default_high_gear) {
163 high_gear_ = default_high_gear;
164 default_high_gear_ = default_high_gear;
165 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700166
167 private:
168 WheelAndThrottle GetWheelAndThrottle(
169 const ::aos::input::driver_station::Data &data) override;
Sabina Davis82b19182017-11-10 09:30:25 -0800170 bool high_gear_;
171 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700172};
173
174class PistolDrivetrainInputReader : public DrivetrainInputReader {
175 public:
176 using DrivetrainInputReader::DrivetrainInputReader;
177
James Kuszmaul8bad2412019-03-10 10:47:56 -0700178 // What to use the top two buttons for on the pistol grip.
179 enum class TopButtonUse {
180 // Normal shifting.
181 kShift,
182 // Line following (currently just uses top button).
183 kLineFollow,
184 };
185
Sabina Davis92d2efa2017-11-04 22:35:25 -0700186 // Creates a DrivetrainInputReader with the corresponding joystick ports and
187 // axis for the (cheap) pistol grip controller.
James Kuszmaul8bad2412019-03-10 10:47:56 -0700188 static std::unique_ptr<PistolDrivetrainInputReader> Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700189 ::aos::EventLoop *event_loop, bool default_high_gear,
190 TopButtonUse top_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700191
192 private:
Austin Schuh2b1fce02018-03-02 20:05:20 -0800193 PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700194 ::aos::EventLoop *event_loop, driver_station::JoystickAxis wheel_high,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800195 driver_station::JoystickAxis wheel_low,
196 driver_station::JoystickAxis wheel_velocity_high,
197 driver_station::JoystickAxis wheel_velocity_low,
198 driver_station::JoystickAxis wheel_torque_high,
199 driver_station::JoystickAxis wheel_torque_low,
200 driver_station::JoystickAxis throttle_high,
201 driver_station::JoystickAxis throttle_low,
202 driver_station::JoystickAxis throttle_velocity_high,
203 driver_station::JoystickAxis throttle_velocity_low,
204 driver_station::JoystickAxis throttle_torque_high,
205 driver_station::JoystickAxis throttle_torque_low,
206 driver_station::ButtonLocation quick_turn,
207 driver_station::ButtonLocation shift_high,
208 driver_station::ButtonLocation shift_low,
209 driver_station::ButtonLocation turn1,
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700210 driver_station::ButtonLocation turn2,
211 driver_station::ButtonLocation slow_down)
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700212 : DrivetrainInputReader(event_loop, wheel_high, throttle_high, quick_turn,
213 turn1, TurnButtonUse::kLineFollow, turn2,
Austin Schuh48d3a962019-03-17 18:12:32 -0700214 TurnButtonUse::kControlLoopDriving),
Austin Schuh2b1fce02018-03-02 20:05:20 -0800215 wheel_low_(wheel_low),
216 wheel_velocity_high_(wheel_velocity_high),
217 wheel_velocity_low_(wheel_velocity_low),
218 wheel_torque_high_(wheel_torque_high),
219 wheel_torque_low_(wheel_torque_low),
220 throttle_low_(throttle_low),
221 throttle_velocity_high_(throttle_velocity_high),
222 throttle_velocity_low_(throttle_velocity_low),
223 throttle_torque_high_(throttle_torque_high),
224 throttle_torque_low_(throttle_torque_low),
225 shift_high_(shift_high),
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700226 shift_low_(shift_low),
227 slow_down_(slow_down) {}
Austin Schuh2b1fce02018-03-02 20:05:20 -0800228
Sabina Davis92d2efa2017-11-04 22:35:25 -0700229 WheelAndThrottle GetWheelAndThrottle(
230 const ::aos::input::driver_station::Data &data) override;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800231
232 // Sets the default shifter position
233 void set_default_high_gear(bool default_high_gear) {
234 high_gear_ = default_high_gear;
235 default_high_gear_ = default_high_gear;
236 }
237
238 const driver_station::JoystickAxis wheel_low_;
239 const driver_station::JoystickAxis wheel_velocity_high_;
240 const driver_station::JoystickAxis wheel_velocity_low_;
241 const driver_station::JoystickAxis wheel_torque_high_;
242 const driver_station::JoystickAxis wheel_torque_low_;
243
244 const driver_station::JoystickAxis throttle_low_;
245 const driver_station::JoystickAxis throttle_velocity_high_;
246 const driver_station::JoystickAxis throttle_velocity_low_;
247 const driver_station::JoystickAxis throttle_torque_high_;
248 const driver_station::JoystickAxis throttle_torque_low_;
249
250 const driver_station::ButtonLocation shift_high_;
251 const driver_station::ButtonLocation shift_low_;
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700252 const driver_station::ButtonLocation slow_down_;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800253
254 bool high_gear_;
255 bool default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700256};
257
258class XboxDrivetrainInputReader : public DrivetrainInputReader {
259 public:
260 using DrivetrainInputReader::DrivetrainInputReader;
261
262 // Creates a DrivetrainInputReader with the corresponding joystick ports and
263 // axis for the Xbox controller.
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700264 static std::unique_ptr<XboxDrivetrainInputReader> Make(
265 ::aos::EventLoop *event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700266
267 private:
268 WheelAndThrottle GetWheelAndThrottle(
269 const ::aos::input::driver_station::Data &data) override;
270};
271
272} // namespace input
273} // namespace aos
274
275#endif // AOS_INPUT_DRIVETRAIN_INPUT_H_