blob: f2984207a6b5757640c327c1f0ff89063d89007f [file] [log] [blame]
Comran Morshede68e3732016-03-12 14:12:11 +00001#include "y2016/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
Austin Schuh8aec1ed2016-05-01 13:29:20 -07005#include <chrono>
Comran Morshedb134e772016-03-16 21:05:05 +00006#include <cmath>
7
Comran Morshede68e3732016-03-12 14:12:11 +00008#include "aos/common/util/phased_loop.h"
9#include "aos/common/logging/logging.h"
Comran Morshed435f1112016-03-12 14:20:45 +000010
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "y2016/control_loops/drivetrain/drivetrain_base.h"
Austin Schuhf59b8ee2016-03-19 21:31:36 -070013#include "y2016/control_loops/shooter/shooter.q.h"
Comran Morshedb134e772016-03-16 21:05:05 +000014#include "y2016/control_loops/superstructure/superstructure.q.h"
15#include "y2016/actors/autonomous_action.q.h"
Austin Schuh23b21802016-04-03 21:18:56 -070016#include "y2016/queues/ball_detector.q.h"
Austin Schuhf59b8ee2016-03-19 21:31:36 -070017#include "y2016/vision/vision.q.h"
Comran Morshede68e3732016-03-12 14:12:11 +000018
19namespace y2016 {
20namespace actors {
Comran Morshed435f1112016-03-12 14:20:45 +000021using ::frc971::control_loops::drivetrain_queue;
22
23namespace {
Austin Schuhf59b8ee2016-03-19 21:31:36 -070024const ProfileParameters kSlowDrive = {0.8, 2.5};
25const ProfileParameters kLowBarDrive = {1.3, 2.5};
26const ProfileParameters kMoatDrive = {1.2, 3.5};
27const ProfileParameters kRealignDrive = {2.0, 2.5};
28const ProfileParameters kRockWallDrive = {0.8, 2.5};
Comran Morshed435f1112016-03-12 14:20:45 +000029const ProfileParameters kFastDrive = {3.0, 2.5};
30
Austin Schuhf59b8ee2016-03-19 21:31:36 -070031const ProfileParameters kSlowTurn = {0.8, 3.0};
Comran Morshed435f1112016-03-12 14:20:45 +000032const ProfileParameters kFastTurn = {3.0, 10.0};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070033const ProfileParameters kStealTurn = {4.0, 15.0};
Austin Schuh23b21802016-04-03 21:18:56 -070034const ProfileParameters kSwerveTurn = {2.0, 7.0};
35const ProfileParameters kFinishTurn = {2.0, 5.0};
36
37const ProfileParameters kTwoBallLowDrive = {1.7, 3.5};
38const ProfileParameters kTwoBallFastDrive = {3.0, 1.5};
39const ProfileParameters kTwoBallReturnDrive = {3.0, 1.9};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070040const ProfileParameters kTwoBallReturnSlow = {3.0, 2.5};
Austin Schuh23b21802016-04-03 21:18:56 -070041const ProfileParameters kTwoBallBallPickup = {2.0, 1.75};
Austin Schuhe4ec49c2016-04-24 19:07:15 -070042const ProfileParameters kTwoBallBallPickupAccel = {2.0, 2.5};
Comran Morshed435f1112016-03-12 14:20:45 +000043} // namespace
Comran Morshede68e3732016-03-12 14:12:11 +000044
45AutonomousActor::AutonomousActor(actors::AutonomousActionQueueGroup *s)
Comran Morshed435f1112016-03-12 14:20:45 +000046 : aos::common::actions::ActorBase<actors::AutonomousActionQueueGroup>(s),
Comran Morshedb134e772016-03-16 21:05:05 +000047 dt_config_(control_loops::drivetrain::GetDrivetrainConfig()),
48 initial_drivetrain_({0.0, 0.0}) {}
Comran Morshed435f1112016-03-12 14:20:45 +000049
50void AutonomousActor::ResetDrivetrain() {
51 LOG(INFO, "resetting the drivetrain\n");
52 drivetrain_queue.goal.MakeWithBuilder()
53 .control_loop_driving(false)
54 .highgear(true)
55 .steering(0.0)
56 .throttle(0.0)
Comran Morshedb134e772016-03-16 21:05:05 +000057 .left_goal(initial_drivetrain_.left)
Comran Morshed435f1112016-03-12 14:20:45 +000058 .left_velocity_goal(0)
Comran Morshedb134e772016-03-16 21:05:05 +000059 .right_goal(initial_drivetrain_.right)
Comran Morshed435f1112016-03-12 14:20:45 +000060 .right_velocity_goal(0)
61 .Send();
62}
63
64void AutonomousActor::StartDrive(double distance, double angle,
65 ProfileParameters linear,
66 ProfileParameters angular) {
67 {
Austin Schuh23b21802016-04-03 21:18:56 -070068 LOG(INFO, "Driving distance %f, angle %f\n", distance, angle);
Comran Morshed435f1112016-03-12 14:20:45 +000069 {
70 const double dangle = angle * dt_config_.robot_radius;
Comran Morshedb134e772016-03-16 21:05:05 +000071 initial_drivetrain_.left += distance - dangle;
72 initial_drivetrain_.right += distance + dangle;
Comran Morshed435f1112016-03-12 14:20:45 +000073 }
74
Comran Morshedb134e772016-03-16 21:05:05 +000075 auto drivetrain_message = drivetrain_queue.goal.MakeMessage();
Comran Morshed435f1112016-03-12 14:20:45 +000076 drivetrain_message->control_loop_driving = true;
77 drivetrain_message->highgear = true;
78 drivetrain_message->steering = 0.0;
79 drivetrain_message->throttle = 0.0;
Comran Morshedb134e772016-03-16 21:05:05 +000080 drivetrain_message->left_goal = initial_drivetrain_.left;
Comran Morshed435f1112016-03-12 14:20:45 +000081 drivetrain_message->left_velocity_goal = 0;
Comran Morshedb134e772016-03-16 21:05:05 +000082 drivetrain_message->right_goal = initial_drivetrain_.right;
Comran Morshed435f1112016-03-12 14:20:45 +000083 drivetrain_message->right_velocity_goal = 0;
84 drivetrain_message->linear = linear;
85 drivetrain_message->angular = angular;
86
87 LOG_STRUCT(DEBUG, "drivetrain_goal", *drivetrain_message);
88
89 drivetrain_message.Send();
90 }
91}
92
93void AutonomousActor::InitializeEncoders() {
94 drivetrain_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +000095 initial_drivetrain_.left = drivetrain_queue.status->estimated_left_position;
96 initial_drivetrain_.right = drivetrain_queue.status->estimated_right_position;
Comran Morshed435f1112016-03-12 14:20:45 +000097}
98
99void AutonomousActor::WaitUntilDoneOrCanceled(
100 ::std::unique_ptr<aos::common::actions::Action> action) {
101 if (!action) {
102 LOG(ERROR, "No action, not waiting\n");
103 return;
104 }
105
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700106 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
107 ::std::chrono::milliseconds(5) / 2);
Comran Morshed435f1112016-03-12 14:20:45 +0000108 while (true) {
109 // Poll the running bit and see if we should cancel.
110 phased_loop.SleepUntilNext();
111 if (!action->Running() || ShouldCancel()) {
112 return;
113 }
114 }
115}
116
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700117constexpr double kDoNotTurnCare = 2.0;
118
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700119bool AutonomousActor::WaitForDriveNear(double distance, double angle) {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700120 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
121 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700122 constexpr double kPositionTolerance = 0.02;
123 constexpr double kProfileTolerance = 0.001;
124
125 while (true) {
126 if (ShouldCancel()) {
127 return false;
128 }
129 phased_loop.SleepUntilNext();
130 drivetrain_queue.status.FetchLatest();
131 if (drivetrain_queue.status.get()) {
132 const double left_profile_error =
133 (initial_drivetrain_.left -
134 drivetrain_queue.status->profiled_left_position_goal);
135 const double right_profile_error =
136 (initial_drivetrain_.right -
137 drivetrain_queue.status->profiled_right_position_goal);
138
139 const double left_error =
140 (initial_drivetrain_.left -
141 drivetrain_queue.status->estimated_left_position);
142 const double right_error =
143 (initial_drivetrain_.right -
144 drivetrain_queue.status->estimated_right_position);
145
146 const double profile_distance_to_go =
147 (left_profile_error + right_profile_error) / 2.0;
148 const double profile_angle_to_go =
149 (right_profile_error - left_profile_error) /
150 (dt_config_.robot_radius * 2.0);
151
152 const double distance_to_go = (left_error + right_error) / 2.0;
153 const double angle_to_go =
154 (right_error - left_error) / (dt_config_.robot_radius * 2.0);
155
156 if (::std::abs(profile_distance_to_go) < distance + kProfileTolerance &&
157 ::std::abs(profile_angle_to_go) < angle + kProfileTolerance &&
158 ::std::abs(distance_to_go) < distance + kPositionTolerance &&
159 ::std::abs(angle_to_go) < angle + kPositionTolerance) {
160 LOG(INFO, "Closer than %f distance, %f angle\n", distance, angle);
161 return true;
162 }
163 }
164 }
165}
166
Austin Schuh23b21802016-04-03 21:18:56 -0700167bool AutonomousActor::WaitForDriveProfileDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700168 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
169 ::std::chrono::milliseconds(5) / 2);
Austin Schuh23b21802016-04-03 21:18:56 -0700170 constexpr double kProfileTolerance = 0.001;
171
172 while (true) {
173 if (ShouldCancel()) {
174 return false;
175 }
176 phased_loop.SleepUntilNext();
177 drivetrain_queue.status.FetchLatest();
178 if (drivetrain_queue.status.get()) {
179 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
180 initial_drivetrain_.left) < kProfileTolerance &&
181 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
182 initial_drivetrain_.right) < kProfileTolerance) {
183 LOG(INFO, "Finished drive\n");
184 return true;
185 }
186 }
187 }
188}
189
Austin Schuh3e4a5272016-04-20 20:11:00 -0700190bool AutonomousActor::WaitForMaxBy(double angle) {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700191 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
192 ::std::chrono::milliseconds(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700193 double max_angle = -M_PI;
194 while (true) {
195 if (ShouldCancel()) {
196 return false;
197 }
198 phased_loop.SleepUntilNext();
199 drivetrain_queue.status.FetchLatest();
200 if (IsDriveDone()) {
201 return true;
202 }
203 if (drivetrain_queue.status.get()) {
204 if (drivetrain_queue.status->ground_angle > max_angle) {
205 max_angle = drivetrain_queue.status->ground_angle;
206 }
207 if (drivetrain_queue.status->ground_angle < max_angle - angle) {
208 return true;
209 }
210 }
211 }
212}
213
214bool AutonomousActor::WaitForAboveAngle(double angle) {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700215 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
216 ::std::chrono::milliseconds(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700217 while (true) {
218 if (ShouldCancel()) {
219 return false;
220 }
221 phased_loop.SleepUntilNext();
222 drivetrain_queue.status.FetchLatest();
223 if (IsDriveDone()) {
224 return true;
225 }
226 if (drivetrain_queue.status.get()) {
227 if (drivetrain_queue.status->ground_angle > angle) {
228 return true;
229 }
230 }
231 }
232}
233
234bool AutonomousActor::WaitForBelowAngle(double angle) {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700235 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
236 ::std::chrono::milliseconds(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700237 while (true) {
238 if (ShouldCancel()) {
239 return false;
240 }
241 phased_loop.SleepUntilNext();
242 drivetrain_queue.status.FetchLatest();
243 if (IsDriveDone()) {
244 return true;
245 }
246 if (drivetrain_queue.status.get()) {
247 if (drivetrain_queue.status->ground_angle < angle) {
248 return true;
249 }
250 }
251 }
252}
253
254bool AutonomousActor::IsDriveDone() {
Comran Morshed435f1112016-03-12 14:20:45 +0000255 constexpr double kPositionTolerance = 0.02;
256 constexpr double kVelocityTolerance = 0.10;
257 constexpr double kProfileTolerance = 0.001;
258
Austin Schuh3e4a5272016-04-20 20:11:00 -0700259 if (drivetrain_queue.status.get()) {
260 if (::std::abs(drivetrain_queue.status->profiled_left_position_goal -
261 initial_drivetrain_.left) < kProfileTolerance &&
262 ::std::abs(drivetrain_queue.status->profiled_right_position_goal -
263 initial_drivetrain_.right) < kProfileTolerance &&
264 ::std::abs(drivetrain_queue.status->estimated_left_position -
265 initial_drivetrain_.left) < kPositionTolerance &&
266 ::std::abs(drivetrain_queue.status->estimated_right_position -
267 initial_drivetrain_.right) < kPositionTolerance &&
268 ::std::abs(drivetrain_queue.status->estimated_left_velocity) <
269 kVelocityTolerance &&
270 ::std::abs(drivetrain_queue.status->estimated_right_velocity) <
271 kVelocityTolerance) {
272 LOG(INFO, "Finished drive\n");
273 return true;
274 }
275 }
276 return false;
277}
278
279bool AutonomousActor::WaitForDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700280 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
281 ::std::chrono::milliseconds(5) / 2);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700282
Comran Morshed435f1112016-03-12 14:20:45 +0000283 while (true) {
284 if (ShouldCancel()) {
285 return false;
286 }
287 phased_loop.SleepUntilNext();
288 drivetrain_queue.status.FetchLatest();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700289 if (IsDriveDone()) {
290 return true;
Comran Morshed435f1112016-03-12 14:20:45 +0000291 }
292 }
293}
Comran Morshede68e3732016-03-12 14:12:11 +0000294
Comran Morshedb134e772016-03-16 21:05:05 +0000295void AutonomousActor::MoveSuperstructure(
296 double intake, double shoulder, double wrist,
297 const ProfileParameters intake_params,
298 const ProfileParameters shoulder_params,
Austin Schuh23b21802016-04-03 21:18:56 -0700299 const ProfileParameters wrist_params, bool traverse_up,
300 double roller_power) {
Comran Morshedb134e772016-03-16 21:05:05 +0000301 superstructure_goal_ = {intake, shoulder, wrist};
302
303 auto new_superstructure_goal =
304 ::y2016::control_loops::superstructure_queue.goal.MakeMessage();
305
306 new_superstructure_goal->angle_intake = intake;
307 new_superstructure_goal->angle_shoulder = shoulder;
308 new_superstructure_goal->angle_wrist = wrist;
309
310 new_superstructure_goal->max_angular_velocity_intake =
311 intake_params.max_velocity;
312 new_superstructure_goal->max_angular_velocity_shoulder =
313 shoulder_params.max_velocity;
314 new_superstructure_goal->max_angular_velocity_wrist =
315 wrist_params.max_velocity;
316
317 new_superstructure_goal->max_angular_acceleration_intake =
318 intake_params.max_acceleration;
319 new_superstructure_goal->max_angular_acceleration_shoulder =
320 shoulder_params.max_acceleration;
321 new_superstructure_goal->max_angular_acceleration_wrist =
322 wrist_params.max_acceleration;
323
Austin Schuh23b21802016-04-03 21:18:56 -0700324 new_superstructure_goal->voltage_top_rollers = roller_power;
325 new_superstructure_goal->voltage_bottom_rollers = roller_power;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700326
327 new_superstructure_goal->traverse_unlatched = true;
328 new_superstructure_goal->traverse_down = !traverse_up;
Diana Vandenberg9cc9ab62016-04-20 21:27:47 -0700329 new_superstructure_goal->voltage_climber = 0.0;
330 new_superstructure_goal->unfold_climber = false;
Comran Morshedb134e772016-03-16 21:05:05 +0000331
332 if (!new_superstructure_goal.Send()) {
333 LOG(ERROR, "Sending superstructure goal failed.\n");
334 }
335}
336
Austin Schuh23b21802016-04-03 21:18:56 -0700337void AutonomousActor::OpenShooter() {
338 shooter_speed_ = 0.0;
339
340 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
341 .angular_velocity(shooter_speed_)
342 .clamp_open(true)
343 .push_to_shooter(false)
344 .force_lights_on(false)
345 .Send()) {
346 LOG(ERROR, "Sending shooter goal failed.\n");
347 }
348}
349
350void AutonomousActor::CloseShooter() {
351 shooter_speed_ = 0.0;
352
353 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
354 .angular_velocity(shooter_speed_)
355 .clamp_open(false)
356 .push_to_shooter(false)
357 .force_lights_on(false)
358 .Send()) {
359 LOG(ERROR, "Sending shooter goal failed.\n");
360 }
361}
362
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700363void AutonomousActor::SetShooterSpeed(double speed) {
364 shooter_speed_ = speed;
365
366 // In auto, we want to have the lights on whenever possible since we have no
367 // hope of a human aligning the robot.
368 bool force_lights_on = shooter_speed_ > 1.0;
369
370 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
371 .angular_velocity(shooter_speed_)
372 .clamp_open(false)
373 .push_to_shooter(false)
374 .force_lights_on(force_lights_on)
375 .Send()) {
376 LOG(ERROR, "Sending shooter goal failed.\n");
377 }
378}
379
380void AutonomousActor::Shoot() {
381 uint32_t initial_shots = 0;
382
383 control_loops::shooter::shooter_queue.status.FetchLatest();
384 if (control_loops::shooter::shooter_queue.status.get()) {
385 initial_shots = control_loops::shooter::shooter_queue.status->shots;
386 }
387
388 // In auto, we want to have the lights on whenever possible since we have no
389 // hope of a human aligning the robot.
390 bool force_lights_on = shooter_speed_ > 1.0;
391
392 if (!control_loops::shooter::shooter_queue.goal.MakeWithBuilder()
393 .angular_velocity(shooter_speed_)
394 .clamp_open(false)
395 .push_to_shooter(true)
396 .force_lights_on(force_lights_on)
397 .Send()) {
398 LOG(ERROR, "Sending shooter goal failed.\n");
399 }
400
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700401 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
402 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700403 while (true) {
404 if (ShouldCancel()) return;
405
406 // Wait for the shot count to change so we know when the shot is complete.
407 control_loops::shooter::shooter_queue.status.FetchLatest();
408 if (control_loops::shooter::shooter_queue.status.get()) {
409 if (initial_shots < control_loops::shooter::shooter_queue.status->shots) {
410 return;
411 }
412 }
413 phased_loop.SleepUntilNext();
414 }
415}
416
417void AutonomousActor::WaitForShooterSpeed() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700418 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
419 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700420 while (true) {
421 if (ShouldCancel()) return;
422
423 control_loops::shooter::shooter_queue.status.FetchLatest();
424 if (control_loops::shooter::shooter_queue.status.get()) {
425 if (control_loops::shooter::shooter_queue.status->left.ready &&
426 control_loops::shooter::shooter_queue.status->right.ready) {
427 return;
428 }
429 }
430 phased_loop.SleepUntilNext();
431 }
432}
433
434void AutonomousActor::AlignWithVisionGoal() {
435 actors::VisionAlignActionParams params;
436 vision_action_ = ::std::move(actors::MakeVisionAlignAction(params));
437 vision_action_->Start();
438}
439
Austin Schuh23b21802016-04-03 21:18:56 -0700440void AutonomousActor::WaitForAlignedWithVision(
441 ::aos::time::Time align_duration) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700442 bool vision_valid = false;
443 double last_angle = 0.0;
444 int ready_to_fire = 0;
445
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700446 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
447 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700448 ::aos::time::Time end_time =
Austin Schuh23b21802016-04-03 21:18:56 -0700449 ::aos::time::Time::Now() + align_duration;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700450 while (end_time > ::aos::time::Time::Now()) {
451 if (ShouldCancel()) break;
452
453 ::y2016::vision::vision_status.FetchLatest();
454 if (::y2016::vision::vision_status.get()) {
455 vision_valid = (::y2016::vision::vision_status->left_image_valid &&
456 ::y2016::vision::vision_status->right_image_valid);
457 last_angle = ::y2016::vision::vision_status->horizontal_angle;
458 }
459
460 drivetrain_queue.status.FetchLatest();
461 drivetrain_queue.goal.FetchLatest();
462
463 if (drivetrain_queue.status.get() && drivetrain_queue.goal.get()) {
464 const double left_goal = drivetrain_queue.goal->left_goal;
465 const double right_goal = drivetrain_queue.goal->right_goal;
466 const double left_current =
467 drivetrain_queue.status->estimated_left_position;
468 const double right_current =
469 drivetrain_queue.status->estimated_right_position;
470 const double left_velocity =
471 drivetrain_queue.status->estimated_left_velocity;
472 const double right_velocity =
473 drivetrain_queue.status->estimated_right_velocity;
474
475 if (vision_valid && ::std::abs(last_angle) < 0.02 &&
476 ::std::abs((left_goal - right_goal) -
477 (left_current - right_current)) /
478 dt_config_.robot_radius / 2.0 <
479 0.02 &&
480 ::std::abs(left_velocity - right_velocity) < 0.01) {
481 ++ready_to_fire;
482 } else {
483 ready_to_fire = 0;
484 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700485 if (ready_to_fire > 15) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700486 break;
Austin Schuh23b21802016-04-03 21:18:56 -0700487 LOG(INFO, "Vision align success!\n");
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700488 }
489 }
490 phased_loop.SleepUntilNext();
491 }
492
493 vision_action_->Cancel();
494 WaitUntilDoneOrCanceled(::std::move(vision_action_));
Austin Schuh23b21802016-04-03 21:18:56 -0700495 LOG(INFO, "Done waiting for vision\n");
496}
497
498bool AutonomousActor::IntakeDone() {
499 control_loops::superstructure_queue.status.FetchAnother();
500
501 constexpr double kProfileError = 1e-5;
502 constexpr double kEpsilon = 0.15;
503
504 if (control_loops::superstructure_queue.status->state < 12 ||
505 control_loops::superstructure_queue.status->state == 16) {
506 LOG(ERROR, "Superstructure no longer running, aborting action\n");
507 return true;
508 }
509
510 if (::std::abs(control_loops::superstructure_queue.status->intake.goal_angle -
511 superstructure_goal_.intake) < kProfileError &&
512 ::std::abs(control_loops::superstructure_queue.status->intake
513 .goal_angular_velocity) < kProfileError) {
514 LOG(DEBUG, "Profile done.\n");
515 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
516 superstructure_goal_.intake) < kEpsilon &&
517 ::std::abs(control_loops::superstructure_queue.status->intake
518 .angular_velocity) < kEpsilon) {
519 LOG(INFO, "Near goal, done.\n");
520 return true;
521 }
522 }
523 return false;
524}
525
526bool AutonomousActor::SuperstructureProfileDone() {
527 constexpr double kProfileError = 1e-5;
528 return ::std::abs(
529 control_loops::superstructure_queue.status->intake.goal_angle -
530 superstructure_goal_.intake) < kProfileError &&
531 ::std::abs(
532 control_loops::superstructure_queue.status->shoulder.goal_angle -
533 superstructure_goal_.shoulder) < kProfileError &&
534 ::std::abs(
535 control_loops::superstructure_queue.status->wrist.goal_angle -
536 superstructure_goal_.wrist) < kProfileError &&
537 ::std::abs(control_loops::superstructure_queue.status->intake
538 .goal_angular_velocity) < kProfileError &&
539 ::std::abs(control_loops::superstructure_queue.status->shoulder
540 .goal_angular_velocity) < kProfileError &&
541 ::std::abs(control_loops::superstructure_queue.status->wrist
542 .goal_angular_velocity) < kProfileError;
543}
544
545bool AutonomousActor::SuperstructureDone() {
546 control_loops::superstructure_queue.status.FetchAnother();
547
548 constexpr double kEpsilon = 0.03;
549
550 if (control_loops::superstructure_queue.status->state < 12 ||
551 control_loops::superstructure_queue.status->state == 16) {
552 LOG(ERROR, "Superstructure no longer running, aborting action\n");
553 return true;
554 }
555
556 if (SuperstructureProfileDone()) {
557 LOG(DEBUG, "Profile done.\n");
558 if (::std::abs(control_loops::superstructure_queue.status->intake.angle -
559 superstructure_goal_.intake) < (kEpsilon + 0.1) &&
560 ::std::abs(control_loops::superstructure_queue.status->shoulder.angle -
561 superstructure_goal_.shoulder) < (kEpsilon + 0.05) &&
562 ::std::abs(control_loops::superstructure_queue.status->wrist.angle -
563 superstructure_goal_.wrist) < (kEpsilon + 0.01) &&
564 ::std::abs(control_loops::superstructure_queue.status->intake
565 .angular_velocity) < (kEpsilon + 0.1) &&
566 ::std::abs(control_loops::superstructure_queue.status->shoulder
567 .angular_velocity) < (kEpsilon + 0.10) &&
568 ::std::abs(control_loops::superstructure_queue.status->wrist
569 .angular_velocity) < (kEpsilon + 0.05)) {
570 LOG(INFO, "Near goal, done.\n");
571 return true;
572 }
573 }
574 return false;
575}
576
577void AutonomousActor::WaitForIntake() {
578 while (true) {
579 if (ShouldCancel()) return;
580 if (IntakeDone()) return;
581 }
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700582}
583
Comran Morshedb134e772016-03-16 21:05:05 +0000584void AutonomousActor::WaitForSuperstructure() {
585 while (true) {
586 if (ShouldCancel()) return;
Austin Schuh23b21802016-04-03 21:18:56 -0700587 if (SuperstructureDone()) return;
588 }
589}
Comran Morshedb134e772016-03-16 21:05:05 +0000590
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700591void AutonomousActor::WaitForSuperstructureProfile() {
592 while (true) {
593 if (ShouldCancel()) return;
594 control_loops::superstructure_queue.status.FetchAnother();
595
596 if (control_loops::superstructure_queue.status->state < 12 ||
597 control_loops::superstructure_queue.status->state == 16) {
598 LOG(ERROR, "Superstructure no longer running, aborting action\n");
599 return;
600 }
601
602 if (SuperstructureProfileDone()) return;
603 }
604}
605
Austin Schuh23b21802016-04-03 21:18:56 -0700606void AutonomousActor::WaitForSuperstructureLow() {
607 while (true) {
608 if (ShouldCancel()) return;
609 control_loops::superstructure_queue.status.FetchAnother();
Comran Morshedb134e772016-03-16 21:05:05 +0000610
611 if (control_loops::superstructure_queue.status->state < 12 ||
612 control_loops::superstructure_queue.status->state == 16) {
613 LOG(ERROR, "Superstructure no longer running, aborting action\n");
614 return;
615 }
Austin Schuh23b21802016-04-03 21:18:56 -0700616 if (SuperstructureProfileDone()) return;
617 if (control_loops::superstructure_queue.status->shoulder.angle < 0.1) {
618 return;
Comran Morshedb134e772016-03-16 21:05:05 +0000619 }
620 }
621}
Austin Schuh23b21802016-04-03 21:18:56 -0700622void AutonomousActor::BackLongShotLowBarTwoBall() {
623 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700624 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 -0700625 {10.0, 25.0}, false, 0.0);
626}
627
628void AutonomousActor::BackLongShotTwoBall() {
629 LOG(INFO, "Expanding for back long shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700630 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.55, {7.0, 40.0}, {4.0, 6.0},
631 {10.0, 25.0}, false, 0.0);
632}
633
634void AutonomousActor::BackLongShotTwoBallFinish() {
635 LOG(INFO, "Expanding for back long shot\n");
Adam Snaidera16f1072016-10-04 11:01:05 -0700636 MoveSuperstructure(
637 0.00, M_PI / 2.0 - 0.2, -0.625 + 0.03, {7.0, 40.0},
638 {4.0, 6.0},
639 {10.0, 25.0}, false, 0.0);
Austin Schuh23b21802016-04-03 21:18:56 -0700640}
641
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700642void AutonomousActor::BackLongShot() {
643 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700644 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 6.0},
645 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700646}
647
648void AutonomousActor::BackMiddleShot() {
649 LOG(INFO, "Expanding for back middle shot\n");
650 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 -0700651 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700652}
653
Austin Schuh3e4a5272016-04-20 20:11:00 -0700654void AutonomousActor::FrontLongShot() {
655 LOG(INFO, "Expanding for front long shot\n");
656 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02, {7.0, 40.0},
657 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
658}
659
660void AutonomousActor::FrontMiddleShot() {
661 LOG(INFO, "Expanding for front middle shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700662 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44, {7.0, 40.0},
Austin Schuh3e4a5272016-04-20 20:11:00 -0700663 {4.0, 10.0}, {10.0, 25.0}, true, 0.0);
664}
665
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700666void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
667 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700668 {4.0, 10.0}, {10.0, 25.0}, !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700669}
670
Austin Schuh3e4a5272016-04-20 20:11:00 -0700671void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700672 if (ShouldCancel()) return;
673 // Make sure that the base is aligned with the base.
674 LOG(INFO, "Waiting for the superstructure\n");
675 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700676
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700677 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.5));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700678
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700679 if (ShouldCancel()) return;
680 LOG(INFO, "Triggering the vision actor\n");
681 AlignWithVisionGoal();
682
683 // Wait for the drive base to be aligned with the target and make sure that
684 // the shooter is up to speed.
685 LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700686 WaitForAlignedWithVision(aos::time::Time::InSeconds(2));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700687 if (ShouldCancel()) return;
688 LOG(INFO, "Waiting for shooter to be up to speed\n");
689 WaitForShooterSpeed();
690 if (ShouldCancel()) return;
691
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700692 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.3));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700693 LOG(INFO, "Shoot!\n");
694 Shoot();
695
696 // Turn off the shooter and fold up the superstructure.
697 if (ShouldCancel()) return;
698 LOG(INFO, "Stopping shooter\n");
699 SetShooterSpeed(0.0);
700 LOG(INFO, "Folding superstructure back down\n");
701 TuckArm(false, false);
702
703 // Wait for everything to be folded up.
704 LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700705 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700706}
707
708void AutonomousActor::LowBarDrive() {
709 TuckArm(false, true);
710 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
711
712 if (!WaitForDriveNear(5.3, 0.0)) return;
713 TuckArm(true, true);
714
715 if (!WaitForDriveNear(5.0, 0.0)) return;
716
717 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
718
719 if (!WaitForDriveNear(3.0, 0.0)) return;
720
721 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
722
723 if (!WaitForDriveNear(1.0, 0.0)) return;
724
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700725 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700726}
727
Austin Schuh3e4a5272016-04-20 20:11:00 -0700728void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
729 double below, double above) {
730 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
731 if (!WaitForBelowAngle(below)) return;
732 if (!WaitForAboveAngle(above)) return;
733 // Ok, we are good now. Compensate by moving the goal by the error.
734 // Should be here at 2.7
735 drivetrain_queue.status.FetchLatest();
736 if (drivetrain_queue.status.get()) {
737 const double left_error =
738 (initial_drivetrain_.left -
739 drivetrain_queue.status->estimated_left_position);
740 const double right_error =
741 (initial_drivetrain_.right -
742 drivetrain_queue.status->estimated_right_position);
743 const double distance_to_go = (left_error + right_error) / 2.0;
744 const double distance_compensation =
745 goal_distance - tip_distance - distance_to_go;
746 LOG(INFO, "Going %f further at the bump\n", distance_compensation);
747 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
748 }
749}
750
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700751void AutonomousActor::MiddleDrive() {
752 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700753 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700754 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700755}
756
757void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700758 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700759 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700760 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700761
762 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700763 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700764}
765
766void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700767 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700768 constexpr double kDriveDistance = 5.10;
769 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
770
771 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
772 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700773
774 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700775 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700776}
Comran Morshedb134e772016-03-16 21:05:05 +0000777
Austin Schuh23b21802016-04-03 21:18:56 -0700778void AutonomousActor::CloseIfBall() {
779 ::y2016::sensors::ball_detector.FetchLatest();
780 if (::y2016::sensors::ball_detector.get()) {
781 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
782 if (ball_detected) {
783 CloseShooter();
784 }
785 }
786}
787
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700788void AutonomousActor::WaitForBallOrDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700789 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
790 ::std::chrono::milliseconds(5) / 2);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700791 while (true) {
792 if (ShouldCancel()) {
793 return;
794 }
795 phased_loop.SleepUntilNext();
796 drivetrain_queue.status.FetchLatest();
797 if (IsDriveDone()) {
798 return;
799 }
800
801 ::y2016::sensors::ball_detector.FetchLatest();
802 if (::y2016::sensors::ball_detector.get()) {
803 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
804 if (ball_detected) {
805 return;
806 }
807 }
808 }
809}
810
Austin Schuh23b21802016-04-03 21:18:56 -0700811void AutonomousActor::WaitForBall() {
812 while (true) {
813 ::y2016::sensors::ball_detector.FetchAnother();
814 if (::y2016::sensors::ball_detector.get()) {
815 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
816 if (ball_detected) {
817 return;
818 }
819 if (ShouldCancel()) return;
820 }
821 }
822}
823
Austin Schuh3e4a5272016-04-20 20:11:00 -0700824void AutonomousActor::TwoBallAuto() {
825 aos::time::Time start_time = aos::time::Time::Now();
826 OpenShooter();
827 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
828 false, 12.0);
829 if (ShouldCancel()) return;
830 LOG(INFO, "Waiting for the intake to come down.\n");
831
832 WaitForIntake();
833 LOG(INFO, "Intake done at %f seconds, starting to drive\n",
834 (aos::time::Time::Now() - start_time).ToSeconds());
835 if (ShouldCancel()) return;
836 const double kDriveDistance = 5.05;
837 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
838
839 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700840 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700841
Austin Schuh295c2d92016-05-01 12:28:04 -0700842 // Check if the ball is there.
843 bool first_ball_there = true;
844 ::y2016::sensors::ball_detector.FetchLatest();
845 if (::y2016::sensors::ball_detector.get()) {
846 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
847 first_ball_there = ball_detected;
848 LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
849 (aos::time::Time::Now() - start_time).ToSeconds());
850 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700851 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
852 false, 0.0);
853 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
854 (aos::time::Time::Now() - start_time).ToSeconds());
855 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
856 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
857 false, 0.0);
858 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700859 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700860
861 // We are now under the low bar. Start lifting.
862 BackLongShotLowBarTwoBall();
863 LOG(INFO, "Spinning up the shooter wheels\n");
864 SetShooterSpeed(640.0);
865 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
866
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700867 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
868 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700869 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
870 BackLongShotTwoBall();
871
872 if (!WaitForDriveDone()) return;
873 LOG(INFO, "First shot done driving at %f seconds\n",
874 (aos::time::Time::Now() - start_time).ToSeconds());
875
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700876 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700877
878 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700879 AlignWithVisionGoal();
880
881 WaitForShooterSpeed();
882 if (ShouldCancel()) return;
883
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700884 constexpr double kVisionExtra = 0.0;
885 WaitForAlignedWithVision(aos::time::Time::InSeconds(0.5 + kVisionExtra));
886 BackLongShotTwoBallFinish();
887 WaitForSuperstructureProfile();
888 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700889 LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700890 if (first_ball_there) {
891 Shoot();
892 } else {
893 LOG(INFO, "Nah, not shooting\n");
894 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700895
896 LOG(INFO, "First shot at %f seconds\n",
897 (aos::time::Time::Now() - start_time).ToSeconds());
898 if (ShouldCancel()) return;
899
900 SetShooterSpeed(0.0);
901 LOG(INFO, "Folding superstructure back down\n");
902 TuckArm(true, true);
903
904 // Undo vision move.
905 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
906 if (!WaitForDriveDone()) return;
907
908 constexpr double kBackDrive = 3.09 - 0.4;
909 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700910 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700911 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700912 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
913 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700914
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700915 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700916 LOG(INFO, "At Low Bar %f\n",
917 (aos::time::Time::Now() - start_time).ToSeconds());
918
919 OpenShooter();
920 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700921 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
922 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700923 constexpr double kBallSmallWallTurn = -0.11;
924 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
925
926 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
927 false, 12.0);
928
929 if (!WaitForDriveProfileDone()) return;
930
931 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
932 false, 12.0);
933
934 LOG(INFO, "Done backing up %f\n",
935 (aos::time::Time::Now() - start_time).ToSeconds());
936
937 constexpr double kDriveBackDistance = 5.15 - 0.4;
938 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
939 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700940 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700941
942 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
943 LOG(INFO, "Straightening up at %f\n",
944 (aos::time::Time::Now() - start_time).ToSeconds());
945
946 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700947 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700948
949 ::y2016::sensors::ball_detector.FetchLatest();
950 if (::y2016::sensors::ball_detector.get()) {
951 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
952 if (!ball_detected) {
953 if (!WaitForDriveDone()) return;
954 LOG(INFO, "Aborting, no ball %f\n",
955 (aos::time::Time::Now() - start_time).ToSeconds());
956 return;
957 }
958 }
959 CloseShooter();
960
961 BackLongShotLowBarTwoBall();
962 LOG(INFO, "Spinning up the shooter wheels\n");
963 SetShooterSpeed(640.0);
964 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
965
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700966 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700967 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
968 BackLongShotTwoBall();
969
970 if (!WaitForDriveDone()) return;
971 LOG(INFO, "Second shot done driving at %f seconds\n",
972 (aos::time::Time::Now() - start_time).ToSeconds());
973 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700974 AlignWithVisionGoal();
975 if (ShouldCancel()) return;
976
977 WaitForShooterSpeed();
978 if (ShouldCancel()) return;
979
980 // 2.2 with 0.4 of vision.
981 // 1.8 without any vision.
982 LOG(INFO, "Going to vision align at %f\n",
983 (aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700984 WaitForAlignedWithVision(start_time + aos::time::Time::InSeconds(13.5 + kVisionExtra * 2) -
Austin Schuh3e4a5272016-04-20 20:11:00 -0700985 aos::time::Time::Now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700986 BackLongShotTwoBallFinish();
987 WaitForSuperstructureProfile();
988 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700989 LOG(INFO, "Shoot at %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
990 Shoot();
991
992 LOG(INFO, "Second shot at %f seconds\n",
993 (aos::time::Time::Now() - start_time).ToSeconds());
994 if (ShouldCancel()) return;
995
996 SetShooterSpeed(0.0);
997 LOG(INFO, "Folding superstructure back down\n");
998 TuckArm(true, false);
999 LOG(INFO, "Shot %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
1000
1001 WaitForSuperstructureLow();
1002
1003 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
1004}
1005
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001006void AutonomousActor::StealAndMoveOverBy(double distance) {
1007 OpenShooter();
1008 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1009 true, 12.0);
1010 if (ShouldCancel()) return;
1011 LOG(INFO, "Waiting for the intake to come down.\n");
1012
1013 WaitForIntake();
1014 if (ShouldCancel()) return;
1015 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
1016 WaitForBallOrDriveDone();
1017 if (ShouldCancel()) return;
1018 MoveSuperstructure(1.0, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1019 true, 12.0);
1020
1021 if (!WaitForDriveDone()) return;
1022 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
1023 if (!WaitForDriveDone()) return;
1024}
1025
Comran Morshede68e3732016-03-12 14:12:11 +00001026bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
Austin Schuh3e4a5272016-04-20 20:11:00 -07001027 aos::time::Time start_time = aos::time::Time::Now();
Comran Morshede68e3732016-03-12 14:12:11 +00001028 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
1029
Comran Morshed435f1112016-03-12 14:20:45 +00001030 InitializeEncoders();
1031 ResetDrivetrain();
1032
Austin Schuh295c2d92016-05-01 12:28:04 -07001033 switch (params.mode) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001034 case 0:
1035 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001036 if (!WaitForDriveDone()) return true;
1037 // Get the superstructure to unfold and get ready for shooting.
1038 LOG(INFO, "Unfolding superstructure\n");
1039 FrontLongShot();
1040
1041 // Spin up the shooter wheels.
1042 LOG(INFO, "Spinning up the shooter wheels\n");
1043 SetShooterSpeed(640.0);
1044
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001045 break;
1046 case 1:
1047 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001048 if (!WaitForDriveDone()) return true;
1049 // Get the superstructure to unfold and get ready for shooting.
1050 LOG(INFO, "Unfolding superstructure\n");
1051 FrontMiddleShot();
1052
1053 // Spin up the shooter wheels.
1054 LOG(INFO, "Spinning up the shooter wheels\n");
1055 SetShooterSpeed(600.0);
1056
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001057 break;
1058 case 2:
1059 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001060 if (!WaitForDriveDone()) return true;
1061 // Get the superstructure to unfold and get ready for shooting.
1062 LOG(INFO, "Unfolding superstructure\n");
1063 FrontMiddleShot();
1064
1065 // Spin up the shooter wheels.
1066 LOG(INFO, "Spinning up the shooter wheels\n");
1067 SetShooterSpeed(600.0);
1068
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001069 break;
1070 case 3:
1071 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001072 if (!WaitForDriveDone()) return true;
1073 // Get the superstructure to unfold and get ready for shooting.
1074 LOG(INFO, "Unfolding superstructure\n");
1075 FrontMiddleShot();
1076
1077 // Spin up the shooter wheels.
1078 LOG(INFO, "Spinning up the shooter wheels\n");
1079 SetShooterSpeed(600.0);
1080
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001081 break;
1082 case 4:
1083 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001084 if (!WaitForDriveDone()) return true;
1085 // Get the superstructure to unfold and get ready for shooting.
1086 LOG(INFO, "Unfolding superstructure\n");
1087 FrontMiddleShot();
1088
1089 // Spin up the shooter wheels.
1090 LOG(INFO, "Spinning up the shooter wheels\n");
1091 SetShooterSpeed(600.0);
1092
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001093 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001094 case 5:
Campbell Crowley9ed61a52016-11-05 17:13:07 -07001095 case 15:
Austin Schuh3e4a5272016-04-20 20:11:00 -07001096 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -07001097 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001098 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001099 case 6:
1100 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
1101 if (ShouldCancel()) return true;
1102
1103 TwoFromMiddleDrive();
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 7:
1115 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
1116 if (ShouldCancel()) return true;
1117
1118 OneFromMiddleDrive(true);
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 8: {
1130 StealAndMoveOverBy(2.95);
1131 if (ShouldCancel()) return true;
1132
1133 MiddleDrive();
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;
1144 case 9: {
1145 StealAndMoveOverBy(1.70);
1146 if (ShouldCancel()) return true;
1147
1148 OneFromMiddleDrive(false);
1149 if (!WaitForDriveDone()) return true;
1150 // Get the superstructure to unfold and get ready for shooting.
1151 LOG(INFO, "Unfolding superstructure\n");
1152 FrontMiddleShot();
1153
1154 // Spin up the shooter wheels.
1155 LOG(INFO, "Spinning up the shooter wheels\n");
1156 SetShooterSpeed(600.0);
1157
1158 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001159 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -07001160 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001161 return true;
1162 }
Comran Morshed435f1112016-03-12 14:20:45 +00001163
Austin Schuh3e4a5272016-04-20 20:11:00 -07001164 DoFullShot();
1165
1166 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +00001167 if (!WaitForDriveDone()) return true;
1168
Austin Schuh3e4a5272016-04-20 20:11:00 -07001169 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
Comran Morshed435f1112016-03-12 14:20:45 +00001170
Austin Schuh8aec1ed2016-05-01 13:29:20 -07001171 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
1172 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001173
Comran Morshed435f1112016-03-12 14:20:45 +00001174 while (!ShouldCancel()) {
1175 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +00001176 }
Comran Morshed435f1112016-03-12 14:20:45 +00001177 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +00001178
1179 return true;
1180}
1181
1182::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
1183 const ::y2016::actors::AutonomousActionParams &params) {
1184 return ::std::unique_ptr<AutonomousAction>(
1185 new AutonomousAction(&::y2016::actors::autonomous_action, params));
1186}
1187
1188} // namespace actors
1189} // namespace y2016