blob: 9c39f27c5412bdca38de2da738d0f6ba621492de [file] [log] [blame]
Brian Silverman17f503e2015-08-02 18:17:18 -07001#include <stdio.h>
2
3#include <memory>
4
5#include "aos/common/util/phased_loop.h"
6#include "aos/common/time.h"
7#include "aos/common/util/trapezoid_profile.h"
8#include "aos/common/logging/logging.h"
9#include "aos/common/logging/queue_logging.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040010#include "aos/common/actions/actions.h"
Brian Silverman17f503e2015-08-02 18:17:18 -070011
12#include "frc971/autonomous/auto.q.h"
Comran Morshed5323ecb2015-12-26 20:50:55 +000013#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040014#include "y2014/actors/drivetrain_actor.h"
Austin Schuh3130b372016-02-17 00:34:51 -080015#include "y2014/actors/shoot_actor.h"
16#include "y2014/constants.h"
17#include "y2014/control_loops/claw/claw.q.h"
18#include "y2014/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
19#include "y2014/control_loops/shooter/shooter.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040020#include "y2014/queues/auto_mode.q.h"
21
Brian Silverman17f503e2015-08-02 18:17:18 -070022#include "y2014/queues/hot_goal.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040023#include "y2014/queues/profile_params.q.h"
Brian Silverman17f503e2015-08-02 18:17:18 -070024
25using ::aos::time::Time;
26
Brian Silvermanb601d892015-12-20 18:24:38 -050027namespace y2014 {
Brian Silverman17f503e2015-08-02 18:17:18 -070028namespace autonomous {
29
30namespace time = ::aos::time;
31
32static double left_initial_position, right_initial_position;
33
34bool ShouldExitAuto() {
35 ::frc971::autonomous::autonomous.FetchLatest();
36 bool ans = !::frc971::autonomous::autonomous->run_auto;
37 if (ans) {
38 LOG(INFO, "Time to exit auto mode\n");
39 }
40 return ans;
41}
42
43void StopDrivetrain() {
44 LOG(INFO, "Stopping the drivetrain\n");
Comran Morshed5323ecb2015-12-26 20:50:55 +000045 frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman17f503e2015-08-02 18:17:18 -070046 .control_loop_driving(true)
Austin Schuh86f895e2015-11-08 13:40:51 -080047 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -070048 .left_goal(left_initial_position)
49 .left_velocity_goal(0)
50 .right_goal(right_initial_position)
51 .right_velocity_goal(0)
52 .quickturn(false)
53 .Send();
54}
55
56void ResetDrivetrain() {
57 LOG(INFO, "resetting the drivetrain\n");
Comran Morshed5323ecb2015-12-26 20:50:55 +000058 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman17f503e2015-08-02 18:17:18 -070059 .control_loop_driving(false)
Austin Schuh86f895e2015-11-08 13:40:51 -080060 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -070061 .steering(0.0)
62 .throttle(0.0)
63 .left_goal(left_initial_position)
64 .left_velocity_goal(0)
65 .right_goal(right_initial_position)
66 .right_velocity_goal(0)
67 .Send();
68}
69
70void WaitUntilDoneOrCanceled(
71 ::std::unique_ptr<aos::common::actions::Action> action) {
72 if (!action) {
73 LOG(ERROR, "No action, not waiting\n");
74 return;
75 }
76 while (true) {
77 // Poll the running bit and auto done bits.
Brian Silvermanbfa00602015-05-17 01:41:29 -040078 ::aos::time::PhasedLoopXMS(10, 5000);
Brian Silverman17f503e2015-08-02 18:17:18 -070079 if (!action->Running() || ShouldExitAuto()) {
80 return;
81 }
82 }
83}
84
85void StepDrive(double distance, double theta) {
86 double left_goal = (left_initial_position + distance -
Austin Schuh3130b372016-02-17 00:34:51 -080087 theta * control_loops::drivetrain::kRobotRadius);
Brian Silverman17f503e2015-08-02 18:17:18 -070088 double right_goal = (right_initial_position + distance +
Austin Schuh3130b372016-02-17 00:34:51 -080089 theta * control_loops::drivetrain::kRobotRadius);
Comran Morshed5323ecb2015-12-26 20:50:55 +000090 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman17f503e2015-08-02 18:17:18 -070091 .control_loop_driving(true)
Austin Schuh86f895e2015-11-08 13:40:51 -080092 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -070093 .left_goal(left_goal)
94 .right_goal(right_goal)
95 .left_velocity_goal(0.0)
96 .right_velocity_goal(0.0)
97 .Send();
98 left_initial_position = left_goal;
99 right_initial_position = right_goal;
100}
101
Brian Silvermanbfa00602015-05-17 01:41:29 -0400102void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
103 if (!control_loops::claw_queue.goal.MakeWithBuilder()
104 .bottom_angle(0.0)
105 .separation_angle(0.0)
106 .intake(intake_power)
107 .centering(centering_power)
108 .Send()) {
109 LOG(WARNING, "sending claw goal failed\n");
110 }
111}
112
113void PositionClawBackIntake() {
114 if (!control_loops::claw_queue.goal.MakeWithBuilder()
115 .bottom_angle(-2.273474)
116 .separation_angle(0.0)
117 .intake(12.0)
118 .centering(12.0)
119 .Send()) {
120 LOG(WARNING, "sending claw goal failed\n");
121 }
122}
123
124void PositionClawUpClosed() {
125 // Move the claw to where we're going to shoot from but keep it closed until
126 // it gets there.
127 if (!control_loops::claw_queue.goal.MakeWithBuilder()
128 .bottom_angle(0.86)
129 .separation_angle(0.0)
130 .intake(4.0)
131 .centering(1.0)
132 .Send()) {
133 LOG(WARNING, "sending claw goal failed\n");
134 }
135}
136
137void PositionClawForShot() {
138 if (!control_loops::claw_queue.goal.MakeWithBuilder()
139 .bottom_angle(0.86)
140 .separation_angle(0.10)
141 .intake(4.0)
142 .centering(1.0)
143 .Send()) {
144 LOG(WARNING, "sending claw goal failed\n");
145 }
146}
147
148void SetShotPower(double power) {
149 LOG(INFO, "Setting shot power to %f\n", power);
150 if (!control_loops::shooter_queue.goal.MakeWithBuilder()
151 .shot_power(power)
152 .shot_requested(false)
153 .unload_requested(false)
154 .load_requested(false)
155 .Send()) {
156 LOG(WARNING, "sending shooter goal failed\n");
157 }
158}
159
Brian Silverman17f503e2015-08-02 18:17:18 -0700160void WaitUntilNear(double distance) {
161 while (true) {
162 if (ShouldExitAuto()) return;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000163 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700164 double left_error = ::std::abs(
165 left_initial_position -
Comran Morshed5323ecb2015-12-26 20:50:55 +0000166 ::frc971::control_loops::drivetrain_queue.status->filtered_left_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700167 double right_error = ::std::abs(
168 right_initial_position -
Comran Morshed5323ecb2015-12-26 20:50:55 +0000169 ::frc971::control_loops::drivetrain_queue.status->filtered_right_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700170 const double kPositionThreshold = 0.05 + distance;
171 if (right_error < kPositionThreshold && left_error < kPositionThreshold) {
172 LOG(INFO, "At the goal\n");
173 return;
174 }
175 }
176}
177
Brian Silvermanbfa00602015-05-17 01:41:29 -0400178const ProfileParams kFastDrive = {3.0, 2.5};
179const ProfileParams kSlowDrive = {2.5, 2.5};
180const ProfileParams kFastWithBallDrive = {3.0, 2.0};
181const ProfileParams kSlowWithBallDrive = {2.5, 2.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700182const ProfileParams kFastTurn = {3.0, 10.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700183
Brian Silvermanb601d892015-12-20 18:24:38 -0500184::std::unique_ptr<::y2014::actors::DrivetrainAction> SetDriveGoal(
Brian Silverman17f503e2015-08-02 18:17:18 -0700185 double distance, const ProfileParams drive_params, double theta = 0,
186 const ProfileParams &turn_params = kFastTurn) {
187 LOG(INFO, "Driving to %f\n", distance);
188
Brian Silvermanb601d892015-12-20 18:24:38 -0500189 ::y2014::actors::DrivetrainActionParams params;
Brian Silverman17f503e2015-08-02 18:17:18 -0700190 params.left_initial_position = left_initial_position;
191 params.right_initial_position = right_initial_position;
192 params.y_offset = distance;
193 params.theta_offset = theta;
194 params.maximum_turn_acceleration = turn_params.acceleration;
195 params.maximum_turn_velocity = turn_params.velocity;
196 params.maximum_velocity = drive_params.velocity;
197 params.maximum_acceleration = drive_params.acceleration;
198 auto drivetrain_action = actors::MakeDrivetrainAction(params);
199 drivetrain_action->Start();
200 left_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800201 distance - theta * control_loops::drivetrain::kRobotRadius;
Brian Silverman17f503e2015-08-02 18:17:18 -0700202 right_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800203 distance + theta * control_loops::drivetrain::kRobotRadius;
Brian Silverman17f503e2015-08-02 18:17:18 -0700204 return ::std::move(drivetrain_action);
205}
206
207void Shoot() {
208 // Shoot.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400209 auto shoot_action = actors::MakeShootAction();
Brian Silverman17f503e2015-08-02 18:17:18 -0700210 shoot_action->Start();
Brian Silvermanbfa00602015-05-17 01:41:29 -0400211 WaitUntilDoneOrCanceled(::std::move(shoot_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700212}
213
214void InitializeEncoders() {
Comran Morshed5323ecb2015-12-26 20:50:55 +0000215 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700216 left_initial_position =
Comran Morshed5323ecb2015-12-26 20:50:55 +0000217 ::frc971::control_loops::drivetrain_queue.status->filtered_left_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700218 right_initial_position =
Comran Morshed5323ecb2015-12-26 20:50:55 +0000219 ::frc971::control_loops::drivetrain_queue.status->filtered_right_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700220}
221
222void WaitUntilClawDone() {
223 while (true) {
224 // Poll the running bit and auto done bits.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400225 ::aos::time::PhasedLoopXMS(10, 5000);
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400226 control_loops::claw_queue.status.FetchLatest();
227 control_loops::claw_queue.goal.FetchLatest();
Brian Silverman17f503e2015-08-02 18:17:18 -0700228 if (ShouldExitAuto()) {
229 return;
230 }
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400231 if (control_loops::claw_queue.status.get() == nullptr ||
232 control_loops::claw_queue.goal.get() == nullptr) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700233 continue;
234 }
235 bool ans =
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400236 control_loops::claw_queue.status->zeroed &&
237 (::std::abs(control_loops::claw_queue.status->bottom_velocity) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700238 1.0) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400239 (::std::abs(control_loops::claw_queue.status->bottom -
240 control_loops::claw_queue.goal->bottom_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700241 0.10) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400242 (::std::abs(control_loops::claw_queue.status->separation -
243 control_loops::claw_queue.goal->separation_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700244 0.4);
245 if (ans) {
246 return;
247 }
248 if (ShouldExitAuto()) return;
249 }
250}
251
252class HotGoalDecoder {
253 public:
254 HotGoalDecoder() {
255 ResetCounts();
256 }
257
258 void ResetCounts() {
259 hot_goal.FetchLatest();
260 if (hot_goal.get()) {
261 start_counts_ = *hot_goal;
262 LOG_STRUCT(INFO, "counts reset to", start_counts_);
263 start_counts_valid_ = true;
264 } else {
265 LOG(WARNING, "no hot goal message. ignoring\n");
266 start_counts_valid_ = false;
267 }
268 }
269
270 void Update(bool block = false) {
271 if (block) {
272 hot_goal.FetchAnother();
273 } else {
274 hot_goal.FetchLatest();
275 }
276 if (hot_goal.get()) LOG_STRUCT(INFO, "new counts", *hot_goal);
277 }
278
279 bool left_triggered() const {
280 if (!start_counts_valid_ || !hot_goal.get()) return false;
281 return (hot_goal->left_count - start_counts_.left_count) > kThreshold;
282 }
283
284 bool right_triggered() const {
285 if (!start_counts_valid_ || !hot_goal.get()) return false;
286 return (hot_goal->right_count - start_counts_.right_count) > kThreshold;
287 }
288
289 bool is_left() const {
290 if (!start_counts_valid_ || !hot_goal.get()) return false;
291 const uint64_t left_difference =
292 hot_goal->left_count - start_counts_.left_count;
293 const uint64_t right_difference =
294 hot_goal->right_count - start_counts_.right_count;
295 if (left_difference > kThreshold) {
296 if (right_difference > kThreshold) {
297 // We've seen a lot of both, so pick the one we've seen the most of.
298 return left_difference > right_difference;
299 } else {
300 // We've seen enough left but not enough right, so go with it.
301 return true;
302 }
303 } else {
304 // We haven't seen enough left, so it's not left.
305 return false;
306 }
307 }
308
309 bool is_right() const {
310 if (!start_counts_valid_ || !hot_goal.get()) return false;
311 const uint64_t left_difference =
312 hot_goal->left_count - start_counts_.left_count;
313 const uint64_t right_difference =
314 hot_goal->right_count - start_counts_.right_count;
315 if (right_difference > kThreshold) {
316 if (left_difference > kThreshold) {
317 // We've seen a lot of both, so pick the one we've seen the most of.
318 return right_difference > left_difference;
319 } else {
320 // We've seen enough right but not enough left, so go with it.
321 return true;
322 }
323 } else {
324 // We haven't seen enough right, so it's not right.
325 return false;
326 }
327 }
328
329 private:
330 static const uint64_t kThreshold = 5;
331
Brian Silvermanb601d892015-12-20 18:24:38 -0500332 ::y2014::HotGoal start_counts_;
Brian Silverman17f503e2015-08-02 18:17:18 -0700333 bool start_counts_valid_;
334};
335
336void HandleAuto() {
337 enum class AutoVersion : uint8_t {
338 kStraight,
339 kDoubleHot,
340 kSingleHot,
341 };
342
343 // The front of the robot is 1.854 meters from the wall
344 static const double kShootDistance = 3.15;
345 static const double kPickupDistance = 0.5;
346 static const double kTurnAngle = 0.3;
347
348 ::aos::time::Time start_time = ::aos::time::Time::Now();
349 LOG(INFO, "Handling auto mode\n");
350
351 AutoVersion auto_version;
Brian Silvermanb601d892015-12-20 18:24:38 -0500352 ::y2014::sensors::auto_mode.FetchLatest();
353 if (!::y2014::sensors::auto_mode.get()) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700354 LOG(WARNING, "not sure which auto mode to use\n");
355 auto_version = AutoVersion::kStraight;
356 } else {
357 static const double kSelectorMin = 0.2, kSelectorMax = 4.4;
358
359 const double kSelectorStep = (kSelectorMax - kSelectorMin) / 3.0;
Brian Silvermanb601d892015-12-20 18:24:38 -0500360 if (::y2014::sensors::auto_mode->voltage < kSelectorStep + kSelectorMin) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700361 auto_version = AutoVersion::kSingleHot;
Brian Silvermanb601d892015-12-20 18:24:38 -0500362 } else if (::y2014::sensors::auto_mode->voltage <
Brian Silverman17f503e2015-08-02 18:17:18 -0700363 2 * kSelectorStep + kSelectorMin) {
364 auto_version = AutoVersion::kStraight;
365 } else {
366 auto_version = AutoVersion::kDoubleHot;
367 }
368 }
369 LOG(INFO, "running auto %" PRIu8 "\n", static_cast<uint8_t>(auto_version));
370
Brian Silvermanbfa00602015-05-17 01:41:29 -0400371 const ProfileParams &drive_params =
372 (auto_version == AutoVersion::kStraight) ? kFastDrive : kSlowDrive;
373 const ProfileParams &drive_with_ball_params =
374 (auto_version == AutoVersion::kStraight) ? kFastWithBallDrive
375 : kSlowWithBallDrive;
Brian Silverman17f503e2015-08-02 18:17:18 -0700376
377 HotGoalDecoder hot_goal_decoder;
378 // True for left, false for right.
379 bool first_shot_left, second_shot_left_default, second_shot_left;
380
381 ResetDrivetrain();
382
383 time::SleepFor(time::Time::InSeconds(0.1));
384 if (ShouldExitAuto()) return;
385 InitializeEncoders();
386
387 // Turn the claw on, keep it straight up until the ball has been grabbed.
388 LOG(INFO, "Claw going up at %f\n",
389 (::aos::time::Time::Now() - start_time).ToSeconds());
390 PositionClawVertically(12.0, 4.0);
391 SetShotPower(115.0);
392
393 // Wait for the ball to enter the claw.
394 time::SleepFor(time::Time::InSeconds(0.25));
395 if (ShouldExitAuto()) return;
396 LOG(INFO, "Readying claw for shot at %f\n",
397 (::aos::time::Time::Now() - start_time).ToSeconds());
398
399 {
400 if (ShouldExitAuto()) return;
401 // Drive to the goal.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400402 auto drivetrain_action = SetDriveGoal(-kShootDistance, drive_params);
Brian Silverman17f503e2015-08-02 18:17:18 -0700403 time::SleepFor(time::Time::InSeconds(0.75));
404 PositionClawForShot();
405 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400406 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700407 if (ShouldExitAuto()) return;
408 }
409
410 hot_goal_decoder.Update();
411 if (hot_goal_decoder.is_left()) {
412 LOG(INFO, "first shot left\n");
413 first_shot_left = true;
414 second_shot_left_default = false;
415 } else if (hot_goal_decoder.is_right()) {
416 LOG(INFO, "first shot right\n");
417 first_shot_left = false;
418 second_shot_left_default = true;
419 } else {
420 LOG(INFO, "first shot defaulting left\n");
421 first_shot_left = true;
422 second_shot_left_default = true;
423 }
424 if (auto_version == AutoVersion::kDoubleHot) {
425 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400426 auto drivetrain_action = SetDriveGoal(
427 0, drive_with_ball_params, first_shot_left ? kTurnAngle : -kTurnAngle);
428 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700429 if (ShouldExitAuto()) return;
430 } else if (auto_version == AutoVersion::kSingleHot) {
431 do {
432 // TODO(brians): Wait for next message with timeout or something.
433 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.003));
434 hot_goal_decoder.Update(false);
435 if (ShouldExitAuto()) return;
436 } while (!hot_goal_decoder.left_triggered() &&
437 (::aos::time::Time::Now() - start_time) <
438 ::aos::time::Time::InSeconds(9));
439 } else if (auto_version == AutoVersion::kStraight) {
440 time::SleepFor(time::Time::InSeconds(0.4));
441 }
442
443 // Shoot.
444 LOG(INFO, "Shooting at %f\n",
445 (::aos::time::Time::Now() - start_time).ToSeconds());
446 Shoot();
447 time::SleepFor(time::Time::InSeconds(0.05));
448
449 if (auto_version == AutoVersion::kDoubleHot) {
450 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400451 auto drivetrain_action = SetDriveGoal(
452 0, drive_with_ball_params, first_shot_left ? -kTurnAngle : kTurnAngle);
453 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700454 if (ShouldExitAuto()) return;
455 } else if (auto_version == AutoVersion::kSingleHot) {
456 LOG(INFO, "auto done at %f\n",
457 (::aos::time::Time::Now() - start_time).ToSeconds());
458 PositionClawVertically(0.0, 0.0);
459 return;
460 }
461
462 {
463 if (ShouldExitAuto()) return;
464 // Intake the new ball.
465 LOG(INFO, "Claw ready for intake at %f\n",
466 (::aos::time::Time::Now() - start_time).ToSeconds());
467 PositionClawBackIntake();
468 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400469 SetDriveGoal(kShootDistance + kPickupDistance, drive_params);
Brian Silverman17f503e2015-08-02 18:17:18 -0700470 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400471 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700472 if (ShouldExitAuto()) return;
473 LOG(INFO, "Wait for the claw at %f\n",
474 (::aos::time::Time::Now() - start_time).ToSeconds());
475 WaitUntilClawDone();
476 if (ShouldExitAuto()) return;
477 }
478
479 // Drive back.
480 {
481 LOG(INFO, "Driving back at %f\n",
482 (::aos::time::Time::Now() - start_time).ToSeconds());
483 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400484 SetDriveGoal(-(kShootDistance + kPickupDistance), drive_params);
Brian Silverman17f503e2015-08-02 18:17:18 -0700485 time::SleepFor(time::Time::InSeconds(0.3));
486 hot_goal_decoder.ResetCounts();
487 if (ShouldExitAuto()) return;
488 PositionClawUpClosed();
489 WaitUntilClawDone();
490 if (ShouldExitAuto()) return;
491 PositionClawForShot();
492 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400493 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700494 if (ShouldExitAuto()) return;
495 WaitUntilClawDone();
496 if (ShouldExitAuto()) return;
497 }
498
499 hot_goal_decoder.Update();
500 if (hot_goal_decoder.is_left()) {
501 LOG(INFO, "second shot left\n");
502 second_shot_left = true;
503 } else if (hot_goal_decoder.is_right()) {
504 LOG(INFO, "second shot right\n");
505 second_shot_left = false;
506 } else {
507 LOG(INFO, "second shot defaulting %s\n",
508 second_shot_left_default ? "left" : "right");
509 second_shot_left = second_shot_left_default;
510 }
511 if (auto_version == AutoVersion::kDoubleHot) {
512 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400513 auto drivetrain_action = SetDriveGoal(
514 0, drive_params, second_shot_left ? kTurnAngle : -kTurnAngle);
515 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700516 if (ShouldExitAuto()) return;
517 } else if (auto_version == AutoVersion::kStraight) {
518 time::SleepFor(time::Time::InSeconds(0.4));
519 }
520
521 LOG(INFO, "Shooting at %f\n",
522 (::aos::time::Time::Now() - start_time).ToSeconds());
523 // Shoot
524 Shoot();
525 if (ShouldExitAuto()) return;
526
527 // Get ready to zero when we come back up.
528 time::SleepFor(time::Time::InSeconds(0.05));
529 PositionClawVertically(0.0, 0.0);
530}
531
532} // namespace autonomous
Brian Silvermanb601d892015-12-20 18:24:38 -0500533} // namespace y2014