blob: 1f6d713a6eb2065f5822f3c21a842db8dfde923f [file] [log] [blame]
Sabina Davis92d2efa2017-11-04 22:35:25 -07001#include "aos/input/drivetrain_input.h"
2
3#include <math.h>
4#include <stdio.h>
5#include <string.h>
6#include <cmath>
7
8#include "aos/common/commonmath.h"
9#include "aos/common/input/driver_station_data.h"
10#include "aos/common/logging/logging.h"
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12
13using ::frc971::control_loops::drivetrain_queue;
14using ::aos::input::driver_station::ButtonLocation;
15using ::aos::input::driver_station::ControlBit;
16using ::aos::input::driver_station::JoystickAxis;
17using ::aos::input::driver_station::POVLocation;
18
19namespace aos {
20namespace input {
21
Sabina Davis82b19182017-11-10 09:30:25 -080022const ButtonLocation kShiftHigh(2, 3), kShiftHigh2(2, 2), kShiftLow(2, 1);
23
Sabina Davis92d2efa2017-11-04 22:35:25 -070024void DrivetrainInputReader::HandleDrivetrain(
25 const ::aos::input::driver_station::Data &data) {
26 bool is_control_loop_driving = false;
27
28 const auto wheel_and_throttle = GetWheelAndThrottle(data);
29 const double wheel = wheel_and_throttle.wheel;
30 const double throttle = wheel_and_throttle.throttle;
Sabina Davis82b19182017-11-10 09:30:25 -080031 const bool high_gear = wheel_and_throttle.high_gear;
Sabina Davis92d2efa2017-11-04 22:35:25 -070032
33 drivetrain_queue.status.FetchLatest();
34 if (drivetrain_queue.status.get()) {
35 robot_velocity_ = drivetrain_queue.status->robot_speed;
36 }
37
Sabina Davis82b19182017-11-10 09:30:25 -080038 if (data.PosEdge(turn1_) || data.PosEdge(turn2_)) {
Sabina Davis92d2efa2017-11-04 22:35:25 -070039 if (drivetrain_queue.status.get()) {
40 left_goal_ = drivetrain_queue.status->estimated_left_position;
41 right_goal_ = drivetrain_queue.status->estimated_right_position;
42 }
43 }
44 const double current_left_goal =
45 left_goal_ - wheel * wheel_multiplier_ + throttle * 0.3;
46 const double current_right_goal =
47 right_goal_ + wheel * wheel_multiplier_ + throttle * 0.3;
Sabina Davis82b19182017-11-10 09:30:25 -080048 if (data.IsPressed(turn1_) || data.IsPressed(turn2_)) {
Sabina Davis92d2efa2017-11-04 22:35:25 -070049 is_control_loop_driving = true;
50 }
51 auto new_drivetrain_goal = drivetrain_queue.goal.MakeMessage();
52 new_drivetrain_goal->steering = wheel;
53 new_drivetrain_goal->throttle = throttle;
Sabina Davis82b19182017-11-10 09:30:25 -080054 new_drivetrain_goal->highgear = high_gear;
55 new_drivetrain_goal->quickturn = data.IsPressed(quick_turn_);
Sabina Davis92d2efa2017-11-04 22:35:25 -070056 new_drivetrain_goal->control_loop_driving = is_control_loop_driving;
57 new_drivetrain_goal->left_goal = current_left_goal;
58 new_drivetrain_goal->right_goal = current_right_goal;
59 new_drivetrain_goal->left_velocity_goal = 0;
60 new_drivetrain_goal->right_velocity_goal = 0;
61
62 new_drivetrain_goal->linear.max_velocity = 3.0;
63 new_drivetrain_goal->linear.max_acceleration = 20.0;
64
65 if (!new_drivetrain_goal.Send()) {
66 LOG(WARNING, "sending stick values failed\n");
67 }
68}
69
70DrivetrainInputReader::WheelAndThrottle
71SteeringWheelDrivetrainInputReader::GetWheelAndThrottle(
72 const ::aos::input::driver_station::Data &data) {
Sabina Davis82b19182017-11-10 09:30:25 -080073 const double wheel = -data.GetAxis(steering_wheel_);
74 const double throttle = -data.GetAxis(drive_throttle_);
75
76 if (!data.GetControlBit(ControlBit::kEnabled)) {
77 high_gear_ = default_high_gear_;
78 }
79
80 if (data.PosEdge(kShiftLow)) {
81 high_gear_ = false;
82 }
83
84 if (data.PosEdge(kShiftHigh) || data.PosEdge(kShiftHigh2)) {
85 high_gear_ = true;
86 }
87
88 return DrivetrainInputReader::WheelAndThrottle{wheel, throttle, high_gear_};
Sabina Davis92d2efa2017-11-04 22:35:25 -070089}
90
91DrivetrainInputReader::WheelAndThrottle
92PistolDrivetrainInputReader::GetWheelAndThrottle(
93 const ::aos::input::driver_station::Data &data) {
Sabina Davis82b19182017-11-10 09:30:25 -080094 const double unscaled_wheel = data.GetAxis(steering_wheel_);
Sabina Davis92d2efa2017-11-04 22:35:25 -070095 double wheel;
96 if (unscaled_wheel < 0.0) {
97 wheel = unscaled_wheel / 0.484375;
98 } else {
99 wheel = unscaled_wheel / 0.385827;
100 }
101
Sabina Davis82b19182017-11-10 09:30:25 -0800102 const double unscaled_throttle = -data.GetAxis(drive_throttle_);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700103 double unmodified_throttle;
104 if (unscaled_throttle < 0.0) {
105 unmodified_throttle = unscaled_throttle / 0.086614;
106 } else {
107 unmodified_throttle = unscaled_throttle / 0.265625;
108 }
109 unmodified_throttle = aos::Deadband(unmodified_throttle, 0.1, 1.0);
110
111 // Apply a sin function that's scaled to make it feel better.
112 constexpr double throttle_range = M_PI_2 * 0.5;
113
114 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
115 ::std::sin(throttle_range);
116 throttle = ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
117 throttle = 2.0 * unmodified_throttle - throttle;
Sabina Davis82b19182017-11-10 09:30:25 -0800118 return DrivetrainInputReader::WheelAndThrottle{wheel, throttle, true};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700119}
120
121DrivetrainInputReader::WheelAndThrottle
122XboxDrivetrainInputReader::GetWheelAndThrottle(
123 const ::aos::input::driver_station::Data &data) {
124 // xbox
125 constexpr double kWheelDeadband = 0.05;
126 constexpr double kThrottleDeadband = 0.05;
127 const double wheel =
Sabina Davis82b19182017-11-10 09:30:25 -0800128 aos::Deadband(-data.GetAxis(steering_wheel_), kWheelDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700129
130 const double unmodified_throttle =
Sabina Davis82b19182017-11-10 09:30:25 -0800131 aos::Deadband(-data.GetAxis(drive_throttle_), kThrottleDeadband, 1.0);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700132
133 // Apply a sin function that's scaled to make it feel better.
134 constexpr double throttle_range = M_PI_2 * 0.9;
135
136 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
137 ::std::sin(throttle_range);
138 throttle = ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
139 throttle = 2.0 * unmodified_throttle - throttle;
Sabina Davis82b19182017-11-10 09:30:25 -0800140 return DrivetrainInputReader::WheelAndThrottle{wheel, throttle, true};
Sabina Davis92d2efa2017-11-04 22:35:25 -0700141}
142
143std::unique_ptr<SteeringWheelDrivetrainInputReader>
Sabina Davis82b19182017-11-10 09:30:25 -0800144SteeringWheelDrivetrainInputReader::Make(bool default_high_gear) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700145 const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
146 const ButtonLocation kQuickTurn(1, 5);
147 const ButtonLocation kTurn1(1, 7);
148 const ButtonLocation kTurn2(1, 11);
149 std::unique_ptr<SteeringWheelDrivetrainInputReader> result(
150 new SteeringWheelDrivetrainInputReader(kSteeringWheel, kDriveThrottle,
151 kQuickTurn, kTurn1, kTurn2));
Sabina Davis82b19182017-11-10 09:30:25 -0800152 result.get()->set_default_high_gear(default_high_gear);
153
Sabina Davis92d2efa2017-11-04 22:35:25 -0700154 return result;
155}
156
157std::unique_ptr<PistolDrivetrainInputReader>
158PistolDrivetrainInputReader::Make() {
159 // Pistol Grip controller
160 const JoystickAxis kSteeringWheel(1, 2), kDriveThrottle(1, 1);
161 const ButtonLocation kQuickTurn(1, 7);
162 const ButtonLocation kTurn1(1, 8);
163
164 // Nop
165 const ButtonLocation kTurn2(1, 9);
166 std::unique_ptr<PistolDrivetrainInputReader> result(
167 new PistolDrivetrainInputReader(kSteeringWheel, kDriveThrottle,
168 kQuickTurn, kTurn1, kTurn2));
169 result->set_wheel_multiplier(0.2);
170 return result;
171}
172
173std::unique_ptr<XboxDrivetrainInputReader> XboxDrivetrainInputReader::Make() {
174 // xbox
175 const JoystickAxis kSteeringWheel(1, 5), kDriveThrottle(1, 2);
176 const ButtonLocation kQuickTurn(1, 5);
177
178 // Nop
179 const ButtonLocation kTurn1(1, 1);
180 const ButtonLocation kTurn2(1, 2);
181
182 std::unique_ptr<XboxDrivetrainInputReader> result(
183 new XboxDrivetrainInputReader(kSteeringWheel, kDriveThrottle, kQuickTurn,
184 kTurn1, kTurn2));
185 return result;
186}
187::std::unique_ptr<DrivetrainInputReader> DrivetrainInputReader::Make(
Sabina Davis82b19182017-11-10 09:30:25 -0800188 InputType type,
189 const ::frc971::control_loops::drivetrain::DrivetrainConfig &dt_config) {
Sabina Davis92d2efa2017-11-04 22:35:25 -0700190 std::unique_ptr<DrivetrainInputReader> drivetrain_input_reader;
191
192 using InputType = DrivetrainInputReader::InputType;
Sabina Davis82b19182017-11-10 09:30:25 -0800193
Sabina Davis92d2efa2017-11-04 22:35:25 -0700194 switch (type) {
195 case InputType::kSteeringWheel:
Sabina Davis82b19182017-11-10 09:30:25 -0800196 drivetrain_input_reader =
197 SteeringWheelDrivetrainInputReader::Make(dt_config.default_high_gear);
Sabina Davis92d2efa2017-11-04 22:35:25 -0700198 break;
199 case InputType::kPistol:
200 drivetrain_input_reader = PistolDrivetrainInputReader::Make();
201 break;
202 case InputType::kXbox:
203 drivetrain_input_reader = XboxDrivetrainInputReader::Make();
204 break;
205 }
206 return drivetrain_input_reader;
207}
208
209} // namespace input
210} // namespace aos