blob: 67bb41a0fe85801891598139030ae3ef43622a62 [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 Schuhf59b8ee2016-03-19 21:31:36 -070015#include "y2016/vision/vision.q.h"
Comran Morshede68e3732016-03-12 14:12:11 +000016
17namespace y2016 {
18namespace actors {
Comran Morshed435f1112016-03-12 14:20:45 +000019using ::frc971::control_loops::drivetrain_queue;
20
21namespace {
Austin Schuhf59b8ee2016-03-19 21:31:36 -070022const ProfileParameters kSlowDrive = {0.8, 2.5};
23const ProfileParameters kLowBarDrive = {1.3, 2.5};
24const ProfileParameters kMoatDrive = {1.2, 3.5};
25const ProfileParameters kRealignDrive = {2.0, 2.5};
26const ProfileParameters kRockWallDrive = {0.8, 2.5};
Comran Morshed435f1112016-03-12 14:20:45 +000027const ProfileParameters kFastDrive = {3.0, 2.5};
28
Austin Schuhf59b8ee2016-03-19 21:31:36 -070029const ProfileParameters kSlowTurn = {0.8, 3.0};
Comran Morshed435f1112016-03-12 14:20:45 +000030const ProfileParameters kFastTurn = {3.0, 10.0};
Austin Schuhf59b8ee2016-03-19 21:31:36 -070031
32const double kDistanceShort = 0.25;
Comran Morshed435f1112016-03-12 14:20:45 +000033} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000034
35AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000036 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000037 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
38 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000039
40void AutonomousActor::ResetDrivetrain() {
41 LOG(INFO, "resetting the drivetrain\n");
42 drivetrain_queue.goal.MakeWithBuilder()
43 .control_loop_driving(false)
44 .highgear(true)
45 .steering(0.0)
46 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000047 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000048 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000049 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000050 .right_velocity_goal(0)
51 .Send();
52}
53
54void AutonomousActor::StartDrive(double distance, double angle,
55 ProfileParameters linear,
56 ProfileParameters angular) {
57 {
58 {
59 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000060 initial_drivetrain_.left += distance - dangle;
61 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000062 }
63
Comran Morshedb134e772016-03-16 21:05:05 +000064 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000065 drivetrain_message->control_loop_driving = true;
66 drivetrain_message->highgear = true;
67 drivetrain_message->steering = 0.0;
68 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000069 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000070 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000071 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000072 drivetrain_message->right_velocity_goal = 0;
73 drivetrain_message->linear = linear;
74 drivetrain_message->angular = angular;
75
76 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
77
78 drivetrain_message.Send();
79 }
80}
81
82void AutonomousActor::InitializeEncoders() {
83 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000084 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
85 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000086}
87
88void AutonomousActor::WaitUntilDoneOrCanceled(
89 ::std::unique_ptr<aos::common::actions::Action> action) {
90 if (!action) {
91 LOG(ERROR, "No action, not waiting\n");
92 return;
93 }
94
95 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
96 ::aos::time::Time::InMS(5) / 2);
97 while (true) {
98 // Poll the running bit and see if we should cancel.
99 phased_loop.SleepUntilNext();
100 if (!action->Running() || ShouldCancel()) {
101 return;
102 }
103 }
104}
105
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700106bool AutonomousActor::WaitForDriveNear(double distance, double angle) {
107 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
108 ::aos::time::Time::InMS(5) / 2);
109 constexpr double kPositionTolerance = 0.02;
110 constexpr double kProfileTolerance = 0.001;
111
112 while (true) {
113 if (ShouldCancel()) {
114 return false;
115 }
116 phased_loop.SleepUntilNext();
117 drivetrain_queue.status.FetchLatest();
118 if (drivetrain_queue.status.get()) {
119 const double left_profile_error =
120 (initial_drivetrain_.left -
121 drivetrain_queue.status->profiled_left_position_goal);
122 const double right_profile_error =
123 (initial_drivetrain_.right -
124 drivetrain_queue.status->profiled_right_position_goal);
125
126 const double left_error =
127 (initial_drivetrain_.left -
128 drivetrain_queue.status->estimated_left_position);
129 const double right_error =
130 (initial_drivetrain_.right -
131 drivetrain_queue.status->estimated_right_position);
132
133 const double profile_distance_to_go =
134 (left_profile_error + right_profile_error) / 2.0;
135 const double profile_angle_to_go =
136 (right_profile_error - left_profile_error) /
137 (dt_config_.robot_radius * 2.0);
138
139 const double distance_to_go = (left_error + right_error) / 2.0;
140 const double angle_to_go =
141 (right_error - left_error) / (dt_config_.robot_radius * 2.0);
142
143 if (::std::abs(profile_distance_to_go) < distance + kProfileTolerance &&
144 ::std::abs(profile_angle_to_go) < angle + kProfileTolerance &&
145 ::std::abs(distance_to_go) < distance + kPositionTolerance &&
146 ::std::abs(angle_to_go) < angle + kPositionTolerance) {
147 LOG(INFO, "Closer than %f distance, %f angle\n", distance, angle);
148 return true;
149 }
150 }
151 }
152}
153
Comran Morshed435f1112016-03-12 14:20:45 +0000154bool AutonomousActor::WaitForDriveDone() {
155 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
156 ::aos::time::Time::InMS(5) / 2);
157 constexpr double kPositionTolerance = 0.02;
158 constexpr double kVelocityTolerance = 0.10;
159 constexpr double kProfileTolerance = 0.001;
160
161 while (true) {
162 if (ShouldCancel()) {
163 return false;
164 }
165 phased_loop.SleepUntilNext();
166 drivetrain_queue.status.FetchLatest();
167 if (drivetrain_queue.status.get()) {
168 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
Comran Morshedb134e772016-03-16 21:05:05 +0000169 initial_drivetrain_.left) < kProfileTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000170 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
Comran Morshedb134e772016-03-16 21:05:05 +0000171 initial_drivetrain_.right) < kProfileTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000172 ::std::abs(drivetrain_queue.status->estimated_left_position -
Comran Morshedb134e772016-03-16 21:05:05 +0000173 initial_drivetrain_.left) < kPositionTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000174 ::std::abs(drivetrain_queue.status->estimated_right_position -
Comran Morshedb134e772016-03-16 21:05:05 +0000175 initial_drivetrain_.right) < kPositionTolerance &&
Comran Morshed435f1112016-03-12 14:20:45 +0000176 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
177 kVelocityTolerance &&
178 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
179 kVelocityTolerance) {
180 LOG(INFO, "Finished drive\n");
181 return true;
182 }
183 }
184 }
185}
Comran Morshede68e3732016-03-12 14:12:11 +0000186
Comran Morshedb134e772016-03-16 21:05:05 +0000187void AutonomousActor::MoveSuperstructure(
188 double intake, double shoulder, double wrist,
189 const ProfileParameters intake_params,
190 const ProfileParameters shoulder_params,
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700191 const ProfileParameters wrist_params, bool traverse_up) {
Comran Morshedb134e772016-03-16 21:05:05 +0000192 superstructure_goal_ = {intake, shoulder, wrist};
193
194 auto new_superstructure_goal =
195 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
196
197 new_superstructure_goal->angle_intake = intake;
198 new_superstructure_goal->angle_shoulder = shoulder;
199 new_superstructure_goal->angle_wrist = wrist;
200
201 new_superstructure_goal->max_angular_velocity_intake =
202 intake_params.max_velocity;
203 new_superstructure_goal->max_angular_velocity_shoulder =
204 shoulder_params.max_velocity;
205 new_superstructure_goal->max_angular_velocity_wrist =
206 wrist_params.max_velocity;
207
208 new_superstructure_goal->max_angular_acceleration_intake =
209 intake_params.max_acceleration;
210 new_superstructure_goal->max_angular_acceleration_shoulder =
211 shoulder_params.max_acceleration;
212 new_superstructure_goal->max_angular_acceleration_wrist =
213 wrist_params.max_acceleration;
214
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700215 new_superstructure_goal->voltage_top_rollers = 0.0;
216 new_superstructure_goal->voltage_bottom_rollers = 0.0;
217
218 new_superstructure_goal->traverse_unlatched = true;
219 new_superstructure_goal->traverse_down = !traverse_up;
Comran Morshedb134e772016-03-16 21:05:05 +0000220
221 if (!new_superstructure_goal.Send()) {
222 LOG(ERROR, "Sending superstructure goal failed.\n");
223 }
224}
225
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700226void AutonomousActor::SetShooterSpeed(double speed) {
227 shooter_speed_ = speed;
228
229 // In auto, we want to have the lights on whenever possible since we have no
230 // hope of a human aligning the robot.
231 bool force_lights_on = shooter_speed_ > 1.0;
232
233 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
234 .angular_velocity(shooter_speed_)
235 .clamp_open(false)
236 .push_to_shooter(false)
237 .force_lights_on(force_lights_on)
238 .Send()) {
239 LOG(ERROR, "Sending shooter goal failed.\n");
240 }
241}
242
243void AutonomousActor::Shoot() {
244 uint32_t initial_shots = 0;
245
246 control_loops::shooter::shooter_queue.status.FetchLatest();
247 if (control_loops::shooter::shooter_queue.status.get()) {
248 initial_shots = control_loops::shooter::shooter_queue.status->shots;
249 }
250
251 // In auto, we want to have the lights on whenever possible since we have no
252 // hope of a human aligning the robot.
253 bool force_lights_on = shooter_speed_ > 1.0;
254
255 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
256 .angular_velocity(shooter_speed_)
257 .clamp_open(false)
258 .push_to_shooter(true)
259 .force_lights_on(force_lights_on)
260 .Send()) {
261 LOG(ERROR, "Sending shooter goal failed.\n");
262 }
263
264 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
265 ::aos::time::Time::InMS(5) / 2);
266 while (true) {
267 if (ShouldCancel()) return;
268
269 // Wait for the shot count to change so we know when the shot is complete.
270 control_loops::shooter::shooter_queue.status.FetchLatest();
271 if (control_loops::shooter::shooter_queue.status.get()) {
272 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
273 return;
274 }
275 }
276 phased_loop.SleepUntilNext();
277 }
278}
279
280void AutonomousActor::WaitForShooterSpeed() {
281 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
282 ::aos::time::Time::InMS(5) / 2);
283 while (true) {
284 if (ShouldCancel()) return;
285
286 control_loops::shooter::shooter_queue.status.FetchLatest();
287 if (control_loops::shooter::shooter_queue.status.get()) {
288 if (control_loops::shooter::shooter_queue.status->left.ready &&
289 control_loops::shooter::shooter_queue.status->right.ready) {
290 return;
291 }
292 }
293 phased_loop.SleepUntilNext();
294 }
295}
296
297void AutonomousActor::AlignWithVisionGoal() {
298 actors::VisionAlignActionParams params;
299 vision_action_ = ::std::move(actors::MakeVisionAlignAction(params));
300 vision_action_->Start();
301}
302
303void AutonomousActor::WaitForAlignedWithVision() {
304 bool vision_valid = false;
305 double last_angle = 0.0;
306 int ready_to_fire = 0;
307
308 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
309 ::aos::time::Time::InMS(5) / 2);
310 ::aos::time::Time end_time =
311 ::aos::time::Time::Now() + aos::time::Time::InSeconds(3);
312 while (end_time > ::aos::time::Time::Now()) {
313 if (ShouldCancel()) break;
314
315 ::y2016::vision::vision_status.FetchLatest();
316 if (::y2016::vision::vision_status.get()) {
317 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
318 ::y2016::vision::vision_status->right_image_valid);
319 last_angle = ::y2016::vision::vision_status->horizontal_angle;
320 }
321
322 drivetrain_queue.status.FetchLatest();
323 drivetrain_queue.goal.FetchLatest();
324
325 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
326 const double left_goal = drivetrain_queue.goal->left_goal;
327 const double right_goal = drivetrain_queue.goal->right_goal;
328 const double left_current =
329 drivetrain_queue.status->estimated_left_position;
330 const double right_current =
331 drivetrain_queue.status->estimated_right_position;
332 const double left_velocity =
333 drivetrain_queue.status->estimated_left_velocity;
334 const double right_velocity =
335 drivetrain_queue.status->estimated_right_velocity;
336
337 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
338 ::std::abs((left_goal - right_goal) -
339 (left_current - right_current)) /
340 dt_config_.robot_radius / 2.0 <
341 0.02 &&
342 ::std::abs(left_velocity - right_velocity) < 0.01) {
343 ++ready_to_fire;
344 } else {
345 ready_to_fire = 0;
346 }
347 if (ready_to_fire > 9) {
348 break;
349 }
350 }
351 phased_loop.SleepUntilNext();
352 }
353
354 vision_action_->Cancel();
355 WaitUntilDoneOrCanceled(::std::move(vision_action_));
356}
357
Comran Morshedb134e772016-03-16 21:05:05 +0000358void AutonomousActor::WaitForSuperstructure() {
359 while (true) {
360 if (ShouldCancel()) return;
361 control_loops::superstructure_queue.status.FetchAnother();
362
363 constexpr double kProfileError = 1e-5;
364 constexpr double kEpsilon = 0.03;
365
366 if (control_loops::superstructure_queue.status->state < 12 ||
367 control_loops::superstructure_queue.status->state == 16) {
368 LOG(ERROR, "Superstructure no longer running, aborting action\n");
369 return;
370 }
371
372 if (::std::abs(
373 control_loops::superstructure_queue.status->intake.goal_angle -
374 superstructure_goal_.intake) < kProfileError &&
375 ::std::abs(
376 control_loops::superstructure_queue.status->shoulder.goal_angle -
377 superstructure_goal_.shoulder) < kProfileError &&
378 ::std::abs(
379 control_loops::superstructure_queue.status->wrist.goal_angle -
380 superstructure_goal_.wrist) < kProfileError &&
381 ::std::abs(control_loops::superstructure_queue.status->intake
382 .goal_angular_velocity) < kProfileError &&
383 ::std::abs(control_loops::superstructure_queue.status->shoulder
384 .goal_angular_velocity) < kProfileError &&
385 ::std::abs(control_loops::superstructure_queue.status->wrist
386 .goal_angular_velocity) < kProfileError) {
387 LOG(INFO, "Profile done.\n");
388 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
389 superstructure_goal_.intake) < kEpsilon &&
390 ::std::abs(
391 control_loops::superstructure_queue.status->shoulder.angle -
392 superstructure_goal_.shoulder) < kEpsilon &&
393 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
394 superstructure_goal_.wrist) < kEpsilon &&
395 ::std::abs(control_loops::superstructure_queue.status->intake
396 .angular_velocity) < kEpsilon &&
397 ::std::abs(control_loops::superstructure_queue.status->shoulder
398 .angular_velocity) < kEpsilon &&
399 ::std::abs(control_loops::superstructure_queue.status->wrist
400 .angular_velocity) < kEpsilon) {
401 LOG(INFO, "Near goal, done.\n");
Austin Schuh1c922402016-03-19 21:41:13 -0700402 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000403 }
404 }
405 }
406}
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700407void AutonomousActor::BackLongShot() {
408 LOG(INFO, "Expanding for back long shot\n");
409 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 10.0},
410 {10.0, 25.0}, false);
411}
412
413void AutonomousActor::BackMiddleShot() {
414 LOG(INFO, "Expanding for back middle shot\n");
415 MoveSuperstructure(-0.05, M_PI / 2.0 - 0.2, -0.665, {7.0, 40.0}, {4.0, 10.0},
416 {10.0, 25.0}, false);
417}
418
419void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
420 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
421 {4.0, 10.0}, {10.0, 25.0}, !traverse_down);
422}
423
424void AutonomousActor::DoFullShot(bool center) {
425 // Get the superstructure to unfold and get ready for shooting.
426 LOG(INFO, "Unfolding superstructure\n");
427 if (center) {
428 BackMiddleShot();
429 } else {
430 BackLongShot();
431 }
432
433 // Spin up the shooter wheels.
434 LOG(INFO, "Spinning up the shooter wheels\n");
435 SetShooterSpeed(640.0);
436
437 if (ShouldCancel()) return;
438 // Make sure that the base is aligned with the base.
439 LOG(INFO, "Waiting for the superstructure\n");
440 WaitForSuperstructure();
441 if (ShouldCancel()) return;
442 LOG(INFO, "Triggering the vision actor\n");
443 AlignWithVisionGoal();
444
445 // Wait for the drive base to be aligned with the target and make sure that
446 // the shooter is up to speed.
447 LOG(INFO, "Waiting for vision to be aligned\n");
448 WaitForAlignedWithVision();
449 if (ShouldCancel()) return;
450 LOG(INFO, "Waiting for shooter to be up to speed\n");
451 WaitForShooterSpeed();
452 if (ShouldCancel()) return;
453
454 LOG(INFO, "Shoot!\n");
455 Shoot();
456
457 // Turn off the shooter and fold up the superstructure.
458 if (ShouldCancel()) return;
459 LOG(INFO, "Stopping shooter\n");
460 SetShooterSpeed(0.0);
461 LOG(INFO, "Folding superstructure back down\n");
462 TuckArm(false, false);
463
464 // Wait for everything to be folded up.
465 LOG(INFO, "Waiting for superstructure to be folded back down\n");
466 WaitForSuperstructure();
467}
468
469void AutonomousActor::LowBarDrive() {
470 TuckArm(false, true);
471 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
472
473 if (!WaitForDriveNear(5.3, 0.0)) return;
474 TuckArm(true, true);
475
476 if (!WaitForDriveNear(5.0, 0.0)) return;
477
478 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
479
480 if (!WaitForDriveNear(3.0, 0.0)) return;
481
482 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
483
484 if (!WaitForDriveNear(1.0, 0.0)) return;
485
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700486 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700487}
488
489void AutonomousActor::MiddleDrive() {
490 TuckArm(false, false);
491 StartDrive(4.7, 0.0, kMoatDrive, kSlowTurn);
492 if (!WaitForDriveDone()) return;
493 StartDrive(0.0, M_PI, kMoatDrive, kFastTurn);
494}
495
496void AutonomousActor::OneFromMiddleDrive(bool left) {
497 const double kTurnAngle = left ? M_PI / 2.0 - 0.40 : (-M_PI / 2.0 + 0.40);
498 const double kFlipTurnAngle =
499 left ? (M_PI - kTurnAngle) : (-M_PI - kTurnAngle);
500 TuckArm(false, false);
501 StartDrive(5.0 - kDistanceShort, 0.0, kMoatDrive, kFastTurn);
502 if (!WaitForDriveDone()) return;
503 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
504 if (!WaitForDriveDone()) return;
505 StartDrive(-1.3, 0.0, kRealignDrive, kFastTurn);
506 if (!WaitForDriveDone()) return;
507 StartDrive(0.0, kFlipTurnAngle, kRealignDrive, kFastTurn);
508
509 if (!WaitForDriveDone()) return;
510 StartDrive(0.3, 0.0, kRealignDrive, kFastTurn);
511}
512
513void AutonomousActor::TwoFromMiddleDrive() {
514 const double kTurnAngle = M_PI / 2.0 - 0.13;
515 TuckArm(false, false);
516 StartDrive(5.0 - kDistanceShort, 0.0, kMoatDrive, kFastTurn);
517 if (!WaitForDriveDone()) return;
518 StartDrive(0.0, kTurnAngle, kMoatDrive, kFastTurn);
519 if (!WaitForDriveDone()) return;
520 StartDrive(-2.6, 0.0, kRealignDrive, kFastTurn);
521 if (!WaitForDriveDone()) return;
522 StartDrive(0.0, M_PI - kTurnAngle, kMoatDrive, kFastTurn);
523
524 if (!WaitForDriveDone()) return;
525 StartDrive(0.3, 0.0, kRealignDrive, kFastTurn);
526}
Comran Morshedb134e772016-03-16 21:05:05 +0000527
Comran Morshede68e3732016-03-12 14:12:11 +0000528bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
529 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
530
Comran Morshed435f1112016-03-12 14:20:45 +0000531 InitializeEncoders();
532 ResetDrivetrain();
533
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700534 int index = 0;
535 switch (index) {
536 case 0:
537 LowBarDrive();
538 break;
539 case 1:
540 TwoFromMiddleDrive();
541 break;
542 case 2:
543 OneFromMiddleDrive(true);
544 break;
545 case 3:
546 MiddleDrive();
547 break;
548 case 4:
549 OneFromMiddleDrive(false);
550 break;
551 default:
552 LOG(ERROR, "Invalid auto index %d\n", index);
553 return true;
554 }
Comran Morshed435f1112016-03-12 14:20:45 +0000555
556 if (!WaitForDriveDone()) return true;
557
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700558 DoFullShot(index != 0);
Comran Morshed435f1112016-03-12 14:20:45 +0000559
560 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
561 ::aos::time::Time::InMS(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700562
Comran Morshed435f1112016-03-12 14:20:45 +0000563 while (!ShouldCancel()) {
564 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +0000565 }
Comran Morshed435f1112016-03-12 14:20:45 +0000566 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +0000567
568 return true;
569}
570
571::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
572 const ::y2016::actors::AutonomousActionParams &params) {
573 return ::std::unique_ptr<AutonomousAction>(
574 new AutonomousAction(&::y2016::actors::autonomous_action, params));
575}
576
577} // namespace actors
578} // namespace y2016