blob: be61cc4500fcd43f421354a571e19ae273c0155a [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"
Alex Perrycb7da4b2019-08-28 19:35:56 -07009#include "frc971/control_loops/control_loops_generated.h"
10#include "frc971/control_loops/drivetrain/drivetrain_goal_generated.h"
11#include "frc971/control_loops/drivetrain/drivetrain_status_generated.h"
James Kuszmaul7077d342021-06-09 20:23:58 -070012#include "frc971/input/driver_station_data.h"
Sabina Davis92d2efa2017-11-04 22:35:25 -070013
James Kuszmaul7077d342021-06-09 20:23:58 -070014using ::frc971::input::driver_station::ButtonLocation;
15using ::frc971::input::driver_station::ControlBit;
16using ::frc971::input::driver_station::JoystickAxis;
17using ::frc971::input::driver_station::POVLocation;
Sabina Davis92d2efa2017-11-04 22:35:25 -070018
Alex Perrycb7da4b2019-08-28 19:35:56 -070019namespace drivetrain = frc971::control_loops::drivetrain;
20
Stephan Pleinesf63bde82024-01-13 15:59:33 -080021namespace frc971::input {
Sabina Davis92d2efa2017-11-04 22:35:25 -070022
Sabina Davis82b19182017-11-10 09:30:25 -080023const ButtonLocation kShiftHigh(2, 3), kShiftHigh2(2, 2), kShiftLow(2, 1);
24
Sabina Davis92d2efa2017-11-04 22:35:25 -070025void DrivetrainInputReader::HandleDrivetrain(
James Kuszmaul7077d342021-06-09 20:23:58 -070026 const ::frc971::input::driver_station::Data &data) {
Sabina Davis92d2efa2017-11-04 22:35:25 -070027 const auto wheel_and_throttle = GetWheelAndThrottle(data);
28 const double wheel = wheel_and_throttle.wheel;
Austin Schuh2b1fce02018-03-02 20:05:20 -080029 const double wheel_velocity = wheel_and_throttle.wheel_velocity;
30 const double wheel_torque = wheel_and_throttle.wheel_torque;
Sabina Davis92d2efa2017-11-04 22:35:25 -070031 const double throttle = wheel_and_throttle.throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -080032 const double throttle_velocity = wheel_and_throttle.throttle_velocity;
33 const double throttle_torque = wheel_and_throttle.throttle_torque;
Sabina Davis82b19182017-11-10 09:30:25 -080034 const bool high_gear = wheel_and_throttle.high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -070035
Austin Schuhbd0a40f2019-06-30 14:56:31 -070036 drivetrain_status_fetcher_.Fetch();
37 if (drivetrain_status_fetcher_.get()) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070038 robot_velocity_ = drivetrain_status_fetcher_->robot_speed();
Sabina Davis92d2efa2017-11-04 22:35:25 -070039 }
40
Austin Schuha250b2d2019-05-27 16:14:02 -070041 // If we have a vision align function, and it is in control, don't run the
42 // normal driving code.
43 if (vision_align_fn_) {
44 if (vision_align_fn_(data)) {
45 return;
46 }
47 }
48
James Kuszmaul8bad2412019-03-10 10:47:56 -070049 bool is_control_loop_driving = false;
50 bool is_line_following = false;
51
52 if (data.IsPressed(turn1_)) {
53 switch (turn1_use_) {
54 case TurnButtonUse::kControlLoopDriving:
55 is_control_loop_driving = true;
56 break;
57 case TurnButtonUse::kLineFollow:
58 is_line_following = true;
59 break;
60 }
61 }
62
63 if (data.IsPressed(turn2_)) {
64 switch (turn2_use_) {
65 case TurnButtonUse::kControlLoopDriving:
66 is_control_loop_driving = true;
67 break;
68 case TurnButtonUse::kLineFollow:
69 is_line_following = true;
70 break;
71 }
72 }
73
Austin Schuhbd0a40f2019-06-30 14:56:31 -070074 if (drivetrain_status_fetcher_.get()) {
Austin Schuh48d3a962019-03-17 18:12:32 -070075 if (is_control_loop_driving && !last_is_control_loop_driving_) {
Alex Perrycb7da4b2019-08-28 19:35:56 -070076 left_goal_ = drivetrain_status_fetcher_->estimated_left_position() +
Austin Schuhf9202e82019-03-22 21:55:11 -070077 wheel * wheel_multiplier_;
Alex Perrycb7da4b2019-08-28 19:35:56 -070078 right_goal_ = drivetrain_status_fetcher_->estimated_right_position() -
Austin Schuhf9202e82019-03-22 21:55:11 -070079 wheel * wheel_multiplier_;
Sabina Davis92d2efa2017-11-04 22:35:25 -070080 }
81 }
Austin Schuh48d3a962019-03-17 18:12:32 -070082
Sabina Davis92d2efa2017-11-04 22:35:25 -070083 const double current_left_goal =
84 left_goal_ - wheel * wheel_multiplier_ + throttle * 0.3;
85 const double current_right_goal =
86 right_goal_ + wheel * wheel_multiplier_ + throttle * 0.3;
Alex Perrycb7da4b2019-08-28 19:35:56 -070087 auto builder = drivetrain_goal_sender_.MakeBuilder();
Sabina Davis92d2efa2017-11-04 22:35:25 -070088
Alex Perrycb7da4b2019-08-28 19:35:56 -070089 frc971::ProfileParameters::Builder linear_builder =
90 builder.MakeBuilder<frc971::ProfileParameters>();
Sabina Davis92d2efa2017-11-04 22:35:25 -070091
Alex Perrycb7da4b2019-08-28 19:35:56 -070092 linear_builder.add_max_velocity(3.0);
93 linear_builder.add_max_acceleration(20.0);
94
95 flatbuffers::Offset<frc971::ProfileParameters> linear_offset =
96 linear_builder.Finish();
97
98 auto goal_builder = builder.MakeBuilder<drivetrain::Goal>();
99 goal_builder.add_wheel(wheel);
100 goal_builder.add_wheel_velocity(wheel_velocity);
101 goal_builder.add_wheel_torque(wheel_torque);
102 goal_builder.add_throttle(throttle);
103 goal_builder.add_throttle_velocity(throttle_velocity);
104 goal_builder.add_throttle_torque(throttle_torque);
105 goal_builder.add_highgear(high_gear);
106 goal_builder.add_quickturn(data.IsPressed(quick_turn_));
107 goal_builder.add_controller_type(
James Kuszmaul7077d342021-06-09 20:23:58 -0700108 is_line_following ? drivetrain::ControllerType::LINE_FOLLOWER
109 : (is_control_loop_driving
110 ? drivetrain::ControllerType::MOTION_PROFILE
111 : drivetrain::ControllerType::POLYDRIVE));
Alex Perrycb7da4b2019-08-28 19:35:56 -0700112 goal_builder.add_left_goal(current_left_goal);
113 goal_builder.add_right_goal(current_right_goal);
114 goal_builder.add_linear(linear_offset);
115
milind1f1dca32021-07-03 13:50:07 -0700116 if (builder.Send(goal_builder.Finish()) != aos::RawSender::Error::kOk) {
Austin Schuhf257f3c2019-10-27 21:00:43 -0700117 AOS_LOG(WARNING, "sending stick values failed\n");
Sabina Davis92d2efa2017-11-04 22:35:25 -0700118 }
Austin Schuh48d3a962019-03-17 18:12:32 -0700119
120 last_is_control_loop_driving_ = is_control_loop_driving;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700121}
122
123DrivetrainInputReader::WheelAndThrottle
124SteeringWheelDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700125 const ::frc971::input::driver_station::Data &data) {
Austin Schuh2b1fce02018-03-02 20:05:20 -0800126 const double wheel = -data.GetAxis(wheel_);
127 const double throttle = -data.GetAxis(throttle_);
Sabina Davis82b19182017-11-10 09:30:25 -0800128
129 if (!data.GetControlBit(ControlBit::kEnabled)) {
130 high_gear_ = default_high_gear_;
131 }
132
133 if (data.PosEdge(kShiftLow)) {
134 high_gear_ = false;
135 }
136
137 if (data.PosEdge(kShiftHigh) || data.PosEdge(kShiftHigh2)) {
138 high_gear_ = true;
139 }
140
Austin Schuh2b1fce02018-03-02 20:05:20 -0800141 return DrivetrainInputReader::WheelAndThrottle{
142 wheel, 0.0, 0.0, throttle, 0.0, 0.0, high_gear_};
143}
144
James Kuszmaul7077d342021-06-09 20:23:58 -0700145double UnwrappedAxis(const ::frc971::input::driver_station::Data &data,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800146 const JoystickAxis &high_bits,
147 const JoystickAxis &low_bits) {
148 const float high_bits_data = data.GetAxis(high_bits);
149 const float low_bits_data = data.GetAxis(low_bits);
150 const int16_t high_bits_data_int =
151 (high_bits_data < 0.0f ? high_bits_data * 128.0f
152 : high_bits_data * 127.0f);
153 const int16_t low_bits_data_int =
154 (low_bits_data < 0.0f ? low_bits_data * 128.0f : low_bits_data * 127.0f);
155
156 const uint16_t high_bits_data_uint =
157 ((static_cast<uint16_t>(high_bits_data_int) & 0xff) + 0x80) & 0xff;
158 const uint16_t low_bits_data_uint =
159 ((static_cast<uint16_t>(low_bits_data_int) & 0xff) + 0x80) & 0xff;
160
161 const uint16_t data_uint = (high_bits_data_uint << 8) | low_bits_data_uint;
162
163 const int32_t data_int = static_cast<int32_t>(data_uint) - 0x8000;
164
165 if (data_int < 0) {
166 return static_cast<double>(data_int) / static_cast<double>(0x8000);
167 } else {
168 return static_cast<double>(data_int) / static_cast<double>(0x7fff);
169 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700170}
171
172DrivetrainInputReader::WheelAndThrottle
173PistolDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700174 const ::frc971::input::driver_station::Data &data) {
175 const double wheel = -UnwrappedAxis(data, wheel_, wheel_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800176 const double wheel_velocity =
177 -UnwrappedAxis(data, wheel_velocity_high_, wheel_velocity_low_) * 50.0;
178 const double wheel_torque =
179 -UnwrappedAxis(data, wheel_torque_high_, wheel_torque_low_) / 2.0;
180
James Kuszmaul7077d342021-06-09 20:23:58 -0700181 double throttle = UnwrappedAxis(data, throttle_, throttle_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800182 const double throttle_velocity =
James Kuszmaul7077d342021-06-09 20:23:58 -0700183 UnwrappedAxis(data, throttle_velocity_high_, throttle_velocity_low_) *
184 50.0;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800185 const double throttle_torque =
186 UnwrappedAxis(data, throttle_torque_high_, throttle_torque_low_) / 2.0;
187
Austin Schuh876b4f02018-03-10 19:16:59 -0800188 // TODO(austin): Deal with haptics here.
189 if (throttle < 0) {
190 throttle = ::std::max(-1.0, throttle / 0.7);
191 }
192
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700193 if (data.IsPressed(slow_down_)) {
194 throttle *= 0.5;
195 }
196
Austin Schuh2b1fce02018-03-02 20:05:20 -0800197 if (!data.GetControlBit(ControlBit::kEnabled)) {
198 high_gear_ = default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700199 }
200
Austin Schuh2b1fce02018-03-02 20:05:20 -0800201 if (data.PosEdge(shift_low_)) {
202 high_gear_ = false;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700203 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700204
Austin Schuh2b1fce02018-03-02 20:05:20 -0800205 if (data.PosEdge(shift_high_)) {
206 high_gear_ = true;
207 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700208
James Kuszmaulf64bc432022-03-25 19:14:42 -0700209 // Emprically, the current pistol grip tends towards steady-state errors at
210 // ~0.01-0.02 on both the wheel/throttle. Having the throttle correctly snap
211 // to zero is more important than the wheel for our internal logic, so force a
212 // deadband there.
213 constexpr double kThrottleDeadband = 0.05;
214 throttle = aos::Deadband(throttle, kThrottleDeadband, 1.0);
215
Austin Schuh2b1fce02018-03-02 20:05:20 -0800216 return DrivetrainInputReader::WheelAndThrottle{
James Kuszmaul7077d342021-06-09 20:23:58 -0700217 wheel, wheel_velocity, wheel_torque,
218 throttle, throttle_velocity, throttle_torque,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800219 high_gear_};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700220}
221
222DrivetrainInputReader::WheelAndThrottle
223XboxDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700224 const ::frc971::input::driver_station::Data &data) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700225 // xbox
226 constexpr double kWheelDeadband = 0.05;
227 constexpr double kThrottleDeadband = 0.05;
228 const double wheel =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800229 aos::Deadband(-data.GetAxis(wheel_), kWheelDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700230
231 const double unmodified_throttle =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800232 aos::Deadband(-data.GetAxis(throttle_), kThrottleDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700233
234 // Apply a sin function that's scaled to make it feel better.
235 constexpr double throttle_range = M_PI_2 * 0.9;
236
237 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
238 ::std::sin(throttle_range);
239 throttle = ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
240 throttle = 2.0 * unmodified_throttle - throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800241 return DrivetrainInputReader::WheelAndThrottle{wheel, 0.0, 0.0, throttle,
242 0.0, 0.0, true};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700243}
244
245std::unique_ptr<SteeringWheelDrivetrainInputReader>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700246SteeringWheelDrivetrainInputReader::Make(::aos::EventLoop *event_loop,
247 bool default_high_gear) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700248 const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
249 const ButtonLocation kQuickTurn(1, 5);
250 const ButtonLocation kTurn1(1, 7);
251 const ButtonLocation kTurn2(1, 11);
252 std::unique_ptr<SteeringWheelDrivetrainInputReader> result(
James Kuszmaul8bad2412019-03-10 10:47:56 -0700253 new SteeringWheelDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700254 event_loop, kSteeringWheel, kDriveThrottle, kQuickTurn, kTurn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700255 TurnButtonUse::kControlLoopDriving, kTurn2,
256 TurnButtonUse::kControlLoopDriving));
Sabina Davis82b19182017-11-10 09:30:25 -0800257 result.get()->set_default_high_gear(default_high_gear);
258
Sabina Davis92d2efa2017-11-04 22:35:25 -0700259 return result;
260}
261
Austin Schuh2b1fce02018-03-02 20:05:20 -0800262std::unique_ptr<PistolDrivetrainInputReader> PistolDrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700263 ::aos::EventLoop *event_loop, bool default_high_gear,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700264 PistolTopButtonUse top_button_use, PistolSecondButtonUse second_button_use,
265 PistolBottomButtonUse bottom_button_use) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700266 // Pistol Grip controller
Austin Schuh2b1fce02018-03-02 20:05:20 -0800267 const JoystickAxis kTriggerHigh(1, 1), kTriggerLow(1, 4),
268 kTriggerVelocityHigh(1, 2), kTriggerVelocityLow(1, 5),
269 kTriggerTorqueHigh(1, 3), kTriggerTorqueLow(1, 6);
270
271 const JoystickAxis kWheelHigh(2, 1), kWheelLow(2, 4),
272 kWheelVelocityHigh(2, 2), kWheelVelocityLow(2, 5), kWheelTorqueHigh(2, 3),
273 kWheelTorqueLow(2, 6);
274
Austin Schuhe8a54c02018-03-05 00:25:58 -0800275 const ButtonLocation kQuickTurn(1, 3);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700276
Austin Schuh91a4e552023-02-24 20:34:01 -0800277 const ButtonLocation kTopButton(1, 1);
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700278
Austin Schuh91a4e552023-02-24 20:34:01 -0800279 const ButtonLocation kSecondButton(1, 2);
280 const ButtonLocation kBottomButton(1, 4);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700281 // Non-existant button for nops.
Ravago Jones8c65c432023-03-25 17:35:39 -0700282 const ButtonLocation kDummyButton(1, 15);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700283
284 // TODO(james): Make a copy assignment operator for ButtonLocation so we don't
285 // have to shoehorn in these ternary operators.
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700286 const ButtonLocation kTurn1 =
287 (second_button_use == PistolSecondButtonUse::kTurn1) ? kSecondButton
288 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700289 // Turn2 does closed loop driving.
290 const ButtonLocation kTurn2 =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700291 (top_button_use == PistolTopButtonUse::kLineFollow) ? kTopButton
292 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700293
James Kuszmaul8bad2412019-03-10 10:47:56 -0700294 const ButtonLocation kShiftHigh =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700295 (top_button_use == PistolTopButtonUse::kShift) ? kTopButton
296 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700297 const ButtonLocation kShiftLow =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700298 (second_button_use == PistolSecondButtonUse::kShiftLow) ? kSecondButton
299 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700300
Sabina Davis92d2efa2017-11-04 22:35:25 -0700301 std::unique_ptr<PistolDrivetrainInputReader> result(
Austin Schuh2b1fce02018-03-02 20:05:20 -0800302 new PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700303 event_loop, kWheelHigh, kWheelLow, kTriggerVelocityHigh,
304 kTriggerVelocityLow, kTriggerTorqueHigh, kTriggerTorqueLow,
305 kTriggerHigh, kTriggerLow, kWheelVelocityHigh, kWheelVelocityLow,
306 kWheelTorqueHigh, kWheelTorqueLow, kQuickTurn, kShiftHigh, kShiftLow,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700307 kTurn1,
308 (bottom_button_use == PistolBottomButtonUse::kControlLoopDriving)
309 ? kBottomButton
310 : kTurn2,
311 (top_button_use == PistolTopButtonUse::kNone) ? kTopButton
312 : kBottomButton));
Austin Schuh2b1fce02018-03-02 20:05:20 -0800313
314 result->set_default_high_gear(default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700315 return result;
316}
317
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700318std::unique_ptr<XboxDrivetrainInputReader> XboxDrivetrainInputReader::Make(
319 ::aos::EventLoop *event_loop) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700320 // xbox
321 const JoystickAxis kSteeringWheel(1, 5), kDriveThrottle(1, 2);
322 const ButtonLocation kQuickTurn(1, 5);
323
324 // Nop
325 const ButtonLocation kTurn1(1, 1);
326 const ButtonLocation kTurn2(1, 2);
327
328 std::unique_ptr<XboxDrivetrainInputReader> result(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700329 new XboxDrivetrainInputReader(event_loop, kSteeringWheel, kDriveThrottle,
330 kQuickTurn, kTurn1,
331 TurnButtonUse::kControlLoopDriving, kTurn2,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700332 TurnButtonUse::kControlLoopDriving));
Sabina Davis92d2efa2017-11-04 22:35:25 -0700333 return result;
334}
335::std::unique_ptr<DrivetrainInputReader> DrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700336 ::aos::EventLoop *event_loop, InputType type,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700337 const drivetrain::DrivetrainConfig<double> &dt_config) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700338 std::unique_ptr<DrivetrainInputReader> drivetrain_input_reader;
339
340 using InputType = DrivetrainInputReader::InputType;
Sabina Davis82b19182017-11-10 09:30:25 -0800341
Sabina Davis92d2efa2017-11-04 22:35:25 -0700342 switch (type) {
343 case InputType::kSteeringWheel:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700344 drivetrain_input_reader = SteeringWheelDrivetrainInputReader::Make(
345 event_loop, dt_config.default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700346 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700347 case InputType::kPistol: {
348 // For backwards compatibility
349 PistolTopButtonUse top_button_use =
James Kuszmaul8bad2412019-03-10 10:47:56 -0700350 dt_config.pistol_grip_shift_enables_line_follow
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700351 ? PistolTopButtonUse::kLineFollow
352 : dt_config.top_button_use;
353
354 PistolSecondButtonUse second_button_use = dt_config.second_button_use;
355 PistolBottomButtonUse bottom_button_use = dt_config.bottom_button_use;
356
357 if (top_button_use == PistolTopButtonUse::kLineFollow) {
358 second_button_use = PistolSecondButtonUse::kTurn1;
359 }
360
361 drivetrain_input_reader = PistolDrivetrainInputReader::Make(
362 event_loop, dt_config.default_high_gear, top_button_use,
363 second_button_use, bottom_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700364 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700365 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700366 case InputType::kXbox:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700367 drivetrain_input_reader = XboxDrivetrainInputReader::Make(event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700368 break;
369 }
370 return drivetrain_input_reader;
371}
372
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800373} // namespace frc971::input