blob: 680ec548fd3cf1e42e61f9f667891c6cf6e9d50e [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 Schuhe4ec49c2016-04-24 19:07:15 -070032const ProfileParameters kStealTurn = {4.0, 15.0};
Austin Schuh23b21802016-04-03 21:18:56 -070033const ProfileParameters kSwerveTurn = {2.0, 7.0};
34const ProfileParameters kFinishTurn = {2.0, 5.0};
35
36const ProfileParameters kTwoBallLowDrive = {1.7, 3.5};
37const ProfileParameters kTwoBallFastDrive = {3.0, 1.5};
38const ProfileParameters kTwoBallReturnDrive = {3.0, 1.9};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070039const ProfileParameters kTwoBallReturnSlow = {3.0, 2.5};
Austin Schuh23b21802016-04-03 21:18:56 -070040const ProfileParameters kTwoBallBallPickup = {2.0, 1.75};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070041const ProfileParameters kTwoBallBallPickupAccel = {2.0, 2.5};
Austin Schuhf59b8ee2016-03-19 21:31:36 -070042
43const double kDistanceShort = 0.25;
Comran Morshed435f1112016-03-12 14:20:45 +000044} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000045
46AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000047 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000048 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
49 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000050
51void AutonomousActor::ResetDrivetrain() {
52 LOG(INFO, "resetting the drivetrain\n");
53 drivetrain_queue.goal.MakeWithBuilder()
54 .control_loop_driving(false)
55 .highgear(true)
56 .steering(0.0)
57 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000058 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000059 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000060 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000061 .right_velocity_goal(0)
62 .Send();
63}
64
65void AutonomousActor::StartDrive(double distance, double angle,
66 ProfileParameters linear,
67 ProfileParameters angular) {
68 {
Austin Schuh23b21802016-04-03 21:18:56 -070069 LOG(INFO, "Driving distance %f, angle %f\n", distance, angle);
Comran Morshed435f1112016-03-12 14:20:45 +000070 {
71 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000072 initial_drivetrain_.left += distance - dangle;
73 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000074 }
75
Comran Morshedb134e772016-03-16 21:05:05 +000076 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000077 drivetrain_message->control_loop_driving = true;
78 drivetrain_message->highgear = true;
79 drivetrain_message->steering = 0.0;
80 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000081 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000082 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000083 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000084 drivetrain_message->right_velocity_goal = 0;
85 drivetrain_message->linear = linear;
86 drivetrain_message->angular = angular;
87
88 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
89
90 drivetrain_message.Send();
91 }
92}
93
94void AutonomousActor::InitializeEncoders() {
95 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000096 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
97 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000098}
99
100void AutonomousActor::WaitUntilDoneOrCanceled(
101 ::std::unique_ptr<aos::common::actions::Action> action) {
102 if (!action) {
103 LOG(ERROR, "No action, not waiting\n");
104 return;
105 }
106
107 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
108 ::aos::time::Time::InMS(5) / 2);
109 while (true) {
110 // Poll the running bit and see if we should cancel.
111 phased_loop.SleepUntilNext();
112 if (!action->Running() || ShouldCancel()) {
113 return;
114 }
115 }
116}
117
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700118constexpr double kDoNotTurnCare = 2.0;
119
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700120bool AutonomousActor::WaitForDriveNear(double distance, double angle) {
121 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
122 ::aos::time::Time::InMS(5) / 2);
123 constexpr double kPositionTolerance = 0.02;
124 constexpr double kProfileTolerance = 0.001;
125
126 while (true) {
127 if (ShouldCancel()) {
128 return false;
129 }
130 phased_loop.SleepUntilNext();
131 drivetrain_queue.status.FetchLatest();
132 if (drivetrain_queue.status.get()) {
133 const double left_profile_error =
134 (initial_drivetrain_.left -
135 drivetrain_queue.status->profiled_left_position_goal);
136 const double right_profile_error =
137 (initial_drivetrain_.right -
138 drivetrain_queue.status->profiled_right_position_goal);
139
140 const double left_error =
141 (initial_drivetrain_.left -
142 drivetrain_queue.status->estimated_left_position);
143 const double right_error =
144 (initial_drivetrain_.right -
145 drivetrain_queue.status->estimated_right_position);
146
147 const double profile_distance_to_go =
148 (left_profile_error + right_profile_error) / 2.0;
149 const double profile_angle_to_go =
150 (right_profile_error - left_profile_error) /
151 (dt_config_.robot_radius * 2.0);
152
153 const double distance_to_go = (left_error + right_error) / 2.0;
154 const double angle_to_go =
155 (right_error - left_error) / (dt_config_.robot_radius * 2.0);
156
157 if (::std::abs(profile_distance_to_go) < distance + kProfileTolerance &&
158 ::std::abs(profile_angle_to_go) < angle + kProfileTolerance &&
159 ::std::abs(distance_to_go) < distance + kPositionTolerance &&
160 ::std::abs(angle_to_go) < angle + kPositionTolerance) {
161 LOG(INFO, "Closer than %f distance, %f angle\n", distance, angle);
162 return true;
163 }
164 }
165 }
166}
167
Austin Schuh23b21802016-04-03 21:18:56 -0700168bool AutonomousActor::WaitForDriveProfileDone() {
169 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
170 ::aos::time::Time::InMS(5) / 2);
171 constexpr double kProfileTolerance = 0.001;
172
173 while (true) {
174 if (ShouldCancel()) {
175 return false;
176 }
177 phased_loop.SleepUntilNext();
178 drivetrain_queue.status.FetchLatest();
179 if (drivetrain_queue.status.get()) {
180 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
181 initial_drivetrain_.left) < kProfileTolerance &&
182 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
183 initial_drivetrain_.right) < kProfileTolerance) {
184 LOG(INFO, "Finished drive\n");
185 return true;
186 }
187 }
188 }
189}
190
Austin Schuh3e4a5272016-04-20 20:11:00 -0700191bool AutonomousActor::WaitForMaxBy(double angle) {
Comran Morshed435f1112016-03-12 14:20:45 +0000192 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
193 ::aos::time::Time::InMS(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700194 double max_angle = -M_PI;
195 while (true) {
196 if (ShouldCancel()) {
197 return false;
198 }
199 phased_loop.SleepUntilNext();
200 drivetrain_queue.status.FetchLatest();
201 if (IsDriveDone()) {
202 return true;
203 }
204 if (drivetrain_queue.status.get()) {
205 if (drivetrain_queue.status->ground_angle > max_angle) {
206 max_angle = drivetrain_queue.status->ground_angle;
207 }
208 if (drivetrain_queue.status->ground_angle < max_angle - angle) {
209 return true;
210 }
211 }
212 }
213}
214
215bool AutonomousActor::WaitForAboveAngle(double angle) {
216 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
217 ::aos::time::Time::InMS(5) / 2);
218 while (true) {
219 if (ShouldCancel()) {
220 return false;
221 }
222 phased_loop.SleepUntilNext();
223 drivetrain_queue.status.FetchLatest();
224 if (IsDriveDone()) {
225 return true;
226 }
227 if (drivetrain_queue.status.get()) {
228 if (drivetrain_queue.status->ground_angle > angle) {
229 return true;
230 }
231 }
232 }
233}
234
235bool AutonomousActor::WaitForBelowAngle(double angle) {
236 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
237 ::aos::time::Time::InMS(5) / 2);
238 while (true) {
239 if (ShouldCancel()) {
240 return false;
241 }
242 phased_loop.SleepUntilNext();
243 drivetrain_queue.status.FetchLatest();
244 if (IsDriveDone()) {
245 return true;
246 }
247 if (drivetrain_queue.status.get()) {
248 if (drivetrain_queue.status->ground_angle < angle) {
249 return true;
250 }
251 }
252 }
253}
254
255bool AutonomousActor::IsDriveDone() {
Comran Morshed435f1112016-03-12 14:20:45 +0000256 constexpr double kPositionTolerance = 0.02;
257 constexpr double kVelocityTolerance = 0.10;
258 constexpr double kProfileTolerance = 0.001;
259
Austin Schuh3e4a5272016-04-20 20:11:00 -0700260 if (drivetrain_queue.status.get()) {
261 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
262 initial_drivetrain_.left) < kProfileTolerance &&
263 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
264 initial_drivetrain_.right) < kProfileTolerance &&
265 ::std::abs(drivetrain_queue.status->estimated_left_position -
266 initial_drivetrain_.left) < kPositionTolerance &&
267 ::std::abs(drivetrain_queue.status->estimated_right_position -
268 initial_drivetrain_.right) < kPositionTolerance &&
269 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
270 kVelocityTolerance &&
271 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
272 kVelocityTolerance) {
273 LOG(INFO, "Finished drive\n");
274 return true;
275 }
276 }
277 return false;
278}
279
280bool AutonomousActor::WaitForDriveDone() {
281 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
282 ::aos::time::Time::InMS(5) / 2);
283
Comran Morshed435f1112016-03-12 14:20:45 +0000284 while (true) {
285 if (ShouldCancel()) {
286 return false;
287 }
288 phased_loop.SleepUntilNext();
289 drivetrain_queue.status.FetchLatest();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700290 if (IsDriveDone()) {
291 return true;
Comran Morshed435f1112016-03-12 14:20:45 +0000292 }
293 }
294}
Comran Morshede68e3732016-03-12 14:12:11 +0000295
Comran Morshedb134e772016-03-16 21:05:05 +0000296void AutonomousActor::MoveSuperstructure(
297 double intake, double shoulder, double wrist,
298 const ProfileParameters intake_params,
299 const ProfileParameters shoulder_params,
Austin Schuh23b21802016-04-03 21:18:56 -0700300 const ProfileParameters wrist_params, bool traverse_up,
301 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +0000302 superstructure_goal_ = {intake, shoulder, wrist};
303
304 auto new_superstructure_goal =
305 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
306
307 new_superstructure_goal->angle_intake = intake;
308 new_superstructure_goal->angle_shoulder = shoulder;
309 new_superstructure_goal->angle_wrist = wrist;
310
311 new_superstructure_goal->max_angular_velocity_intake =
312 intake_params.max_velocity;
313 new_superstructure_goal->max_angular_velocity_shoulder =
314 shoulder_params.max_velocity;
315 new_superstructure_goal->max_angular_velocity_wrist =
316 wrist_params.max_velocity;
317
318 new_superstructure_goal->max_angular_acceleration_intake =
319 intake_params.max_acceleration;
320 new_superstructure_goal->max_angular_acceleration_shoulder =
321 shoulder_params.max_acceleration;
322 new_superstructure_goal->max_angular_acceleration_wrist =
323 wrist_params.max_acceleration;
324
Austin Schuh23b21802016-04-03 21:18:56 -0700325 new_superstructure_goal->voltage_top_rollers = roller_power;
326 new_superstructure_goal->voltage_bottom_rollers = roller_power;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700327
328 new_superstructure_goal->traverse_unlatched = true;
329 new_superstructure_goal->traverse_down = !traverse_up;
Diana Vandenberg9cc9ab62016-04-20 21:27:47 -0700330 new_superstructure_goal->voltage_climber = 0.0;
331 new_superstructure_goal->unfold_climber = false;
Comran Morshedb134e772016-03-16 21:05:05 +0000332
333 if (!new_superstructure_goal.Send()) {
334 LOG(ERROR, "Sending superstructure goal failed.\n");
335 }
336}
337
Austin Schuh23b21802016-04-03 21:18:56 -0700338void AutonomousActor::OpenShooter() {
339 shooter_speed_ = 0.0;
340
341 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
342 .angular_velocity(shooter_speed_)
343 .clamp_open(true)
344 .push_to_shooter(false)
345 .force_lights_on(false)
346 .Send()) {
347 LOG(ERROR, "Sending shooter goal failed.\n");
348 }
349}
350
351void AutonomousActor::CloseShooter() {
352 shooter_speed_ = 0.0;
353
354 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
355 .angular_velocity(shooter_speed_)
356 .clamp_open(false)
357 .push_to_shooter(false)
358 .force_lights_on(false)
359 .Send()) {
360 LOG(ERROR, "Sending shooter goal failed.\n");
361 }
362}
363
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700364void AutonomousActor::SetShooterSpeed(double speed) {
365 shooter_speed_ = speed;
366
367 // In auto, we want to have the lights on whenever possible since we have no
368 // hope of a human aligning the robot.
369 bool force_lights_on = shooter_speed_ > 1.0;
370
371 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
372 .angular_velocity(shooter_speed_)
373 .clamp_open(false)
374 .push_to_shooter(false)
375 .force_lights_on(force_lights_on)
376 .Send()) {
377 LOG(ERROR, "Sending shooter goal failed.\n");
378 }
379}
380
381void AutonomousActor::Shoot() {
382 uint32_t initial_shots = 0;
383
384 control_loops::shooter::shooter_queue.status.FetchLatest();
385 if (control_loops::shooter::shooter_queue.status.get()) {
386 initial_shots = control_loops::shooter::shooter_queue.status->shots;
387 }
388
389 // In auto, we want to have the lights on whenever possible since we have no
390 // hope of a human aligning the robot.
391 bool force_lights_on = shooter_speed_ > 1.0;
392
393 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
394 .angular_velocity(shooter_speed_)
395 .clamp_open(false)
396 .push_to_shooter(true)
397 .force_lights_on(force_lights_on)
398 .Send()) {
399 LOG(ERROR, "Sending shooter goal failed.\n");
400 }
401
402 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
403 ::aos::time::Time::InMS(5) / 2);
404 while (true) {
405 if (ShouldCancel()) return;
406
407 // Wait for the shot count to change so we know when the shot is complete.
408 control_loops::shooter::shooter_queue.status.FetchLatest();
409 if (control_loops::shooter::shooter_queue.status.get()) {
410 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
411 return;
412 }
413 }
414 phased_loop.SleepUntilNext();
415 }
416}
417
418void AutonomousActor::WaitForShooterSpeed() {
419 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
420 ::aos::time::Time::InMS(5) / 2);
421 while (true) {
422 if (ShouldCancel()) return;
423
424 control_loops::shooter::shooter_queue.status.FetchLatest();
425 if (control_loops::shooter::shooter_queue.status.get()) {
426 if (control_loops::shooter::shooter_queue.status->left.ready &&
427 control_loops::shooter::shooter_queue.status->right.ready) {
428 return;
429 }
430 }
431 phased_loop.SleepUntilNext();
432 }
433}
434
435void AutonomousActor::AlignWithVisionGoal() {
436 actors::VisionAlignActionParams params;
437 vision_action_ = ::std::move(actors::MakeVisionAlignAction(params));
438 vision_action_->Start();
439}
440
Austin Schuh23b21802016-04-03 21:18:56 -0700441void AutonomousActor::WaitForAlignedWithVision(
442 ::aos::time::Time align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700443 bool vision_valid = false;
444 double last_angle = 0.0;
445 int ready_to_fire = 0;
446
447 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
448 ::aos::time::Time::InMS(5) / 2);
449 ::aos::time::Time end_time =
Austin Schuh23b21802016-04-03 21:18:56 -0700450 ::aos::time::Time::Now() + align_duration;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700451 while (end_time > ::aos::time::Time::Now()) {
452 if (ShouldCancel()) break;
453
454 ::y2016::vision::vision_status.FetchLatest();
455 if (::y2016::vision::vision_status.get()) {
456 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
457 ::y2016::vision::vision_status->right_image_valid);
458 last_angle = ::y2016::vision::vision_status->horizontal_angle;
459 }
460
461 drivetrain_queue.status.FetchLatest();
462 drivetrain_queue.goal.FetchLatest();
463
464 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
465 const double left_goal = drivetrain_queue.goal->left_goal;
466 const double right_goal = drivetrain_queue.goal->right_goal;
467 const double left_current =
468 drivetrain_queue.status->estimated_left_position;
469 const double right_current =
470 drivetrain_queue.status->estimated_right_position;
471 const double left_velocity =
472 drivetrain_queue.status->estimated_left_velocity;
473 const double right_velocity =
474 drivetrain_queue.status->estimated_right_velocity;
475
476 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
477 ::std::abs((left_goal - right_goal) -
478 (left_current - right_current)) /
479 dt_config_.robot_radius / 2.0 <
480 0.02 &&
481 ::std::abs(left_velocity - right_velocity) < 0.01) {
482 ++ready_to_fire;
483 } else {
484 ready_to_fire = 0;
485 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700486 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700487 break;
Austin Schuh23b21802016-04-03 21:18:56 -0700488 LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700489 }
490 }
491 phased_loop.SleepUntilNext();
492 }
493
494 vision_action_->Cancel();
495 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuh23b21802016-04-03 21:18:56 -0700496 LOG(INFO, "Done waiting for vision\n");
497}
498
499bool AutonomousActor::IntakeDone() {
500 control_loops::superstructure_queue.status.FetchAnother();
501
502 constexpr double kProfileError = 1e-5;
503 constexpr double kEpsilon = 0.15;
504
505 if (control_loops::superstructure_queue.status->state < 12 ||
506 control_loops::superstructure_queue.status->state == 16) {
507 LOG(ERROR, "Superstructure no longer running, aborting action\n");
508 return true;
509 }
510
511 if (::std::abs(control_loops::superstructure_queue.status->intake.goal_angle -
512 superstructure_goal_.intake) < kProfileError &&
513 ::std::abs(control_loops::superstructure_queue.status->intake
514 .goal_angular_velocity) < kProfileError) {
515 LOG(DEBUG, "Profile done.\n");
516 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
517 superstructure_goal_.intake) < kEpsilon &&
518 ::std::abs(control_loops::superstructure_queue.status->intake
519 .angular_velocity) < kEpsilon) {
520 LOG(INFO, "Near goal, done.\n");
521 return true;
522 }
523 }
524 return false;
525}
526
527bool AutonomousActor::SuperstructureProfileDone() {
528 constexpr double kProfileError = 1e-5;
529 return ::std::abs(
530 control_loops::superstructure_queue.status->intake.goal_angle -
531 superstructure_goal_.intake) < kProfileError &&
532 ::std::abs(
533 control_loops::superstructure_queue.status->shoulder.goal_angle -
534 superstructure_goal_.shoulder) < kProfileError &&
535 ::std::abs(
536 control_loops::superstructure_queue.status->wrist.goal_angle -
537 superstructure_goal_.wrist) < kProfileError &&
538 ::std::abs(control_loops::superstructure_queue.status->intake
539 .goal_angular_velocity) < kProfileError &&
540 ::std::abs(control_loops::superstructure_queue.status->shoulder
541 .goal_angular_velocity) < kProfileError &&
542 ::std::abs(control_loops::superstructure_queue.status->wrist
543 .goal_angular_velocity) < kProfileError;
544}
545
546bool AutonomousActor::SuperstructureDone() {
547 control_loops::superstructure_queue.status.FetchAnother();
548
549 constexpr double kEpsilon = 0.03;
550
551 if (control_loops::superstructure_queue.status->state < 12 ||
552 control_loops::superstructure_queue.status->state == 16) {
553 LOG(ERROR, "Superstructure no longer running, aborting action\n");
554 return true;
555 }
556
557 if (SuperstructureProfileDone()) {
558 LOG(DEBUG, "Profile done.\n");
559 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
560 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
561 ::std::abs(control_loops::superstructure_queue.status->shoulder.angle -
562 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
563 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
564 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
565 ::std::abs(control_loops::superstructure_queue.status->intake
566 .angular_velocity) < (kEpsilon + 0.1) &&
567 ::std::abs(control_loops::superstructure_queue.status->shoulder
568 .angular_velocity) < (kEpsilon + 0.10) &&
569 ::std::abs(control_loops::superstructure_queue.status->wrist
570 .angular_velocity) < (kEpsilon + 0.05)) {
571 LOG(INFO, "Near goal, done.\n");
572 return true;
573 }
574 }
575 return false;
576}
577
578void AutonomousActor::WaitForIntake() {
579 while (true) {
580 if (ShouldCancel()) return;
581 if (IntakeDone()) return;
582 }
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700583}
584
Comran Morshedb134e772016-03-16 21:05:05 +0000585void AutonomousActor::WaitForSuperstructure() {
586 while (true) {
587 if (ShouldCancel()) return;
Austin Schuh23b21802016-04-03 21:18:56 -0700588 if (SuperstructureDone()) return;
589 }
590}
Comran Morshedb134e772016-03-16 21:05:05 +0000591
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700592void AutonomousActor::WaitForSuperstructureProfile() {
593 while (true) {
594 if (ShouldCancel()) return;
595 control_loops::superstructure_queue.status.FetchAnother();
596
597 if (control_loops::superstructure_queue.status->state < 12 ||
598 control_loops::superstructure_queue.status->state == 16) {
599 LOG(ERROR, "Superstructure no longer running, aborting action\n");
600 return;
601 }
602
603 if (SuperstructureProfileDone()) return;
604 }
605}
606
Austin Schuh23b21802016-04-03 21:18:56 -0700607void AutonomousActor::WaitForSuperstructureLow() {
608 while (true) {
609 if (ShouldCancel()) return;
610 control_loops::superstructure_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +0000611
612 if (control_loops::superstructure_queue.status->state < 12 ||
613 control_loops::superstructure_queue.status->state == 16) {
614 LOG(ERROR, "Superstructure no longer running, aborting action\n");
615 return;
616 }
Austin Schuh23b21802016-04-03 21:18:56 -0700617 if (SuperstructureProfileDone()) return;
618 if (control_loops::superstructure_queue.status->shoulder.angle < 0.1) {
619 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000620 }
621 }
622}
Austin Schuh23b21802016-04-03 21:18:56 -0700623void AutonomousActor::BackLongShotLowBarTwoBall() {
624 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700625 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 -0700626 {10.0, 25.0}, false, 0.0);
627}
628
629void AutonomousActor::BackLongShotTwoBall() {
630 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700631 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55, {7.0, 40.0}, {4.0, 6.0},
632 {10.0, 25.0}, false, 0.0);
633}
634
635void AutonomousActor::BackLongShotTwoBallFinish() {
636 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh90963362016-05-01 12:27:31 -0700637 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625, {7.0, 40.0}, {4.0, 6.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700638 {10.0, 25.0}, false, 0.0);
639}
640
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700641void AutonomousActor::BackLongShot() {
642 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700643 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 6.0},
644 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700645}
646
647void AutonomousActor::BackMiddleShot() {
648 LOG(INFO, "Expanding for back middle shot\n");
649 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 -0700650 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700651}
652
Austin Schuh3e4a5272016-04-20 20:11:00 -0700653void AutonomousActor::FrontLongShot() {
654 LOG(INFO, "Expanding for front long shot\n");
655 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02, {7.0, 40.0},
656 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
657}
658
659void AutonomousActor::FrontMiddleShot() {
660 LOG(INFO, "Expanding for front middle shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700661 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44, {7.0, 40.0},
Austin Schuh3e4a5272016-04-20 20:11:00 -0700662 {4.0, 10.0}, {10.0, 25.0}, true, 0.0);
663}
664
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700665void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
666 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700667 {4.0, 10.0}, {10.0, 25.0}, !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700668}
669
Austin Schuh3e4a5272016-04-20 20:11:00 -0700670void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700671 if (ShouldCancel()) return;
672 // Make sure that the base is aligned with the base.
673 LOG(INFO, "Waiting for the superstructure\n");
674 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700675
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700676 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.5));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700677
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700678 if (ShouldCancel()) return;
679 LOG(INFO, "Triggering the vision actor\n");
680 AlignWithVisionGoal();
681
682 // Wait for the drive base to be aligned with the target and make sure that
683 // the shooter is up to speed.
684 LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700685 WaitForAlignedWithVision(aos::time::Time::InSeconds(2));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700686 if (ShouldCancel()) return;
687 LOG(INFO, "Waiting for shooter to be up to speed\n");
688 WaitForShooterSpeed();
689 if (ShouldCancel()) return;
690
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700691 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.3));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700692 LOG(INFO, "Shoot!\n");
693 Shoot();
694
695 // Turn off the shooter and fold up the superstructure.
696 if (ShouldCancel()) return;
697 LOG(INFO, "Stopping shooter\n");
698 SetShooterSpeed(0.0);
699 LOG(INFO, "Folding superstructure back down\n");
700 TuckArm(false, false);
701
702 // Wait for everything to be folded up.
703 LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700704 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700705}
706
707void AutonomousActor::LowBarDrive() {
708 TuckArm(false, true);
709 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
710
711 if (!WaitForDriveNear(5.3, 0.0)) return;
712 TuckArm(true, true);
713
714 if (!WaitForDriveNear(5.0, 0.0)) return;
715
716 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
717
718 if (!WaitForDriveNear(3.0, 0.0)) return;
719
720 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
721
722 if (!WaitForDriveNear(1.0, 0.0)) return;
723
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700724 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700725}
726
Austin Schuh3e4a5272016-04-20 20:11:00 -0700727void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
728 double below, double above) {
729 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
730 if (!WaitForBelowAngle(below)) return;
731 if (!WaitForAboveAngle(above)) return;
732 // Ok, we are good now. Compensate by moving the goal by the error.
733 // Should be here at 2.7
734 drivetrain_queue.status.FetchLatest();
735 if (drivetrain_queue.status.get()) {
736 const double left_error =
737 (initial_drivetrain_.left -
738 drivetrain_queue.status->estimated_left_position);
739 const double right_error =
740 (initial_drivetrain_.right -
741 drivetrain_queue.status->estimated_right_position);
742 const double distance_to_go = (left_error + right_error) / 2.0;
743 const double distance_compensation =
744 goal_distance - tip_distance - distance_to_go;
745 LOG(INFO, "Going %f further at the bump\n", distance_compensation);
746 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
747 }
748}
749
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700750void AutonomousActor::MiddleDrive() {
751 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700752 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700753 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700754}
755
756void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700757 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700758 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700759 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700760
761 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700762 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700763}
764
765void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700766 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700767 constexpr double kDriveDistance = 5.10;
768 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
769
770 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
771 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700772
773 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700774 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700775}
Comran Morshedb134e772016-03-16 21:05:05 +0000776
Austin Schuh23b21802016-04-03 21:18:56 -0700777void AutonomousActor::CloseIfBall() {
778 ::y2016::sensors::ball_detector.FetchLatest();
779 if (::y2016::sensors::ball_detector.get()) {
780 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
781 if (ball_detected) {
782 CloseShooter();
783 }
784 }
785}
786
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700787void AutonomousActor::WaitForBallOrDriveDone() {
788 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
789 ::aos::time::Time::InMS(5) / 2);
790 while (true) {
791 if (ShouldCancel()) {
792 return;
793 }
794 phased_loop.SleepUntilNext();
795 drivetrain_queue.status.FetchLatest();
796 if (IsDriveDone()) {
797 return;
798 }
799
800 ::y2016::sensors::ball_detector.FetchLatest();
801 if (::y2016::sensors::ball_detector.get()) {
802 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
803 if (ball_detected) {
804 return;
805 }
806 }
807 }
808}
809
Austin Schuh23b21802016-04-03 21:18:56 -0700810void AutonomousActor::WaitForBall() {
811 while (true) {
812 ::y2016::sensors::ball_detector.FetchAnother();
813 if (::y2016::sensors::ball_detector.get()) {
814 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
815 if (ball_detected) {
816 return;
817 }
818 if (ShouldCancel()) return;
819 }
820 }
821}
822
Austin Schuh3e4a5272016-04-20 20:11:00 -0700823void AutonomousActor::TwoBallAuto() {
824 aos::time::Time start_time = aos::time::Time::Now();
825 OpenShooter();
826 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
827 false, 12.0);
828 if (ShouldCancel()) return;
829 LOG(INFO, "Waiting for the intake to come down.\n");
830
831 WaitForIntake();
832 LOG(INFO, "Intake done at %f seconds, starting to drive\n",
833 (aos::time::Time::Now() - start_time).ToSeconds());
834 if (ShouldCancel()) return;
835 const double kDriveDistance = 5.05;
836 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
837
838 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700839 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700840
841 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
842 false, 0.0);
843 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
844 (aos::time::Time::Now() - start_time).ToSeconds());
845 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
846 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
847 false, 0.0);
848 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700849 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700850
851 // We are now under the low bar. Start lifting.
852 BackLongShotLowBarTwoBall();
853 LOG(INFO, "Spinning up the shooter wheels\n");
854 SetShooterSpeed(640.0);
855 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
856
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700857 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
858 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700859 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
860 BackLongShotTwoBall();
861
862 if (!WaitForDriveDone()) return;
863 LOG(INFO, "First shot done driving at %f seconds\n",
864 (aos::time::Time::Now() - start_time).ToSeconds());
865
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700866 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700867
868 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700869 AlignWithVisionGoal();
870
871 WaitForShooterSpeed();
872 if (ShouldCancel()) return;
873
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700874 constexpr double kVisionExtra = 0.0;
875 WaitForAlignedWithVision(aos::time::Time::InSeconds(0.5 + kVisionExtra));
876 BackLongShotTwoBallFinish();
877 WaitForSuperstructureProfile();
878 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700879 LOG(INFO, "Shoot!\n");
880 Shoot();
881
882 LOG(INFO, "First shot at %f seconds\n",
883 (aos::time::Time::Now() - start_time).ToSeconds());
884 if (ShouldCancel()) return;
885
886 SetShooterSpeed(0.0);
887 LOG(INFO, "Folding superstructure back down\n");
888 TuckArm(true, true);
889
890 // Undo vision move.
891 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
892 if (!WaitForDriveDone()) return;
893
894 constexpr double kBackDrive = 3.09 - 0.4;
895 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700896 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700897 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700898 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
899 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700900
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700901 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700902 LOG(INFO, "At Low Bar %f\n",
903 (aos::time::Time::Now() - start_time).ToSeconds());
904
905 OpenShooter();
906 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700907 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
908 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700909 constexpr double kBallSmallWallTurn = -0.11;
910 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
911
912 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
913 false, 12.0);
914
915 if (!WaitForDriveProfileDone()) return;
916
917 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
918 false, 12.0);
919
920 LOG(INFO, "Done backing up %f\n",
921 (aos::time::Time::Now() - start_time).ToSeconds());
922
923 constexpr double kDriveBackDistance = 5.15 - 0.4;
924 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
925 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700926 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700927
928 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
929 LOG(INFO, "Straightening up at %f\n",
930 (aos::time::Time::Now() - start_time).ToSeconds());
931
932 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700933 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700934
935 ::y2016::sensors::ball_detector.FetchLatest();
936 if (::y2016::sensors::ball_detector.get()) {
937 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
938 if (!ball_detected) {
939 if (!WaitForDriveDone()) return;
940 LOG(INFO, "Aborting, no ball %f\n",
941 (aos::time::Time::Now() - start_time).ToSeconds());
942 return;
943 }
944 }
945 CloseShooter();
946
947 BackLongShotLowBarTwoBall();
948 LOG(INFO, "Spinning up the shooter wheels\n");
949 SetShooterSpeed(640.0);
950 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
951
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700952 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700953 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
954 BackLongShotTwoBall();
955
956 if (!WaitForDriveDone()) return;
957 LOG(INFO, "Second shot done driving at %f seconds\n",
958 (aos::time::Time::Now() - start_time).ToSeconds());
959 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700960 AlignWithVisionGoal();
961 if (ShouldCancel()) return;
962
963 WaitForShooterSpeed();
964 if (ShouldCancel()) return;
965
966 // 2.2 with 0.4 of vision.
967 // 1.8 without any vision.
968 LOG(INFO, "Going to vision align at %f\n",
969 (aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700970 WaitForAlignedWithVision(start_time + aos::time::Time::InSeconds(13.5 + kVisionExtra * 2) -
Austin Schuh3e4a5272016-04-20 20:11:00 -0700971 aos::time::Time::Now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700972 BackLongShotTwoBallFinish();
973 WaitForSuperstructureProfile();
974 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700975 LOG(INFO, "Shoot at %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
976 Shoot();
977
978 LOG(INFO, "Second shot at %f seconds\n",
979 (aos::time::Time::Now() - start_time).ToSeconds());
980 if (ShouldCancel()) return;
981
982 SetShooterSpeed(0.0);
983 LOG(INFO, "Folding superstructure back down\n");
984 TuckArm(true, false);
985 LOG(INFO, "Shot %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
986
987 WaitForSuperstructureLow();
988
989 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
990}
991
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700992void AutonomousActor::StealAndMoveOverBy(double distance) {
993 OpenShooter();
994 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
995 true, 12.0);
996 if (ShouldCancel()) return;
997 LOG(INFO, "Waiting for the intake to come down.\n");
998
999 WaitForIntake();
1000 if (ShouldCancel()) return;
1001 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
1002 WaitForBallOrDriveDone();
1003 if (ShouldCancel()) return;
1004 MoveSuperstructure(1.0, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1005 true, 12.0);
1006
1007 if (!WaitForDriveDone()) return;
1008 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
1009 if (!WaitForDriveDone()) return;
1010}
1011
Comran Morshede68e3732016-03-12 14:12:11 +00001012bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
Austin Schuh3e4a5272016-04-20 20:11:00 -07001013 aos::time::Time start_time = aos::time::Time::Now();
Comran Morshede68e3732016-03-12 14:12:11 +00001014 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
1015
Comran Morshed435f1112016-03-12 14:20:45 +00001016 InitializeEncoders();
1017 ResetDrivetrain();
1018
Austin Schuh3e4a5272016-04-20 20:11:00 -07001019 switch (1) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001020 case 0:
1021 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001022 if (!WaitForDriveDone()) return true;
1023 // Get the superstructure to unfold and get ready for shooting.
1024 LOG(INFO, "Unfolding superstructure\n");
1025 FrontLongShot();
1026
1027 // Spin up the shooter wheels.
1028 LOG(INFO, "Spinning up the shooter wheels\n");
1029 SetShooterSpeed(640.0);
1030
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001031 break;
1032 case 1:
1033 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001034 if (!WaitForDriveDone()) return true;
1035 // Get the superstructure to unfold and get ready for shooting.
1036 LOG(INFO, "Unfolding superstructure\n");
1037 FrontMiddleShot();
1038
1039 // Spin up the shooter wheels.
1040 LOG(INFO, "Spinning up the shooter wheels\n");
1041 SetShooterSpeed(600.0);
1042
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001043 break;
1044 case 2:
1045 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001046 if (!WaitForDriveDone()) return true;
1047 // Get the superstructure to unfold and get ready for shooting.
1048 LOG(INFO, "Unfolding superstructure\n");
1049 FrontMiddleShot();
1050
1051 // Spin up the shooter wheels.
1052 LOG(INFO, "Spinning up the shooter wheels\n");
1053 SetShooterSpeed(600.0);
1054
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001055 break;
1056 case 3:
1057 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001058 if (!WaitForDriveDone()) return true;
1059 // Get the superstructure to unfold and get ready for shooting.
1060 LOG(INFO, "Unfolding superstructure\n");
1061 FrontMiddleShot();
1062
1063 // Spin up the shooter wheels.
1064 LOG(INFO, "Spinning up the shooter wheels\n");
1065 SetShooterSpeed(600.0);
1066
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001067 break;
1068 case 4:
1069 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001070 if (!WaitForDriveDone()) return true;
1071 // Get the superstructure to unfold and get ready for shooting.
1072 LOG(INFO, "Unfolding superstructure\n");
1073 FrontMiddleShot();
1074
1075 // Spin up the shooter wheels.
1076 LOG(INFO, "Spinning up the shooter wheels\n");
1077 SetShooterSpeed(600.0);
1078
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001079 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001080 case 5:
1081 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -07001082 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001083 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001084 case 6:
1085 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
1086 if (ShouldCancel()) return true;
1087
1088 TwoFromMiddleDrive();
1089 if (!WaitForDriveDone()) return true;
1090 // Get the superstructure to unfold and get ready for shooting.
1091 LOG(INFO, "Unfolding superstructure\n");
1092 FrontMiddleShot();
1093
1094 // Spin up the shooter wheels.
1095 LOG(INFO, "Spinning up the shooter wheels\n");
1096 SetShooterSpeed(600.0);
1097
1098 break;
1099 case 7:
1100 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
1101 if (ShouldCancel()) return true;
1102
1103 OneFromMiddleDrive(true);
1104 if (!WaitForDriveDone()) return true;
1105 // Get the superstructure to unfold and get ready for shooting.
1106 LOG(INFO, "Unfolding superstructure\n");
1107 FrontMiddleShot();
1108
1109 // Spin up the shooter wheels.
1110 LOG(INFO, "Spinning up the shooter wheels\n");
1111 SetShooterSpeed(600.0);
1112
1113 break;
1114 case 8: {
1115 StealAndMoveOverBy(2.95);
1116 if (ShouldCancel()) return true;
1117
1118 MiddleDrive();
1119 if (!WaitForDriveDone()) return true;
1120 // Get the superstructure to unfold and get ready for shooting.
1121 LOG(INFO, "Unfolding superstructure\n");
1122 FrontMiddleShot();
1123
1124 // Spin up the shooter wheels.
1125 LOG(INFO, "Spinning up the shooter wheels\n");
1126 SetShooterSpeed(600.0);
1127
1128 } break;
1129 case 9: {
1130 StealAndMoveOverBy(1.70);
1131 if (ShouldCancel()) return true;
1132
1133 OneFromMiddleDrive(false);
1134 if (!WaitForDriveDone()) return true;
1135 // Get the superstructure to unfold and get ready for shooting.
1136 LOG(INFO, "Unfolding superstructure\n");
1137 FrontMiddleShot();
1138
1139 // Spin up the shooter wheels.
1140 LOG(INFO, "Spinning up the shooter wheels\n");
1141 SetShooterSpeed(600.0);
1142
1143 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001144 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -07001145 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001146 return true;
1147 }
Comran Morshed435f1112016-03-12 14:20:45 +00001148
Austin Schuh3e4a5272016-04-20 20:11:00 -07001149 DoFullShot();
1150
1151 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +00001152 if (!WaitForDriveDone()) return true;
1153
Austin Schuh3e4a5272016-04-20 20:11:00 -07001154 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
Comran Morshed435f1112016-03-12 14:20:45 +00001155
1156 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
1157 ::aos::time::Time::InMS(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001158
Comran Morshed435f1112016-03-12 14:20:45 +00001159 while (!ShouldCancel()) {
1160 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +00001161 }
Comran Morshed435f1112016-03-12 14:20:45 +00001162 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +00001163
1164 return true;
1165}
1166
1167::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
1168 const ::y2016::actors::AutonomousActionParams &params) {
1169 return ::std::unique_ptr<AutonomousAction>(
1170 new AutonomousAction(&::y2016::actors::autonomous_action, params));
1171}
1172
1173} // namespace actors
1174} // namespace y2016