blob: 72082b1f24a7e797af514600e549b84e38aa9b62 [file] [log] [blame]
Comran Morshed0d6cf9b2015-06-17 19:29:57 +00001#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <math.h>
5
6#include "aos/linux_code/init.h"
Brian Silvermanc2065732015-11-28 22:55:30 +00007#include "aos/input/joystick_input.h"
Comran Morshed0d6cf9b2015-06-17 19:29:57 +00008#include "aos/common/input/driver_station_data.h"
9#include "aos/common/logging/logging.h"
10#include "aos/common/util/log_interval.h"
11#include "aos/common/time.h"
12#include "aos/common/actions/actions.h"
13
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000014#include "frc971/queues/gyro.q.h"
Austin Schuh6d1ee0c2015-11-21 14:36:04 -080015#include "y2015_bot3/autonomous/auto.q.h"
16#include "y2015_bot3/control_loops/elevator/elevator.h"
17#include "y2015_bot3/control_loops/drivetrain/drivetrain.q.h"
18#include "y2015_bot3/control_loops/elevator/elevator.q.h"
19#include "y2015_bot3/control_loops/intake/intake.q.h"
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000020
Austin Schuh6d1ee0c2015-11-21 14:36:04 -080021using ::y2015_bot3::control_loops::drivetrain_queue;
22using ::y2015_bot3::control_loops::elevator_queue;
23using ::y2015_bot3::control_loops::intake_queue;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000024using ::frc971::sensors::gyro_reading;
25
26using ::aos::input::driver_station::ButtonLocation;
27using ::aos::input::driver_station::POVLocation;
28using ::aos::input::driver_station::JoystickAxis;
29using ::aos::input::driver_station::ControlBit;
30
Austin Schuh6d1ee0c2015-11-21 14:36:04 -080031namespace y2015_bot3 {
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000032namespace input {
33namespace joysticks {
34
Austin Schuhedd63012015-09-13 05:09:03 +000035struct ProfileParams {
36 double velocity;
37 double acceleration;
38};
39
40// Preset motion limits.
41constexpr ProfileParams kElevatorMove{0.3, 1.0};
Austin Schuh8fc29c52015-09-13 20:19:05 +000042constexpr ProfileParams kFastElevatorMove{1.0, 5.0};
43
44// Preset goals for autostacking
Austin Schuh1ed71ad2015-09-14 21:24:03 +000045constexpr double kOneToteHeight{0.46};
Austin Schuh8fc29c52015-09-13 20:19:05 +000046constexpr double kCarryHeight{0.180};
47constexpr double kGroundHeight{0.030};
Austin Schuhedd63012015-09-13 05:09:03 +000048
49// Joystick & button addresses.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000050const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
51const ButtonLocation kShiftHigh(2, 1), kShiftLow(2, 3);
52const ButtonLocation kQuickTurn(1, 5);
53
Austin Schuhedd63012015-09-13 05:09:03 +000054// essential
55const ButtonLocation kMoveToteHeight(4, 9);
56const ButtonLocation kOpenIntake(3, 8);
57const ButtonLocation kCloseIntake(3, 6);
58const ButtonLocation kOpenCanRestraint(4, 5);
59const ButtonLocation kCloseCanRestraint(4, 1);
60const POVLocation kOpenPassiveSupport(4, 0);
61const POVLocation kClosePassiveSupport(4, 180);
62
Austin Schuh8fc29c52015-09-13 20:19:05 +000063const ButtonLocation kIntakeOut(3, 7);
64const ButtonLocation kIntakeIn(4, 12);
Austin Schuhedd63012015-09-13 05:09:03 +000065
66const ButtonLocation kAutoStack(4, 7);
67const ButtonLocation kManualStack(4, 6);
68
69const ButtonLocation kCarry(4, 10);
70const ButtonLocation kSetDown(3, 9);
71const ButtonLocation kSkyscraper(4, 11);
72
73const ButtonLocation kScoreBegin(4, 8);
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000074
Austin Schuh8e287fe2015-09-28 00:35:07 +000075const ButtonLocation kCanGrabberLift(3, 2);
Comran Morshed34f891d2015-09-15 22:04:43 +000076const ButtonLocation kFastCanGrabberLift(2, 3);
Austin Schuh8e287fe2015-09-28 00:35:07 +000077const ButtonLocation kCanGrabberLower(3, 5);
Comran Morshed34f891d2015-09-15 22:04:43 +000078
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000079class Reader : public ::aos::input::JoystickInput {
80 public:
81 Reader() : was_running_(false) {}
82
83 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
84 bool last_auto_running = auto_running_;
85 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
86 data.GetControlBit(ControlBit::kEnabled);
87 if (auto_running_ != last_auto_running) {
88 if (auto_running_) {
89 StartAuto();
90 } else {
91 StopAuto();
92 }
Austin Schuhbd01a582015-09-21 00:05:31 +000093 intake_closed_ = true;
94 can_restraint_open_ = false;
95 passive_support_open_ = true;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000096 }
97
98 if (!data.GetControlBit(ControlBit::kAutonomous)) {
99 HandleDrivetrain(data);
100 HandleTeleop(data);
101 }
102 }
103
104 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
105 const double wheel = -data.GetAxis(kSteeringWheel);
106 const double throttle = -data.GetAxis(kDriveThrottle);
107
108 if (!drivetrain_queue.goal.MakeWithBuilder()
109 .steering(wheel)
110 .throttle(throttle)
111 .quickturn(data.IsPressed(kQuickTurn))
112 .control_loop_driving(false)
113 .Send()) {
114 LOG(WARNING, "sending stick values failed\n");
115 }
116 }
117
118 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
Austin Schuhedd63012015-09-13 05:09:03 +0000119 double intake_goal = 0;
120
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000121 if (!data.GetControlBit(ControlBit::kEnabled)) {
122 action_queue_.CancelAllActions();
Austin Schuh8fc29c52015-09-13 20:19:05 +0000123 LOG(DEBUG, "Canceling\n");
124 }
125
126 elevator_queue.status.FetchLatest();
127 if (!elevator_queue.status.get()) {
128 LOG(ERROR, "Got no elevator status packet.\n");
129 }
130
131 if (elevator_queue.status.get() && elevator_queue.status->zeroed) {
132 if (waiting_for_zero_) {
133 LOG(INFO, "Zeroed! Starting teleop mode.\n");
134 waiting_for_zero_ = false;
135
136 // Set the initial goals to the bottom, since otherwise the driver seems
137 // to get confused and think that the end of the zeroing sequence is the
138 // same location and then wonders why it doesn't work...
139 elevator_goal_ = kGroundHeight;
140 }
141 } else {
142 waiting_for_zero_ = true;
143 }
144
145 if (data.PosEdge(kAutoStack)) {
146 action_queue_.CancelAllActions();
147 if (tote_count_ == 6) {
148 stacking_state_machine_ = FULL;
149 } else {
150 stacking_state_machine_ = WAITING;
151 }
152 }
153 if (data.IsPressed(kAutoStack)) {
154 switch (stacking_state_machine_) {
155 case WAITING:
156 elevator_params_ = kFastElevatorMove;
157 elevator_goal_ = kOneToteHeight;
158 if (elevator_queue.status->has_tote) {
159 stacking_state_machine_ = GOING_DOWN;
160 }
161 break;
162 case GOING_DOWN:
163 elevator_params_ = kFastElevatorMove;
164 elevator_goal_ = kGroundHeight;
165 if (elevator_queue.status->height < 0.05) {
166 ++tote_count_;
167 if (tote_count_ == 6) {
168 stacking_state_machine_ = FULL;
169 } else {
170 stacking_state_machine_ = GOING_UP;
171 }
172 }
173 break;
174 case GOING_UP:
175 elevator_params_ = kFastElevatorMove;
176 elevator_goal_ = kOneToteHeight;
177 if (elevator_queue.status->height > kOneToteHeight - 0.05) {
178 stacking_state_machine_ = WAITING;
179 }
180 break;
181 case FULL:
182 elevator_goal_ = kCarryHeight;
183 elevator_params_ = kFastElevatorMove;
184 break;
185 case OFF:
186 stacking_state_machine_ = WAITING;
187 break;
188 }
189 } else {
190 stacking_state_machine_ = OFF;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000191 }
192
Austin Schuhedd63012015-09-13 05:09:03 +0000193 // Buttons for intaking.
194 if (data.IsPressed(kIntakeIn)) {
195 intake_goal = 10.0;
Austin Schuh8fc29c52015-09-13 20:19:05 +0000196 if (stacking_state_machine_ != OFF &&
197 elevator_queue.status->height < 0.43) {
198 intake_goal = 0.0;
199 }
Austin Schuhedd63012015-09-13 05:09:03 +0000200 } else if (data.IsPressed(kIntakeOut)) {
201 intake_goal = -10.0;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000202
Austin Schuhedd63012015-09-13 05:09:03 +0000203 action_queue_.CancelAllActions();
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000204 }
Austin Schuhedd63012015-09-13 05:09:03 +0000205 // TODO(Adam): Implement essential actors/goals.
206 if (data.PosEdge(kMoveToteHeight)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000207 elevator_goal_ = 0.45;
208 elevator_params_ = {1.0, 5.0};
209 action_queue_.CancelAllActions();
210 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000211
Austin Schuhbd01a582015-09-21 00:05:31 +0000212 if (data.IsPressed(kOpenIntake)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000213 intake_closed_ = false;
214 }
215
Austin Schuhbd01a582015-09-21 00:05:31 +0000216 if (data.IsPressed(kCloseIntake)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000217 intake_closed_ = true;
218 }
219
Austin Schuhbd01a582015-09-21 00:05:31 +0000220 if (data.IsPressed(kOpenCanRestraint)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000221 can_restraint_open_ = true;
222 }
223
Austin Schuhbd01a582015-09-21 00:05:31 +0000224 if (data.IsPressed(kCloseCanRestraint)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000225 can_restraint_open_ = false;
226 }
227
Austin Schuhbd01a582015-09-21 00:05:31 +0000228 if (data.IsPressed(kOpenPassiveSupport)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000229 passive_support_open_ = true;
230 }
231
Austin Schuhbd01a582015-09-21 00:05:31 +0000232 if (data.IsPressed(kClosePassiveSupport)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000233 passive_support_open_ = false;
234 }
235
Austin Schuhedd63012015-09-13 05:09:03 +0000236 // Buttons for elevator.
Austin Schuhbd01a582015-09-21 00:05:31 +0000237 if (data.IsPressed(kCarry)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000238 // TODO(comran): Get actual height/velocity/acceleration values.
239 elevator_goal_ = 0.180;
240 elevator_params_ = {1.0, 2.0};
241 action_queue_.CancelAllActions();
242 }
243
Austin Schuhbd01a582015-09-21 00:05:31 +0000244 if (data.IsPressed(kSetDown)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000245 // TODO(comran): Get actual height/velocity/acceleration values.
Austin Schuh8fc29c52015-09-13 20:19:05 +0000246 elevator_goal_ = 0.005;
Austin Schuhedd63012015-09-13 05:09:03 +0000247 elevator_params_ = {1.0, 5.0};
248 action_queue_.CancelAllActions();
249 }
250
Austin Schuhbd01a582015-09-21 00:05:31 +0000251 if (data.IsPressed(kSkyscraper)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000252 // TODO(comran): Get actual height/velocity/acceleration values.
253 elevator_goal_ = 1.0;
Austin Schuhd54e0c42015-09-13 08:15:55 +0000254 elevator_params_ = {1.0, 5.0};
Austin Schuhedd63012015-09-13 05:09:03 +0000255 }
256
Austin Schuhbd01a582015-09-21 00:05:31 +0000257 if (data.IsPressed(kScoreBegin)) {
Austin Schuhedd63012015-09-13 05:09:03 +0000258 // TODO(comran): Get actual height/velocity/acceleration values.
Austin Schuhe9423dd2015-09-28 00:35:26 +0000259 elevator_goal_ = 0.005;
Austin Schuh8fc29c52015-09-13 20:19:05 +0000260 elevator_params_ = {1.0, 5.0};
261 intake_closed_ = false;
262 can_restraint_open_ = true;
263 passive_support_open_ = true;
264 tote_count_ = 0;
Austin Schuhedd63012015-09-13 05:09:03 +0000265 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000266
Comran Morshed34f891d2015-09-15 22:04:43 +0000267 // Buttons for can grabber.
268 if (data.IsPressed(kCanGrabberLift)) {
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800269 ::y2015_bot3::autonomous::can_grabber_control.MakeWithBuilder()
270 .can_grabber_voltage(-3)
271 .can_grabbers(false)
272 .Send();
Comran Morshed34f891d2015-09-15 22:04:43 +0000273 } else if (data.IsPressed(kFastCanGrabberLift)) {
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800274 ::y2015_bot3::autonomous::can_grabber_control.MakeWithBuilder()
Austin Schuhbd01a582015-09-21 00:05:31 +0000275 .can_grabber_voltage(-12).can_grabbers(false).Send();
276 } else if (data.IsPressed(kCanGrabberLower)) {
Austin Schuh8e287fe2015-09-28 00:35:07 +0000277 if (grab_delay_ > 5) {
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800278 ::y2015_bot3::autonomous::can_grabber_control.MakeWithBuilder()
Austin Schuh8e287fe2015-09-28 00:35:07 +0000279 .can_grabber_voltage(2).can_grabbers(true).Send();
280 } else {
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800281 ::y2015_bot3::autonomous::can_grabber_control.MakeWithBuilder()
Austin Schuh8e287fe2015-09-28 00:35:07 +0000282 .can_grabber_voltage(0).can_grabbers(true).Send();
283 }
284 ++grab_delay_;
285 } else {
286 grab_delay_ = 0;
Comran Morshed34f891d2015-09-15 22:04:43 +0000287 }
288
Austin Schuhedd63012015-09-13 05:09:03 +0000289 // Send our goals if everything looks OK.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000290 if (!waiting_for_zero_) {
291 if (!action_queue_.Running()) {
Austin Schuhedd63012015-09-13 05:09:03 +0000292 // Send our elevator goals, with limits set in the profile params.
293 auto new_elevator_goal = elevator_queue.goal.MakeMessage();
294 new_elevator_goal->max_velocity = elevator_params_.velocity;
295 new_elevator_goal->max_acceleration = elevator_params_.acceleration;
296 new_elevator_goal->height = elevator_goal_;
297 new_elevator_goal->velocity = 0.0;
298 new_elevator_goal->passive_support = passive_support_open_;
299 new_elevator_goal->can_support = can_restraint_open_;
300
301 if (new_elevator_goal.Send()) {
302 LOG(DEBUG, "sending goals: elevator: %f\n", elevator_goal_);
303 } else {
304 LOG(ERROR, "Sending elevator goal failed.\n");
305 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000306 }
307 }
308
Austin Schuhedd63012015-09-13 05:09:03 +0000309 // Send our intake goals.
310 if (!intake_queue.goal.MakeWithBuilder().movement(intake_goal)
311 .claw_closed(intake_closed_).Send()) {
312 LOG(ERROR, "Sending intake goal failed.\n");
313 }
314
315 // If an action is running, use the action's goals for the profiled
316 // superstructure subsystems & bypass others.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000317 if (action_queue_.Running()) {
Austin Schuhedd63012015-09-13 05:09:03 +0000318 control_loops::elevator_queue.status.FetchLatest();
319 if (control_loops::elevator_queue.status.get()) {
320 elevator_goal_ = control_loops::elevator_queue.status->goal_height;
321 } else {
322 LOG(ERROR, "No elevator status!\n");
323 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000324 }
325 action_queue_.Tick();
326 was_running_ = action_queue_.Running();
327 }
328
329 private:
330 void StartAuto() {
331 LOG(INFO, "Starting auto mode\n");
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800332 ::y2015_bot3::autonomous::autonomous.MakeWithBuilder().run_auto(true).Send();
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000333 }
334
335 void StopAuto() {
336 LOG(INFO, "Stopping auto mode\n");
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800337 ::y2015_bot3::autonomous::autonomous.MakeWithBuilder().run_auto(false).Send();
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000338 }
339
340 bool was_running_;
341
Austin Schuhedd63012015-09-13 05:09:03 +0000342 double elevator_goal_ = 0.2;
343
344 ProfileParams elevator_params_ = kElevatorMove;
345
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000346 // If we're waiting for the subsystems to zero.
347 bool waiting_for_zero_ = true;
348
349 bool auto_running_ = false;
350
Austin Schuhedd63012015-09-13 05:09:03 +0000351 bool intake_closed_ = false;
352
Austin Schuh8fc29c52015-09-13 20:19:05 +0000353 bool can_restraint_open_ = true;
Austin Schuhedd63012015-09-13 05:09:03 +0000354
Austin Schuh8fc29c52015-09-13 20:19:05 +0000355 bool passive_support_open_ = true;
356
357 int tote_count_ = 0;
Austin Schuhedd63012015-09-13 05:09:03 +0000358
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000359 ::aos::common::actions::ActionQueue action_queue_;
360
Austin Schuh8fc29c52015-09-13 20:19:05 +0000361 enum StackingStateMachine {
362 WAITING,
363 GOING_DOWN,
364 GOING_UP,
365 FULL,
366 OFF
367 };
368
369 StackingStateMachine stacking_state_machine_;
370
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000371 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
372 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
373 "no drivetrain status");
Austin Schuh8e287fe2015-09-28 00:35:07 +0000374 int grab_delay_ = 0;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000375};
376
377} // namespace joysticks
378} // namespace input
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800379} // namespace y2015_bot3
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000380
381int main() {
382 ::aos::Init();
Austin Schuh6d1ee0c2015-11-21 14:36:04 -0800383 ::y2015_bot3::input::joysticks::Reader reader;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000384 reader.Run();
385 ::aos::Cleanup();
386}