blob: d93d140eb48a3e0eea6e2c1037299f985c9f730d [file] [log] [blame]
James Kuszmaul7077d342021-06-09 20:23:58 -07001#include "frc971/input/drivetrain_input.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -07002
Sabina Davis92d2efa2017-11-04 22:35:25 -07003#include <cmath>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07004#include <cstdio>
5#include <cstring>
Sabina Davis92d2efa2017-11-04 22:35:25 -07006
John Park33858a32018-09-28 23:05:48 -07007#include "aos/commonmath.h"
John Park33858a32018-09-28 23:05:48 -07008#include "aos/logging/logging.h"
Nikolai Sohmers0991b1f2024-10-20 14:24:34 -07009#include "drivetrain_input.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -070010#include "frc971/control_loops/control_loops_generated.h"
11#include "frc971/control_loops/drivetrain/drivetrain_goal_generated.h"
12#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070013#include "frc971/input/driver_station_data.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070014
James Kuszmaul7077d342021-06-09 20:23:58 -070015using ::frc971::input::driver_station::ButtonLocation;
16using ::frc971::input::driver_station::ControlBit;
17using ::frc971::input::driver_station::JoystickAxis;
18using ::frc971::input::driver_station::POVLocation;
Sabina Davis92d2efa2017-11-04 22:35:25 -070019
Alex Perrycb7da4b2019-08-28 19:35:56 -070020namespace drivetrain = frc971::control_loops::drivetrain;
21
Stephan Pleinesf63bde82024-01-13 15:59:33 -080022namespace frc971::input {
Sabina Davis92d2efa2017-11-04 22:35:25 -070023
Sabina Davis82b19182017-11-10 09:30:25 -080024const ButtonLocation kShiftHigh(2, 3), kShiftHigh2(2, 2), kShiftLow(2, 1);
25
Sabina Davis92d2efa2017-11-04 22:35:25 -070026void DrivetrainInputReader::HandleDrivetrain(
James Kuszmaul7077d342021-06-09 20:23:58 -070027 const ::frc971::input::driver_station::Data &data) {
Sabina Davis92d2efa2017-11-04 22:35:25 -070028 const auto wheel_and_throttle = GetWheelAndThrottle(data);
29 const double wheel = wheel_and_throttle.wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -080030 const double wheel_velocity = wheel_and_throttle.wheel_velocity;
31 const double wheel_torque = wheel_and_throttle.wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -070032 const double throttle = wheel_and_throttle.throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -080033 const double throttle_velocity = wheel_and_throttle.throttle_velocity;
34 const double throttle_torque = wheel_and_throttle.throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -080035 const bool high_gear = wheel_and_throttle.high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -070036
Austin Schuhbd0a40f2019-06-30 14:56:31 -070037 drivetrain_status_fetcher_.Fetch();
38 if (drivetrain_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070039 robot_velocity_ = drivetrain_status_fetcher_->robot_speed();
Sabina Davis92d2efa2017-11-04 22:35:25 -070040 }
41
Austin Schuha250b2d2019-05-27 16:14:02 -070042 // If we have a vision align function, and it is in control, don't run the
43 // normal driving code.
44 if (vision_align_fn_) {
45 if (vision_align_fn_(data)) {
46 return;
47 }
48 }
49
James Kuszmaul8bad2412019-03-10 10:47:56 -070050 bool is_control_loop_driving = false;
51 bool is_line_following = false;
52
53 if (data.IsPressed(turn1_)) {
54 switch (turn1_use_) {
55 case TurnButtonUse::kControlLoopDriving:
56 is_control_loop_driving = true;
57 break;
58 case TurnButtonUse::kLineFollow:
59 is_line_following = true;
60 break;
61 }
62 }
63
64 if (data.IsPressed(turn2_)) {
65 switch (turn2_use_) {
66 case TurnButtonUse::kControlLoopDriving:
67 is_control_loop_driving = true;
68 break;
69 case TurnButtonUse::kLineFollow:
70 is_line_following = true;
71 break;
72 }
73 }
74
Austin Schuhbd0a40f2019-06-30 14:56:31 -070075 if (drivetrain_status_fetcher_.get()) {
Austin Schuh48d3a962019-03-17 18:12:32 -070076 if (is_control_loop_driving && !last_is_control_loop_driving_) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070077 left_goal_ = drivetrain_status_fetcher_->estimated_left_position() +
Austin Schuhf9202e82019-03-22 21:55:11 -070078 wheel * wheel_multiplier_;
Alex Perrycb7da4b2019-08-28 19:35:56 -070079 right_goal_ = drivetrain_status_fetcher_->estimated_right_position() -
Austin Schuhf9202e82019-03-22 21:55:11 -070080 wheel * wheel_multiplier_;
Sabina Davis92d2efa2017-11-04 22:35:25 -070081 }
82 }
Austin Schuh48d3a962019-03-17 18:12:32 -070083
Sabina Davis92d2efa2017-11-04 22:35:25 -070084 const double current_left_goal =
85 left_goal_ - wheel * wheel_multiplier_ + throttle * 0.3;
86 const double current_right_goal =
87 right_goal_ + wheel * wheel_multiplier_ + throttle * 0.3;
Alex Perrycb7da4b2019-08-28 19:35:56 -070088 auto builder = drivetrain_goal_sender_.MakeBuilder();
Sabina Davis92d2efa2017-11-04 22:35:25 -070089
Alex Perrycb7da4b2019-08-28 19:35:56 -070090 frc971::ProfileParameters::Builder linear_builder =
91 builder.MakeBuilder<frc971::ProfileParameters>();
Sabina Davis92d2efa2017-11-04 22:35:25 -070092
Alex Perrycb7da4b2019-08-28 19:35:56 -070093 linear_builder.add_max_velocity(3.0);
94 linear_builder.add_max_acceleration(20.0);
95
96 flatbuffers::Offset<frc971::ProfileParameters> linear_offset =
97 linear_builder.Finish();
98
99 auto goal_builder = builder.MakeBuilder<drivetrain::Goal>();
100 goal_builder.add_wheel(wheel);
101 goal_builder.add_wheel_velocity(wheel_velocity);
102 goal_builder.add_wheel_torque(wheel_torque);
103 goal_builder.add_throttle(throttle);
104 goal_builder.add_throttle_velocity(throttle_velocity);
105 goal_builder.add_throttle_torque(throttle_torque);
106 goal_builder.add_highgear(high_gear);
107 goal_builder.add_quickturn(data.IsPressed(quick_turn_));
108 goal_builder.add_controller_type(
James Kuszmaul7077d342021-06-09 20:23:58 -0700109 is_line_following ? drivetrain::ControllerType::LINE_FOLLOWER
110 : (is_control_loop_driving
111 ? drivetrain::ControllerType::MOTION_PROFILE
112 : drivetrain::ControllerType::POLYDRIVE));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700113 goal_builder.add_left_goal(current_left_goal);
114 goal_builder.add_right_goal(current_right_goal);
115 goal_builder.add_linear(linear_offset);
116
milind1f1dca32021-07-03 13:50:07 -0700117 if (builder.Send(goal_builder.Finish()) != aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700118 AOS_LOG(WARNING, "sending stick values failed\n");
Sabina Davis92d2efa2017-11-04 22:35:25 -0700119 }
Austin Schuh48d3a962019-03-17 18:12:32 -0700120
121 last_is_control_loop_driving_ = is_control_loop_driving;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700122}
123
Nikolai Sohmers0991b1f2024-10-20 14:24:34 -0700124void SwerveDrivetrainInputReader::HandleDrivetrain(
125 const ::frc971::input::driver_station::Data &data) {
126 const auto swerve_goals = GetSwerveGoals(data);
127 const double vx = swerve_goals.vx;
128 const double vy = swerve_goals.vy;
129 const double omega = swerve_goals.omega;
130
131 auto builder = goal_sender_.MakeStaticBuilder();
132
133 auto joystick_goal = builder->add_joystick_goal();
134
135 joystick_goal->set_vx(vx);
136 joystick_goal->set_vy(vy);
137 joystick_goal->set_omega(omega);
138
139 builder.CheckOk(builder.Send());
140}
141
142std::unique_ptr<SwerveDrivetrainInputReader> SwerveDrivetrainInputReader::Make(
143 ::aos::EventLoop *event_loop) {
144 // Swerve Controller
145 // axis (2, 2) will give you alternative omega axis (controls with vertical
146 // movement)
147 const JoystickAxis kVxAxis(2, 1), kVyAxis(1, 1), kOmegaAxis(1, 2);
148
149 std::unique_ptr<SwerveDrivetrainInputReader> result(
150 new SwerveDrivetrainInputReader(event_loop, kVxAxis, kVyAxis,
151 kOmegaAxis));
152 return result;
153}
154
155SwerveDrivetrainInputReader::SwerveGoals
156SwerveDrivetrainInputReader::GetSwerveGoals(
157 const ::frc971::input::driver_station::Data &data) {
158 // xbox
159 constexpr double kMovementDeadband = 0.05;
160 constexpr double kRotationDeadband = 0.05;
161
162 const double omega =
163 -aos::Deadband(-data.GetAxis(omega_axis_), kRotationDeadband, 1.0);
164
165 const double vx =
166 aos::Deadband(-data.GetAxis(vx_axis_), kMovementDeadband, 1.0);
167
168 const double vy =
169 aos::Deadband(-data.GetAxis(vy_axis_), kMovementDeadband, 1.0);
170
171 return SwerveDrivetrainInputReader::SwerveGoals{vx, vy, omega};
172}
173
Sabina Davis92d2efa2017-11-04 22:35:25 -0700174DrivetrainInputReader::WheelAndThrottle
175SteeringWheelDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700176 const ::frc971::input::driver_station::Data &data) {
Austin Schuh2b1fce02018-03-02 20:05:20 -0800177 const double wheel = -data.GetAxis(wheel_);
178 const double throttle = -data.GetAxis(throttle_);
Sabina Davis82b19182017-11-10 09:30:25 -0800179
180 if (!data.GetControlBit(ControlBit::kEnabled)) {
181 high_gear_ = default_high_gear_;
182 }
183
184 if (data.PosEdge(kShiftLow)) {
185 high_gear_ = false;
186 }
187
188 if (data.PosEdge(kShiftHigh) || data.PosEdge(kShiftHigh2)) {
189 high_gear_ = true;
190 }
191
Austin Schuh2b1fce02018-03-02 20:05:20 -0800192 return DrivetrainInputReader::WheelAndThrottle{
193 wheel, 0.0, 0.0, throttle, 0.0, 0.0, high_gear_};
194}
195
James Kuszmaul7077d342021-06-09 20:23:58 -0700196double UnwrappedAxis(const ::frc971::input::driver_station::Data &data,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800197 const JoystickAxis &high_bits,
198 const JoystickAxis &low_bits) {
199 const float high_bits_data = data.GetAxis(high_bits);
200 const float low_bits_data = data.GetAxis(low_bits);
201 const int16_t high_bits_data_int =
202 (high_bits_data < 0.0f ? high_bits_data * 128.0f
203 : high_bits_data * 127.0f);
204 const int16_t low_bits_data_int =
205 (low_bits_data < 0.0f ? low_bits_data * 128.0f : low_bits_data * 127.0f);
206
207 const uint16_t high_bits_data_uint =
208 ((static_cast<uint16_t>(high_bits_data_int) & 0xff) + 0x80) & 0xff;
209 const uint16_t low_bits_data_uint =
210 ((static_cast<uint16_t>(low_bits_data_int) & 0xff) + 0x80) & 0xff;
211
212 const uint16_t data_uint = (high_bits_data_uint << 8) | low_bits_data_uint;
213
214 const int32_t data_int = static_cast<int32_t>(data_uint) - 0x8000;
215
216 if (data_int < 0) {
217 return static_cast<double>(data_int) / static_cast<double>(0x8000);
218 } else {
219 return static_cast<double>(data_int) / static_cast<double>(0x7fff);
220 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700221}
222
223DrivetrainInputReader::WheelAndThrottle
224PistolDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700225 const ::frc971::input::driver_station::Data &data) {
226 const double wheel = -UnwrappedAxis(data, wheel_, wheel_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800227 const double wheel_velocity =
228 -UnwrappedAxis(data, wheel_velocity_high_, wheel_velocity_low_) * 50.0;
229 const double wheel_torque =
230 -UnwrappedAxis(data, wheel_torque_high_, wheel_torque_low_) / 2.0;
231
James Kuszmaul7077d342021-06-09 20:23:58 -0700232 double throttle = UnwrappedAxis(data, throttle_, throttle_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800233 const double throttle_velocity =
James Kuszmaul7077d342021-06-09 20:23:58 -0700234 UnwrappedAxis(data, throttle_velocity_high_, throttle_velocity_low_) *
235 50.0;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800236 const double throttle_torque =
237 UnwrappedAxis(data, throttle_torque_high_, throttle_torque_low_) / 2.0;
238
Austin Schuh876b4f02018-03-10 19:16:59 -0800239 // TODO(austin): Deal with haptics here.
240 if (throttle < 0) {
241 throttle = ::std::max(-1.0, throttle / 0.7);
242 }
243
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700244 if (data.IsPressed(slow_down_)) {
245 throttle *= 0.5;
246 }
247
Austin Schuh2b1fce02018-03-02 20:05:20 -0800248 if (!data.GetControlBit(ControlBit::kEnabled)) {
249 high_gear_ = default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700250 }
251
Austin Schuh2b1fce02018-03-02 20:05:20 -0800252 if (data.PosEdge(shift_low_)) {
253 high_gear_ = false;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700254 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700255
Austin Schuh2b1fce02018-03-02 20:05:20 -0800256 if (data.PosEdge(shift_high_)) {
257 high_gear_ = true;
258 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700259
James Kuszmaulf64bc432022-03-25 19:14:42 -0700260 // Emprically, the current pistol grip tends towards steady-state errors at
261 // ~0.01-0.02 on both the wheel/throttle. Having the throttle correctly snap
262 // to zero is more important than the wheel for our internal logic, so force a
263 // deadband there.
264 constexpr double kThrottleDeadband = 0.05;
265 throttle = aos::Deadband(throttle, kThrottleDeadband, 1.0);
266
Austin Schuh2b1fce02018-03-02 20:05:20 -0800267 return DrivetrainInputReader::WheelAndThrottle{
James Kuszmaul7077d342021-06-09 20:23:58 -0700268 wheel, wheel_velocity, wheel_torque,
269 throttle, throttle_velocity, throttle_torque,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800270 high_gear_};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700271}
272
273DrivetrainInputReader::WheelAndThrottle
274XboxDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700275 const ::frc971::input::driver_station::Data &data) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700276 // xbox
277 constexpr double kWheelDeadband = 0.05;
278 constexpr double kThrottleDeadband = 0.05;
279 const double wheel =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800280 aos::Deadband(-data.GetAxis(wheel_), kWheelDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700281
282 const double unmodified_throttle =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800283 aos::Deadband(-data.GetAxis(throttle_), kThrottleDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700284
285 // Apply a sin function that's scaled to make it feel better.
286 constexpr double throttle_range = M_PI_2 * 0.9;
287
288 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
289 ::std::sin(throttle_range);
290 throttle = ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
291 throttle = 2.0 * unmodified_throttle - throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800292 return DrivetrainInputReader::WheelAndThrottle{wheel, 0.0, 0.0, throttle,
293 0.0, 0.0, true};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700294}
295
296std::unique_ptr<SteeringWheelDrivetrainInputReader>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700297SteeringWheelDrivetrainInputReader::Make(::aos::EventLoop *event_loop,
298 bool default_high_gear) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700299 const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
300 const ButtonLocation kQuickTurn(1, 5);
301 const ButtonLocation kTurn1(1, 7);
302 const ButtonLocation kTurn2(1, 11);
303 std::unique_ptr<SteeringWheelDrivetrainInputReader> result(
James Kuszmaul8bad2412019-03-10 10:47:56 -0700304 new SteeringWheelDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700305 event_loop, kSteeringWheel, kDriveThrottle, kQuickTurn, kTurn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700306 TurnButtonUse::kControlLoopDriving, kTurn2,
307 TurnButtonUse::kControlLoopDriving));
Sabina Davis82b19182017-11-10 09:30:25 -0800308 result.get()->set_default_high_gear(default_high_gear);
309
Sabina Davis92d2efa2017-11-04 22:35:25 -0700310 return result;
311}
312
Austin Schuh2b1fce02018-03-02 20:05:20 -0800313std::unique_ptr<PistolDrivetrainInputReader> PistolDrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700314 ::aos::EventLoop *event_loop, bool default_high_gear,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700315 PistolTopButtonUse top_button_use, PistolSecondButtonUse second_button_use,
316 PistolBottomButtonUse bottom_button_use) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700317 // Pistol Grip controller
Austin Schuh2b1fce02018-03-02 20:05:20 -0800318 const JoystickAxis kTriggerHigh(1, 1), kTriggerLow(1, 4),
319 kTriggerVelocityHigh(1, 2), kTriggerVelocityLow(1, 5),
320 kTriggerTorqueHigh(1, 3), kTriggerTorqueLow(1, 6);
321
322 const JoystickAxis kWheelHigh(2, 1), kWheelLow(2, 4),
323 kWheelVelocityHigh(2, 2), kWheelVelocityLow(2, 5), kWheelTorqueHigh(2, 3),
324 kWheelTorqueLow(2, 6);
325
Austin Schuhe8a54c02018-03-05 00:25:58 -0800326 const ButtonLocation kQuickTurn(1, 3);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700327
Austin Schuh91a4e552023-02-24 20:34:01 -0800328 const ButtonLocation kTopButton(1, 1);
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700329
Austin Schuh91a4e552023-02-24 20:34:01 -0800330 const ButtonLocation kSecondButton(1, 2);
331 const ButtonLocation kBottomButton(1, 4);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700332 // Non-existant button for nops.
Ravago Jones8c65c432023-03-25 17:35:39 -0700333 const ButtonLocation kDummyButton(1, 15);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700334
335 // TODO(james): Make a copy assignment operator for ButtonLocation so we don't
336 // have to shoehorn in these ternary operators.
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700337 const ButtonLocation kTurn1 =
338 (second_button_use == PistolSecondButtonUse::kTurn1) ? kSecondButton
339 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700340 // Turn2 does closed loop driving.
341 const ButtonLocation kTurn2 =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700342 (top_button_use == PistolTopButtonUse::kLineFollow) ? kTopButton
343 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700344
James Kuszmaul8bad2412019-03-10 10:47:56 -0700345 const ButtonLocation kShiftHigh =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700346 (top_button_use == PistolTopButtonUse::kShift) ? kTopButton
347 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700348 const ButtonLocation kShiftLow =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700349 (second_button_use == PistolSecondButtonUse::kShiftLow) ? kSecondButton
350 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700351
Sabina Davis92d2efa2017-11-04 22:35:25 -0700352 std::unique_ptr<PistolDrivetrainInputReader> result(
Austin Schuh2b1fce02018-03-02 20:05:20 -0800353 new PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700354 event_loop, kWheelHigh, kWheelLow, kTriggerVelocityHigh,
355 kTriggerVelocityLow, kTriggerTorqueHigh, kTriggerTorqueLow,
356 kTriggerHigh, kTriggerLow, kWheelVelocityHigh, kWheelVelocityLow,
357 kWheelTorqueHigh, kWheelTorqueLow, kQuickTurn, kShiftHigh, kShiftLow,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700358 kTurn1,
359 (bottom_button_use == PistolBottomButtonUse::kControlLoopDriving)
360 ? kBottomButton
361 : kTurn2,
362 (top_button_use == PistolTopButtonUse::kNone) ? kTopButton
363 : kBottomButton));
Austin Schuh2b1fce02018-03-02 20:05:20 -0800364
365 result->set_default_high_gear(default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700366 return result;
367}
368
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700369std::unique_ptr<XboxDrivetrainInputReader> XboxDrivetrainInputReader::Make(
370 ::aos::EventLoop *event_loop) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700371 // xbox
372 const JoystickAxis kSteeringWheel(1, 5), kDriveThrottle(1, 2);
373 const ButtonLocation kQuickTurn(1, 5);
374
375 // Nop
376 const ButtonLocation kTurn1(1, 1);
377 const ButtonLocation kTurn2(1, 2);
378
379 std::unique_ptr<XboxDrivetrainInputReader> result(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700380 new XboxDrivetrainInputReader(event_loop, kSteeringWheel, kDriveThrottle,
381 kQuickTurn, kTurn1,
382 TurnButtonUse::kControlLoopDriving, kTurn2,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700383 TurnButtonUse::kControlLoopDriving));
Sabina Davis92d2efa2017-11-04 22:35:25 -0700384 return result;
385}
386::std::unique_ptr<DrivetrainInputReader> DrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700387 ::aos::EventLoop *event_loop, InputType type,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700388 const drivetrain::DrivetrainConfig<double> &dt_config) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700389 std::unique_ptr<DrivetrainInputReader> drivetrain_input_reader;
390
391 using InputType = DrivetrainInputReader::InputType;
Sabina Davis82b19182017-11-10 09:30:25 -0800392
Sabina Davis92d2efa2017-11-04 22:35:25 -0700393 switch (type) {
394 case InputType::kSteeringWheel:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700395 drivetrain_input_reader = SteeringWheelDrivetrainInputReader::Make(
396 event_loop, dt_config.default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700397 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700398 case InputType::kPistol: {
399 // For backwards compatibility
400 PistolTopButtonUse top_button_use =
James Kuszmaul8bad2412019-03-10 10:47:56 -0700401 dt_config.pistol_grip_shift_enables_line_follow
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700402 ? PistolTopButtonUse::kLineFollow
403 : dt_config.top_button_use;
404
405 PistolSecondButtonUse second_button_use = dt_config.second_button_use;
406 PistolBottomButtonUse bottom_button_use = dt_config.bottom_button_use;
407
408 if (top_button_use == PistolTopButtonUse::kLineFollow) {
409 second_button_use = PistolSecondButtonUse::kTurn1;
410 }
411
412 drivetrain_input_reader = PistolDrivetrainInputReader::Make(
413 event_loop, dt_config.default_high_gear, top_button_use,
414 second_button_use, bottom_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700415 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700416 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700417 case InputType::kXbox:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700418 drivetrain_input_reader = XboxDrivetrainInputReader::Make(event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700419 break;
420 }
421 return drivetrain_input_reader;
422}
423
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800424} // namespace frc971::input