blob: 1a225d639f2e2f7e68acecfd8d9ef9b2d4129064 [file] [log] [blame]
Campbell Crowley71b5f132017-02-18 13:16:08 -08001#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <math.h>
5
Austin Schuh3028b1d2017-03-11 22:12:13 -08006#include "aos/common/actions/actions.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -08007#include "aos/common/input/driver_station_data.h"
8#include "aos/common/logging/logging.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -08009#include "aos/common/time.h"
Austin Schuh3028b1d2017-03-11 22:12:13 -080010#include "aos/common/util/log_interval.h"
11#include "aos/input/joystick_input.h"
12#include "aos/linux_code/init.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -080013#include "frc971/autonomous/auto.q.h"
Austin Schuh3028b1d2017-03-11 22:12:13 -080014#include "frc971/autonomous/base_autonomous_actor.h"
15#include "frc971/control_loops/drivetrain/drivetrain.q.h"
16#include "y2017/constants.h"
17#include "y2017/control_loops/superstructure/superstructure.q.h"
Campbell Crowley71b5f132017-02-18 13:16:08 -080018
19using ::frc971::control_loops::drivetrain_queue;
20using ::y2017::control_loops::superstructure_queue;
21
22using ::aos::input::driver_station::ButtonLocation;
23using ::aos::input::driver_station::ControlBit;
24using ::aos::input::driver_station::JoystickAxis;
25using ::aos::input::driver_station::POVLocation;
26
27namespace y2017 {
28namespace input {
29namespace joysticks {
30
Austin Schuh51b1bae2017-04-09 18:31:57 -070031// Keep the other versions around so we can switch quickly.
32//#define STEERINGWHEEL
33#define PISTOL
34//#define XBOX
35
36#ifdef STEERINGWHEEL
Campbell Crowley71b5f132017-02-18 13:16:08 -080037const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
38const ButtonLocation kQuickTurn(1, 5);
Campbell Crowley71b5f132017-02-18 13:16:08 -080039const ButtonLocation kTurn1(1, 7);
40const ButtonLocation kTurn2(1, 11);
41
Austin Schuh51b1bae2017-04-09 18:31:57 -070042#endif
43
44#ifdef PISTOL
45// Pistol Grip controller
46const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(1, 2);
47//const ButtonLocation kQuickTurn(1, 7);
48const ButtonLocation kQuickTurn(1, 8);
49
50// Nop
51//const ButtonLocation kTurn1(1, 8);
52const ButtonLocation kTurn2(1, 9);
53
54const ButtonLocation kTurn1(1, 7);
55#endif
56
57#ifdef XBOX
58// xbox
59const JoystickAxis kSteeringWheel(1, 5), kDriveThrottle(1, 2);
60const ButtonLocation kQuickTurn(1, 5);
61
62// Nop
63const ButtonLocation kTurn1(1, 1);
64const ButtonLocation kTurn2(1, 2);
65
66#endif
67
68
Austin Schuh55c8d302017-04-05 19:25:37 -070069const ButtonLocation kGearSlotBack(2, 11);
70
Campbell Crowley71b5f132017-02-18 13:16:08 -080071const ButtonLocation kIntakeDown(3, 9);
Austin Schuhd0629b12017-03-22 22:37:16 -070072const POVLocation kIntakeUp(3, 90);
Campbell Crowley71b5f132017-02-18 13:16:08 -080073const ButtonLocation kIntakeIn(3, 12);
74const ButtonLocation kIntakeOut(3, 8);
Campbell Crowley71b5f132017-02-18 13:16:08 -080075const ButtonLocation kFire(3, 3);
76const ButtonLocation kCloseShot(3, 7);
77const ButtonLocation kMiddleShot(3, 6);
78const POVLocation kFarShot(3, 270);
79
80const ButtonLocation kVisionAlign(3, 5);
81
82const ButtonLocation kReverseIndexer(3, 4);
83const ButtonLocation kExtra1(3, 11);
84const ButtonLocation kExtra2(3, 10);
Austin Schuhd0629b12017-03-22 22:37:16 -070085const ButtonLocation kHang(3, 2);
Campbell Crowley71b5f132017-02-18 13:16:08 -080086
87class Reader : public ::aos::input::JoystickInput {
88 public:
89 Reader() {}
90
Austin Schuhd0629b12017-03-22 22:37:16 -070091 enum class ShotDistance { CLOSE_SHOT, MIDDLE_SHOT, FAR_SHOT };
92
93 ShotDistance last_shot_distance_ = ShotDistance::FAR_SHOT;
94
Campbell Crowley71b5f132017-02-18 13:16:08 -080095 void RunIteration(const ::aos::input::driver_station::Data &data) override {
96 bool last_auto_running = auto_running_;
97 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
98 data.GetControlBit(ControlBit::kEnabled);
99 if (auto_running_ != last_auto_running) {
100 if (auto_running_) {
101 StartAuto();
102 } else {
103 StopAuto();
104 }
105 }
106
107 vision_valid_ = false;
108
109 if (!auto_running_) {
110 HandleDrivetrain(data);
111 HandleTeleop(data);
112 }
113
114 // Process any pending actions.
115 action_queue_.Tick();
116 was_running_ = action_queue_.Running();
117 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700118 int intake_accumulator_ = 0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800119
Austin Schuh51b1bae2017-04-09 18:31:57 -0700120 double Deadband(double value, const double deadband) {
121 if (::std::abs(value) < deadband) {
122 value = 0.0;
123 } else if (value > 0.0) {
124 value = (value - deadband) / (1.0 - deadband);
125 } else {
126 value = (value + deadband) / (1.0 - deadband);
127 }
128 return value;
129 }
130
Campbell Crowley71b5f132017-02-18 13:16:08 -0800131 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
132 bool is_control_loop_driving = false;
133
Austin Schuh51b1bae2017-04-09 18:31:57 -0700134#ifdef STEERINGWHEEL
Campbell Crowley71b5f132017-02-18 13:16:08 -0800135 const double wheel = -data.GetAxis(kSteeringWheel);
136 const double throttle = -data.GetAxis(kDriveThrottle);
Austin Schuh51b1bae2017-04-09 18:31:57 -0700137#endif
138
139#ifdef XBOX
140 // xbox
141 constexpr double kWheelDeadband = 0.05;
142 constexpr double kThrottleDeadband = 0.05;
143 const double wheel =
144 Deadband(-data.GetAxis(kSteeringWheel), kWheelDeadband);
145
146 const double unmodified_throttle =
147 Deadband(-data.GetAxis(kDriveThrottle), kThrottleDeadband);
148
149 // Apply a sin function that's scaled to make it feel better.
150 constexpr double throttle_range = M_PI_2 * 0.9;
151
152 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
153 ::std::sin(throttle_range);
154 throttle =
155 ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
156 throttle = 2.0 * unmodified_throttle - throttle;
157#endif
158
159#ifdef PISTOL
160 const double wheel = data.GetAxis(kSteeringWheel) / 0.488;
161
162 const double unscaled_throttle = -data.GetAxis(kDriveThrottle);
163 double unmodified_throttle;
164 if (unscaled_throttle < 0.0) {
165 unmodified_throttle = unscaled_throttle / 0.228;
166 } else {
167 unmodified_throttle = unscaled_throttle / 0.484;
168 }
169 unmodified_throttle = Deadband(unmodified_throttle, 0.1);
170
171 // Apply a sin function that's scaled to make it feel better.
172 constexpr double throttle_range = M_PI_2 * 0.5;
173
174 double throttle = ::std::sin(throttle_range * unmodified_throttle) /
175 ::std::sin(throttle_range);
176 throttle =
177 ::std::sin(throttle_range * throttle) / ::std::sin(throttle_range);
178 throttle = 2.0 * unmodified_throttle - throttle;
179#endif
180
Campbell Crowley71b5f132017-02-18 13:16:08 -0800181 drivetrain_queue.status.FetchLatest();
Austin Schuhd0629b12017-03-22 22:37:16 -0700182 if (drivetrain_queue.status.get()) {
183 robot_velocity_ = drivetrain_queue.status->robot_speed;
184 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800185
Austin Schuh55c8d302017-04-05 19:25:37 -0700186 if (data.PosEdge(kTurn1) || data.PosEdge(kTurn2) ||
187 data.PosEdge(kGearSlotBack)) {
Campbell Crowley71b5f132017-02-18 13:16:08 -0800188 if (drivetrain_queue.status.get()) {
189 left_goal_ = drivetrain_queue.status->estimated_left_position;
190 right_goal_ = drivetrain_queue.status->estimated_right_position;
191 }
192 }
Austin Schuh51b1bae2017-04-09 18:31:57 -0700193#ifdef PISTOL
194 double current_left_goal = left_goal_ - wheel * 0.20 + throttle * 0.3;
195 double current_right_goal = right_goal_ + wheel * 0.20 + throttle * 0.3;
196#else
Austin Schuh55c8d302017-04-05 19:25:37 -0700197 double current_left_goal = left_goal_ - wheel * 0.5 + throttle * 0.3;
198 double current_right_goal = right_goal_ + wheel * 0.5 + throttle * 0.3;
Austin Schuh51b1bae2017-04-09 18:31:57 -0700199#endif
Campbell Crowley71b5f132017-02-18 13:16:08 -0800200 if (data.IsPressed(kTurn1) || data.IsPressed(kTurn2)) {
201 is_control_loop_driving = true;
202 }
Austin Schuh55c8d302017-04-05 19:25:37 -0700203 if (data.IsPressed(kGearSlotBack)) {
204 is_control_loop_driving = true;
205 current_left_goal = left_goal_ - 0.03;
206 current_right_goal = right_goal_ - 0.03;
207 }
208 auto new_drivetrain_goal = drivetrain_queue.goal.MakeMessage();
209 new_drivetrain_goal->steering = wheel;
210 new_drivetrain_goal->throttle = throttle;
211 new_drivetrain_goal->quickturn = data.IsPressed(kQuickTurn);
212 new_drivetrain_goal->control_loop_driving = is_control_loop_driving;
213 new_drivetrain_goal->left_goal = current_left_goal;
214 new_drivetrain_goal->right_goal = current_right_goal;
215 new_drivetrain_goal->left_velocity_goal = 0;
216 new_drivetrain_goal->right_velocity_goal = 0;
217
218 new_drivetrain_goal->linear.max_velocity = 3.0;
219 new_drivetrain_goal->linear.max_acceleration = 20.0;
220
221 if (!new_drivetrain_goal.Send()) {
Campbell Crowley71b5f132017-02-18 13:16:08 -0800222 LOG(WARNING, "sending stick values failed\n");
223 }
224 }
225
226 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
227 // Default the intake to in.
Austin Schuhd0629b12017-03-22 22:37:16 -0700228 intake_goal_ = 0.07;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800229 bool lights_on = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700230 bool vision_track = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800231
232 if (!data.GetControlBit(ControlBit::kEnabled)) {
233 action_queue_.CancelAllActions();
234 LOG(DEBUG, "Canceling\n");
235 }
236
237 superstructure_queue.status.FetchLatest();
238 if (!superstructure_queue.status.get()) {
239 LOG(ERROR, "Got no superstructure status packet.\n");
240 return;
241 }
242
243 if (data.IsPressed(kIntakeDown)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700244 intake_goal_ = 0.235;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800245 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700246 if (data.IsPressed(kIntakeUp)) {
247 intake_goal_ = 0.0;
248 turret_goal_ = 0.0;
249 }
250
Campbell Crowley71b5f132017-02-18 13:16:08 -0800251
252 if (data.IsPressed(kVisionAlign)) {
253 // Align shot using vision
254 // TODO(campbell): Add vision aligning.
Adam Snaidere0554ef2017-03-11 23:02:45 -0800255 lights_on = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700256 vision_track = true;
257 }
258 if (data.PosEdge(kMiddleShot)) {
259 turret_goal_ = -M_PI;
260 }
261 if (data.PosEdge(kFarShot)) {
262 turret_goal_ = 0.0;
263 }
264
265 if (data.IsPressed(kCloseShot)) {
266 last_shot_distance_ = ShotDistance::CLOSE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800267 } else if (data.IsPressed(kMiddleShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700268 last_shot_distance_ = ShotDistance::MIDDLE_SHOT;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800269 } else if (data.IsPressed(kFarShot)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700270 last_shot_distance_ = ShotDistance::FAR_SHOT;
271 }
272
273 if (data.IsPressed(kVisionAlign) || data.IsPressed(kCloseShot) ||
274 data.IsPressed(kMiddleShot) || data.IsPressed(kFarShot) ||
275 data.IsPressed(kFire)) {
276 switch (last_shot_distance_) {
277 case ShotDistance::CLOSE_SHOT:
278 hood_goal_ = 0.285;
279 shooter_velocity_ = 335.0;
280 break;
281 case ShotDistance::MIDDLE_SHOT:
282 hood_goal_ = 0.63;
283 shooter_velocity_ = 384.0;
284 break;
285 case ShotDistance::FAR_SHOT:
286 hood_goal_ = 0.63;
287 shooter_velocity_ = 378.0;
288 break;
289 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800290 } else {
Austin Schuhd0629b12017-03-22 22:37:16 -0700291 //hood_goal_ = 0.15;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800292 shooter_velocity_ = 0.0;
293 }
294
295 if (data.IsPressed(kExtra1)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700296 //turret_goal_ = -M_PI * 3.0 / 4.0;
297 turret_goal_ += 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800298 }
299 if (data.IsPressed(kExtra2)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700300 //turret_goal_ = M_PI * 3.0 / 4.0;
301 turret_goal_ -= 0.150;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800302 }
Austin Schuhd0629b12017-03-22 22:37:16 -0700303 turret_goal_ = ::std::max(::std::min(turret_goal_, M_PI), -M_PI);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800304
305 fire_ = data.IsPressed(kFire) && shooter_velocity_ != 0.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700306 if (data.IsPressed(kVisionAlign)) {
307 fire_ = fire_ && superstructure_queue.status->turret.vision_tracking;
308 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800309
310 auto new_superstructure_goal = superstructure_queue.goal.MakeMessage();
Austin Schuhd0629b12017-03-22 22:37:16 -0700311 if (data.IsPressed(kHang)) {
312 intake_goal_ = 0.23;
313 }
314
Campbell Crowley71b5f132017-02-18 13:16:08 -0800315 new_superstructure_goal->intake.distance = intake_goal_;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800316 new_superstructure_goal->intake.disable_intake = false;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800317 new_superstructure_goal->turret.angle = turret_goal_;
Austin Schuhd0629b12017-03-22 22:37:16 -0700318 new_superstructure_goal->turret.track = vision_track;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800319 new_superstructure_goal->hood.angle = hood_goal_;
320 new_superstructure_goal->shooter.angular_velocity = shooter_velocity_;
321
Austin Schuh6a8131b2017-04-08 15:39:22 -0700322 if (data.IsPressed(kIntakeUp)) {
323 new_superstructure_goal->intake.gear_servo = 0.37;
324 } else {
325 // Clamp the gear
326 new_superstructure_goal->intake.gear_servo = 0.64;
327 }
328
Campbell Crowley71b5f132017-02-18 13:16:08 -0800329 new_superstructure_goal->intake.profile_params.max_velocity = 0.50;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800330 new_superstructure_goal->hood.profile_params.max_velocity = 5.0;
331
332 new_superstructure_goal->intake.profile_params.max_acceleration = 5.0;
Austin Schuhd0629b12017-03-22 22:37:16 -0700333 if (vision_track) {
334 new_superstructure_goal->turret.profile_params.max_acceleration = 35.0;
335 new_superstructure_goal->turret.profile_params.max_velocity = 10.0;
336 } else {
337 new_superstructure_goal->turret.profile_params.max_acceleration = 15.0;
338 new_superstructure_goal->turret.profile_params.max_velocity = 6.0;
339 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800340 new_superstructure_goal->hood.profile_params.max_acceleration = 25.0;
341
Austin Schuh3028b1d2017-03-11 22:12:13 -0800342 new_superstructure_goal->intake.voltage_rollers = 0.0;
Adam Snaidere0554ef2017-03-11 23:02:45 -0800343 new_superstructure_goal->lights_on = lights_on;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800344
Austin Schuh8e4a7ee2017-04-05 19:26:06 -0700345 if (superstructure_queue.status->intake.position >
346 superstructure_queue.status->intake.unprofiled_goal_position + 0.01) {
347 intake_accumulator_ = 10;
348 }
349 if (intake_accumulator_ > 0) {
350 --intake_accumulator_;
351 if (!superstructure_queue.status->intake.estopped) {
352 new_superstructure_goal->intake.voltage_rollers = 10.0;
353 }
354 }
355
Campbell Crowley71b5f132017-02-18 13:16:08 -0800356 if (data.IsPressed(kHang)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700357 new_superstructure_goal->intake.voltage_rollers = -10.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800358 new_superstructure_goal->intake.disable_intake = true;
Austin Schuhd0629b12017-03-22 22:37:16 -0700359 } else if (data.IsPressed(kIntakeIn) || data.IsPressed(kFire)) {
360 if (robot_velocity_ > 2.0) {
361 new_superstructure_goal->intake.voltage_rollers = 12.0;
362 } else {
363 new_superstructure_goal->intake.voltage_rollers = 10.0;
364 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800365 } else if (data.IsPressed(kIntakeOut)) {
366 new_superstructure_goal->intake.voltage_rollers = -8.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800367 }
368 if (intake_goal_ < 0.1) {
369 new_superstructure_goal->intake.voltage_rollers =
370 ::std::min(8.0, new_superstructure_goal->intake.voltage_rollers);
Campbell Crowley71b5f132017-02-18 13:16:08 -0800371 }
372
373 if (data.IsPressed(kReverseIndexer)) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700374 new_superstructure_goal->indexer.voltage_rollers = -12.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800375 new_superstructure_goal->indexer.angular_velocity = 4.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800376 new_superstructure_goal->indexer.angular_velocity = 1.0;
Austin Schuh3028b1d2017-03-11 22:12:13 -0800377 } else if (fire_) {
Austin Schuhd0629b12017-03-22 22:37:16 -0700378 new_superstructure_goal->indexer.voltage_rollers = 12.0;
379 switch (last_shot_distance_) {
380 case ShotDistance::CLOSE_SHOT:
381 new_superstructure_goal->indexer.angular_velocity = -0.90 * M_PI;
382 break;
383 case ShotDistance::MIDDLE_SHOT:
384 case ShotDistance::FAR_SHOT:
385 new_superstructure_goal->indexer.angular_velocity = -2.25 * M_PI;
386 break;
387 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800388 } else {
389 new_superstructure_goal->indexer.voltage_rollers = 0.0;
390 new_superstructure_goal->indexer.angular_velocity = 0.0;
391 }
392
393 LOG_STRUCT(DEBUG, "sending goal", *new_superstructure_goal);
394 if (!new_superstructure_goal.Send()) {
395 LOG(ERROR, "Sending superstructure goal failed.\n");
396 }
397 }
398
399 private:
Austin Schuh3028b1d2017-03-11 22:12:13 -0800400 void StartAuto() {
401 LOG(INFO, "Starting auto mode\n");
402
403 ::frc971::autonomous::AutonomousActionParams params;
404 ::frc971::autonomous::auto_mode.FetchLatest();
405 if (::frc971::autonomous::auto_mode.get() != nullptr) {
406 params.mode = ::frc971::autonomous::auto_mode->mode;
407 } else {
408 LOG(WARNING, "no auto mode values\n");
409 params.mode = 0;
410 }
411 action_queue_.EnqueueAction(
412 ::frc971::autonomous::MakeAutonomousAction(params));
413 }
Campbell Crowley71b5f132017-02-18 13:16:08 -0800414
415 void StopAuto() {
416 LOG(INFO, "Stopping auto mode\n");
417 action_queue_.CancelAllActions();
418 }
419
420 // Current goals to send to the robot.
421 double intake_goal_ = 0.0;
422 double turret_goal_ = 0.0;
423 double hood_goal_ = 0.3;
424 double shooter_velocity_ = 0.0;
425
426 // Goals to send to the drivetrain in closed loop mode.
Austin Schuh3028b1d2017-03-11 22:12:13 -0800427 double left_goal_ = 0.0;
428 double right_goal_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800429
430 bool was_running_ = false;
431 bool auto_running_ = false;
432
433 bool vision_valid_ = false;
434
435 bool fire_ = false;
Austin Schuhd0629b12017-03-22 22:37:16 -0700436 double robot_velocity_ = 0.0;
Campbell Crowley71b5f132017-02-18 13:16:08 -0800437
438 ::aos::common::actions::ActionQueue action_queue_;
439};
440
441} // namespace joysticks
442} // namespace input
443} // namespace y2017
444
445int main() {
446 ::aos::Init(-1);
447 ::y2017::input::joysticks::Reader reader;
448 reader.Run();
449 ::aos::Cleanup();
450}