blob: a5621b318224e4486a55ea56c411c13716e45e38 [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
Austin Schuh8aec1ed2016-05-01 13:29:20 -07005#include <chrono>
Comran Morshedb134e772016-03-16 21:05:05 +00006#include <cmath>
7
John Park33858a32018-09-28 23:05:48 -07008#include "aos/logging/logging.h"
James Kuszmaul651fc3f2019-05-15 21:14:25 -07009#include "aos/util/phased_loop.h"
Comran Morshed435f1112016-03-12 14:20:45 +000010
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Austin Schuhf59b8ee2016-03-19 21:31:36 -070013#include "y2016/control_loops/shooter/shooter.q.h"
Comran Morshedb134e772016-03-16 21:05:05 +000014#include "y2016/control_loops/superstructure/superstructure.q.h"
Austin Schuh23b21802016-04-03 21:18:56 -070015#include "y2016/queues/ball_detector.q.h"
Austin Schuhf59b8ee2016-03-19 21:31:36 -070016#include "y2016/vision/vision.q.h"
Comran Morshede68e3732016-03-12 14:12:11 +000017
18namespace y2016 {
19namespace actors {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080020using ::aos::monotonic_clock;
James Kuszmaul651fc3f2019-05-15 21:14:25 -070021using ::frc971::control_loops::drivetrain_queue;
Austin Schuhf2a50ba2016-12-24 16:16:26 -080022namespace chrono = ::std::chrono;
23namespace this_thread = ::std::this_thread;
Comran Morshed435f1112016-03-12 14:20:45 +000024
25namespace {
Austin Schuhf59b8ee2016-03-19 21:31:36 -070026const ProfileParameters kSlowDrive = {0.8, 2.5};
27const ProfileParameters kLowBarDrive = {1.3, 2.5};
28const ProfileParameters kMoatDrive = {1.2, 3.5};
29const ProfileParameters kRealignDrive = {2.0, 2.5};
30const ProfileParameters kRockWallDrive = {0.8, 2.5};
Comran Morshed435f1112016-03-12 14:20:45 +000031const ProfileParameters kFastDrive = {3.0, 2.5};
32
Austin Schuhf59b8ee2016-03-19 21:31:36 -070033const ProfileParameters kSlowTurn = {0.8, 3.0};
Comran Morshed435f1112016-03-12 14:20:45 +000034const ProfileParameters kFastTurn = {3.0, 10.0};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070035const ProfileParameters kStealTurn = {4.0, 15.0};
Austin Schuh23b21802016-04-03 21:18:56 -070036const ProfileParameters kSwerveTurn = {2.0, 7.0};
37const ProfileParameters kFinishTurn = {2.0, 5.0};
38
39const ProfileParameters kTwoBallLowDrive = {1.7, 3.5};
40const ProfileParameters kTwoBallFastDrive = {3.0, 1.5};
41const ProfileParameters kTwoBallReturnDrive = {3.0, 1.9};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070042const ProfileParameters kTwoBallReturnSlow = {3.0, 2.5};
Austin Schuh23b21802016-04-03 21:18:56 -070043const ProfileParameters kTwoBallBallPickup = {2.0, 1.75};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070044const ProfileParameters kTwoBallBallPickupAccel = {2.0, 2.5};
Austin Schuhf2a50ba2016-12-24 16:16:26 -080045
Comran Morshed435f1112016-03-12 14:20:45 +000046} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000047
Austin Schuh1bf8a212019-05-26 22:13:14 -070048AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
Philipp Schrader4bd29b12017-02-22 04:42:27 +000049 : frc971::autonomous::BaseAutonomousActor(
Austin Schuh1bf8a212019-05-26 22:13:14 -070050 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
51 vision_align_actor_factory_(
52 actors::VisionAlignActor::MakeFactory(event_loop)) {}
Comran Morshed435f1112016-03-12 14:20:45 +000053
Austin Schuhe4ec49c2016-04-24 19:07:15 -070054constexpr double kDoNotTurnCare = 2.0;
55
Comran Morshedb134e772016-03-16 21:05:05 +000056void AutonomousActor::MoveSuperstructure(
57 double intake, double shoulder, double wrist,
58 const ProfileParameters intake_params,
59 const ProfileParameters shoulder_params,
Austin Schuh23b21802016-04-03 21:18:56 -070060 const ProfileParameters wrist_params, bool traverse_up,
61 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +000062 superstructure_goal_ = {intake, shoulder, wrist};
63
64 auto new_superstructure_goal =
65 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
66
67 new_superstructure_goal->angle_intake = intake;
68 new_superstructure_goal->angle_shoulder = shoulder;
69 new_superstructure_goal->angle_wrist = wrist;
70
71 new_superstructure_goal->max_angular_velocity_intake =
72 intake_params.max_velocity;
73 new_superstructure_goal->max_angular_velocity_shoulder =
74 shoulder_params.max_velocity;
75 new_superstructure_goal->max_angular_velocity_wrist =
76 wrist_params.max_velocity;
77
78 new_superstructure_goal->max_angular_acceleration_intake =
79 intake_params.max_acceleration;
80 new_superstructure_goal->max_angular_acceleration_shoulder =
81 shoulder_params.max_acceleration;
82 new_superstructure_goal->max_angular_acceleration_wrist =
83 wrist_params.max_acceleration;
84
Austin Schuh23b21802016-04-03 21:18:56 -070085 new_superstructure_goal->voltage_top_rollers = roller_power;
86 new_superstructure_goal->voltage_bottom_rollers = roller_power;
Austin Schuhf59b8ee2016-03-19 21:31:36 -070087
88 new_superstructure_goal->traverse_unlatched = true;
89 new_superstructure_goal->traverse_down = !traverse_up;
Diana Vandenberg9cc9ab62016-04-20 21:27:47 -070090 new_superstructure_goal->voltage_climber = 0.0;
91 new_superstructure_goal->unfold_climber = false;
Comran Morshedb134e772016-03-16 21:05:05 +000092
93 if (!new_superstructure_goal.Send()) {
94 LOG(ERROR, "Sending superstructure goal failed.\n");
95 }
96}
97
Austin Schuh23b21802016-04-03 21:18:56 -070098void AutonomousActor::OpenShooter() {
99 shooter_speed_ = 0.0;
100
101 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
102 .angular_velocity(shooter_speed_)
103 .clamp_open(true)
104 .push_to_shooter(false)
105 .force_lights_on(false)
106 .Send()) {
107 LOG(ERROR, "Sending shooter goal failed.\n");
108 }
109}
110
111void AutonomousActor::CloseShooter() {
112 shooter_speed_ = 0.0;
113
114 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
115 .angular_velocity(shooter_speed_)
116 .clamp_open(false)
117 .push_to_shooter(false)
118 .force_lights_on(false)
119 .Send()) {
120 LOG(ERROR, "Sending shooter goal failed.\n");
121 }
122}
123
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700124void AutonomousActor::SetShooterSpeed(double speed) {
125 shooter_speed_ = speed;
126
127 // In auto, we want to have the lights on whenever possible since we have no
128 // hope of a human aligning the robot.
129 bool force_lights_on = shooter_speed_ > 1.0;
130
131 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
132 .angular_velocity(shooter_speed_)
133 .clamp_open(false)
134 .push_to_shooter(false)
135 .force_lights_on(force_lights_on)
136 .Send()) {
137 LOG(ERROR, "Sending shooter goal failed.\n");
138 }
139}
140
141void AutonomousActor::Shoot() {
142 uint32_t initial_shots = 0;
143
144 control_loops::shooter::shooter_queue.status.FetchLatest();
145 if (control_loops::shooter::shooter_queue.status.get()) {
146 initial_shots = control_loops::shooter::shooter_queue.status->shots;
147 }
148
149 // In auto, we want to have the lights on whenever possible since we have no
150 // hope of a human aligning the robot.
151 bool force_lights_on = shooter_speed_ > 1.0;
152
153 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
154 .angular_velocity(shooter_speed_)
155 .clamp_open(false)
156 .push_to_shooter(true)
157 .force_lights_on(force_lights_on)
158 .Send()) {
159 LOG(ERROR, "Sending shooter goal failed.\n");
160 }
161
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700162 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
163 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700164 while (true) {
165 if (ShouldCancel()) return;
166
167 // Wait for the shot count to change so we know when the shot is complete.
168 control_loops::shooter::shooter_queue.status.FetchLatest();
169 if (control_loops::shooter::shooter_queue.status.get()) {
170 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
171 return;
172 }
173 }
174 phased_loop.SleepUntilNext();
175 }
176}
177
178void AutonomousActor::WaitForShooterSpeed() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700179 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
180 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700181 while (true) {
182 if (ShouldCancel()) return;
183
184 control_loops::shooter::shooter_queue.status.FetchLatest();
185 if (control_loops::shooter::shooter_queue.status.get()) {
186 if (control_loops::shooter::shooter_queue.status->left.ready &&
187 control_loops::shooter::shooter_queue.status->right.ready) {
188 return;
189 }
190 }
191 phased_loop.SleepUntilNext();
192 }
193}
194
195void AutonomousActor::AlignWithVisionGoal() {
196 actors::VisionAlignActionParams params;
Austin Schuh1bf8a212019-05-26 22:13:14 -0700197 vision_action_ = vision_align_actor_factory_.Make(params);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700198 vision_action_->Start();
199}
200
Austin Schuh23b21802016-04-03 21:18:56 -0700201void AutonomousActor::WaitForAlignedWithVision(
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800202 chrono::nanoseconds align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700203 bool vision_valid = false;
204 double last_angle = 0.0;
205 int ready_to_fire = 0;
206
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700207 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
208 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800209 monotonic_clock::time_point end_time =
210 monotonic_clock::now() + align_duration;
211 while (end_time > monotonic_clock::now()) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700212 if (ShouldCancel()) break;
213
214 ::y2016::vision::vision_status.FetchLatest();
215 if (::y2016::vision::vision_status.get()) {
216 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000217 ::y2016::vision::vision_status->right_image_valid);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700218 last_angle = ::y2016::vision::vision_status->horizontal_angle;
219 }
220
221 drivetrain_queue.status.FetchLatest();
222 drivetrain_queue.goal.FetchLatest();
223
224 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
225 const double left_goal = drivetrain_queue.goal->left_goal;
226 const double right_goal = drivetrain_queue.goal->right_goal;
227 const double left_current =
228 drivetrain_queue.status->estimated_left_position;
229 const double right_current =
230 drivetrain_queue.status->estimated_right_position;
231 const double left_velocity =
232 drivetrain_queue.status->estimated_left_velocity;
233 const double right_velocity =
234 drivetrain_queue.status->estimated_right_velocity;
235
236 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
237 ::std::abs((left_goal - right_goal) -
238 (left_current - right_current)) /
239 dt_config_.robot_radius / 2.0 <
240 0.02 &&
241 ::std::abs(left_velocity - right_velocity) < 0.01) {
242 ++ready_to_fire;
243 } else {
244 ready_to_fire = 0;
245 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700246 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700247 break;
Austin Schuh23b21802016-04-03 21:18:56 -0700248 LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700249 }
250 }
251 phased_loop.SleepUntilNext();
252 }
253
254 vision_action_->Cancel();
255 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuh23b21802016-04-03 21:18:56 -0700256 LOG(INFO, "Done waiting for vision\n");
257}
258
259bool AutonomousActor::IntakeDone() {
260 control_loops::superstructure_queue.status.FetchAnother();
261
262 constexpr double kProfileError = 1e-5;
263 constexpr double kEpsilon = 0.15;
264
265 if (control_loops::superstructure_queue.status->state < 12 ||
266 control_loops::superstructure_queue.status->state == 16) {
267 LOG(ERROR, "Superstructure no longer running, aborting action\n");
268 return true;
269 }
270
271 if (::std::abs(control_loops::superstructure_queue.status->intake.goal_angle -
272 superstructure_goal_.intake) < kProfileError &&
273 ::std::abs(control_loops::superstructure_queue.status->intake
274 .goal_angular_velocity) < kProfileError) {
275 LOG(DEBUG, "Profile done.\n");
276 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
277 superstructure_goal_.intake) < kEpsilon &&
278 ::std::abs(control_loops::superstructure_queue.status->intake
279 .angular_velocity) < kEpsilon) {
280 LOG(INFO, "Near goal, done.\n");
281 return true;
282 }
283 }
284 return false;
285}
286
287bool AutonomousActor::SuperstructureProfileDone() {
288 constexpr double kProfileError = 1e-5;
289 return ::std::abs(
290 control_loops::superstructure_queue.status->intake.goal_angle -
291 superstructure_goal_.intake) < kProfileError &&
292 ::std::abs(
293 control_loops::superstructure_queue.status->shoulder.goal_angle -
294 superstructure_goal_.shoulder) < kProfileError &&
295 ::std::abs(
296 control_loops::superstructure_queue.status->wrist.goal_angle -
297 superstructure_goal_.wrist) < kProfileError &&
298 ::std::abs(control_loops::superstructure_queue.status->intake
299 .goal_angular_velocity) < kProfileError &&
300 ::std::abs(control_loops::superstructure_queue.status->shoulder
301 .goal_angular_velocity) < kProfileError &&
302 ::std::abs(control_loops::superstructure_queue.status->wrist
303 .goal_angular_velocity) < kProfileError;
304}
305
306bool AutonomousActor::SuperstructureDone() {
307 control_loops::superstructure_queue.status.FetchAnother();
308
309 constexpr double kEpsilon = 0.03;
310
311 if (control_loops::superstructure_queue.status->state < 12 ||
312 control_loops::superstructure_queue.status->state == 16) {
313 LOG(ERROR, "Superstructure no longer running, aborting action\n");
314 return true;
315 }
316
317 if (SuperstructureProfileDone()) {
318 LOG(DEBUG, "Profile done.\n");
319 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
320 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
321 ::std::abs(control_loops::superstructure_queue.status->shoulder.angle -
322 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
323 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
324 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
325 ::std::abs(control_loops::superstructure_queue.status->intake
326 .angular_velocity) < (kEpsilon + 0.1) &&
327 ::std::abs(control_loops::superstructure_queue.status->shoulder
328 .angular_velocity) < (kEpsilon + 0.10) &&
329 ::std::abs(control_loops::superstructure_queue.status->wrist
330 .angular_velocity) < (kEpsilon + 0.05)) {
331 LOG(INFO, "Near goal, done.\n");
332 return true;
333 }
334 }
335 return false;
336}
337
338void AutonomousActor::WaitForIntake() {
339 while (true) {
340 if (ShouldCancel()) return;
341 if (IntakeDone()) return;
342 }
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700343}
344
Comran Morshedb134e772016-03-16 21:05:05 +0000345void AutonomousActor::WaitForSuperstructure() {
346 while (true) {
347 if (ShouldCancel()) return;
Austin Schuh23b21802016-04-03 21:18:56 -0700348 if (SuperstructureDone()) return;
349 }
350}
Comran Morshedb134e772016-03-16 21:05:05 +0000351
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700352void AutonomousActor::WaitForSuperstructureProfile() {
353 while (true) {
354 if (ShouldCancel()) return;
355 control_loops::superstructure_queue.status.FetchAnother();
356
357 if (control_loops::superstructure_queue.status->state < 12 ||
358 control_loops::superstructure_queue.status->state == 16) {
359 LOG(ERROR, "Superstructure no longer running, aborting action\n");
360 return;
361 }
362
363 if (SuperstructureProfileDone()) return;
364 }
365}
366
Austin Schuh23b21802016-04-03 21:18:56 -0700367void AutonomousActor::WaitForSuperstructureLow() {
368 while (true) {
369 if (ShouldCancel()) return;
370 control_loops::superstructure_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +0000371
372 if (control_loops::superstructure_queue.status->state < 12 ||
373 control_loops::superstructure_queue.status->state == 16) {
374 LOG(ERROR, "Superstructure no longer running, aborting action\n");
375 return;
376 }
Austin Schuh23b21802016-04-03 21:18:56 -0700377 if (SuperstructureProfileDone()) return;
378 if (control_loops::superstructure_queue.status->shoulder.angle < 0.1) {
379 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000380 }
381 }
382}
Austin Schuh23b21802016-04-03 21:18:56 -0700383void AutonomousActor::BackLongShotLowBarTwoBall() {
384 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700385 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55, {7.0, 40.0}, {4.0, 6.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700386 {10.0, 25.0}, false, 0.0);
387}
388
389void AutonomousActor::BackLongShotTwoBall() {
390 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700391 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55, {7.0, 40.0}, {4.0, 6.0},
392 {10.0, 25.0}, false, 0.0);
393}
394
395void AutonomousActor::BackLongShotTwoBallFinish() {
396 LOG(INFO, "Expanding for back long shot\n");
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000397 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03, {7.0, 40.0},
398 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700399}
400
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700401void AutonomousActor::BackLongShot() {
402 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700403 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 6.0},
404 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700405}
406
407void AutonomousActor::BackMiddleShot() {
408 LOG(INFO, "Expanding for back middle shot\n");
409 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.665, {7.0, 40.0}, {4.0, 10.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700410 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700411}
412
Austin Schuh3e4a5272016-04-20 20:11:00 -0700413void AutonomousActor::FrontLongShot() {
414 LOG(INFO, "Expanding for front long shot\n");
415 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02, {7.0, 40.0},
416 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
417}
418
419void AutonomousActor::FrontMiddleShot() {
420 LOG(INFO, "Expanding for front middle shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700421 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44, {7.0, 40.0},
Austin Schuh3e4a5272016-04-20 20:11:00 -0700422 {4.0, 10.0}, {10.0, 25.0}, true, 0.0);
423}
424
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700425void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
426 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700427 {4.0, 10.0}, {10.0, 25.0}, !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700428}
429
Austin Schuh3e4a5272016-04-20 20:11:00 -0700430void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700431 if (ShouldCancel()) return;
432 // Make sure that the base is aligned with the base.
433 LOG(INFO, "Waiting for the superstructure\n");
434 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700435
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800436 this_thread::sleep_for(chrono::milliseconds(500));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700437
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700438 if (ShouldCancel()) return;
439 LOG(INFO, "Triggering the vision actor\n");
440 AlignWithVisionGoal();
441
442 // Wait for the drive base to be aligned with the target and make sure that
443 // the shooter is up to speed.
444 LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800445 WaitForAlignedWithVision(chrono::milliseconds(2000));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700446 if (ShouldCancel()) return;
447 LOG(INFO, "Waiting for shooter to be up to speed\n");
448 WaitForShooterSpeed();
449 if (ShouldCancel()) return;
450
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800451 this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700452 LOG(INFO, "Shoot!\n");
453 Shoot();
454
455 // Turn off the shooter and fold up the superstructure.
456 if (ShouldCancel()) return;
457 LOG(INFO, "Stopping shooter\n");
458 SetShooterSpeed(0.0);
459 LOG(INFO, "Folding superstructure back down\n");
460 TuckArm(false, false);
461
462 // Wait for everything to be folded up.
463 LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700464 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700465}
466
467void AutonomousActor::LowBarDrive() {
468 TuckArm(false, true);
469 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
470
471 if (!WaitForDriveNear(5.3, 0.0)) return;
472 TuckArm(true, true);
473
474 if (!WaitForDriveNear(5.0, 0.0)) return;
475
476 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
477
478 if (!WaitForDriveNear(3.0, 0.0)) return;
479
480 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
481
482 if (!WaitForDriveNear(1.0, 0.0)) return;
483
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700484 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700485}
486
Austin Schuh3e4a5272016-04-20 20:11:00 -0700487void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
488 double below, double above) {
489 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
490 if (!WaitForBelowAngle(below)) return;
491 if (!WaitForAboveAngle(above)) return;
492 // Ok, we are good now. Compensate by moving the goal by the error.
493 // Should be here at 2.7
494 drivetrain_queue.status.FetchLatest();
495 if (drivetrain_queue.status.get()) {
496 const double left_error =
497 (initial_drivetrain_.left -
498 drivetrain_queue.status->estimated_left_position);
499 const double right_error =
500 (initial_drivetrain_.right -
501 drivetrain_queue.status->estimated_right_position);
502 const double distance_to_go = (left_error + right_error) / 2.0;
503 const double distance_compensation =
504 goal_distance - tip_distance - distance_to_go;
505 LOG(INFO, "Going %f further at the bump\n", distance_compensation);
506 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
507 }
508}
509
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700510void AutonomousActor::MiddleDrive() {
511 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700512 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700513 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700514}
515
516void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700517 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700518 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700519 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700520
521 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700522 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700523}
524
525void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700526 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700527 constexpr double kDriveDistance = 5.10;
528 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
529
530 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
531 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700532
533 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700534 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700535}
Comran Morshedb134e772016-03-16 21:05:05 +0000536
Austin Schuh23b21802016-04-03 21:18:56 -0700537void AutonomousActor::CloseIfBall() {
538 ::y2016::sensors::ball_detector.FetchLatest();
539 if (::y2016::sensors::ball_detector.get()) {
540 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
541 if (ball_detected) {
542 CloseShooter();
543 }
544 }
545}
546
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700547void AutonomousActor::WaitForBallOrDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700548 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
549 ::std::chrono::milliseconds(5) / 2);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700550 while (true) {
551 if (ShouldCancel()) {
552 return;
553 }
554 phased_loop.SleepUntilNext();
555 drivetrain_queue.status.FetchLatest();
556 if (IsDriveDone()) {
557 return;
558 }
559
560 ::y2016::sensors::ball_detector.FetchLatest();
561 if (::y2016::sensors::ball_detector.get()) {
562 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
563 if (ball_detected) {
564 return;
565 }
566 }
567 }
568}
569
Austin Schuh23b21802016-04-03 21:18:56 -0700570void AutonomousActor::WaitForBall() {
571 while (true) {
572 ::y2016::sensors::ball_detector.FetchAnother();
573 if (::y2016::sensors::ball_detector.get()) {
574 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
575 if (ball_detected) {
576 return;
577 }
578 if (ShouldCancel()) return;
579 }
580 }
581}
582
Austin Schuh3e4a5272016-04-20 20:11:00 -0700583void AutonomousActor::TwoBallAuto() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800584 monotonic_clock::time_point start_time = monotonic_clock::now();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700585 OpenShooter();
586 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
587 false, 12.0);
588 if (ShouldCancel()) return;
589 LOG(INFO, "Waiting for the intake to come down.\n");
590
591 WaitForIntake();
592 LOG(INFO, "Intake done at %f seconds, starting to drive\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700593 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700594 if (ShouldCancel()) return;
595 const double kDriveDistance = 5.05;
596 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
597
598 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700599 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700600
Austin Schuh295c2d92016-05-01 12:28:04 -0700601 // Check if the ball is there.
602 bool first_ball_there = true;
603 ::y2016::sensors::ball_detector.FetchLatest();
604 if (::y2016::sensors::ball_detector.get()) {
605 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
606 first_ball_there = ball_detected;
607 LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700608 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh295c2d92016-05-01 12:28:04 -0700609 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700610 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
611 false, 0.0);
612 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700613 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700614 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
615 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
616 false, 0.0);
617 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700618 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700619
620 // We are now under the low bar. Start lifting.
621 BackLongShotLowBarTwoBall();
622 LOG(INFO, "Spinning up the shooter wheels\n");
623 SetShooterSpeed(640.0);
624 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
625
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700626 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
627 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700628 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
629 BackLongShotTwoBall();
630
631 if (!WaitForDriveDone()) return;
632 LOG(INFO, "First shot done driving at %f seconds\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700633 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700634
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700635 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700636
637 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700638 AlignWithVisionGoal();
639
640 WaitForShooterSpeed();
641 if (ShouldCancel()) return;
642
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800643 constexpr chrono::milliseconds kVisionExtra{0};
644 WaitForAlignedWithVision(chrono::milliseconds(500) + kVisionExtra);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700645 BackLongShotTwoBallFinish();
646 WaitForSuperstructureProfile();
647 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700648 LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700649 if (first_ball_there) {
650 Shoot();
651 } else {
652 LOG(INFO, "Nah, not shooting\n");
653 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700654
655 LOG(INFO, "First shot at %f seconds\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700656 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700657 if (ShouldCancel()) return;
658
659 SetShooterSpeed(0.0);
660 LOG(INFO, "Folding superstructure back down\n");
661 TuckArm(true, true);
662
663 // Undo vision move.
664 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
665 if (!WaitForDriveDone()) return;
666
667 constexpr double kBackDrive = 3.09 - 0.4;
668 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700669 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700670 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700671 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
672 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700673
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700674 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700675 LOG(INFO, "At Low Bar %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700676 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700677
678 OpenShooter();
679 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700680 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
681 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700682 constexpr double kBallSmallWallTurn = -0.11;
683 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
684
685 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
686 false, 12.0);
687
688 if (!WaitForDriveProfileDone()) return;
689
690 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
691 false, 12.0);
692
693 LOG(INFO, "Done backing up %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700694 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700695
696 constexpr double kDriveBackDistance = 5.15 - 0.4;
697 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
698 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700699 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700700
701 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
702 LOG(INFO, "Straightening up at %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700703 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700704
705 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700706 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700707
708 ::y2016::sensors::ball_detector.FetchLatest();
709 if (::y2016::sensors::ball_detector.get()) {
710 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
711 if (!ball_detected) {
712 if (!WaitForDriveDone()) return;
713 LOG(INFO, "Aborting, no ball %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700714 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700715 return;
716 }
717 }
718 CloseShooter();
719
720 BackLongShotLowBarTwoBall();
721 LOG(INFO, "Spinning up the shooter wheels\n");
722 SetShooterSpeed(640.0);
723 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
724
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700725 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700726 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
727 BackLongShotTwoBall();
728
729 if (!WaitForDriveDone()) return;
730 LOG(INFO, "Second shot done driving at %f seconds\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700731 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700732 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700733 AlignWithVisionGoal();
734 if (ShouldCancel()) return;
735
736 WaitForShooterSpeed();
737 if (ShouldCancel()) return;
738
739 // 2.2 with 0.4 of vision.
740 // 1.8 without any vision.
741 LOG(INFO, "Going to vision align at %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700742 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800743 WaitForAlignedWithVision(
744 (start_time + chrono::milliseconds(13500) + kVisionExtra * 2) -
745 monotonic_clock::now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700746 BackLongShotTwoBallFinish();
747 WaitForSuperstructureProfile();
748 if (ShouldCancel()) return;
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800749 LOG(INFO, "Shoot at %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700750 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700751 Shoot();
752
753 LOG(INFO, "Second shot at %f seconds\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700754 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700755 if (ShouldCancel()) return;
756
757 SetShooterSpeed(0.0);
758 LOG(INFO, "Folding superstructure back down\n");
759 TuckArm(true, false);
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700760 LOG(INFO, "Shot %f\n",
761 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700762
763 WaitForSuperstructureLow();
764
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700765 LOG(INFO, "Done %f\n",
766 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700767}
768
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700769void AutonomousActor::StealAndMoveOverBy(double distance) {
770 OpenShooter();
771 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
772 true, 12.0);
773 if (ShouldCancel()) return;
774 LOG(INFO, "Waiting for the intake to come down.\n");
775
776 WaitForIntake();
777 if (ShouldCancel()) return;
778 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
779 WaitForBallOrDriveDone();
780 if (ShouldCancel()) return;
781 MoveSuperstructure(1.0, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
782 true, 12.0);
783
784 if (!WaitForDriveDone()) return;
785 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
786 if (!WaitForDriveDone()) return;
787}
788
Philipp Schrader4bd29b12017-02-22 04:42:27 +0000789bool AutonomousActor::RunAction(
790 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800791 monotonic_clock::time_point start_time = monotonic_clock::now();
Comran Morshede68e3732016-03-12 14:12:11 +0000792 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
793
Comran Morshed435f1112016-03-12 14:20:45 +0000794 InitializeEncoders();
795 ResetDrivetrain();
796
Austin Schuh295c2d92016-05-01 12:28:04 -0700797 switch (params.mode) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700798 case 0:
799 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700800 if (!WaitForDriveDone()) return true;
801 // Get the superstructure to unfold and get ready for shooting.
802 LOG(INFO, "Unfolding superstructure\n");
803 FrontLongShot();
804
805 // Spin up the shooter wheels.
806 LOG(INFO, "Spinning up the shooter wheels\n");
807 SetShooterSpeed(640.0);
808
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700809 break;
810 case 1:
811 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700812 if (!WaitForDriveDone()) return true;
813 // Get the superstructure to unfold and get ready for shooting.
814 LOG(INFO, "Unfolding superstructure\n");
815 FrontMiddleShot();
816
817 // Spin up the shooter wheels.
818 LOG(INFO, "Spinning up the shooter wheels\n");
819 SetShooterSpeed(600.0);
820
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700821 break;
822 case 2:
823 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700824 if (!WaitForDriveDone()) return true;
825 // Get the superstructure to unfold and get ready for shooting.
826 LOG(INFO, "Unfolding superstructure\n");
827 FrontMiddleShot();
828
829 // Spin up the shooter wheels.
830 LOG(INFO, "Spinning up the shooter wheels\n");
831 SetShooterSpeed(600.0);
832
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700833 break;
834 case 3:
835 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700836 if (!WaitForDriveDone()) return true;
837 // Get the superstructure to unfold and get ready for shooting.
838 LOG(INFO, "Unfolding superstructure\n");
839 FrontMiddleShot();
840
841 // Spin up the shooter wheels.
842 LOG(INFO, "Spinning up the shooter wheels\n");
843 SetShooterSpeed(600.0);
844
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700845 break;
846 case 4:
847 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700848 if (!WaitForDriveDone()) return true;
849 // Get the superstructure to unfold and get ready for shooting.
850 LOG(INFO, "Unfolding superstructure\n");
851 FrontMiddleShot();
852
853 // Spin up the shooter wheels.
854 LOG(INFO, "Spinning up the shooter wheels\n");
855 SetShooterSpeed(600.0);
856
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700857 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700858 case 5:
Campbell Crowley9ed61a52016-11-05 17:13:07 -0700859 case 15:
Austin Schuh3e4a5272016-04-20 20:11:00 -0700860 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -0700861 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700862 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700863 case 6:
864 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
865 if (ShouldCancel()) return true;
866
867 TwoFromMiddleDrive();
868 if (!WaitForDriveDone()) return true;
869 // Get the superstructure to unfold and get ready for shooting.
870 LOG(INFO, "Unfolding superstructure\n");
871 FrontMiddleShot();
872
873 // Spin up the shooter wheels.
874 LOG(INFO, "Spinning up the shooter wheels\n");
875 SetShooterSpeed(600.0);
876
877 break;
878 case 7:
879 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
880 if (ShouldCancel()) return true;
881
882 OneFromMiddleDrive(true);
883 if (!WaitForDriveDone()) return true;
884 // Get the superstructure to unfold and get ready for shooting.
885 LOG(INFO, "Unfolding superstructure\n");
886 FrontMiddleShot();
887
888 // Spin up the shooter wheels.
889 LOG(INFO, "Spinning up the shooter wheels\n");
890 SetShooterSpeed(600.0);
891
892 break;
893 case 8: {
894 StealAndMoveOverBy(2.95);
895 if (ShouldCancel()) return true;
896
897 MiddleDrive();
898 if (!WaitForDriveDone()) return true;
899 // Get the superstructure to unfold and get ready for shooting.
900 LOG(INFO, "Unfolding superstructure\n");
901 FrontMiddleShot();
902
903 // Spin up the shooter wheels.
904 LOG(INFO, "Spinning up the shooter wheels\n");
905 SetShooterSpeed(600.0);
906
907 } break;
908 case 9: {
909 StealAndMoveOverBy(1.70);
910 if (ShouldCancel()) return true;
911
912 OneFromMiddleDrive(false);
913 if (!WaitForDriveDone()) return true;
914 // Get the superstructure to unfold and get ready for shooting.
915 LOG(INFO, "Unfolding superstructure\n");
916 FrontMiddleShot();
917
918 // Spin up the shooter wheels.
919 LOG(INFO, "Spinning up the shooter wheels\n");
920 SetShooterSpeed(600.0);
921
922 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700923 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -0700924 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700925 return true;
926 }
Comran Morshed435f1112016-03-12 14:20:45 +0000927
Austin Schuh3e4a5272016-04-20 20:11:00 -0700928 DoFullShot();
929
930 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +0000931 if (!WaitForDriveDone()) return true;
932
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700933 LOG(INFO, "Done %f\n",
934 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Comran Morshed435f1112016-03-12 14:20:45 +0000935
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700936 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
937 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700938
Comran Morshed435f1112016-03-12 14:20:45 +0000939 while (!ShouldCancel()) {
940 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +0000941 }
Comran Morshed435f1112016-03-12 14:20:45 +0000942 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +0000943
944 return true;
945}
946
Comran Morshede68e3732016-03-12 14:12:11 +0000947} // namespace actors
948} // namespace y2016