blob: 239eddf28c5016d5adf645e01011ef17237d290a [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
James Kuszmaul7077d342021-06-09 20:23:58 -070021namespace frc971 {
Sabina Davis92d2efa2017-11-04 22:35:25 -070022namespace input {
23
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
124DrivetrainInputReader::WheelAndThrottle
125SteeringWheelDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700126 const ::frc971::input::driver_station::Data &data) {
Austin Schuh2b1fce02018-03-02 20:05:20 -0800127 const double wheel = -data.GetAxis(wheel_);
128 const double throttle = -data.GetAxis(throttle_);
Sabina Davis82b19182017-11-10 09:30:25 -0800129
130 if (!data.GetControlBit(ControlBit::kEnabled)) {
131 high_gear_ = default_high_gear_;
132 }
133
134 if (data.PosEdge(kShiftLow)) {
135 high_gear_ = false;
136 }
137
138 if (data.PosEdge(kShiftHigh) || data.PosEdge(kShiftHigh2)) {
139 high_gear_ = true;
140 }
141
Austin Schuh2b1fce02018-03-02 20:05:20 -0800142 return DrivetrainInputReader::WheelAndThrottle{
143 wheel, 0.0, 0.0, throttle, 0.0, 0.0, high_gear_};
144}
145
James Kuszmaul7077d342021-06-09 20:23:58 -0700146double UnwrappedAxis(const ::frc971::input::driver_station::Data &data,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800147 const JoystickAxis &high_bits,
148 const JoystickAxis &low_bits) {
149 const float high_bits_data = data.GetAxis(high_bits);
150 const float low_bits_data = data.GetAxis(low_bits);
151 const int16_t high_bits_data_int =
152 (high_bits_data < 0.0f ? high_bits_data * 128.0f
153 : high_bits_data * 127.0f);
154 const int16_t low_bits_data_int =
155 (low_bits_data < 0.0f ? low_bits_data * 128.0f : low_bits_data * 127.0f);
156
157 const uint16_t high_bits_data_uint =
158 ((static_cast<uint16_t>(high_bits_data_int) & 0xff) + 0x80) & 0xff;
159 const uint16_t low_bits_data_uint =
160 ((static_cast<uint16_t>(low_bits_data_int) & 0xff) + 0x80) & 0xff;
161
162 const uint16_t data_uint = (high_bits_data_uint << 8) | low_bits_data_uint;
163
164 const int32_t data_int = static_cast<int32_t>(data_uint) - 0x8000;
165
166 if (data_int < 0) {
167 return static_cast<double>(data_int) / static_cast<double>(0x8000);
168 } else {
169 return static_cast<double>(data_int) / static_cast<double>(0x7fff);
170 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700171}
172
173DrivetrainInputReader::WheelAndThrottle
174PistolDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700175 const ::frc971::input::driver_station::Data &data) {
176 const double wheel = -UnwrappedAxis(data, wheel_, wheel_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800177 const double wheel_velocity =
178 -UnwrappedAxis(data, wheel_velocity_high_, wheel_velocity_low_) * 50.0;
179 const double wheel_torque =
180 -UnwrappedAxis(data, wheel_torque_high_, wheel_torque_low_) / 2.0;
181
James Kuszmaul7077d342021-06-09 20:23:58 -0700182 double throttle = UnwrappedAxis(data, throttle_, throttle_low_);
Austin Schuh2b1fce02018-03-02 20:05:20 -0800183 const double throttle_velocity =
James Kuszmaul7077d342021-06-09 20:23:58 -0700184 UnwrappedAxis(data, throttle_velocity_high_, throttle_velocity_low_) *
185 50.0;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800186 const double throttle_torque =
187 UnwrappedAxis(data, throttle_torque_high_, throttle_torque_low_) / 2.0;
188
Austin Schuh876b4f02018-03-10 19:16:59 -0800189 // TODO(austin): Deal with haptics here.
190 if (throttle < 0) {
191 throttle = ::std::max(-1.0, throttle / 0.7);
192 }
193
James Kuszmaulc4eb1b22019-04-13 15:48:34 -0700194 if (data.IsPressed(slow_down_)) {
195 throttle *= 0.5;
196 }
197
Austin Schuh2b1fce02018-03-02 20:05:20 -0800198 if (!data.GetControlBit(ControlBit::kEnabled)) {
199 high_gear_ = default_high_gear_;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700200 }
201
Austin Schuh2b1fce02018-03-02 20:05:20 -0800202 if (data.PosEdge(shift_low_)) {
203 high_gear_ = false;
Sabina Davis92d2efa2017-11-04 22:35:25 -0700204 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700205
Austin Schuh2b1fce02018-03-02 20:05:20 -0800206 if (data.PosEdge(shift_high_)) {
207 high_gear_ = true;
208 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700209
James Kuszmaulf64bc432022-03-25 19:14:42 -0700210 // Emprically, the current pistol grip tends towards steady-state errors at
211 // ~0.01-0.02 on both the wheel/throttle. Having the throttle correctly snap
212 // to zero is more important than the wheel for our internal logic, so force a
213 // deadband there.
214 constexpr double kThrottleDeadband = 0.05;
215 throttle = aos::Deadband(throttle, kThrottleDeadband, 1.0);
216
Austin Schuh2b1fce02018-03-02 20:05:20 -0800217 return DrivetrainInputReader::WheelAndThrottle{
James Kuszmaul7077d342021-06-09 20:23:58 -0700218 wheel, wheel_velocity, wheel_torque,
219 throttle, throttle_velocity, throttle_torque,
Austin Schuh2b1fce02018-03-02 20:05:20 -0800220 high_gear_};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700221}
222
223DrivetrainInputReader::WheelAndThrottle
224XboxDrivetrainInputReader::GetWheelAndThrottle(
James Kuszmaul7077d342021-06-09 20:23:58 -0700225 const ::frc971::input::driver_station::Data &data) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700226 // xbox
227 constexpr double kWheelDeadband = 0.05;
228 constexpr double kThrottleDeadband = 0.05;
229 const double wheel =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800230 aos::Deadband(-data.GetAxis(wheel_), kWheelDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700231
232 const double unmodified_throttle =
Austin Schuh2b1fce02018-03-02 20:05:20 -0800233 aos::Deadband(-data.GetAxis(throttle_), kThrottleDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700234
235 // Apply a sin function that's scaled to make it feel better.
236 constexpr double throttle_range = M_PI_2 * 0.9;
237
238 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
239 ::std::sin(throttle_range);
240 throttle = ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
241 throttle = 2.0 * unmodified_throttle - throttle;
Austin Schuh2b1fce02018-03-02 20:05:20 -0800242 return DrivetrainInputReader::WheelAndThrottle{wheel, 0.0, 0.0, throttle,
243 0.0, 0.0, true};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700244}
245
246std::unique_ptr<SteeringWheelDrivetrainInputReader>
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700247SteeringWheelDrivetrainInputReader::Make(::aos::EventLoop *event_loop,
248 bool default_high_gear) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700249 const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
250 const ButtonLocation kQuickTurn(1, 5);
251 const ButtonLocation kTurn1(1, 7);
252 const ButtonLocation kTurn2(1, 11);
253 std::unique_ptr<SteeringWheelDrivetrainInputReader> result(
James Kuszmaul8bad2412019-03-10 10:47:56 -0700254 new SteeringWheelDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700255 event_loop, kSteeringWheel, kDriveThrottle, kQuickTurn, kTurn1,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700256 TurnButtonUse::kControlLoopDriving, kTurn2,
257 TurnButtonUse::kControlLoopDriving));
Sabina Davis82b19182017-11-10 09:30:25 -0800258 result.get()->set_default_high_gear(default_high_gear);
259
Sabina Davis92d2efa2017-11-04 22:35:25 -0700260 return result;
261}
262
Austin Schuh2b1fce02018-03-02 20:05:20 -0800263std::unique_ptr<PistolDrivetrainInputReader> PistolDrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700264 ::aos::EventLoop *event_loop, bool default_high_gear,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700265 PistolTopButtonUse top_button_use, PistolSecondButtonUse second_button_use,
266 PistolBottomButtonUse bottom_button_use) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700267 // Pistol Grip controller
Austin Schuh2b1fce02018-03-02 20:05:20 -0800268 const JoystickAxis kTriggerHigh(1, 1), kTriggerLow(1, 4),
269 kTriggerVelocityHigh(1, 2), kTriggerVelocityLow(1, 5),
270 kTriggerTorqueHigh(1, 3), kTriggerTorqueLow(1, 6);
271
272 const JoystickAxis kWheelHigh(2, 1), kWheelLow(2, 4),
273 kWheelVelocityHigh(2, 2), kWheelVelocityLow(2, 5), kWheelTorqueHigh(2, 3),
274 kWheelTorqueLow(2, 6);
275
Austin Schuhe8a54c02018-03-05 00:25:58 -0800276 const ButtonLocation kQuickTurn(1, 3);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700277
Austin Schuh91a4e552023-02-24 20:34:01 -0800278 const ButtonLocation kTopButton(1, 1);
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700279
Austin Schuh91a4e552023-02-24 20:34:01 -0800280 const ButtonLocation kSecondButton(1, 2);
281 const ButtonLocation kBottomButton(1, 4);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700282 // Non-existant button for nops.
Austin Schuh91a4e552023-02-24 20:34:01 -0800283 const ButtonLocation kDummyButton(1, 10);
James Kuszmaul8bad2412019-03-10 10:47:56 -0700284
285 // TODO(james): Make a copy assignment operator for ButtonLocation so we don't
286 // have to shoehorn in these ternary operators.
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700287 const ButtonLocation kTurn1 =
288 (second_button_use == PistolSecondButtonUse::kTurn1) ? kSecondButton
289 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700290 // Turn2 does closed loop driving.
291 const ButtonLocation kTurn2 =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700292 (top_button_use == PistolTopButtonUse::kLineFollow) ? kTopButton
293 : kDummyButton;
Austin Schuh48d3a962019-03-17 18:12:32 -0700294
James Kuszmaul8bad2412019-03-10 10:47:56 -0700295 const ButtonLocation kShiftHigh =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700296 (top_button_use == PistolTopButtonUse::kShift) ? kTopButton
297 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700298 const ButtonLocation kShiftLow =
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700299 (second_button_use == PistolSecondButtonUse::kShiftLow) ? kSecondButton
300 : kDummyButton;
James Kuszmaul8bad2412019-03-10 10:47:56 -0700301
Sabina Davis92d2efa2017-11-04 22:35:25 -0700302 std::unique_ptr<PistolDrivetrainInputReader> result(
Austin Schuh2b1fce02018-03-02 20:05:20 -0800303 new PistolDrivetrainInputReader(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700304 event_loop, kWheelHigh, kWheelLow, kTriggerVelocityHigh,
305 kTriggerVelocityLow, kTriggerTorqueHigh, kTriggerTorqueLow,
306 kTriggerHigh, kTriggerLow, kWheelVelocityHigh, kWheelVelocityLow,
307 kWheelTorqueHigh, kWheelTorqueLow, kQuickTurn, kShiftHigh, kShiftLow,
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700308 kTurn1,
309 (bottom_button_use == PistolBottomButtonUse::kControlLoopDriving)
310 ? kBottomButton
311 : kTurn2,
312 (top_button_use == PistolTopButtonUse::kNone) ? kTopButton
313 : kBottomButton));
Austin Schuh2b1fce02018-03-02 20:05:20 -0800314
315 result->set_default_high_gear(default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700316 return result;
317}
318
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700319std::unique_ptr<XboxDrivetrainInputReader> XboxDrivetrainInputReader::Make(
320 ::aos::EventLoop *event_loop) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700321 // xbox
322 const JoystickAxis kSteeringWheel(1, 5), kDriveThrottle(1, 2);
323 const ButtonLocation kQuickTurn(1, 5);
324
325 // Nop
326 const ButtonLocation kTurn1(1, 1);
327 const ButtonLocation kTurn2(1, 2);
328
329 std::unique_ptr<XboxDrivetrainInputReader> result(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700330 new XboxDrivetrainInputReader(event_loop, kSteeringWheel, kDriveThrottle,
331 kQuickTurn, kTurn1,
332 TurnButtonUse::kControlLoopDriving, kTurn2,
James Kuszmaul8bad2412019-03-10 10:47:56 -0700333 TurnButtonUse::kControlLoopDriving));
Sabina Davis92d2efa2017-11-04 22:35:25 -0700334 return result;
335}
336::std::unique_ptr<DrivetrainInputReader> DrivetrainInputReader::Make(
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700337 ::aos::EventLoop *event_loop, InputType type,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700338 const drivetrain::DrivetrainConfig<double> &dt_config) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700339 std::unique_ptr<DrivetrainInputReader> drivetrain_input_reader;
340
341 using InputType = DrivetrainInputReader::InputType;
Sabina Davis82b19182017-11-10 09:30:25 -0800342
Sabina Davis92d2efa2017-11-04 22:35:25 -0700343 switch (type) {
344 case InputType::kSteeringWheel:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700345 drivetrain_input_reader = SteeringWheelDrivetrainInputReader::Make(
346 event_loop, dt_config.default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700347 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700348 case InputType::kPistol: {
349 // For backwards compatibility
350 PistolTopButtonUse top_button_use =
James Kuszmaul8bad2412019-03-10 10:47:56 -0700351 dt_config.pistol_grip_shift_enables_line_follow
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700352 ? PistolTopButtonUse::kLineFollow
353 : dt_config.top_button_use;
354
355 PistolSecondButtonUse second_button_use = dt_config.second_button_use;
356 PistolBottomButtonUse bottom_button_use = dt_config.bottom_button_use;
357
358 if (top_button_use == PistolTopButtonUse::kLineFollow) {
359 second_button_use = PistolSecondButtonUse::kTurn1;
360 }
361
362 drivetrain_input_reader = PistolDrivetrainInputReader::Make(
363 event_loop, dt_config.default_high_gear, top_button_use,
364 second_button_use, bottom_button_use);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700365 break;
Maxwell Henderson24f89f32023-03-25 15:55:46 -0700366 }
Sabina Davis92d2efa2017-11-04 22:35:25 -0700367 case InputType::kXbox:
Austin Schuhbd0a40f2019-06-30 14:56:31 -0700368 drivetrain_input_reader = XboxDrivetrainInputReader::Make(event_loop);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700369 break;
370 }
371 return drivetrain_input_reader;
372}
373
374} // namespace input
James Kuszmaul7077d342021-06-09 20:23:58 -0700375} // namespace frc971