blob: 826c5f0e5928fe3f6bf7165319d0e7b0ce1d993f [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"
7#include "aos/prime/input/joystick_input.h"
8#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"
15#include "bot3/autonomous/auto.q.h"
Austin Schuhedd63012015-09-13 05:09:03 +000016#include "bot3/control_loops/elevator/elevator.h"
17#include "bot3/control_loops/drivetrain/drivetrain.q.h"
18#include "bot3/control_loops/elevator/elevator.q.h"
19#include "bot3/control_loops/intake/intake.q.h"
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000020
21using ::bot3::control_loops::drivetrain_queue;
Austin Schuhedd63012015-09-13 05:09:03 +000022using ::bot3::control_loops::elevator_queue;
23using ::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
31namespace bot3 {
32namespace 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};
42
43// Joystick & button addresses.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000044const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
45const ButtonLocation kShiftHigh(2, 1), kShiftLow(2, 3);
46const ButtonLocation kQuickTurn(1, 5);
47
Austin Schuhedd63012015-09-13 05:09:03 +000048// essential
49const ButtonLocation kMoveToteHeight(4, 9);
50const ButtonLocation kOpenIntake(3, 8);
51const ButtonLocation kCloseIntake(3, 6);
52const ButtonLocation kOpenCanRestraint(4, 5);
53const ButtonLocation kCloseCanRestraint(4, 1);
54const POVLocation kOpenPassiveSupport(4, 0);
55const POVLocation kClosePassiveSupport(4, 180);
56
57const ButtonLocation kIntakeIn(3, 7);
58const ButtonLocation kIntakeOut(4, 12);
59
60const ButtonLocation kAutoStack(4, 7);
61const ButtonLocation kManualStack(4, 6);
62
63const ButtonLocation kCarry(4, 10);
64const ButtonLocation kSetDown(3, 9);
65const ButtonLocation kSkyscraper(4, 11);
66
67const ButtonLocation kScoreBegin(4, 8);
Comran Morshed0d6cf9b2015-06-17 19:29:57 +000068
69class Reader : public ::aos::input::JoystickInput {
70 public:
71 Reader() : was_running_(false) {}
72
73 virtual void RunIteration(const ::aos::input::driver_station::Data &data) {
74 bool last_auto_running = auto_running_;
75 auto_running_ = data.GetControlBit(ControlBit::kAutonomous) &&
76 data.GetControlBit(ControlBit::kEnabled);
77 if (auto_running_ != last_auto_running) {
78 if (auto_running_) {
79 StartAuto();
80 } else {
81 StopAuto();
82 }
83 }
84
85 if (!data.GetControlBit(ControlBit::kAutonomous)) {
86 HandleDrivetrain(data);
87 HandleTeleop(data);
88 }
89 }
90
91 void HandleDrivetrain(const ::aos::input::driver_station::Data &data) {
92 const double wheel = -data.GetAxis(kSteeringWheel);
93 const double throttle = -data.GetAxis(kDriveThrottle);
94
95 if (!drivetrain_queue.goal.MakeWithBuilder()
96 .steering(wheel)
97 .throttle(throttle)
98 .quickturn(data.IsPressed(kQuickTurn))
99 .control_loop_driving(false)
100 .Send()) {
101 LOG(WARNING, "sending stick values failed\n");
102 }
103 }
104
105 void HandleTeleop(const ::aos::input::driver_station::Data &data) {
Austin Schuhedd63012015-09-13 05:09:03 +0000106 double intake_goal = 0;
107
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000108 if (!data.GetControlBit(ControlBit::kEnabled)) {
109 action_queue_.CancelAllActions();
110 LOG(DEBUG, "Canceling\n");
Austin Schuhedd63012015-09-13 05:09:03 +0000111 intake_closed_ = false;
112 can_restraint_open_ = true;
113 passive_support_open_ = true;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000114 }
115
Austin Schuhedd63012015-09-13 05:09:03 +0000116 // Buttons for intaking.
117 if (data.IsPressed(kIntakeIn)) {
118 intake_goal = 10.0;
119 } else if (data.IsPressed(kIntakeOut)) {
120 intake_goal = -10.0;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000121
Austin Schuhedd63012015-09-13 05:09:03 +0000122 action_queue_.CancelAllActions();
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000123 }
Austin Schuhedd63012015-09-13 05:09:03 +0000124 // TODO(Adam): Implement essential actors/goals.
125 if (data.PosEdge(kMoveToteHeight)) {
126 // TODO(adams): Find correct values for height, velocity, and acceleration.
127 elevator_goal_ = 0.45;
128 elevator_params_ = {1.0, 5.0};
129 action_queue_.CancelAllActions();
130 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000131
Austin Schuhedd63012015-09-13 05:09:03 +0000132 if (data.PosEdge(kOpenIntake)) {
133 intake_closed_ = false;
134 }
135
136 if (data.PosEdge(kCloseIntake)) {
137 intake_closed_ = true;
138 }
139
140 if (data.PosEdge(kOpenCanRestraint)) {
141 can_restraint_open_ = true;
142 }
143
144 if (data.PosEdge(kCloseCanRestraint)) {
145 can_restraint_open_ = false;
146 }
147
148 if (data.PosEdge(kOpenPassiveSupport)) {
149 passive_support_open_ = true;
150 }
151
152 if (data.PosEdge(kClosePassiveSupport)) {
153 passive_support_open_ = false;
154 }
155
156
157 // Buttons for elevator.
158
159 if (data.PosEdge(kCarry)) {
160 // TODO(comran): Get actual height/velocity/acceleration values.
161 elevator_goal_ = 0.180;
162 elevator_params_ = {1.0, 2.0};
163 action_queue_.CancelAllActions();
164 }
165
166 if (data.PosEdge(kSetDown)) {
167 // TODO(comran): Get actual height/velocity/acceleration values.
168 elevator_goal_ = 0.030;
169 elevator_params_ = {1.0, 5.0};
170 action_queue_.CancelAllActions();
171 }
172
173 if (data.PosEdge(kSkyscraper)) {
174 // TODO(comran): Get actual height/velocity/acceleration values.
175 elevator_goal_ = 1.0;
Austin Schuhd54e0c42015-09-13 08:15:55 +0000176 elevator_params_ = {1.0, 5.0};
Austin Schuhedd63012015-09-13 05:09:03 +0000177 }
178
179 if (data.PosEdge(kScoreBegin)) {
180 // TODO(comran): Get actual height/velocity/acceleration values.
181 elevator_goal_ = 0.0;
182 elevator_params_ = {1.0, 1.5};
183 }
184
185 if (data.PosEdge(ControlBit::kEnabled)) {
186 // If we got enabled, wait for everything to zero.
187 LOG(INFO, "Waiting for zero.\n");
188 waiting_for_zero_ = true;
189 }
190
191 elevator_queue.status.FetchLatest();
192 if (!elevator_queue.status.get()) {
193 LOG(ERROR, "Got no elevator status packet.\n");
194 }
195
196 if (elevator_queue.status.get() && elevator_queue.status->zeroed) {
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000197 if (waiting_for_zero_) {
198 LOG(INFO, "Zeroed! Starting teleop mode.\n");
199 waiting_for_zero_ = false;
200
201 // Set the initial goals to where we are now.
Austin Schuhedd63012015-09-13 05:09:03 +0000202 elevator_goal_ = elevator_queue.status->goal_height;
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000203 }
204 } else {
205 waiting_for_zero_ = true;
Austin Schuhedd63012015-09-13 05:09:03 +0000206 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000207
Austin Schuhedd63012015-09-13 05:09:03 +0000208 // Send our goals if everything looks OK.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000209 if (!waiting_for_zero_) {
210 if (!action_queue_.Running()) {
Austin Schuhedd63012015-09-13 05:09:03 +0000211 // Send our elevator goals, with limits set in the profile params.
212 auto new_elevator_goal = elevator_queue.goal.MakeMessage();
213 new_elevator_goal->max_velocity = elevator_params_.velocity;
214 new_elevator_goal->max_acceleration = elevator_params_.acceleration;
215 new_elevator_goal->height = elevator_goal_;
216 new_elevator_goal->velocity = 0.0;
217 new_elevator_goal->passive_support = passive_support_open_;
218 new_elevator_goal->can_support = can_restraint_open_;
219
220 if (new_elevator_goal.Send()) {
221 LOG(DEBUG, "sending goals: elevator: %f\n", elevator_goal_);
222 } else {
223 LOG(ERROR, "Sending elevator goal failed.\n");
224 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000225 }
226 }
227
Austin Schuhedd63012015-09-13 05:09:03 +0000228 // Send our intake goals.
229 if (!intake_queue.goal.MakeWithBuilder().movement(intake_goal)
230 .claw_closed(intake_closed_).Send()) {
231 LOG(ERROR, "Sending intake goal failed.\n");
232 }
233
234 // If an action is running, use the action's goals for the profiled
235 // superstructure subsystems & bypass others.
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000236 if (action_queue_.Running()) {
Austin Schuhedd63012015-09-13 05:09:03 +0000237 control_loops::elevator_queue.status.FetchLatest();
238 if (control_loops::elevator_queue.status.get()) {
239 elevator_goal_ = control_loops::elevator_queue.status->goal_height;
240 } else {
241 LOG(ERROR, "No elevator status!\n");
242 }
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000243 }
244 action_queue_.Tick();
245 was_running_ = action_queue_.Running();
246 }
247
248 private:
249 void StartAuto() {
250 LOG(INFO, "Starting auto mode\n");
251 ::bot3::autonomous::autonomous.MakeWithBuilder().run_auto(true).Send();
252 }
253
254 void StopAuto() {
255 LOG(INFO, "Stopping auto mode\n");
256 ::bot3::autonomous::autonomous.MakeWithBuilder().run_auto(false).Send();
257 }
258
259 bool was_running_;
260
Austin Schuhedd63012015-09-13 05:09:03 +0000261 double elevator_goal_ = 0.2;
262
263 ProfileParams elevator_params_ = kElevatorMove;
264
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000265 // If we're waiting for the subsystems to zero.
266 bool waiting_for_zero_ = true;
267
268 bool auto_running_ = false;
269
Austin Schuhedd63012015-09-13 05:09:03 +0000270 bool intake_closed_ = false;
271
272 bool can_restraint_open_ = false;
273
274 bool passive_support_open_ = false;
275
Comran Morshed0d6cf9b2015-06-17 19:29:57 +0000276 ::aos::common::actions::ActionQueue action_queue_;
277
278 ::aos::util::SimpleLogInterval no_drivetrain_status_ =
279 ::aos::util::SimpleLogInterval(::aos::time::Time::InSeconds(0.2), WARNING,
280 "no drivetrain status");
281};
282
283} // namespace joysticks
284} // namespace input
285} // namespace bot3
286
287int main() {
288 ::aos::Init();
289 ::bot3::input::joysticks::Reader reader;
290 reader.Run();
291 ::aos::Cleanup();
292}