blob: 1f5b3dfd3b0193787d7652e7b1416a7327590d58 [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};
Comran Morshed435f1112016-03-12 14:20:45 +000042} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000043
44AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000045 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000046 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
47 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000048
49void AutonomousActor::ResetDrivetrain() {
50 LOG(INFO, "resetting the drivetrain\n");
51 drivetrain_queue.goal.MakeWithBuilder()
52 .control_loop_driving(false)
53 .highgear(true)
54 .steering(0.0)
55 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000056 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000057 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000058 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000059 .right_velocity_goal(0)
60 .Send();
61}
62
63void AutonomousActor::StartDrive(double distance, double angle,
64 ProfileParameters linear,
65 ProfileParameters angular) {
66 {
Austin Schuh23b21802016-04-03 21:18:56 -070067 LOG(INFO, "Driving distance %f, angle %f\n", distance, angle);
Comran Morshed435f1112016-03-12 14:20:45 +000068 {
69 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000070 initial_drivetrain_.left += distance - dangle;
71 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000072 }
73
Comran Morshedb134e772016-03-16 21:05:05 +000074 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000075 drivetrain_message->control_loop_driving = true;
76 drivetrain_message->highgear = true;
77 drivetrain_message->steering = 0.0;
78 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000079 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000080 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000081 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000082 drivetrain_message->right_velocity_goal = 0;
83 drivetrain_message->linear = linear;
84 drivetrain_message->angular = angular;
85
86 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
87
88 drivetrain_message.Send();
89 }
90}
91
92void AutonomousActor::InitializeEncoders() {
93 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000094 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
95 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000096}
97
98void AutonomousActor::WaitUntilDoneOrCanceled(
99 ::std::unique_ptr<aos::common::actions::Action> action) {
100 if (!action) {
101 LOG(ERROR, "No action, not waiting\n");
102 return;
103 }
104
105 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
106 ::aos::time::Time::InMS(5) / 2);
107 while (true) {
108 // Poll the running bit and see if we should cancel.
109 phased_loop.SleepUntilNext();
110 if (!action->Running() || ShouldCancel()) {
111 return;
112 }
113 }
114}
115
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700116constexpr double kDoNotTurnCare = 2.0;
117
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700118bool AutonomousActor::WaitForDriveNear(double distance, double angle) {
119 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
120 ::aos::time::Time::InMS(5) / 2);
121 constexpr double kPositionTolerance = 0.02;
122 constexpr double kProfileTolerance = 0.001;
123
124 while (true) {
125 if (ShouldCancel()) {
126 return false;
127 }
128 phased_loop.SleepUntilNext();
129 drivetrain_queue.status.FetchLatest();
130 if (drivetrain_queue.status.get()) {
131 const double left_profile_error =
132 (initial_drivetrain_.left -
133 drivetrain_queue.status->profiled_left_position_goal);
134 const double right_profile_error =
135 (initial_drivetrain_.right -
136 drivetrain_queue.status->profiled_right_position_goal);
137
138 const double left_error =
139 (initial_drivetrain_.left -
140 drivetrain_queue.status->estimated_left_position);
141 const double right_error =
142 (initial_drivetrain_.right -
143 drivetrain_queue.status->estimated_right_position);
144
145 const double profile_distance_to_go =
146 (left_profile_error + right_profile_error) / 2.0;
147 const double profile_angle_to_go =
148 (right_profile_error - left_profile_error) /
149 (dt_config_.robot_radius * 2.0);
150
151 const double distance_to_go = (left_error + right_error) / 2.0;
152 const double angle_to_go =
153 (right_error - left_error) / (dt_config_.robot_radius * 2.0);
154
155 if (::std::abs(profile_distance_to_go) < distance + kProfileTolerance &&
156 ::std::abs(profile_angle_to_go) < angle + kProfileTolerance &&
157 ::std::abs(distance_to_go) < distance + kPositionTolerance &&
158 ::std::abs(angle_to_go) < angle + kPositionTolerance) {
159 LOG(INFO, "Closer than %f distance, %f angle\n", distance, angle);
160 return true;
161 }
162 }
163 }
164}
165
Austin Schuh23b21802016-04-03 21:18:56 -0700166bool AutonomousActor::WaitForDriveProfileDone() {
167 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
168 ::aos::time::Time::InMS(5) / 2);
169 constexpr double kProfileTolerance = 0.001;
170
171 while (true) {
172 if (ShouldCancel()) {
173 return false;
174 }
175 phased_loop.SleepUntilNext();
176 drivetrain_queue.status.FetchLatest();
177 if (drivetrain_queue.status.get()) {
178 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
179 initial_drivetrain_.left) < kProfileTolerance &&
180 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
181 initial_drivetrain_.right) < kProfileTolerance) {
182 LOG(INFO, "Finished drive\n");
183 return true;
184 }
185 }
186 }
187}
188
Austin Schuh3e4a5272016-04-20 20:11:00 -0700189bool AutonomousActor::WaitForMaxBy(double angle) {
Comran Morshed435f1112016-03-12 14:20:45 +0000190 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
191 ::aos::time::Time::InMS(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700192 double max_angle = -M_PI;
193 while (true) {
194 if (ShouldCancel()) {
195 return false;
196 }
197 phased_loop.SleepUntilNext();
198 drivetrain_queue.status.FetchLatest();
199 if (IsDriveDone()) {
200 return true;
201 }
202 if (drivetrain_queue.status.get()) {
203 if (drivetrain_queue.status->ground_angle > max_angle) {
204 max_angle = drivetrain_queue.status->ground_angle;
205 }
206 if (drivetrain_queue.status->ground_angle < max_angle - angle) {
207 return true;
208 }
209 }
210 }
211}
212
213bool AutonomousActor::WaitForAboveAngle(double angle) {
214 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
215 ::aos::time::Time::InMS(5) / 2);
216 while (true) {
217 if (ShouldCancel()) {
218 return false;
219 }
220 phased_loop.SleepUntilNext();
221 drivetrain_queue.status.FetchLatest();
222 if (IsDriveDone()) {
223 return true;
224 }
225 if (drivetrain_queue.status.get()) {
226 if (drivetrain_queue.status->ground_angle > angle) {
227 return true;
228 }
229 }
230 }
231}
232
233bool AutonomousActor::WaitForBelowAngle(double angle) {
234 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
235 ::aos::time::Time::InMS(5) / 2);
236 while (true) {
237 if (ShouldCancel()) {
238 return false;
239 }
240 phased_loop.SleepUntilNext();
241 drivetrain_queue.status.FetchLatest();
242 if (IsDriveDone()) {
243 return true;
244 }
245 if (drivetrain_queue.status.get()) {
246 if (drivetrain_queue.status->ground_angle < angle) {
247 return true;
248 }
249 }
250 }
251}
252
253bool AutonomousActor::IsDriveDone() {
Comran Morshed435f1112016-03-12 14:20:45 +0000254 constexpr double kPositionTolerance = 0.02;
255 constexpr double kVelocityTolerance = 0.10;
256 constexpr double kProfileTolerance = 0.001;
257
Austin Schuh3e4a5272016-04-20 20:11:00 -0700258 if (drivetrain_queue.status.get()) {
259 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
260 initial_drivetrain_.left) < kProfileTolerance &&
261 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
262 initial_drivetrain_.right) < kProfileTolerance &&
263 ::std::abs(drivetrain_queue.status->estimated_left_position -
264 initial_drivetrain_.left) < kPositionTolerance &&
265 ::std::abs(drivetrain_queue.status->estimated_right_position -
266 initial_drivetrain_.right) < kPositionTolerance &&
267 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
268 kVelocityTolerance &&
269 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
270 kVelocityTolerance) {
271 LOG(INFO, "Finished drive\n");
272 return true;
273 }
274 }
275 return false;
276}
277
278bool AutonomousActor::WaitForDriveDone() {
279 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
280 ::aos::time::Time::InMS(5) / 2);
281
Comran Morshed435f1112016-03-12 14:20:45 +0000282 while (true) {
283 if (ShouldCancel()) {
284 return false;
285 }
286 phased_loop.SleepUntilNext();
287 drivetrain_queue.status.FetchLatest();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700288 if (IsDriveDone()) {
289 return true;
Comran Morshed435f1112016-03-12 14:20:45 +0000290 }
291 }
292}
Comran Morshede68e3732016-03-12 14:12:11 +0000293
Comran Morshedb134e772016-03-16 21:05:05 +0000294void AutonomousActor::MoveSuperstructure(
295 double intake, double shoulder, double wrist,
296 const ProfileParameters intake_params,
297 const ProfileParameters shoulder_params,
Austin Schuh23b21802016-04-03 21:18:56 -0700298 const ProfileParameters wrist_params, bool traverse_up,
299 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +0000300 superstructure_goal_ = {intake, shoulder, wrist};
301
302 auto new_superstructure_goal =
303 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
304
305 new_superstructure_goal->angle_intake = intake;
306 new_superstructure_goal->angle_shoulder = shoulder;
307 new_superstructure_goal->angle_wrist = wrist;
308
309 new_superstructure_goal->max_angular_velocity_intake =
310 intake_params.max_velocity;
311 new_superstructure_goal->max_angular_velocity_shoulder =
312 shoulder_params.max_velocity;
313 new_superstructure_goal->max_angular_velocity_wrist =
314 wrist_params.max_velocity;
315
316 new_superstructure_goal->max_angular_acceleration_intake =
317 intake_params.max_acceleration;
318 new_superstructure_goal->max_angular_acceleration_shoulder =
319 shoulder_params.max_acceleration;
320 new_superstructure_goal->max_angular_acceleration_wrist =
321 wrist_params.max_acceleration;
322
Austin Schuh23b21802016-04-03 21:18:56 -0700323 new_superstructure_goal->voltage_top_rollers = roller_power;
324 new_superstructure_goal->voltage_bottom_rollers = roller_power;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700325
326 new_superstructure_goal->traverse_unlatched = true;
327 new_superstructure_goal->traverse_down = !traverse_up;
Diana Vandenberg9cc9ab62016-04-20 21:27:47 -0700328 new_superstructure_goal->voltage_climber = 0.0;
329 new_superstructure_goal->unfold_climber = false;
Comran Morshedb134e772016-03-16 21:05:05 +0000330
331 if (!new_superstructure_goal.Send()) {
332 LOG(ERROR, "Sending superstructure goal failed.\n");
333 }
334}
335
Austin Schuh23b21802016-04-03 21:18:56 -0700336void AutonomousActor::OpenShooter() {
337 shooter_speed_ = 0.0;
338
339 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
340 .angular_velocity(shooter_speed_)
341 .clamp_open(true)
342 .push_to_shooter(false)
343 .force_lights_on(false)
344 .Send()) {
345 LOG(ERROR, "Sending shooter goal failed.\n");
346 }
347}
348
349void AutonomousActor::CloseShooter() {
350 shooter_speed_ = 0.0;
351
352 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
353 .angular_velocity(shooter_speed_)
354 .clamp_open(false)
355 .push_to_shooter(false)
356 .force_lights_on(false)
357 .Send()) {
358 LOG(ERROR, "Sending shooter goal failed.\n");
359 }
360}
361
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700362void AutonomousActor::SetShooterSpeed(double speed) {
363 shooter_speed_ = speed;
364
365 // In auto, we want to have the lights on whenever possible since we have no
366 // hope of a human aligning the robot.
367 bool force_lights_on = shooter_speed_ > 1.0;
368
369 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
370 .angular_velocity(shooter_speed_)
371 .clamp_open(false)
372 .push_to_shooter(false)
373 .force_lights_on(force_lights_on)
374 .Send()) {
375 LOG(ERROR, "Sending shooter goal failed.\n");
376 }
377}
378
379void AutonomousActor::Shoot() {
380 uint32_t initial_shots = 0;
381
382 control_loops::shooter::shooter_queue.status.FetchLatest();
383 if (control_loops::shooter::shooter_queue.status.get()) {
384 initial_shots = control_loops::shooter::shooter_queue.status->shots;
385 }
386
387 // In auto, we want to have the lights on whenever possible since we have no
388 // hope of a human aligning the robot.
389 bool force_lights_on = shooter_speed_ > 1.0;
390
391 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
392 .angular_velocity(shooter_speed_)
393 .clamp_open(false)
394 .push_to_shooter(true)
395 .force_lights_on(force_lights_on)
396 .Send()) {
397 LOG(ERROR, "Sending shooter goal failed.\n");
398 }
399
400 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
401 ::aos::time::Time::InMS(5) / 2);
402 while (true) {
403 if (ShouldCancel()) return;
404
405 // Wait for the shot count to change so we know when the shot is complete.
406 control_loops::shooter::shooter_queue.status.FetchLatest();
407 if (control_loops::shooter::shooter_queue.status.get()) {
408 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
409 return;
410 }
411 }
412 phased_loop.SleepUntilNext();
413 }
414}
415
416void AutonomousActor::WaitForShooterSpeed() {
417 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
418 ::aos::time::Time::InMS(5) / 2);
419 while (true) {
420 if (ShouldCancel()) return;
421
422 control_loops::shooter::shooter_queue.status.FetchLatest();
423 if (control_loops::shooter::shooter_queue.status.get()) {
424 if (control_loops::shooter::shooter_queue.status->left.ready &&
425 control_loops::shooter::shooter_queue.status->right.ready) {
426 return;
427 }
428 }
429 phased_loop.SleepUntilNext();
430 }
431}
432
433void AutonomousActor::AlignWithVisionGoal() {
434 actors::VisionAlignActionParams params;
435 vision_action_ = ::std::move(actors::MakeVisionAlignAction(params));
436 vision_action_->Start();
437}
438
Austin Schuh23b21802016-04-03 21:18:56 -0700439void AutonomousActor::WaitForAlignedWithVision(
440 ::aos::time::Time align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700441 bool vision_valid = false;
442 double last_angle = 0.0;
443 int ready_to_fire = 0;
444
445 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
446 ::aos::time::Time::InMS(5) / 2);
447 ::aos::time::Time end_time =
Austin Schuh23b21802016-04-03 21:18:56 -0700448 ::aos::time::Time::Now() + align_duration;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700449 while (end_time > ::aos::time::Time::Now()) {
450 if (ShouldCancel()) break;
451
452 ::y2016::vision::vision_status.FetchLatest();
453 if (::y2016::vision::vision_status.get()) {
454 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
455 ::y2016::vision::vision_status->right_image_valid);
456 last_angle = ::y2016::vision::vision_status->horizontal_angle;
457 }
458
459 drivetrain_queue.status.FetchLatest();
460 drivetrain_queue.goal.FetchLatest();
461
462 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
463 const double left_goal = drivetrain_queue.goal->left_goal;
464 const double right_goal = drivetrain_queue.goal->right_goal;
465 const double left_current =
466 drivetrain_queue.status->estimated_left_position;
467 const double right_current =
468 drivetrain_queue.status->estimated_right_position;
469 const double left_velocity =
470 drivetrain_queue.status->estimated_left_velocity;
471 const double right_velocity =
472 drivetrain_queue.status->estimated_right_velocity;
473
474 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
475 ::std::abs((left_goal - right_goal) -
476 (left_current - right_current)) /
477 dt_config_.robot_radius / 2.0 <
478 0.02 &&
479 ::std::abs(left_velocity - right_velocity) < 0.01) {
480 ++ready_to_fire;
481 } else {
482 ready_to_fire = 0;
483 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700484 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700485 break;
Austin Schuh23b21802016-04-03 21:18:56 -0700486 LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700487 }
488 }
489 phased_loop.SleepUntilNext();
490 }
491
492 vision_action_->Cancel();
493 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuh23b21802016-04-03 21:18:56 -0700494 LOG(INFO, "Done waiting for vision\n");
495}
496
497bool AutonomousActor::IntakeDone() {
498 control_loops::superstructure_queue.status.FetchAnother();
499
500 constexpr double kProfileError = 1e-5;
501 constexpr double kEpsilon = 0.15;
502
503 if (control_loops::superstructure_queue.status->state < 12 ||
504 control_loops::superstructure_queue.status->state == 16) {
505 LOG(ERROR, "Superstructure no longer running, aborting action\n");
506 return true;
507 }
508
509 if (::std::abs(control_loops::superstructure_queue.status->intake.goal_angle -
510 superstructure_goal_.intake) < kProfileError &&
511 ::std::abs(control_loops::superstructure_queue.status->intake
512 .goal_angular_velocity) < kProfileError) {
513 LOG(DEBUG, "Profile done.\n");
514 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
515 superstructure_goal_.intake) < kEpsilon &&
516 ::std::abs(control_loops::superstructure_queue.status->intake
517 .angular_velocity) < kEpsilon) {
518 LOG(INFO, "Near goal, done.\n");
519 return true;
520 }
521 }
522 return false;
523}
524
525bool AutonomousActor::SuperstructureProfileDone() {
526 constexpr double kProfileError = 1e-5;
527 return ::std::abs(
528 control_loops::superstructure_queue.status->intake.goal_angle -
529 superstructure_goal_.intake) < kProfileError &&
530 ::std::abs(
531 control_loops::superstructure_queue.status->shoulder.goal_angle -
532 superstructure_goal_.shoulder) < kProfileError &&
533 ::std::abs(
534 control_loops::superstructure_queue.status->wrist.goal_angle -
535 superstructure_goal_.wrist) < kProfileError &&
536 ::std::abs(control_loops::superstructure_queue.status->intake
537 .goal_angular_velocity) < kProfileError &&
538 ::std::abs(control_loops::superstructure_queue.status->shoulder
539 .goal_angular_velocity) < kProfileError &&
540 ::std::abs(control_loops::superstructure_queue.status->wrist
541 .goal_angular_velocity) < kProfileError;
542}
543
544bool AutonomousActor::SuperstructureDone() {
545 control_loops::superstructure_queue.status.FetchAnother();
546
547 constexpr double kEpsilon = 0.03;
548
549 if (control_loops::superstructure_queue.status->state < 12 ||
550 control_loops::superstructure_queue.status->state == 16) {
551 LOG(ERROR, "Superstructure no longer running, aborting action\n");
552 return true;
553 }
554
555 if (SuperstructureProfileDone()) {
556 LOG(DEBUG, "Profile done.\n");
557 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
558 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
559 ::std::abs(control_loops::superstructure_queue.status->shoulder.angle -
560 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
561 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
562 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
563 ::std::abs(control_loops::superstructure_queue.status->intake
564 .angular_velocity) < (kEpsilon + 0.1) &&
565 ::std::abs(control_loops::superstructure_queue.status->shoulder
566 .angular_velocity) < (kEpsilon + 0.10) &&
567 ::std::abs(control_loops::superstructure_queue.status->wrist
568 .angular_velocity) < (kEpsilon + 0.05)) {
569 LOG(INFO, "Near goal, done.\n");
570 return true;
571 }
572 }
573 return false;
574}
575
576void AutonomousActor::WaitForIntake() {
577 while (true) {
578 if (ShouldCancel()) return;
579 if (IntakeDone()) return;
580 }
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700581}
582
Comran Morshedb134e772016-03-16 21:05:05 +0000583void AutonomousActor::WaitForSuperstructure() {
584 while (true) {
585 if (ShouldCancel()) return;
Austin Schuh23b21802016-04-03 21:18:56 -0700586 if (SuperstructureDone()) return;
587 }
588}
Comran Morshedb134e772016-03-16 21:05:05 +0000589
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700590void AutonomousActor::WaitForSuperstructureProfile() {
591 while (true) {
592 if (ShouldCancel()) return;
593 control_loops::superstructure_queue.status.FetchAnother();
594
595 if (control_loops::superstructure_queue.status->state < 12 ||
596 control_loops::superstructure_queue.status->state == 16) {
597 LOG(ERROR, "Superstructure no longer running, aborting action\n");
598 return;
599 }
600
601 if (SuperstructureProfileDone()) return;
602 }
603}
604
Austin Schuh23b21802016-04-03 21:18:56 -0700605void AutonomousActor::WaitForSuperstructureLow() {
606 while (true) {
607 if (ShouldCancel()) return;
608 control_loops::superstructure_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +0000609
610 if (control_loops::superstructure_queue.status->state < 12 ||
611 control_loops::superstructure_queue.status->state == 16) {
612 LOG(ERROR, "Superstructure no longer running, aborting action\n");
613 return;
614 }
Austin Schuh23b21802016-04-03 21:18:56 -0700615 if (SuperstructureProfileDone()) return;
616 if (control_loops::superstructure_queue.status->shoulder.angle < 0.1) {
617 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000618 }
619 }
620}
Austin Schuh23b21802016-04-03 21:18:56 -0700621void AutonomousActor::BackLongShotLowBarTwoBall() {
622 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700623 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 -0700624 {10.0, 25.0}, false, 0.0);
625}
626
627void AutonomousActor::BackLongShotTwoBall() {
628 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700629 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55, {7.0, 40.0}, {4.0, 6.0},
630 {10.0, 25.0}, false, 0.0);
631}
632
633void AutonomousActor::BackLongShotTwoBallFinish() {
634 LOG(INFO, "Expanding for back long shot\n");
Adam Snaidera16f1072016-10-04 11:01:05 -0700635 MoveSuperstructure(
636 0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03, {7.0, 40.0},
637 {4.0, 6.0},
638 {10.0, 25.0}, false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700639}
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
Austin Schuh295c2d92016-05-01 12:28:04 -0700841 // Check if the ball is there.
842 bool first_ball_there = true;
843 ::y2016::sensors::ball_detector.FetchLatest();
844 if (::y2016::sensors::ball_detector.get()) {
845 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
846 first_ball_there = ball_detected;
847 LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
848 (aos::time::Time::Now() - start_time).ToSeconds());
849 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700850 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
851 false, 0.0);
852 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
853 (aos::time::Time::Now() - start_time).ToSeconds());
854 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
855 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
856 false, 0.0);
857 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700858 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700859
860 // We are now under the low bar. Start lifting.
861 BackLongShotLowBarTwoBall();
862 LOG(INFO, "Spinning up the shooter wheels\n");
863 SetShooterSpeed(640.0);
864 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
865
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700866 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
867 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700868 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
869 BackLongShotTwoBall();
870
871 if (!WaitForDriveDone()) return;
872 LOG(INFO, "First shot done driving at %f seconds\n",
873 (aos::time::Time::Now() - start_time).ToSeconds());
874
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700875 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700876
877 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700878 AlignWithVisionGoal();
879
880 WaitForShooterSpeed();
881 if (ShouldCancel()) return;
882
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700883 constexpr double kVisionExtra = 0.0;
884 WaitForAlignedWithVision(aos::time::Time::InSeconds(0.5 + kVisionExtra));
885 BackLongShotTwoBallFinish();
886 WaitForSuperstructureProfile();
887 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700888 LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700889 if (first_ball_there) {
890 Shoot();
891 } else {
892 LOG(INFO, "Nah, not shooting\n");
893 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700894
895 LOG(INFO, "First shot at %f seconds\n",
896 (aos::time::Time::Now() - start_time).ToSeconds());
897 if (ShouldCancel()) return;
898
899 SetShooterSpeed(0.0);
900 LOG(INFO, "Folding superstructure back down\n");
901 TuckArm(true, true);
902
903 // Undo vision move.
904 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
905 if (!WaitForDriveDone()) return;
906
907 constexpr double kBackDrive = 3.09 - 0.4;
908 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700909 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700910 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700911 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
912 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700913
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700914 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700915 LOG(INFO, "At Low Bar %f\n",
916 (aos::time::Time::Now() - start_time).ToSeconds());
917
918 OpenShooter();
919 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700920 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
921 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700922 constexpr double kBallSmallWallTurn = -0.11;
923 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
924
925 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
926 false, 12.0);
927
928 if (!WaitForDriveProfileDone()) return;
929
930 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
931 false, 12.0);
932
933 LOG(INFO, "Done backing up %f\n",
934 (aos::time::Time::Now() - start_time).ToSeconds());
935
936 constexpr double kDriveBackDistance = 5.15 - 0.4;
937 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
938 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700939 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700940
941 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
942 LOG(INFO, "Straightening up at %f\n",
943 (aos::time::Time::Now() - start_time).ToSeconds());
944
945 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700946 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700947
948 ::y2016::sensors::ball_detector.FetchLatest();
949 if (::y2016::sensors::ball_detector.get()) {
950 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
951 if (!ball_detected) {
952 if (!WaitForDriveDone()) return;
953 LOG(INFO, "Aborting, no ball %f\n",
954 (aos::time::Time::Now() - start_time).ToSeconds());
955 return;
956 }
957 }
958 CloseShooter();
959
960 BackLongShotLowBarTwoBall();
961 LOG(INFO, "Spinning up the shooter wheels\n");
962 SetShooterSpeed(640.0);
963 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
964
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700965 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700966 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
967 BackLongShotTwoBall();
968
969 if (!WaitForDriveDone()) return;
970 LOG(INFO, "Second shot done driving at %f seconds\n",
971 (aos::time::Time::Now() - start_time).ToSeconds());
972 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700973 AlignWithVisionGoal();
974 if (ShouldCancel()) return;
975
976 WaitForShooterSpeed();
977 if (ShouldCancel()) return;
978
979 // 2.2 with 0.4 of vision.
980 // 1.8 without any vision.
981 LOG(INFO, "Going to vision align at %f\n",
982 (aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700983 WaitForAlignedWithVision(start_time + aos::time::Time::InSeconds(13.5 + kVisionExtra * 2) -
Austin Schuh3e4a5272016-04-20 20:11:00 -0700984 aos::time::Time::Now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700985 BackLongShotTwoBallFinish();
986 WaitForSuperstructureProfile();
987 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700988 LOG(INFO, "Shoot at %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
989 Shoot();
990
991 LOG(INFO, "Second shot at %f seconds\n",
992 (aos::time::Time::Now() - start_time).ToSeconds());
993 if (ShouldCancel()) return;
994
995 SetShooterSpeed(0.0);
996 LOG(INFO, "Folding superstructure back down\n");
997 TuckArm(true, false);
998 LOG(INFO, "Shot %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
999
1000 WaitForSuperstructureLow();
1001
1002 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
1003}
1004
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001005void AutonomousActor::StealAndMoveOverBy(double distance) {
1006 OpenShooter();
1007 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1008 true, 12.0);
1009 if (ShouldCancel()) return;
1010 LOG(INFO, "Waiting for the intake to come down.\n");
1011
1012 WaitForIntake();
1013 if (ShouldCancel()) return;
1014 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
1015 WaitForBallOrDriveDone();
1016 if (ShouldCancel()) return;
1017 MoveSuperstructure(1.0, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1018 true, 12.0);
1019
1020 if (!WaitForDriveDone()) return;
1021 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
1022 if (!WaitForDriveDone()) return;
1023}
1024
Comran Morshede68e3732016-03-12 14:12:11 +00001025bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
Austin Schuh3e4a5272016-04-20 20:11:00 -07001026 aos::time::Time start_time = aos::time::Time::Now();
Comran Morshede68e3732016-03-12 14:12:11 +00001027 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
1028
Comran Morshed435f1112016-03-12 14:20:45 +00001029 InitializeEncoders();
1030 ResetDrivetrain();
1031
Austin Schuh295c2d92016-05-01 12:28:04 -07001032 switch (params.mode) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001033 case 0:
1034 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001035 if (!WaitForDriveDone()) return true;
1036 // Get the superstructure to unfold and get ready for shooting.
1037 LOG(INFO, "Unfolding superstructure\n");
1038 FrontLongShot();
1039
1040 // Spin up the shooter wheels.
1041 LOG(INFO, "Spinning up the shooter wheels\n");
1042 SetShooterSpeed(640.0);
1043
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001044 break;
1045 case 1:
1046 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001047 if (!WaitForDriveDone()) return true;
1048 // Get the superstructure to unfold and get ready for shooting.
1049 LOG(INFO, "Unfolding superstructure\n");
1050 FrontMiddleShot();
1051
1052 // Spin up the shooter wheels.
1053 LOG(INFO, "Spinning up the shooter wheels\n");
1054 SetShooterSpeed(600.0);
1055
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001056 break;
1057 case 2:
1058 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001059 if (!WaitForDriveDone()) return true;
1060 // Get the superstructure to unfold and get ready for shooting.
1061 LOG(INFO, "Unfolding superstructure\n");
1062 FrontMiddleShot();
1063
1064 // Spin up the shooter wheels.
1065 LOG(INFO, "Spinning up the shooter wheels\n");
1066 SetShooterSpeed(600.0);
1067
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001068 break;
1069 case 3:
1070 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001071 if (!WaitForDriveDone()) return true;
1072 // Get the superstructure to unfold and get ready for shooting.
1073 LOG(INFO, "Unfolding superstructure\n");
1074 FrontMiddleShot();
1075
1076 // Spin up the shooter wheels.
1077 LOG(INFO, "Spinning up the shooter wheels\n");
1078 SetShooterSpeed(600.0);
1079
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001080 break;
1081 case 4:
1082 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001083 if (!WaitForDriveDone()) return true;
1084 // Get the superstructure to unfold and get ready for shooting.
1085 LOG(INFO, "Unfolding superstructure\n");
1086 FrontMiddleShot();
1087
1088 // Spin up the shooter wheels.
1089 LOG(INFO, "Spinning up the shooter wheels\n");
1090 SetShooterSpeed(600.0);
1091
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001092 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001093 case 5:
1094 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -07001095 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001096 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001097 case 6:
1098 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
1099 if (ShouldCancel()) return true;
1100
1101 TwoFromMiddleDrive();
1102 if (!WaitForDriveDone()) return true;
1103 // Get the superstructure to unfold and get ready for shooting.
1104 LOG(INFO, "Unfolding superstructure\n");
1105 FrontMiddleShot();
1106
1107 // Spin up the shooter wheels.
1108 LOG(INFO, "Spinning up the shooter wheels\n");
1109 SetShooterSpeed(600.0);
1110
1111 break;
1112 case 7:
1113 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
1114 if (ShouldCancel()) return true;
1115
1116 OneFromMiddleDrive(true);
1117 if (!WaitForDriveDone()) return true;
1118 // Get the superstructure to unfold and get ready for shooting.
1119 LOG(INFO, "Unfolding superstructure\n");
1120 FrontMiddleShot();
1121
1122 // Spin up the shooter wheels.
1123 LOG(INFO, "Spinning up the shooter wheels\n");
1124 SetShooterSpeed(600.0);
1125
1126 break;
1127 case 8: {
1128 StealAndMoveOverBy(2.95);
1129 if (ShouldCancel()) return true;
1130
1131 MiddleDrive();
1132 if (!WaitForDriveDone()) return true;
1133 // Get the superstructure to unfold and get ready for shooting.
1134 LOG(INFO, "Unfolding superstructure\n");
1135 FrontMiddleShot();
1136
1137 // Spin up the shooter wheels.
1138 LOG(INFO, "Spinning up the shooter wheels\n");
1139 SetShooterSpeed(600.0);
1140
1141 } break;
1142 case 9: {
1143 StealAndMoveOverBy(1.70);
1144 if (ShouldCancel()) return true;
1145
1146 OneFromMiddleDrive(false);
1147 if (!WaitForDriveDone()) return true;
1148 // Get the superstructure to unfold and get ready for shooting.
1149 LOG(INFO, "Unfolding superstructure\n");
1150 FrontMiddleShot();
1151
1152 // Spin up the shooter wheels.
1153 LOG(INFO, "Spinning up the shooter wheels\n");
1154 SetShooterSpeed(600.0);
1155
1156 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001157 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -07001158 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001159 return true;
1160 }
Comran Morshed435f1112016-03-12 14:20:45 +00001161
Austin Schuh3e4a5272016-04-20 20:11:00 -07001162 DoFullShot();
1163
1164 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +00001165 if (!WaitForDriveDone()) return true;
1166
Austin Schuh3e4a5272016-04-20 20:11:00 -07001167 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
Comran Morshed435f1112016-03-12 14:20:45 +00001168
1169 ::aos::time::PhasedLoop phased_loop(::aos::time::Time::InMS(5),
1170 ::aos::time::Time::InMS(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001171
Comran Morshed435f1112016-03-12 14:20:45 +00001172 while (!ShouldCancel()) {
1173 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +00001174 }
Comran Morshed435f1112016-03-12 14:20:45 +00001175 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +00001176
1177 return true;
1178}
1179
1180::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
1181 const ::y2016::actors::AutonomousActionParams &params) {
1182 return ::std::unique_ptr<AutonomousAction>(
1183 new AutonomousAction(&::y2016::actors::autonomous_action, params));
1184}
1185
1186} // namespace actors
1187} // namespace y2016