blob: 4d0f92c30c56e436fbaf578f360cbc458e2d00e9 [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
Comran Morshedb134e772016-03-16 21:05:05 +00005#include <cmath>
6
Comran Morshede68e3732016-03-12 14:12:11 +00007#include "aos/common/util/phased_loop.h"
8#include "aos/common/logging/logging.h"
Comran Morshed435f1112016-03-12 14:20:45 +00009
10#include "frc971/control_loops/drivetrain/drivetrain.q.h"
11#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Austin Schuhf59b8ee2016-03-19 21:31:36 -070012#include "y2016/control_loops/shooter/shooter.q.h"
Comran Morshedb134e772016-03-16 21:05:05 +000013#include "y2016/control_loops/superstructure/superstructure.q.h"
14#include "y2016/actors/autonomous_action.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 {
Comran Morshed435f1112016-03-12 14:20:45 +000020using ::frc971::control_loops::drivetrain_queue;
21
22namespace {
Austin Schuhf59b8ee2016-03-19 21:31:36 -070023const ProfileParameters kSlowDrive = {0.8, 2.5};
24const ProfileParameters kLowBarDrive = {1.3, 2.5};
25const ProfileParameters kMoatDrive = {1.2, 3.5};
26const ProfileParameters kRealignDrive = {2.0, 2.5};
27const ProfileParameters kRockWallDrive = {0.8, 2.5};
Comran Morshed435f1112016-03-12 14:20:45 +000028const ProfileParameters kFastDrive = {3.0, 2.5};
29
Austin Schuhf59b8ee2016-03-19 21:31:36 -070030const ProfileParameters kSlowTurn = {0.8, 3.0};
Comran Morshed435f1112016-03-12 14:20:45 +000031const ProfileParameters kFastTurn = {3.0, 10.0};
Austin Schuh23b21802016-04-03 21:18:56 -070032const ProfileParameters kSwerveTurn = {2.0, 7.0};
33const ProfileParameters kFinishTurn = {2.0, 5.0};
34
35const ProfileParameters kTwoBallLowDrive = {1.7, 3.5};
36const ProfileParameters kTwoBallFastDrive = {3.0, 1.5};
37const ProfileParameters kTwoBallReturnDrive = {3.0, 1.9};
38const ProfileParameters kTwoBallBallPickup = {2.0, 1.75};
Austin Schuhf59b8ee2016-03-19 21:31:36 -070039
40const double kDistanceShort = 0.25;
Comran Morshed435f1112016-03-12 14:20:45 +000041} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000042
43AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000044 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000045 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
46 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000047
48void AutonomousActor::ResetDrivetrain() {
49 LOG(INFO, "resetting the drivetrain\n");
50 drivetrain_queue.goal.MakeWithBuilder()
51 .control_loop_driving(false)
52 .highgear(true)
53 .steering(0.0)
54 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000055 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000056 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000057 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000058 .right_velocity_goal(0)
59 .Send();
60}
61
62void AutonomousActor::StartDrive(double distance, double angle,
63 ProfileParameters linear,
64 ProfileParameters angular) {
65 {
Austin Schuh23b21802016-04-03 21:18:56 -070066 LOG(INFO, "Driving distance %f, angle %f\n", distance, angle);
Comran Morshed435f1112016-03-12 14:20:45 +000067 {
68 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000069 initial_drivetrain_.left += distance - dangle;
70 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000071 }
72
Comran Morshedb134e772016-03-16 21:05:05 +000073 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000074 drivetrain_message->control_loop_driving = true;
75 drivetrain_message->highgear = true;
76 drivetrain_message->steering = 0.0;
77 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000078 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000079 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000080 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000081 drivetrain_message->right_velocity_goal = 0;
82 drivetrain_message->linear = linear;
83 drivetrain_message->angular = angular;
84
85 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
86
87 drivetrain_message.Send();
88 }
89}
90
91void AutonomousActor::InitializeEncoders() {
92 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000093 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
94 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000095}
96
97void AutonomousActor::WaitUntilDoneOrCanceled(
98 ::std::unique_ptr<aos::common::actions::Action> action) {
99 if (!action) {
100 LOG(ERROR, "No action, not waiting\n");
101 return;
102 }
103
104 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
105 ::aos::time::Time::InMS(5) / 2);
106 while (true) {
107 // Poll the running bit and see if we should cancel.
108 phased_loop.SleepUntilNext();
109 if (!action->Running() || ShouldCancel()) {
110 return;
111 }
112 }
113}
114
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700115bool AutonomousActor::WaitForDriveNear(double distance, double angle) {
116 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
117 ::aos::time::Time::InMS(5) / 2);
118 constexpr double kPositionTolerance = 0.02;
119 constexpr double kProfileTolerance = 0.001;
120
121 while (true) {
122 if (ShouldCancel()) {
123 return false;
124 }
125 phased_loop.SleepUntilNext();
126 drivetrain_queue.status.FetchLatest();
127 if (drivetrain_queue.status.get()) {
128 const double left_profile_error =
129 (initial_drivetrain_.left -
130 drivetrain_queue.status->profiled_left_position_goal);
131 const double right_profile_error =
132 (initial_drivetrain_.right -
133 drivetrain_queue.status->profiled_right_position_goal);
134
135 const double left_error =
136 (initial_drivetrain_.left -
137 drivetrain_queue.status->estimated_left_position);
138 const double right_error =
139 (initial_drivetrain_.right -
140 drivetrain_queue.status->estimated_right_position);
141
142 const double profile_distance_to_go =
143 (left_profile_error + right_profile_error) / 2.0;
144 const double profile_angle_to_go =
145 (right_profile_error - left_profile_error) /
146 (dt_config_.robot_radius * 2.0);
147
148 const double distance_to_go = (left_error + right_error) / 2.0;
149 const double angle_to_go =
150 (right_error - left_error) / (dt_config_.robot_radius * 2.0);
151
152 if (::std::abs(profile_distance_to_go) < distance + kProfileTolerance &&
153 ::std::abs(profile_angle_to_go) < angle + kProfileTolerance &&
154 ::std::abs(distance_to_go) < distance + kPositionTolerance &&
155 ::std::abs(angle_to_go) < angle + kPositionTolerance) {
156 LOG(INFO, "Closer than %f distance, %f angle\n", distance, angle);
157 return true;
158 }
159 }
160 }
161}
162
Austin Schuh23b21802016-04-03 21:18:56 -0700163bool AutonomousActor::WaitForDriveProfileDone() {
164 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
165 ::aos::time::Time::InMS(5) / 2);
166 constexpr double kProfileTolerance = 0.001;
167
168 while (true) {
169 if (ShouldCancel()) {
170 return false;
171 }
172 phased_loop.SleepUntilNext();
173 drivetrain_queue.status.FetchLatest();
174 if (drivetrain_queue.status.get()) {
175 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
176 initial_drivetrain_.left) < kProfileTolerance &&
177 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
178 initial_drivetrain_.right) < kProfileTolerance) {
179 LOG(INFO, "Finished drive\n");
180 return true;
181 }
182 }
183 }
184}
185
Austin Schuh3e4a5272016-04-20 20:11:00 -0700186bool AutonomousActor::WaitForMaxBy(double angle) {
Comran Morshed435f1112016-03-12 14:20:45 +0000187 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
188 ::aos::time::Time::InMS(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700189 double max_angle = -M_PI;
190 while (true) {
191 if (ShouldCancel()) {
192 return false;
193 }
194 phased_loop.SleepUntilNext();
195 drivetrain_queue.status.FetchLatest();
196 if (IsDriveDone()) {
197 return true;
198 }
199 if (drivetrain_queue.status.get()) {
200 if (drivetrain_queue.status->ground_angle > max_angle) {
201 max_angle = drivetrain_queue.status->ground_angle;
202 }
203 if (drivetrain_queue.status->ground_angle < max_angle - angle) {
204 return true;
205 }
206 }
207 }
208}
209
210bool AutonomousActor::WaitForAboveAngle(double angle) {
211 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
212 ::aos::time::Time::InMS(5) / 2);
213 while (true) {
214 if (ShouldCancel()) {
215 return false;
216 }
217 phased_loop.SleepUntilNext();
218 drivetrain_queue.status.FetchLatest();
219 if (IsDriveDone()) {
220 return true;
221 }
222 if (drivetrain_queue.status.get()) {
223 if (drivetrain_queue.status->ground_angle > angle) {
224 return true;
225 }
226 }
227 }
228}
229
230bool AutonomousActor::WaitForBelowAngle(double angle) {
231 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
232 ::aos::time::Time::InMS(5) / 2);
233 while (true) {
234 if (ShouldCancel()) {
235 return false;
236 }
237 phased_loop.SleepUntilNext();
238 drivetrain_queue.status.FetchLatest();
239 if (IsDriveDone()) {
240 return true;
241 }
242 if (drivetrain_queue.status.get()) {
243 if (drivetrain_queue.status->ground_angle < angle) {
244 return true;
245 }
246 }
247 }
248}
249
250bool AutonomousActor::IsDriveDone() {
Comran Morshed435f1112016-03-12 14:20:45 +0000251 constexpr double kPositionTolerance = 0.02;
252 constexpr double kVelocityTolerance = 0.10;
253 constexpr double kProfileTolerance = 0.001;
254
Austin Schuh3e4a5272016-04-20 20:11:00 -0700255 if (drivetrain_queue.status.get()) {
256 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
257 initial_drivetrain_.left) < kProfileTolerance &&
258 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
259 initial_drivetrain_.right) < kProfileTolerance &&
260 ::std::abs(drivetrain_queue.status->estimated_left_position -
261 initial_drivetrain_.left) < kPositionTolerance &&
262 ::std::abs(drivetrain_queue.status->estimated_right_position -
263 initial_drivetrain_.right) < kPositionTolerance &&
264 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
265 kVelocityTolerance &&
266 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
267 kVelocityTolerance) {
268 LOG(INFO, "Finished drive\n");
269 return true;
270 }
271 }
272 return false;
273}
274
275bool AutonomousActor::WaitForDriveDone() {
276 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
277 ::aos::time::Time::InMS(5) / 2);
278
Comran Morshed435f1112016-03-12 14:20:45 +0000279 while (true) {
280 if (ShouldCancel()) {
281 return false;
282 }
283 phased_loop.SleepUntilNext();
284 drivetrain_queue.status.FetchLatest();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700285 if (IsDriveDone()) {
286 return true;
Comran Morshed435f1112016-03-12 14:20:45 +0000287 }
288 }
289}
Comran Morshede68e3732016-03-12 14:12:11 +0000290
Comran Morshedb134e772016-03-16 21:05:05 +0000291void AutonomousActor::MoveSuperstructure(
292 double intake, double shoulder, double wrist,
293 const ProfileParameters intake_params,
294 const ProfileParameters shoulder_params,
Austin Schuh23b21802016-04-03 21:18:56 -0700295 const ProfileParameters wrist_params, bool traverse_up,
296 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +0000297 superstructure_goal_ = {intake, shoulder, wrist};
298
299 auto new_superstructure_goal =
300 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
301
302 new_superstructure_goal->angle_intake = intake;
303 new_superstructure_goal->angle_shoulder = shoulder;
304 new_superstructure_goal->angle_wrist = wrist;
305
306 new_superstructure_goal->max_angular_velocity_intake =
307 intake_params.max_velocity;
308 new_superstructure_goal->max_angular_velocity_shoulder =
309 shoulder_params.max_velocity;
310 new_superstructure_goal->max_angular_velocity_wrist =
311 wrist_params.max_velocity;
312
313 new_superstructure_goal->max_angular_acceleration_intake =
314 intake_params.max_acceleration;
315 new_superstructure_goal->max_angular_acceleration_shoulder =
316 shoulder_params.max_acceleration;
317 new_superstructure_goal->max_angular_acceleration_wrist =
318 wrist_params.max_acceleration;
319
Austin Schuh23b21802016-04-03 21:18:56 -0700320 new_superstructure_goal->voltage_top_rollers = roller_power;
321 new_superstructure_goal->voltage_bottom_rollers = roller_power;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700322
323 new_superstructure_goal->traverse_unlatched = true;
324 new_superstructure_goal->traverse_down = !traverse_up;
Diana Vandenberg9cc9ab62016-04-20 21:27:47 -0700325 new_superstructure_goal->voltage_climber = 0.0;
326 new_superstructure_goal->unfold_climber = false;
Comran Morshedb134e772016-03-16 21:05:05 +0000327
328 if (!new_superstructure_goal.Send()) {
329 LOG(ERROR, "Sending superstructure goal failed.\n");
330 }
331}
332
Austin Schuh23b21802016-04-03 21:18:56 -0700333void AutonomousActor::OpenShooter() {
334 shooter_speed_ = 0.0;
335
336 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
337 .angular_velocity(shooter_speed_)
338 .clamp_open(true)
339 .push_to_shooter(false)
340 .force_lights_on(false)
341 .Send()) {
342 LOG(ERROR, "Sending shooter goal failed.\n");
343 }
344}
345
346void AutonomousActor::CloseShooter() {
347 shooter_speed_ = 0.0;
348
349 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
350 .angular_velocity(shooter_speed_)
351 .clamp_open(false)
352 .push_to_shooter(false)
353 .force_lights_on(false)
354 .Send()) {
355 LOG(ERROR, "Sending shooter goal failed.\n");
356 }
357}
358
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700359void AutonomousActor::SetShooterSpeed(double speed) {
360 shooter_speed_ = speed;
361
362 // In auto, we want to have the lights on whenever possible since we have no
363 // hope of a human aligning the robot.
364 bool force_lights_on = shooter_speed_ > 1.0;
365
366 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
367 .angular_velocity(shooter_speed_)
368 .clamp_open(false)
369 .push_to_shooter(false)
370 .force_lights_on(force_lights_on)
371 .Send()) {
372 LOG(ERROR, "Sending shooter goal failed.\n");
373 }
374}
375
376void AutonomousActor::Shoot() {
377 uint32_t initial_shots = 0;
378
379 control_loops::shooter::shooter_queue.status.FetchLatest();
380 if (control_loops::shooter::shooter_queue.status.get()) {
381 initial_shots = control_loops::shooter::shooter_queue.status->shots;
382 }
383
384 // In auto, we want to have the lights on whenever possible since we have no
385 // hope of a human aligning the robot.
386 bool force_lights_on = shooter_speed_ > 1.0;
387
388 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
389 .angular_velocity(shooter_speed_)
390 .clamp_open(false)
391 .push_to_shooter(true)
392 .force_lights_on(force_lights_on)
393 .Send()) {
394 LOG(ERROR, "Sending shooter goal failed.\n");
395 }
396
397 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
398 ::aos::time::Time::InMS(5) / 2);
399 while (true) {
400 if (ShouldCancel()) return;
401
402 // Wait for the shot count to change so we know when the shot is complete.
403 control_loops::shooter::shooter_queue.status.FetchLatest();
404 if (control_loops::shooter::shooter_queue.status.get()) {
405 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
406 return;
407 }
408 }
409 phased_loop.SleepUntilNext();
410 }
411}
412
413void AutonomousActor::WaitForShooterSpeed() {
414 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
415 ::aos::time::Time::InMS(5) / 2);
416 while (true) {
417 if (ShouldCancel()) return;
418
419 control_loops::shooter::shooter_queue.status.FetchLatest();
420 if (control_loops::shooter::shooter_queue.status.get()) {
421 if (control_loops::shooter::shooter_queue.status->left.ready &&
422 control_loops::shooter::shooter_queue.status->right.ready) {
423 return;
424 }
425 }
426 phased_loop.SleepUntilNext();
427 }
428}
429
430void AutonomousActor::AlignWithVisionGoal() {
431 actors::VisionAlignActionParams params;
432 vision_action_ = ::std::move(actors::MakeVisionAlignAction(params));
433 vision_action_->Start();
434}
435
Austin Schuh23b21802016-04-03 21:18:56 -0700436void AutonomousActor::WaitForAlignedWithVision(
437 ::aos::time::Time align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700438 bool vision_valid = false;
439 double last_angle = 0.0;
440 int ready_to_fire = 0;
441
442 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
443 ::aos::time::Time::InMS(5) / 2);
444 ::aos::time::Time end_time =
Austin Schuh23b21802016-04-03 21:18:56 -0700445 ::aos::time::Time::Now() + align_duration;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700446 while (end_time > ::aos::time::Time::Now()) {
447 if (ShouldCancel()) break;
448
449 ::y2016::vision::vision_status.FetchLatest();
450 if (::y2016::vision::vision_status.get()) {
451 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
452 ::y2016::vision::vision_status->right_image_valid);
453 last_angle = ::y2016::vision::vision_status->horizontal_angle;
454 }
455
456 drivetrain_queue.status.FetchLatest();
457 drivetrain_queue.goal.FetchLatest();
458
459 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
460 const double left_goal = drivetrain_queue.goal->left_goal;
461 const double right_goal = drivetrain_queue.goal->right_goal;
462 const double left_current =
463 drivetrain_queue.status->estimated_left_position;
464 const double right_current =
465 drivetrain_queue.status->estimated_right_position;
466 const double left_velocity =
467 drivetrain_queue.status->estimated_left_velocity;
468 const double right_velocity =
469 drivetrain_queue.status->estimated_right_velocity;
470
471 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
472 ::std::abs((left_goal - right_goal) -
473 (left_current - right_current)) /
474 dt_config_.robot_radius / 2.0 <
475 0.02 &&
476 ::std::abs(left_velocity - right_velocity) < 0.01) {
477 ++ready_to_fire;
478 } else {
479 ready_to_fire = 0;
480 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700481 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700482 break;
Austin Schuh23b21802016-04-03 21:18:56 -0700483 LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700484 }
485 }
486 phased_loop.SleepUntilNext();
487 }
488
489 vision_action_->Cancel();
490 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuh23b21802016-04-03 21:18:56 -0700491 LOG(INFO, "Done waiting for vision\n");
492}
493
494bool AutonomousActor::IntakeDone() {
495 control_loops::superstructure_queue.status.FetchAnother();
496
497 constexpr double kProfileError = 1e-5;
498 constexpr double kEpsilon = 0.15;
499
500 if (control_loops::superstructure_queue.status->state < 12 ||
501 control_loops::superstructure_queue.status->state == 16) {
502 LOG(ERROR, "Superstructure no longer running, aborting action\n");
503 return true;
504 }
505
506 if (::std::abs(control_loops::superstructure_queue.status->intake.goal_angle -
507 superstructure_goal_.intake) < kProfileError &&
508 ::std::abs(control_loops::superstructure_queue.status->intake
509 .goal_angular_velocity) < kProfileError) {
510 LOG(DEBUG, "Profile done.\n");
511 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
512 superstructure_goal_.intake) < kEpsilon &&
513 ::std::abs(control_loops::superstructure_queue.status->intake
514 .angular_velocity) < kEpsilon) {
515 LOG(INFO, "Near goal, done.\n");
516 return true;
517 }
518 }
519 return false;
520}
521
522bool AutonomousActor::SuperstructureProfileDone() {
523 constexpr double kProfileError = 1e-5;
524 return ::std::abs(
525 control_loops::superstructure_queue.status->intake.goal_angle -
526 superstructure_goal_.intake) < kProfileError &&
527 ::std::abs(
528 control_loops::superstructure_queue.status->shoulder.goal_angle -
529 superstructure_goal_.shoulder) < kProfileError &&
530 ::std::abs(
531 control_loops::superstructure_queue.status->wrist.goal_angle -
532 superstructure_goal_.wrist) < kProfileError &&
533 ::std::abs(control_loops::superstructure_queue.status->intake
534 .goal_angular_velocity) < kProfileError &&
535 ::std::abs(control_loops::superstructure_queue.status->shoulder
536 .goal_angular_velocity) < kProfileError &&
537 ::std::abs(control_loops::superstructure_queue.status->wrist
538 .goal_angular_velocity) < kProfileError;
539}
540
541bool AutonomousActor::SuperstructureDone() {
542 control_loops::superstructure_queue.status.FetchAnother();
543
544 constexpr double kEpsilon = 0.03;
545
546 if (control_loops::superstructure_queue.status->state < 12 ||
547 control_loops::superstructure_queue.status->state == 16) {
548 LOG(ERROR, "Superstructure no longer running, aborting action\n");
549 return true;
550 }
551
552 if (SuperstructureProfileDone()) {
553 LOG(DEBUG, "Profile done.\n");
554 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
555 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
556 ::std::abs(control_loops::superstructure_queue.status->shoulder.angle -
557 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
558 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
559 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
560 ::std::abs(control_loops::superstructure_queue.status->intake
561 .angular_velocity) < (kEpsilon + 0.1) &&
562 ::std::abs(control_loops::superstructure_queue.status->shoulder
563 .angular_velocity) < (kEpsilon + 0.10) &&
564 ::std::abs(control_loops::superstructure_queue.status->wrist
565 .angular_velocity) < (kEpsilon + 0.05)) {
566 LOG(INFO, "Near goal, done.\n");
567 return true;
568 }
569 }
570 return false;
571}
572
573void AutonomousActor::WaitForIntake() {
574 while (true) {
575 if (ShouldCancel()) return;
576 if (IntakeDone()) return;
577 }
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700578}
579
Comran Morshedb134e772016-03-16 21:05:05 +0000580void AutonomousActor::WaitForSuperstructure() {
581 while (true) {
582 if (ShouldCancel()) return;
Austin Schuh23b21802016-04-03 21:18:56 -0700583 if (SuperstructureDone()) return;
584 }
585}
Comran Morshedb134e772016-03-16 21:05:05 +0000586
Austin Schuh23b21802016-04-03 21:18:56 -0700587void AutonomousActor::WaitForSuperstructureLow() {
588 while (true) {
589 if (ShouldCancel()) return;
590 control_loops::superstructure_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +0000591
592 if (control_loops::superstructure_queue.status->state < 12 ||
593 control_loops::superstructure_queue.status->state == 16) {
594 LOG(ERROR, "Superstructure no longer running, aborting action\n");
595 return;
596 }
Austin Schuh23b21802016-04-03 21:18:56 -0700597 if (SuperstructureProfileDone()) return;
598 if (control_loops::superstructure_queue.status->shoulder.angle < 0.1) {
599 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000600 }
601 }
602}
Austin Schuh23b21802016-04-03 21:18:56 -0700603void AutonomousActor::BackLongShotLowBarTwoBall() {
604 LOG(INFO, "Expanding for back long shot\n");
605 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625, {7.0, 40.0}, {4.0, 6.0},
606 {10.0, 25.0}, false, 0.0);
607}
608
609void AutonomousActor::BackLongShotTwoBall() {
610 LOG(INFO, "Expanding for back long shot\n");
611 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.625, {7.0, 40.0}, {4.0, 6.0},
612 {10.0, 25.0}, false, 0.0);
613}
614
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700615void AutonomousActor::BackLongShot() {
616 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700617 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 6.0},
618 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700619}
620
621void AutonomousActor::BackMiddleShot() {
622 LOG(INFO, "Expanding for back middle shot\n");
623 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 -0700624 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700625}
626
Austin Schuh3e4a5272016-04-20 20:11:00 -0700627void AutonomousActor::FrontLongShot() {
628 LOG(INFO, "Expanding for front long shot\n");
629 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02, {7.0, 40.0},
630 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
631}
632
633void AutonomousActor::FrontMiddleShot() {
634 LOG(INFO, "Expanding for front middle shot\n");
635 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.42, {7.0, 40.0},
636 {4.0, 10.0}, {10.0, 25.0}, true, 0.0);
637}
638
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700639void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
640 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700641 {4.0, 10.0}, {10.0, 25.0}, !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700642}
643
Austin Schuh3e4a5272016-04-20 20:11:00 -0700644void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700645 if (ShouldCancel()) return;
646 // Make sure that the base is aligned with the base.
647 LOG(INFO, "Waiting for the superstructure\n");
648 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700649
650 ::aos::time::SleepFor(::aos::time::Time::InSeconds(1.5));
651
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700652 if (ShouldCancel()) return;
653 LOG(INFO, "Triggering the vision actor\n");
654 AlignWithVisionGoal();
655
656 // Wait for the drive base to be aligned with the target and make sure that
657 // the shooter is up to speed.
658 LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700659 WaitForAlignedWithVision(aos::time::Time::InSeconds(3));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700660 if (ShouldCancel()) return;
661 LOG(INFO, "Waiting for shooter to be up to speed\n");
662 WaitForShooterSpeed();
663 if (ShouldCancel()) return;
664
Austin Schuh3e4a5272016-04-20 20:11:00 -0700665 ::aos::time::SleepFor(::aos::time::Time::InSeconds(1.0));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700666 LOG(INFO, "Shoot!\n");
667 Shoot();
668
669 // Turn off the shooter and fold up the superstructure.
670 if (ShouldCancel()) return;
671 LOG(INFO, "Stopping shooter\n");
672 SetShooterSpeed(0.0);
673 LOG(INFO, "Folding superstructure back down\n");
674 TuckArm(false, false);
675
676 // Wait for everything to be folded up.
677 LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700678 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700679}
680
681void AutonomousActor::LowBarDrive() {
682 TuckArm(false, true);
683 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
684
685 if (!WaitForDriveNear(5.3, 0.0)) return;
686 TuckArm(true, true);
687
688 if (!WaitForDriveNear(5.0, 0.0)) return;
689
690 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
691
692 if (!WaitForDriveNear(3.0, 0.0)) return;
693
694 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
695
696 if (!WaitForDriveNear(1.0, 0.0)) return;
697
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700698 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700699}
700
Austin Schuh3e4a5272016-04-20 20:11:00 -0700701void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
702 double below, double above) {
703 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
704 if (!WaitForBelowAngle(below)) return;
705 if (!WaitForAboveAngle(above)) return;
706 // Ok, we are good now. Compensate by moving the goal by the error.
707 // Should be here at 2.7
708 drivetrain_queue.status.FetchLatest();
709 if (drivetrain_queue.status.get()) {
710 const double left_error =
711 (initial_drivetrain_.left -
712 drivetrain_queue.status->estimated_left_position);
713 const double right_error =
714 (initial_drivetrain_.right -
715 drivetrain_queue.status->estimated_right_position);
716 const double distance_to_go = (left_error + right_error) / 2.0;
717 const double distance_compensation =
718 goal_distance - tip_distance - distance_to_go;
719 LOG(INFO, "Going %f further at the bump\n", distance_compensation);
720 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
721 }
722}
723
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700724void AutonomousActor::MiddleDrive() {
725 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700726 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700727 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700728}
729
730void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700731 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700732 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700733 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700734
735 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700736 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700737}
738
739void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700740 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700741 constexpr double kDriveDistance = 5.10;
742 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
743
744 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
745 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700746
747 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700748 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700749}
Comran Morshedb134e772016-03-16 21:05:05 +0000750
Austin Schuh23b21802016-04-03 21:18:56 -0700751void AutonomousActor::CloseIfBall() {
752 ::y2016::sensors::ball_detector.FetchLatest();
753 if (::y2016::sensors::ball_detector.get()) {
754 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
755 if (ball_detected) {
756 CloseShooter();
757 }
758 }
759}
760
761void AutonomousActor::WaitForBall() {
762 while (true) {
763 ::y2016::sensors::ball_detector.FetchAnother();
764 if (::y2016::sensors::ball_detector.get()) {
765 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
766 if (ball_detected) {
767 return;
768 }
769 if (ShouldCancel()) return;
770 }
771 }
772}
773
Austin Schuh3e4a5272016-04-20 20:11:00 -0700774void AutonomousActor::TwoBallAuto() {
775 aos::time::Time start_time = aos::time::Time::Now();
776 OpenShooter();
777 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
778 false, 12.0);
779 if (ShouldCancel()) return;
780 LOG(INFO, "Waiting for the intake to come down.\n");
781
782 WaitForIntake();
783 LOG(INFO, "Intake done at %f seconds, starting to drive\n",
784 (aos::time::Time::Now() - start_time).ToSeconds());
785 if (ShouldCancel()) return;
786 const double kDriveDistance = 5.05;
787 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
788
789 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
790 if (!WaitForDriveNear(kDriveDistance - 0.5, 0.0)) return;
791
792 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
793 false, 0.0);
794 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
795 (aos::time::Time::Now() - start_time).ToSeconds());
796 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
797 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
798 false, 0.0);
799 CloseShooter();
800 if (!WaitForDriveNear(kDriveDistance - 2.4, 0.0)) return;
801
802 // We are now under the low bar. Start lifting.
803 BackLongShotLowBarTwoBall();
804 LOG(INFO, "Spinning up the shooter wheels\n");
805 SetShooterSpeed(640.0);
806 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
807
808 if (!WaitForDriveNear(1.50, 0.0)) return;
809 constexpr double kShootTurnAngle = -M_PI / 4.0 + 0.05;
810 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
811 BackLongShotTwoBall();
812
813 if (!WaitForDriveDone()) return;
814 LOG(INFO, "First shot done driving at %f seconds\n",
815 (aos::time::Time::Now() - start_time).ToSeconds());
816
817 WaitForSuperstructure();
818
819 if (ShouldCancel()) return;
820 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.1));
821 AlignWithVisionGoal();
822
823 WaitForShooterSpeed();
824 if (ShouldCancel()) return;
825
826 WaitForAlignedWithVision(aos::time::Time::InSeconds(0.2));
827 LOG(INFO, "Shoot!\n");
828 Shoot();
829
830 LOG(INFO, "First shot at %f seconds\n",
831 (aos::time::Time::Now() - start_time).ToSeconds());
832 if (ShouldCancel()) return;
833
834 SetShooterSpeed(0.0);
835 LOG(INFO, "Folding superstructure back down\n");
836 TuckArm(true, true);
837
838 // Undo vision move.
839 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
840 if (!WaitForDriveDone()) return;
841
842 constexpr double kBackDrive = 3.09 - 0.4;
843 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
844 if (!WaitForDriveNear(kBackDrive - 0.19, 0.0)) return;
845 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
846
847 if (!WaitForDriveNear(0.06, 0.0)) return;
848 LOG(INFO, "At Low Bar %f\n",
849 (aos::time::Time::Now() - start_time).ToSeconds());
850
851 OpenShooter();
852 constexpr double kSecondBallAfterBarDrive = 2.10;
853 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickup, kSlowTurn);
854 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, 0.0)) return;
855 constexpr double kBallSmallWallTurn = -0.11;
856 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
857
858 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
859 false, 12.0);
860
861 if (!WaitForDriveProfileDone()) return;
862
863 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
864 false, 12.0);
865
866 LOG(INFO, "Done backing up %f\n",
867 (aos::time::Time::Now() - start_time).ToSeconds());
868
869 constexpr double kDriveBackDistance = 5.15 - 0.4;
870 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
871 CloseIfBall();
872 if (!WaitForDriveNear(kDriveBackDistance - 0.75, 0.0)) return;
873
874 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
875 LOG(INFO, "Straightening up at %f\n",
876 (aos::time::Time::Now() - start_time).ToSeconds());
877
878 CloseIfBall();
879 if (!WaitForDriveNear(kDriveBackDistance - 2.3, 0.0)) return;
880
881 ::y2016::sensors::ball_detector.FetchLatest();
882 if (::y2016::sensors::ball_detector.get()) {
883 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
884 if (!ball_detected) {
885 if (!WaitForDriveDone()) return;
886 LOG(INFO, "Aborting, no ball %f\n",
887 (aos::time::Time::Now() - start_time).ToSeconds());
888 return;
889 }
890 }
891 CloseShooter();
892
893 BackLongShotLowBarTwoBall();
894 LOG(INFO, "Spinning up the shooter wheels\n");
895 SetShooterSpeed(640.0);
896 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
897
898 if (!WaitForDriveNear(1.80, 0.0)) return;
899 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
900 BackLongShotTwoBall();
901
902 if (!WaitForDriveDone()) return;
903 LOG(INFO, "Second shot done driving at %f seconds\n",
904 (aos::time::Time::Now() - start_time).ToSeconds());
905 WaitForSuperstructure();
906 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.1));
907 AlignWithVisionGoal();
908 if (ShouldCancel()) return;
909
910 WaitForShooterSpeed();
911 if (ShouldCancel()) return;
912
913 // 2.2 with 0.4 of vision.
914 // 1.8 without any vision.
915 LOG(INFO, "Going to vision align at %f\n",
916 (aos::time::Time::Now() - start_time).ToSeconds());
917 WaitForAlignedWithVision(start_time + aos::time::Time::InSeconds(13.1) -
918 aos::time::Time::Now());
919 LOG(INFO, "Shoot at %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
920 Shoot();
921
922 LOG(INFO, "Second shot at %f seconds\n",
923 (aos::time::Time::Now() - start_time).ToSeconds());
924 if (ShouldCancel()) return;
925
926 SetShooterSpeed(0.0);
927 LOG(INFO, "Folding superstructure back down\n");
928 TuckArm(true, false);
929 LOG(INFO, "Shot %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
930
931 WaitForSuperstructureLow();
932
933 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
934}
935
Comran Morshede68e3732016-03-12 14:12:11 +0000936bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700937 aos::time::Time start_time = aos::time::Time::Now();
Comran Morshede68e3732016-03-12 14:12:11 +0000938 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
939
Comran Morshed435f1112016-03-12 14:20:45 +0000940 InitializeEncoders();
941 ResetDrivetrain();
942
Austin Schuh3e4a5272016-04-20 20:11:00 -0700943 switch (1) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700944 case 0:
945 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700946 if (!WaitForDriveDone()) return true;
947 // Get the superstructure to unfold and get ready for shooting.
948 LOG(INFO, "Unfolding superstructure\n");
949 FrontLongShot();
950
951 // Spin up the shooter wheels.
952 LOG(INFO, "Spinning up the shooter wheels\n");
953 SetShooterSpeed(640.0);
954
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700955 break;
956 case 1:
957 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700958 if (!WaitForDriveDone()) return true;
959 // Get the superstructure to unfold and get ready for shooting.
960 LOG(INFO, "Unfolding superstructure\n");
961 FrontMiddleShot();
962
963 // Spin up the shooter wheels.
964 LOG(INFO, "Spinning up the shooter wheels\n");
965 SetShooterSpeed(600.0);
966
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700967 break;
968 case 2:
969 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700970 if (!WaitForDriveDone()) return true;
971 // Get the superstructure to unfold and get ready for shooting.
972 LOG(INFO, "Unfolding superstructure\n");
973 FrontMiddleShot();
974
975 // Spin up the shooter wheels.
976 LOG(INFO, "Spinning up the shooter wheels\n");
977 SetShooterSpeed(600.0);
978
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700979 break;
980 case 3:
981 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700982 if (!WaitForDriveDone()) return true;
983 // Get the superstructure to unfold and get ready for shooting.
984 LOG(INFO, "Unfolding superstructure\n");
985 FrontMiddleShot();
986
987 // Spin up the shooter wheels.
988 LOG(INFO, "Spinning up the shooter wheels\n");
989 SetShooterSpeed(600.0);
990
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700991 break;
992 case 4:
993 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700994 if (!WaitForDriveDone()) return true;
995 // Get the superstructure to unfold and get ready for shooting.
996 LOG(INFO, "Unfolding superstructure\n");
997 FrontMiddleShot();
998
999 // Spin up the shooter wheels.
1000 LOG(INFO, "Spinning up the shooter wheels\n");
1001 SetShooterSpeed(600.0);
1002
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001003 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001004 case 5:
1005 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -07001006 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001007 break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001008 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -07001009 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001010 return true;
1011 }
Comran Morshed435f1112016-03-12 14:20:45 +00001012
Austin Schuh3e4a5272016-04-20 20:11:00 -07001013 DoFullShot();
1014
1015 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +00001016 if (!WaitForDriveDone()) return true;
1017
Austin Schuh3e4a5272016-04-20 20:11:00 -07001018 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
Comran Morshed435f1112016-03-12 14:20:45 +00001019
1020 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
1021 ::aos::time::Time::InMS(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001022
Comran Morshed435f1112016-03-12 14:20:45 +00001023 while (!ShouldCancel()) {
1024 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +00001025 }
Comran Morshed435f1112016-03-12 14:20:45 +00001026 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +00001027
1028 return true;
1029}
1030
1031::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
1032 const ::y2016::actors::AutonomousActionParams &params) {
1033 return ::std::unique_ptr<AutonomousAction>(
1034 new AutonomousAction(&::y2016::actors::autonomous_action, params));
1035}
1036
1037} // namespace actors
1038} // namespace y2016