blob: edbe4064464f3b1c7c3f6f3d2f3d0adb80e92f98 [file] [log] [blame]
Austin Schuha3c148e2018-03-09 21:04:05 -08001#include "y2018/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
5#include <chrono>
6#include <cmath>
7
8#include "aos/common/util/phased_loop.h"
9#include "aos/common/logging/logging.h"
10
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "y2018/control_loops/drivetrain/drivetrain_base.h"
13
14namespace y2018 {
15namespace actors {
16using ::frc971::ProfileParameters;
17
18using ::frc971::control_loops::drivetrain_queue;
19using ::aos::monotonic_clock;
20namespace chrono = ::std::chrono;
21namespace this_thread = ::std::this_thread;
22
23namespace {
24
25double DoubleSeconds(monotonic_clock::duration duration) {
26 return ::std::chrono::duration_cast<::std::chrono::duration<double>>(duration)
27 .count();
28}
29
Austin Schuhc231df42018-03-21 20:43:24 -070030const ProfileParameters kFinalSwitchDrive = {0.5, 0.5};
31const ProfileParameters kDrive = {5.0, 2.5};
Austin Schuhf79c0e52018-04-04 20:13:21 -070032const ProfileParameters kThirdBoxDrive = {3.0, 2.5};
Austin Schuhc231df42018-03-21 20:43:24 -070033const ProfileParameters kSlowDrive = {1.5, 2.5};
Austin Schuhf79c0e52018-04-04 20:13:21 -070034const ProfileParameters kScaleTurnDrive = {3.0, 2.5};
Austin Schuhc231df42018-03-21 20:43:24 -070035const ProfileParameters kFarSwitchTurnDrive = {2.0, 2.5};
36const ProfileParameters kTurn = {4.0, 2.0};
37const ProfileParameters kSweepingTurn = {5.0, 7.0};
38const ProfileParameters kFastTurn = {5.0, 7.0};
Austin Schuhf79c0e52018-04-04 20:13:21 -070039const ProfileParameters kReallyFastTurn = {1.5, 9.0};
40
41const ProfileParameters kThirdBoxSlowBackup = {0.35, 1.5};
42const ProfileParameters kThirdBoxSlowTurn = {1.5, 4.0};
43
44const ProfileParameters kThirdBoxPlaceDrive = {4.0, 2.3};
45
46const ProfileParameters kFinalFrontFarSwitchDrive = {2.0, 2.0};
Austin Schuha3c148e2018-03-09 21:04:05 -080047
48} // namespace
49
50AutonomousActor::AutonomousActor(
51 ::frc971::autonomous::AutonomousActionQueueGroup *s)
52 : frc971::autonomous::BaseAutonomousActor(
53 s, control_loops::drivetrain::GetDrivetrainConfig()) {}
54
55bool AutonomousActor::RunAction(
56 const ::frc971::autonomous::AutonomousActionParams &params) {
57 monotonic_clock::time_point start_time = monotonic_clock::now();
58 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
59 Reset();
60
Austin Schuhc231df42018-03-21 20:43:24 -070061 switch (params.mode) {
62 case 1: {
63 constexpr double kDriveDistance = 3.2;
64 // Start on the left. Drive, arc a turn, and drop in the close switch.
65 StartDrive(-kDriveDistance, 0.0, kDrive, kTurn);
66 if (!WaitForDriveNear(2.0, M_PI / 2.0)) return true;
Austin Schuha3c148e2018-03-09 21:04:05 -080067
Austin Schuhc231df42018-03-21 20:43:24 -070068 // Now, close so let's move the arm up.
69 set_arm_goal_position(arm::BackSwitchIndex());
70 SendSuperstructureGoal();
71
72 StartDrive(0.0, 0.0, kSlowDrive, kSweepingTurn);
73 if (!WaitForDriveNear(1.6, M_PI / 2.0)) return true;
74
75 StartDrive(0.0, -M_PI / 4.0 - 0.2, kSlowDrive, kSweepingTurn);
76 if (!WaitForDriveNear(0.2, 0.2)) return true;
77 set_max_drivetrain_voltage(6.0);
78 ::std::this_thread::sleep_for(chrono::milliseconds(300));
79
80 set_open_claw(true);
81 SendSuperstructureGoal();
82
83 ::std::this_thread::sleep_for(chrono::milliseconds(500));
84 set_max_drivetrain_voltage(12.0);
85 StartDrive(0.2, 0.0, kDrive, kTurn);
86 if (!WaitForTurnProfileDone()) return true;
87
88 set_arm_goal_position(arm::NeutralIndex());
89 SendSuperstructureGoal();
90
91 } break;
92 case 0: {
Austin Schuhf79c0e52018-04-04 20:13:21 -070093 StartDrive(-3.2, 0.0, kDrive, kTurn);
Austin Schuhc231df42018-03-21 20:43:24 -070094 if (!WaitForDriveProfileDone()) return true;
Austin Schuhf79c0e52018-04-04 20:13:21 -070095 } break;
96 case 200:
97 {
98 constexpr bool kDriveBehind = true;
99 if (kDriveBehind) {
100 // Start on the left. Hit the switch.
101 constexpr double kFullDriveLength = 9.95;
102 constexpr double kTurnDistance = 4.40;
103 StartDrive(-kFullDriveLength, 0.0, kDrive, kTurn);
104 if (!WaitForDriveProfileNear(kFullDriveLength - (kTurnDistance - 1.4)))
105 return true;
106 StartDrive(0.0, 0.0, kFarSwitchTurnDrive, kTurn);
Austin Schuhc231df42018-03-21 20:43:24 -0700107
Austin Schuhf79c0e52018-04-04 20:13:21 -0700108 if (!WaitForDriveProfileNear(kFullDriveLength - kTurnDistance))
109 return true;
110 StartDrive(0.0, -M_PI / 2.0, kFarSwitchTurnDrive, kSweepingTurn);
111 if (!WaitForTurnProfileDone()) return true;
112 StartDrive(0.0, 0.0, kDrive, kTurn);
113 if (!WaitForDriveProfileDone()) return true;
Austin Schuhc231df42018-03-21 20:43:24 -0700114
Austin Schuhf79c0e52018-04-04 20:13:21 -0700115 // Now, close so let's move the arm up.
116 set_arm_goal_position(arm::FrontSwitchAutoIndex());
117 SendSuperstructureGoal();
Austin Schuhc231df42018-03-21 20:43:24 -0700118
Austin Schuhf79c0e52018-04-04 20:13:21 -0700119 StartDrive(0.0, M_PI / 2.0, kDrive, kFastTurn);
120 if (!WaitForTurnProfileDone()) return true;
Austin Schuhc231df42018-03-21 20:43:24 -0700121
Austin Schuhf79c0e52018-04-04 20:13:21 -0700122 set_max_drivetrain_voltage(6.0);
123 StartDrive(0.35, 0.0, kFinalSwitchDrive, kTurn);
124 if (!WaitForArmTrajectoryClose(0.001)) return true;
125 // if (!WaitForDriveNear(0.2, M_PI / 2.0)) return true;
126 ::std::this_thread::sleep_for(chrono::milliseconds(1500));
Austin Schuhc231df42018-03-21 20:43:24 -0700127
Austin Schuhf79c0e52018-04-04 20:13:21 -0700128 set_open_claw(true);
129 SendSuperstructureGoal();
130
131 ::std::this_thread::sleep_for(chrono::milliseconds(1500));
132 set_arm_goal_position(arm::NeutralIndex());
133 SendSuperstructureGoal();
134 if (ShouldCancel()) return true;
135 set_max_drivetrain_voltage(12.0);
136 StartDrive(-0.5, 0.0, kDrive, kTurn);
137 if (!WaitForDriveProfileDone()) return true;
138 } else {
139 // Start on the left. Hit the switch.
140 constexpr double kFullDriveLength = 5.55;
141 constexpr double kTurnDistance = 0.35;
142 StartDrive(-kFullDriveLength, 0.0, kFarSwitchTurnDrive, kTurn);
143
144 if (!WaitForDriveProfileNear(kFullDriveLength - kTurnDistance))
145 return true;
146 StartDrive(0.0, -M_PI / 2.0, kFarSwitchTurnDrive, kSweepingTurn);
147 if (!WaitForTurnProfileDone()) return true;
148 StartDrive(0.0, 0.0, kDrive, kTurn);
149 if (!WaitForDriveProfileDone()) return true;
150
151 // Now, close so let's move the arm up.
152 set_arm_goal_position(arm::FrontSwitchIndex());
153 SendSuperstructureGoal();
154
155 StartDrive(0.0, -M_PI / 2.0, kDrive, kFastTurn);
156 if (!WaitForTurnProfileDone()) return true;
157
158 set_max_drivetrain_voltage(10.0);
159 StartDrive(1.1, 0.0, kDrive, kTurn);
160 if (!WaitForArmTrajectoryClose(0.001)) return true;
161 if (!WaitForDriveNear(0.6, M_PI / 2.0)) return true;
162 StartDrive(0.0, 0.0, kFinalFrontFarSwitchDrive, kTurn);
163
164 if (!WaitForDriveNear(0.3, M_PI / 2.0)) return true;
165 set_max_drivetrain_voltage(6.0);
166 StartDrive(0.0, 0.0, kFinalFrontFarSwitchDrive, kTurn);
167
168 // if (!WaitForDriveNear(0.2, M_PI / 2.0)) return true;
169 ::std::this_thread::sleep_for(chrono::milliseconds(300));
170
171 set_open_claw(true);
172 SendSuperstructureGoal();
173
174 ::std::this_thread::sleep_for(chrono::milliseconds(1000));
175 set_arm_goal_position(arm::NeutralIndex());
176 SendSuperstructureGoal();
177 if (ShouldCancel()) return true;
178 set_max_drivetrain_voltage(12.0);
179 StartDrive(-0.5, 0.0, kDrive, kTurn);
180 if (!WaitForDriveProfileDone()) return true;
181 }
Austin Schuhc231df42018-03-21 20:43:24 -0700182 } break;
183
184 case 3:
185 case 2: {
186 // Start on the left. Hit the scale.
Austin Schuhf79c0e52018-04-04 20:13:21 -0700187 constexpr double kDriveDistance = 6.95;
188 // Distance and angle to do the big drive to the third cube.
189 constexpr double kThirdCubeDrive = 1.57;
190 constexpr double kThirdCubeTurn = M_PI / 4.0 - 0.1;
191 // Angle to do the slow pickup turn on the third box.
192 constexpr double kThirdBoxEndTurnAngle = 0.20;
193
194 // Distance to drive back to the scale with the third cube.
195 constexpr double kThirdCubeDropDrive = kThirdCubeDrive + 0.30;
196
Austin Schuhc231df42018-03-21 20:43:24 -0700197 // Drive.
198 StartDrive(-kDriveDistance, 0.0, kDrive, kTurn);
199 if (!WaitForDriveNear(kDriveDistance - 1.0, M_PI / 2.0)) return true;
200 // Once we are away from the wall, start the arm.
Austin Schuhf79c0e52018-04-04 20:13:21 -0700201 set_arm_goal_position(arm::BackMiddle2BoxIndex());
Austin Schuhc231df42018-03-21 20:43:24 -0700202 SendSuperstructureGoal();
203
204 // We are starting to get close. Slow down for the turn.
Austin Schuhf79c0e52018-04-04 20:13:21 -0700205 if (!WaitForDriveNear(4.0, M_PI / 2.0)) return true;
206 StartDrive(0.0, 0.0, kScaleTurnDrive, kFastTurn);
Austin Schuhc231df42018-03-21 20:43:24 -0700207
208 // Once we've gotten slowed down a bit, start turning.
Austin Schuhf79c0e52018-04-04 20:13:21 -0700209 if (!WaitForDriveNear(3.25, M_PI / 2.0)) return true;
210 StartDrive(0.0, -M_PI / 6.0, kScaleTurnDrive, kFastTurn);
211
212 if (!WaitForDriveNear(1.0, M_PI / 2.0)) return true;
213 StartDrive(0.0, M_PI / 6.0, kScaleTurnDrive, kFastTurn);
Austin Schuhc231df42018-03-21 20:43:24 -0700214
215 // Get close and open the claw.
Austin Schuhf79c0e52018-04-04 20:13:21 -0700216 if (!WaitForDriveNear(0.15, 0.25)) return true;
Austin Schuhc231df42018-03-21 20:43:24 -0700217 set_open_claw(true);
218 SendSuperstructureGoal();
Austin Schuhf79c0e52018-04-04 20:13:21 -0700219 set_intake_angle(-0.40);
220 LOG(INFO, "Dropped first box %f\n",
221 DoubleSeconds(monotonic_clock::now() - start_time));
Austin Schuhc231df42018-03-21 20:43:24 -0700222
223 ::std::this_thread::sleep_for(chrono::milliseconds(500));
224
Austin Schuhf79c0e52018-04-04 20:13:21 -0700225 set_grab_box(true);
226 SendSuperstructureGoal();
227
228 ::std::this_thread::sleep_for(chrono::milliseconds(200));
229
230 LOG(INFO, "Starting second box drive %f\n",
231 DoubleSeconds(monotonic_clock::now() - start_time));
232 constexpr double kSecondBoxSwerveAngle = 0.35;
233 constexpr double kSecondBoxDrive = 1.43;
234 StartDrive(kSecondBoxDrive, 0.0, kDrive, kFastTurn);
235 if (!WaitForDriveNear(kSecondBoxDrive - 0.2, M_PI / 2.0)) return true;
236
237 StartDrive(0.0, kSecondBoxSwerveAngle, kDrive, kFastTurn);
238 if (!WaitForDriveNear(0.5, M_PI / 2.0)) return true;
239
240 set_open_claw(true);
241 set_disable_box_correct(false);
242 SendSuperstructureGoal();
243
244 StartDrive(0.0, -kSecondBoxSwerveAngle, kDrive, kFastTurn);
245
Austin Schuhc231df42018-03-21 20:43:24 -0700246 if (!WaitForDriveProfileDone()) return true;
Austin Schuhf79c0e52018-04-04 20:13:21 -0700247 set_intake_angle(0.10);
248 set_arm_goal_position(arm::BackHighBoxIndex());
249 set_open_claw(false);
250
251 set_roller_voltage(10.0);
252 SendSuperstructureGoal();
253
254 LOG(INFO, "Grabbing second box %f\n",
255 DoubleSeconds(monotonic_clock::now() - start_time));
256 if (!WaitForBoxGrabed()) return true;
257
258 LOG(INFO, "Got second box %f\n",
259 DoubleSeconds(monotonic_clock::now() - start_time));
260 ::std::this_thread::sleep_for(chrono::milliseconds(600));
261
262 set_grab_box(false);
263 set_arm_goal_position(arm::UpIndex());
264 set_roller_voltage(0.0);
265 set_disable_box_correct(false);
266 SendSuperstructureGoal();
267 LOG(INFO, "Driving to place second box %f\n",
268 DoubleSeconds(monotonic_clock::now() - start_time));
269
270 StartDrive(-kSecondBoxDrive + 0.2, kSecondBoxSwerveAngle, kDrive,
271 kFastTurn);
272 if (!WaitForDriveNear(0.4, M_PI / 2.0)) return true;
273
274 constexpr double kSecondBoxEndExtraAngle = 0.3;
275 StartDrive(0.0, -kSecondBoxSwerveAngle - kSecondBoxEndExtraAngle, kDrive,
276 kFastTurn);
277
278 LOG(INFO, "Starting throw %f\n",
279 DoubleSeconds(monotonic_clock::now() - start_time));
280 if (!WaitForDriveNear(0.4, M_PI / 2.0)) return true;
281 set_arm_goal_position(arm::BackHighBoxIndex());
282 SendSuperstructureGoal();
283
284 // Throw the box.
285 if (!WaitForArmTrajectoryClose(0.03)) return true;
286
287 set_open_claw(true);
288 set_intake_angle(-M_PI / 4.0);
289 LOG(INFO, "Releasing second box %f\n",
290 DoubleSeconds(monotonic_clock::now() - start_time));
291 SendSuperstructureGoal();
292
293 ::std::this_thread::sleep_for(chrono::milliseconds(700));
294 set_open_claw(false);
295 set_grab_box(true);
296 SendSuperstructureGoal();
297
298 LOG(INFO, "Driving to third box %f\n",
299 DoubleSeconds(monotonic_clock::now() - start_time));
300 StartDrive(kThirdCubeDrive, kSecondBoxEndExtraAngle, kThirdBoxDrive,
301 kFastTurn);
302 if (!WaitForDriveNear(kThirdCubeDrive - 0.1, M_PI / 4.0)) return true;
303
304 StartDrive(0.0, kThirdCubeTurn, kThirdBoxDrive, kFastTurn);
305 if (!WaitForDriveNear(0.3, M_PI / 4.0)) return true;
306
307 set_intake_angle(0.05);
308 set_roller_voltage(9.0);
309 SendSuperstructureGoal();
310
311 if (!WaitForDriveProfileDone()) return true;
312 if (!WaitForTurnProfileDone()) return true;
313 StartDrive(0.30, kThirdBoxEndTurnAngle, kThirdBoxSlowBackup, kThirdBoxSlowTurn);
314 if (!WaitForDriveProfileDone()) return true;
315
316 if (!WaitForBoxGrabed()) return true;
317 LOG(INFO, "Third box grabbed %f\n",
318 DoubleSeconds(monotonic_clock::now() - start_time));
319 const bool too_late =
320 monotonic_clock::now() > start_time + chrono::milliseconds(12000);
321 if (too_late) {
322 LOG(INFO, "Third box too long, going up. %f\n",
323 DoubleSeconds(monotonic_clock::now() - start_time));
324 set_grab_box(false);
325 set_arm_goal_position(arm::UpIndex());
326 set_roller_voltage(0.0);
327 SendSuperstructureGoal();
328 }
329 ::std::this_thread::sleep_for(chrono::milliseconds(600));
330
331 set_grab_box(false);
332 if (!too_late) {
333 set_arm_goal_position(arm::BackMiddle2BoxIndex());
334 }
335 set_roller_voltage(0.0);
336 SendSuperstructureGoal();
337
338 StartDrive(-kThirdCubeDropDrive, 0.0,
339 kThirdBoxPlaceDrive, kReallyFastTurn);
340
341 if (!WaitForDriveNear(1.40, M_PI / 4.0)) return true;
342 StartDrive(0.0, -kThirdCubeTurn - 0.2 - kThirdBoxEndTurnAngle - 0.3,
343 kThirdBoxPlaceDrive, kReallyFastTurn);
344
345 if (!WaitForArmTrajectoryClose(0.005)) return true;
346 if (!WaitForDriveProfileDone()) return true;
347 if (!WaitForTurnProfileDone()) return true;
348
349 if (!too_late) {
350 set_open_claw(true);
351 set_intake_angle(-M_PI / 4.0);
352 set_roller_voltage(0.0);
353 SendSuperstructureGoal();
354
355 LOG(INFO, "Final open %f\n",
356 DoubleSeconds(monotonic_clock::now() - start_time));
357 }
358
359 ::std::this_thread::sleep_for(chrono::milliseconds(14750) -
360 (monotonic_clock::now() - start_time));
361
362 set_arm_goal_position(arm::UpIndex());
363 SendSuperstructureGoal();
364
365 ::std::this_thread::sleep_for(chrono::milliseconds(15000) -
366 (monotonic_clock::now() - start_time));
367
368 set_close_claw(true);
369 SendSuperstructureGoal();
370
Austin Schuhc231df42018-03-21 20:43:24 -0700371 } break;
Austin Schuha3c148e2018-03-09 21:04:05 -0800372 }
373
374 LOG(INFO, "Done %f\n", DoubleSeconds(monotonic_clock::now() - start_time));
375
376 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
377 ::std::chrono::milliseconds(5) / 2);
378
379 while (!ShouldCancel()) {
380 phased_loop.SleepUntilNext();
381 }
382 LOG(DEBUG, "Done running\n");
383
384 return true;
385}
386
387} // namespace actors
388} // namespace y2018