blob: 6636e77b0eaca6e1056a3398fbc0b435ba8b9003 [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");
Austin Schuh90963362016-05-01 12:27:31 -0700636 MoveSuperstructure(0.00, M_PI / 2.0 - 0.2, -0.625, {7.0, 40.0}, {4.0, 6.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700637 {10.0, 25.0}, false, 0.0);
638}
639
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700640void AutonomousActor::BackLongShot() {
641 LOG(INFO, "Expanding for back long shot\n");
Austin Schuh23b21802016-04-03 21:18:56 -0700642 MoveSuperstructure(0.80, M_PI / 2.0 - 0.2, -0.62, {7.0, 40.0}, {4.0, 6.0},
643 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700644}
645
646void AutonomousActor::BackMiddleShot() {
647 LOG(INFO, "Expanding for back middle shot\n");
648 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 -0700649 {10.0, 25.0}, false, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700650}
651
Austin Schuh3e4a5272016-04-20 20:11:00 -0700652void AutonomousActor::FrontLongShot() {
653 LOG(INFO, "Expanding for front long shot\n");
654 MoveSuperstructure(0.80, M_PI / 2.0 + 0.1, M_PI + 0.41 + 0.02, {7.0, 40.0},
655 {4.0, 6.0}, {10.0, 25.0}, false, 0.0);
656}
657
658void AutonomousActor::FrontMiddleShot() {
659 LOG(INFO, "Expanding for front middle shot\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700660 MoveSuperstructure(-0.05, M_PI / 2.0 + 0.1, M_PI + 0.44, {7.0, 40.0},
Austin Schuh3e4a5272016-04-20 20:11:00 -0700661 {4.0, 10.0}, {10.0, 25.0}, true, 0.0);
662}
663
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700664void AutonomousActor::TuckArm(bool low_bar, bool traverse_down) {
665 MoveSuperstructure(low_bar ? -0.05 : 2.0, -0.010, 0.0, {7.0, 40.0},
Austin Schuh23b21802016-04-03 21:18:56 -0700666 {4.0, 10.0}, {10.0, 25.0}, !traverse_down, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700667}
668
Austin Schuh3e4a5272016-04-20 20:11:00 -0700669void AutonomousActor::DoFullShot() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700670 if (ShouldCancel()) return;
671 // Make sure that the base is aligned with the base.
672 LOG(INFO, "Waiting for the superstructure\n");
673 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700674
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700675 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.5));
Austin Schuh3e4a5272016-04-20 20:11:00 -0700676
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700677 if (ShouldCancel()) return;
678 LOG(INFO, "Triggering the vision actor\n");
679 AlignWithVisionGoal();
680
681 // Wait for the drive base to be aligned with the target and make sure that
682 // the shooter is up to speed.
683 LOG(INFO, "Waiting for vision to be aligned\n");
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700684 WaitForAlignedWithVision(aos::time::Time::InSeconds(2));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700685 if (ShouldCancel()) return;
686 LOG(INFO, "Waiting for shooter to be up to speed\n");
687 WaitForShooterSpeed();
688 if (ShouldCancel()) return;
689
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700690 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.3));
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700691 LOG(INFO, "Shoot!\n");
692 Shoot();
693
694 // Turn off the shooter and fold up the superstructure.
695 if (ShouldCancel()) return;
696 LOG(INFO, "Stopping shooter\n");
697 SetShooterSpeed(0.0);
698 LOG(INFO, "Folding superstructure back down\n");
699 TuckArm(false, false);
700
701 // Wait for everything to be folded up.
702 LOG(INFO, "Waiting for superstructure to be folded back down\n");
Austin Schuh3e4a5272016-04-20 20:11:00 -0700703 WaitForSuperstructureLow();
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700704}
705
706void AutonomousActor::LowBarDrive() {
707 TuckArm(false, true);
708 StartDrive(-5.5, 0.0, kLowBarDrive, kSlowTurn);
709
710 if (!WaitForDriveNear(5.3, 0.0)) return;
711 TuckArm(true, true);
712
713 if (!WaitForDriveNear(5.0, 0.0)) return;
714
715 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
716
717 if (!WaitForDriveNear(3.0, 0.0)) return;
718
719 StartDrive(0.0, 0.0, kLowBarDrive, kSlowTurn);
720
721 if (!WaitForDriveNear(1.0, 0.0)) return;
722
Austin Schuh15b5f6a2016-03-26 19:43:56 -0700723 StartDrive(0, -M_PI / 4.0 - 0.2, kLowBarDrive, kSlowTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700724}
725
Austin Schuh3e4a5272016-04-20 20:11:00 -0700726void AutonomousActor::TippyDrive(double goal_distance, double tip_distance,
727 double below, double above) {
728 StartDrive(goal_distance, 0.0, kMoatDrive, kSlowTurn);
729 if (!WaitForBelowAngle(below)) return;
730 if (!WaitForAboveAngle(above)) return;
731 // Ok, we are good now. Compensate by moving the goal by the error.
732 // Should be here at 2.7
733 drivetrain_queue.status.FetchLatest();
734 if (drivetrain_queue.status.get()) {
735 const double left_error =
736 (initial_drivetrain_.left -
737 drivetrain_queue.status->estimated_left_position);
738 const double right_error =
739 (initial_drivetrain_.right -
740 drivetrain_queue.status->estimated_right_position);
741 const double distance_to_go = (left_error + right_error) / 2.0;
742 const double distance_compensation =
743 goal_distance - tip_distance - distance_to_go;
744 LOG(INFO, "Going %f further at the bump\n", distance_compensation);
745 StartDrive(distance_compensation, 0.0, kMoatDrive, kSlowTurn);
746 }
747}
748
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700749void AutonomousActor::MiddleDrive() {
750 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700751 TippyDrive(3.65, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700752 if (!WaitForDriveDone()) return;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700753}
754
755void AutonomousActor::OneFromMiddleDrive(bool left) {
Austin Schuh3e4a5272016-04-20 20:11:00 -0700756 const double kTurnAngle = left ? -0.41 : 0.41;
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700757 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700758 TippyDrive(4.05, 2.7, -0.2, 0.0);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700759
760 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700761 StartDrive(0.0, kTurnAngle, kRealignDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700762}
763
764void AutonomousActor::TwoFromMiddleDrive() {
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700765 TuckArm(false, false);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700766 constexpr double kDriveDistance = 5.10;
767 TippyDrive(kDriveDistance, 2.7, -0.2, 0.0);
768
769 if (!WaitForDriveNear(kDriveDistance - 3.0, 2.0)) return;
770 StartDrive(0, -M_PI / 2 - 0.10, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700771
772 if (!WaitForDriveDone()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700773 StartDrive(0, M_PI / 3 + 0.35, kMoatDrive, kFastTurn);
Austin Schuhf59b8ee2016-03-19 21:31:36 -0700774}
Comran Morshedb134e772016-03-16 21:05:05 +0000775
Austin Schuh23b21802016-04-03 21:18:56 -0700776void AutonomousActor::CloseIfBall() {
777 ::y2016::sensors::ball_detector.FetchLatest();
778 if (::y2016::sensors::ball_detector.get()) {
779 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
780 if (ball_detected) {
781 CloseShooter();
782 }
783 }
784}
785
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700786void AutonomousActor::WaitForBallOrDriveDone() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -0700787 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
788 ::std::chrono::milliseconds(5) / 2);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700789 while (true) {
790 if (ShouldCancel()) {
791 return;
792 }
793 phased_loop.SleepUntilNext();
794 drivetrain_queue.status.FetchLatest();
795 if (IsDriveDone()) {
796 return;
797 }
798
799 ::y2016::sensors::ball_detector.FetchLatest();
800 if (::y2016::sensors::ball_detector.get()) {
801 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
802 if (ball_detected) {
803 return;
804 }
805 }
806 }
807}
808
Austin Schuh23b21802016-04-03 21:18:56 -0700809void AutonomousActor::WaitForBall() {
810 while (true) {
811 ::y2016::sensors::ball_detector.FetchAnother();
812 if (::y2016::sensors::ball_detector.get()) {
813 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
814 if (ball_detected) {
815 return;
816 }
817 if (ShouldCancel()) return;
818 }
819 }
820}
821
Austin Schuh3e4a5272016-04-20 20:11:00 -0700822void AutonomousActor::TwoBallAuto() {
823 aos::time::Time start_time = aos::time::Time::Now();
824 OpenShooter();
825 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
826 false, 12.0);
827 if (ShouldCancel()) return;
828 LOG(INFO, "Waiting for the intake to come down.\n");
829
830 WaitForIntake();
831 LOG(INFO, "Intake done at %f seconds, starting to drive\n",
832 (aos::time::Time::Now() - start_time).ToSeconds());
833 if (ShouldCancel()) return;
834 const double kDriveDistance = 5.05;
835 StartDrive(-kDriveDistance, 0.0, kTwoBallLowDrive, kSlowTurn);
836
837 StartDrive(0.0, 0.4, kTwoBallLowDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700838 if (!WaitForDriveNear(kDriveDistance - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700839
Austin Schuh295c2d92016-05-01 12:28:04 -0700840 // Check if the ball is there.
841 bool first_ball_there = true;
842 ::y2016::sensors::ball_detector.FetchLatest();
843 if (::y2016::sensors::ball_detector.get()) {
844 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
845 first_ball_there = ball_detected;
846 LOG(INFO, "Saw the ball: %d at %f\n", first_ball_there,
847 (aos::time::Time::Now() - start_time).ToSeconds());
848 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700849 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
850 false, 0.0);
851 LOG(INFO, "Shutting off rollers at %f seconds, starting to straighten out\n",
852 (aos::time::Time::Now() - start_time).ToSeconds());
853 StartDrive(0.0, -0.4, kTwoBallLowDrive, kSwerveTurn);
854 MoveSuperstructure(-0.05, -0.010, 0.0, {8.0, 40.0}, {4.0, 10.0}, {10.0, 25.0},
855 false, 0.0);
856 CloseShooter();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700857 if (!WaitForDriveNear(kDriveDistance - 2.4, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700858
859 // We are now under the low bar. Start lifting.
860 BackLongShotLowBarTwoBall();
861 LOG(INFO, "Spinning up the shooter wheels\n");
862 SetShooterSpeed(640.0);
863 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
864
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700865 if (!WaitForDriveNear(1.50, kDoNotTurnCare)) return;
866 constexpr double kShootTurnAngle = -M_PI / 4.0 - 0.05;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700867 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
868 BackLongShotTwoBall();
869
870 if (!WaitForDriveDone()) return;
871 LOG(INFO, "First shot done driving at %f seconds\n",
872 (aos::time::Time::Now() - start_time).ToSeconds());
873
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700874 WaitForSuperstructureProfile();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700875
876 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700877 AlignWithVisionGoal();
878
879 WaitForShooterSpeed();
880 if (ShouldCancel()) return;
881
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700882 constexpr double kVisionExtra = 0.0;
883 WaitForAlignedWithVision(aos::time::Time::InSeconds(0.5 + kVisionExtra));
884 BackLongShotTwoBallFinish();
885 WaitForSuperstructureProfile();
886 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700887 LOG(INFO, "Shoot!\n");
Austin Schuh295c2d92016-05-01 12:28:04 -0700888 if (first_ball_there) {
889 Shoot();
890 } else {
891 LOG(INFO, "Nah, not shooting\n");
892 }
Austin Schuh3e4a5272016-04-20 20:11:00 -0700893
894 LOG(INFO, "First shot at %f seconds\n",
895 (aos::time::Time::Now() - start_time).ToSeconds());
896 if (ShouldCancel()) return;
897
898 SetShooterSpeed(0.0);
899 LOG(INFO, "Folding superstructure back down\n");
900 TuckArm(true, true);
901
902 // Undo vision move.
903 StartDrive(0.0, 0.0, kTwoBallFastDrive, kFinishTurn);
904 if (!WaitForDriveDone()) return;
905
906 constexpr double kBackDrive = 3.09 - 0.4;
907 StartDrive(kBackDrive, 0.0, kTwoBallReturnDrive, kSlowTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700908 if (!WaitForDriveNear(kBackDrive - 0.19, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700909 StartDrive(0, -kShootTurnAngle, kTwoBallReturnDrive, kSwerveTurn);
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700910 if (!WaitForDriveNear(1.0, kDoNotTurnCare)) return;
911 StartDrive(0, 0, kTwoBallReturnSlow, kSwerveTurn);
Austin Schuh3e4a5272016-04-20 20:11:00 -0700912
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700913 if (!WaitForDriveNear(0.06, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700914 LOG(INFO, "At Low Bar %f\n",
915 (aos::time::Time::Now() - start_time).ToSeconds());
916
917 OpenShooter();
918 constexpr double kSecondBallAfterBarDrive = 2.10;
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700919 StartDrive(kSecondBallAfterBarDrive, 0.0, kTwoBallBallPickupAccel, kSlowTurn);
920 if (!WaitForDriveNear(kSecondBallAfterBarDrive - 0.5, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700921 constexpr double kBallSmallWallTurn = -0.11;
922 StartDrive(0, kBallSmallWallTurn, kTwoBallBallPickup, kFinishTurn);
923
924 MoveSuperstructure(0.03, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
925 false, 12.0);
926
927 if (!WaitForDriveProfileDone()) return;
928
929 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
930 false, 12.0);
931
932 LOG(INFO, "Done backing up %f\n",
933 (aos::time::Time::Now() - start_time).ToSeconds());
934
935 constexpr double kDriveBackDistance = 5.15 - 0.4;
936 StartDrive(-kDriveBackDistance, 0.0, kTwoBallLowDrive, kFinishTurn);
937 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700938 if (!WaitForDriveNear(kDriveBackDistance - 0.75, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700939
940 StartDrive(0.0, -kBallSmallWallTurn, kTwoBallLowDrive, kFinishTurn);
941 LOG(INFO, "Straightening up at %f\n",
942 (aos::time::Time::Now() - start_time).ToSeconds());
943
944 CloseIfBall();
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700945 if (!WaitForDriveNear(kDriveBackDistance - 2.3, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700946
947 ::y2016::sensors::ball_detector.FetchLatest();
948 if (::y2016::sensors::ball_detector.get()) {
949 const bool ball_detected = ::y2016::sensors::ball_detector->voltage > 2.5;
950 if (!ball_detected) {
951 if (!WaitForDriveDone()) return;
952 LOG(INFO, "Aborting, no ball %f\n",
953 (aos::time::Time::Now() - start_time).ToSeconds());
954 return;
955 }
956 }
957 CloseShooter();
958
959 BackLongShotLowBarTwoBall();
960 LOG(INFO, "Spinning up the shooter wheels\n");
961 SetShooterSpeed(640.0);
962 StartDrive(0.0, 0.0, kTwoBallFastDrive, kSwerveTurn);
963
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700964 if (!WaitForDriveNear(1.80, kDoNotTurnCare)) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700965 StartDrive(0, kShootTurnAngle, kTwoBallFastDrive, kFinishTurn);
966 BackLongShotTwoBall();
967
968 if (!WaitForDriveDone()) return;
969 LOG(INFO, "Second shot done driving at %f seconds\n",
970 (aos::time::Time::Now() - start_time).ToSeconds());
971 WaitForSuperstructure();
Austin Schuh3e4a5272016-04-20 20:11:00 -0700972 AlignWithVisionGoal();
973 if (ShouldCancel()) return;
974
975 WaitForShooterSpeed();
976 if (ShouldCancel()) return;
977
978 // 2.2 with 0.4 of vision.
979 // 1.8 without any vision.
980 LOG(INFO, "Going to vision align at %f\n",
981 (aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700982 WaitForAlignedWithVision(start_time + aos::time::Time::InSeconds(13.5 + kVisionExtra * 2) -
Austin Schuh3e4a5272016-04-20 20:11:00 -0700983 aos::time::Time::Now());
Austin Schuhe4ec49c2016-04-24 19:07:15 -0700984 BackLongShotTwoBallFinish();
985 WaitForSuperstructureProfile();
986 if (ShouldCancel()) return;
Austin Schuh3e4a5272016-04-20 20:11:00 -0700987 LOG(INFO, "Shoot at %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
988 Shoot();
989
990 LOG(INFO, "Second shot at %f seconds\n",
991 (aos::time::Time::Now() - start_time).ToSeconds());
992 if (ShouldCancel()) return;
993
994 SetShooterSpeed(0.0);
995 LOG(INFO, "Folding superstructure back down\n");
996 TuckArm(true, false);
997 LOG(INFO, "Shot %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
998
999 WaitForSuperstructureLow();
1000
1001 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
1002}
1003
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001004void AutonomousActor::StealAndMoveOverBy(double distance) {
1005 OpenShooter();
1006 MoveSuperstructure(0.10, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1007 true, 12.0);
1008 if (ShouldCancel()) return;
1009 LOG(INFO, "Waiting for the intake to come down.\n");
1010
1011 WaitForIntake();
1012 if (ShouldCancel()) return;
1013 StartDrive(-distance, M_PI / 2.0, kFastDrive, kStealTurn);
1014 WaitForBallOrDriveDone();
1015 if (ShouldCancel()) return;
1016 MoveSuperstructure(1.0, -0.010, 0.0, {8.0, 60.0}, {4.0, 10.0}, {10.0, 25.0},
1017 true, 12.0);
1018
1019 if (!WaitForDriveDone()) return;
1020 StartDrive(0.0, M_PI / 2.0, kFastDrive, kStealTurn);
1021 if (!WaitForDriveDone()) return;
1022}
1023
Comran Morshede68e3732016-03-12 14:12:11 +00001024bool AutonomousActor::RunAction(const actors::AutonomousActionParams &params) {
Austin Schuh3e4a5272016-04-20 20:11:00 -07001025 aos::time::Time start_time = aos::time::Time::Now();
Comran Morshede68e3732016-03-12 14:12:11 +00001026 LOG(INFO, "Starting autonomous action with mode %" PRId32 "\n", params.mode);
1027
Comran Morshed435f1112016-03-12 14:20:45 +00001028 InitializeEncoders();
1029 ResetDrivetrain();
1030
Austin Schuh295c2d92016-05-01 12:28:04 -07001031 switch (params.mode) {
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001032 case 0:
1033 LowBarDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001034 if (!WaitForDriveDone()) return true;
1035 // Get the superstructure to unfold and get ready for shooting.
1036 LOG(INFO, "Unfolding superstructure\n");
1037 FrontLongShot();
1038
1039 // Spin up the shooter wheels.
1040 LOG(INFO, "Spinning up the shooter wheels\n");
1041 SetShooterSpeed(640.0);
1042
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001043 break;
1044 case 1:
1045 TwoFromMiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001046 if (!WaitForDriveDone()) return true;
1047 // Get the superstructure to unfold and get ready for shooting.
1048 LOG(INFO, "Unfolding superstructure\n");
1049 FrontMiddleShot();
1050
1051 // Spin up the shooter wheels.
1052 LOG(INFO, "Spinning up the shooter wheels\n");
1053 SetShooterSpeed(600.0);
1054
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001055 break;
1056 case 2:
1057 OneFromMiddleDrive(true);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001058 if (!WaitForDriveDone()) return true;
1059 // Get the superstructure to unfold and get ready for shooting.
1060 LOG(INFO, "Unfolding superstructure\n");
1061 FrontMiddleShot();
1062
1063 // Spin up the shooter wheels.
1064 LOG(INFO, "Spinning up the shooter wheels\n");
1065 SetShooterSpeed(600.0);
1066
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001067 break;
1068 case 3:
1069 MiddleDrive();
Austin Schuh3e4a5272016-04-20 20:11:00 -07001070 if (!WaitForDriveDone()) return true;
1071 // Get the superstructure to unfold and get ready for shooting.
1072 LOG(INFO, "Unfolding superstructure\n");
1073 FrontMiddleShot();
1074
1075 // Spin up the shooter wheels.
1076 LOG(INFO, "Spinning up the shooter wheels\n");
1077 SetShooterSpeed(600.0);
1078
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001079 break;
1080 case 4:
1081 OneFromMiddleDrive(false);
Austin Schuh3e4a5272016-04-20 20:11:00 -07001082 if (!WaitForDriveDone()) return true;
1083 // Get the superstructure to unfold and get ready for shooting.
1084 LOG(INFO, "Unfolding superstructure\n");
1085 FrontMiddleShot();
1086
1087 // Spin up the shooter wheels.
1088 LOG(INFO, "Spinning up the shooter wheels\n");
1089 SetShooterSpeed(600.0);
1090
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001091 break;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001092 case 5:
1093 TwoBallAuto();
Austin Schuh23b21802016-04-03 21:18:56 -07001094 return true;
Austin Schuh3e4a5272016-04-20 20:11:00 -07001095 break;
Austin Schuhe4ec49c2016-04-24 19:07:15 -07001096 case 6:
1097 StealAndMoveOverBy(3.10 + 2 * 52 * 2.54 / 100.0);
1098 if (ShouldCancel()) return true;
1099
1100 TwoFromMiddleDrive();
1101 if (!WaitForDriveDone()) return true;
1102 // Get the superstructure to unfold and get ready for shooting.
1103 LOG(INFO, "Unfolding superstructure\n");
1104 FrontMiddleShot();
1105
1106 // Spin up the shooter wheels.
1107 LOG(INFO, "Spinning up the shooter wheels\n");
1108 SetShooterSpeed(600.0);
1109
1110 break;
1111 case 7:
1112 StealAndMoveOverBy(2.95 + 52 * 2.54 / 100.0);
1113 if (ShouldCancel()) return true;
1114
1115 OneFromMiddleDrive(true);
1116 if (!WaitForDriveDone()) return true;
1117 // Get the superstructure to unfold and get ready for shooting.
1118 LOG(INFO, "Unfolding superstructure\n");
1119 FrontMiddleShot();
1120
1121 // Spin up the shooter wheels.
1122 LOG(INFO, "Spinning up the shooter wheels\n");
1123 SetShooterSpeed(600.0);
1124
1125 break;
1126 case 8: {
1127 StealAndMoveOverBy(2.95);
1128 if (ShouldCancel()) return true;
1129
1130 MiddleDrive();
1131 if (!WaitForDriveDone()) return true;
1132 // Get the superstructure to unfold and get ready for shooting.
1133 LOG(INFO, "Unfolding superstructure\n");
1134 FrontMiddleShot();
1135
1136 // Spin up the shooter wheels.
1137 LOG(INFO, "Spinning up the shooter wheels\n");
1138 SetShooterSpeed(600.0);
1139
1140 } break;
1141 case 9: {
1142 StealAndMoveOverBy(1.70);
1143 if (ShouldCancel()) return true;
1144
1145 OneFromMiddleDrive(false);
1146 if (!WaitForDriveDone()) return true;
1147 // Get the superstructure to unfold and get ready for shooting.
1148 LOG(INFO, "Unfolding superstructure\n");
1149 FrontMiddleShot();
1150
1151 // Spin up the shooter wheels.
1152 LOG(INFO, "Spinning up the shooter wheels\n");
1153 SetShooterSpeed(600.0);
1154
1155 } break;
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001156 default:
Austin Schuh6c9bc622016-03-26 19:44:12 -07001157 LOG(ERROR, "Invalid auto mode %d\n", params.mode);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001158 return true;
1159 }
Comran Morshed435f1112016-03-12 14:20:45 +00001160
Austin Schuh3e4a5272016-04-20 20:11:00 -07001161 DoFullShot();
1162
1163 StartDrive(0.5, 0.0, kMoatDrive, kFastTurn);
Comran Morshed435f1112016-03-12 14:20:45 +00001164 if (!WaitForDriveDone()) return true;
1165
Austin Schuh3e4a5272016-04-20 20:11:00 -07001166 LOG(INFO, "Done %f\n", (aos::time::Time::Now() - start_time).ToSeconds());
Comran Morshed435f1112016-03-12 14:20:45 +00001167
Austin Schuh8aec1ed2016-05-01 13:29:20 -07001168 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
1169 ::std::chrono::milliseconds(5) / 2);
Austin Schuhf59b8ee2016-03-19 21:31:36 -07001170
Comran Morshed435f1112016-03-12 14:20:45 +00001171 while (!ShouldCancel()) {
1172 phased_loop.SleepUntilNext();
Comran Morshede68e3732016-03-12 14:12:11 +00001173 }
Comran Morshed435f1112016-03-12 14:20:45 +00001174 LOG(DEBUG, "Done running\n");
Comran Morshede68e3732016-03-12 14:12:11 +00001175
1176 return true;
1177}
1178
1179::std::unique_ptr<AutonomousAction> MakeAutonomousAction(
1180 const ::y2016::actors::AutonomousActionParams &params) {
1181 return ::std::unique_ptr<AutonomousAction>(
1182 new AutonomousAction(&::y2016::actors::autonomous_action, params));
1183}
1184
1185} // namespace actors
1186} // namespace y2016