blob: d6fef3abca8804cd33de1e6a9810818755dbd68a [file] [log] [blame]
Austin Schuh80ff2e12014-03-08 12:06:19 -08001#include <stdio.h>
2
3#include <memory>
Austin Schuh47017412013-03-10 11:50:46 -07004
Brian3afd6fc2014-04-02 20:41:49 -07005#include "aos/common/util/phased_loop.h"
Austin Schuh47017412013-03-10 11:50:46 -07006#include "aos/common/time.h"
Austin Schuh6be011a2013-03-19 10:07:02 +00007#include "aos/common/util/trapezoid_profile.h"
Brian Silverman598800f2013-05-09 17:08:42 -07008#include "aos/common/logging/logging.h"
Brian Silverman96d9cea2013-11-12 21:10:50 -08009#include "aos/common/network/team_number.h"
Brian Silverman6f621542014-04-06 16:00:41 -070010#include "aos/common/logging/queue_logging.h"
Brian Silverman598800f2013-05-09 17:08:42 -070011
12#include "frc971/autonomous/auto.q.h"
Austin Schuh6be011a2013-03-19 10:07:02 +000013#include "frc971/constants.h"
14#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Austin Schuh80ff2e12014-03-08 12:06:19 -080015#include "frc971/control_loops/shooter/shooter.q.h"
16#include "frc971/control_loops/claw/claw.q.h"
17#include "frc971/actions/action_client.h"
18#include "frc971/actions/shoot_action.h"
19#include "frc971/actions/drivetrain_action.h"
Brian Silverman45ceeb52014-04-17 15:15:18 -070020#include "frc971/queues/other_sensors.q.h"
Brian Silverman6f621542014-04-06 16:00:41 -070021#include "frc971/queues/hot_goal.q.h"
Austin Schuh47017412013-03-10 11:50:46 -070022
23using ::aos::time::Time;
24
25namespace frc971 {
26namespace autonomous {
27
Austin Schuh80ff2e12014-03-08 12:06:19 -080028namespace time = ::aos::time;
29
Brian Silverman3b89ed82013-03-22 18:59:16 -070030static double left_initial_position, right_initial_position;
31
Austin Schuh6be011a2013-03-19 10:07:02 +000032bool ShouldExitAuto() {
33 ::frc971::autonomous::autonomous.FetchLatest();
34 bool ans = !::frc971::autonomous::autonomous->run_auto;
35 if (ans) {
36 LOG(INFO, "Time to exit auto mode\n");
37 }
38 return ans;
39}
40
Austin Schuh6be011a2013-03-19 10:07:02 +000041void StopDrivetrain() {
42 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh47017412013-03-10 11:50:46 -070043 control_loops::drivetrain.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070044 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070045 .left_goal(left_initial_position)
46 .left_velocity_goal(0)
47 .right_goal(right_initial_position)
48 .right_velocity_goal(0)
49 .quickturn(false)
50 .Send();
51}
52
53void ResetDrivetrain() {
54 LOG(INFO, "resetting the drivetrain\n");
55 control_loops::drivetrain.goal.MakeWithBuilder()
56 .control_loop_driving(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000057 .highgear(false)
58 .steering(0.0)
59 .throttle(0.0)
Brian Silverman38ea9bf2014-04-19 22:57:54 -070060 .left_goal(left_initial_position)
61 .left_velocity_goal(0)
62 .right_goal(right_initial_position)
63 .right_velocity_goal(0)
Austin Schuh6be011a2013-03-19 10:07:02 +000064 .Send();
65}
66
Brian Silverman3b89ed82013-03-22 18:59:16 -070067void DriveSpin(double radians) {
68 LOG(INFO, "going to spin %f\n", radians);
69
70 ::aos::util::TrapezoidProfile profile(::aos::time::Time::InMS(10));
71 ::Eigen::Matrix<double, 2, 1> driveTrainState;
72 const double goal_velocity = 0.0;
73 const double epsilon = 0.01;
Brian Silverman13be6682013-03-22 21:02:07 -070074 // in drivetrain "meters"
Brian Silverman3b89ed82013-03-22 18:59:16 -070075 const double kRobotWidth = 0.4544;
76
Brian Silverman7992d6e2013-03-24 19:20:54 -070077 profile.set_maximum_acceleration(1.5);
78 profile.set_maximum_velocity(0.8);
Brian Silverman3b89ed82013-03-22 18:59:16 -070079
80 const double side_offset = kRobotWidth * radians / 2.0;
81
82 while (true) {
Brian Silverman7f09f972013-03-22 23:11:39 -070083 ::aos::time::PhasedLoop10MS(5000); // wait until next 10ms tick
Brian Silverman3b89ed82013-03-22 18:59:16 -070084 driveTrainState = profile.Update(side_offset, goal_velocity);
85
86 if (::std::abs(driveTrainState(0, 0) - side_offset) < epsilon) break;
87 if (ShouldExitAuto()) return;
88
89 LOG(DEBUG, "Driving left to %f, right to %f\n",
Brian Silverman7992d6e2013-03-24 19:20:54 -070090 left_initial_position - driveTrainState(0, 0),
91 right_initial_position + driveTrainState(0, 0));
Brian Silverman3b89ed82013-03-22 18:59:16 -070092 control_loops::drivetrain.goal.MakeWithBuilder()
93 .control_loop_driving(true)
94 .highgear(false)
Brian Silverman7992d6e2013-03-24 19:20:54 -070095 .left_goal(left_initial_position - driveTrainState(0, 0))
96 .right_goal(right_initial_position + driveTrainState(0, 0))
97 .left_velocity_goal(-driveTrainState(1, 0))
98 .right_velocity_goal(driveTrainState(1, 0))
Brian Silverman3b89ed82013-03-22 18:59:16 -070099 .Send();
100 }
Brian Silverman7992d6e2013-03-24 19:20:54 -0700101 left_initial_position -= side_offset;
102 right_initial_position += side_offset;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700103 LOG(INFO, "Done moving\n");
104}
105
Austin Schuh80ff2e12014-03-08 12:06:19 -0800106void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
107 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
108 .bottom_angle(0.0)
109 .separation_angle(0.0)
110 .intake(intake_power)
111 .centering(centering_power)
112 .Send()) {
113 LOG(WARNING, "sending claw goal failed\n");
114 }
115}
Brian Silvermance86bac2013-03-31 19:07:24 -0700116
Austin Schuh80ff2e12014-03-08 12:06:19 -0800117void PositionClawBackIntake() {
118 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
119 .bottom_angle(-2.273474)
120 .separation_angle(0.0)
121 .intake(12.0)
122 .centering(12.0)
123 .Send()) {
124 LOG(WARNING, "sending claw goal failed\n");
125 }
126}
Brian Silvermance86bac2013-03-31 19:07:24 -0700127
Brian Silverman2bd5a062014-04-26 07:35:56 -0500128void PositionClawUpClosed() {
129 // Move the claw to where we're going to shoot from but keep it closed until
130 // it gets there.
131 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
132 .bottom_angle(0.86)
133 .separation_angle(0.0)
134 .intake(4.0)
135 .centering(1.0)
136 .Send()) {
137 LOG(WARNING, "sending claw goal failed\n");
138 }
139}
140
Austin Schuh80ff2e12014-03-08 12:06:19 -0800141void PositionClawForShot() {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800142 if (!control_loops::claw_queue_group.goal.MakeWithBuilder()
Brian Silverman31b5b822014-03-14 18:50:39 -0700143 .bottom_angle(0.86)
Austin Schuha4faacc2014-03-09 00:50:50 -0800144 .separation_angle(0.10)
145 .intake(4.0)
Austin Schuh80ff2e12014-03-08 12:06:19 -0800146 .centering(1.0)
147 .Send()) {
148 LOG(WARNING, "sending claw goal failed\n");
149 }
150}
151
152void SetShotPower(double power) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800153 LOG(INFO, "Setting shot power to %f\n", power);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800154 if (!control_loops::shooter_queue_group.goal.MakeWithBuilder()
155 .shot_power(power)
156 .shot_requested(false)
157 .unload_requested(false)
158 .load_requested(false)
159 .Send()) {
160 LOG(WARNING, "sending shooter goal failed\n");
161 }
162}
163
164void WaitUntilDoneOrCanceled(Action *action) {
165 while (true) {
166 // Poll the running bit and auto done bits.
167 ::aos::time::PhasedLoop10MS(5000);
168 if (!action->Running() || ShouldExitAuto()) {
169 return;
170 }
171 }
172}
173
174void Shoot() {
175 // Shoot.
176 auto shoot_action = actions::MakeShootAction();
177 shoot_action->Start();
178 WaitUntilDoneOrCanceled(shoot_action.get());
179}
180
181::std::unique_ptr<TypedAction< ::frc971::actions::DrivetrainActionQueueGroup>>
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700182SetDriveGoal(double distance, bool slow_acceleration,
183 double maximum_velocity = 1.7, double theta = 0) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800184 LOG(INFO, "Driving to %f\n", distance);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800185 auto drivetrain_action = actions::MakeDrivetrainAction();
186 drivetrain_action->GetGoal()->left_initial_position = left_initial_position;
187 drivetrain_action->GetGoal()->right_initial_position = right_initial_position;
188 drivetrain_action->GetGoal()->y_offset = distance;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700189 drivetrain_action->GetGoal()->theta_offset = theta;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800190 drivetrain_action->GetGoal()->maximum_velocity = maximum_velocity;
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700191 drivetrain_action->GetGoal()->maximum_acceleration =
192 slow_acceleration ? 2.5 : 3.0;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800193 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700194 left_initial_position +=
195 distance - theta * constants::GetValues().turn_width / 2.0;
196 right_initial_position +=
197 distance + theta * constants::GetValues().turn_width / 2. -
198 theta * constants::GetValues().turn_width / 2.00;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800199 return ::std::move(drivetrain_action);
200}
201
202void InitializeEncoders() {
Austin Schuh577edf62014-04-13 10:33:05 -0700203 control_loops::drivetrain.status.FetchLatest();
204 while (!control_loops::drivetrain.status.get()) {
Brian Silverman2c1e0342014-04-11 16:15:01 -0700205 LOG(WARNING,
206 "No previous drivetrain position packet, trying to fetch again\n");
Austin Schuh577edf62014-04-13 10:33:05 -0700207 control_loops::drivetrain.status.FetchNextBlocking();
Brian Silverman3b89ed82013-03-22 18:59:16 -0700208 }
209 left_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700210 control_loops::drivetrain.status->filtered_left_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700211 right_initial_position =
Austin Schuh577edf62014-04-13 10:33:05 -0700212 control_loops::drivetrain.status->filtered_right_position;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700213
Austin Schuh80ff2e12014-03-08 12:06:19 -0800214}
215
Austin Schuha4faacc2014-03-09 00:50:50 -0800216void WaitUntilClawDone() {
217 while (true) {
218 // Poll the running bit and auto done bits.
219 ::aos::time::PhasedLoop10MS(5000);
220 control_loops::claw_queue_group.status.FetchLatest();
221 control_loops::claw_queue_group.goal.FetchLatest();
222 if (ShouldExitAuto()) {
223 return;
224 }
225 if (control_loops::claw_queue_group.status.get() == nullptr ||
226 control_loops::claw_queue_group.goal.get() == nullptr) {
227 continue;
228 }
229 bool ans =
230 control_loops::claw_queue_group.status->zeroed &&
231 (::std::abs(control_loops::claw_queue_group.status->bottom_velocity) <
232 1.0) &&
233 (::std::abs(control_loops::claw_queue_group.status->bottom -
234 control_loops::claw_queue_group.goal->bottom_angle) <
235 0.10) &&
236 (::std::abs(control_loops::claw_queue_group.status->separation -
237 control_loops::claw_queue_group.goal->separation_angle) <
238 0.4);
239 if (ans) {
240 return;
241 }
242 }
243}
244
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700245class HotGoalDecoder {
246 public:
247 HotGoalDecoder() {
248 ResetCounts();
249 }
250
251 void ResetCounts() {
252 hot_goal.FetchLatest();
253 if (hot_goal.get()) {
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700254 start_counts_ = *hot_goal;
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700255 LOG_STRUCT(INFO, "counts reset to", start_counts_);
256 start_counts_valid_ = true;
257 } else {
258 LOG(WARNING, "no hot goal message. ignoring\n");
259 start_counts_valid_ = false;
260 }
261 }
262
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700263 void Update(bool block = false) {
264 if (block) {
265 hot_goal.FetchAnother();
266 } else {
267 hot_goal.FetchLatest();
268 }
Brian Silvermanfa577e42014-04-19 12:03:00 -0700269 if (hot_goal.get()) LOG_STRUCT(INFO, "new counts", *hot_goal);
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700270 }
271
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700272 bool left_triggered() const {
273 if (!start_counts_valid_ || !hot_goal.get()) return false;
274 return (hot_goal->left_count - start_counts_.left_count) > kThreshold;
275 }
276
277 bool right_triggered() const {
278 if (!start_counts_valid_ || !hot_goal.get()) return false;
279 return (hot_goal->right_count - start_counts_.right_count) > kThreshold;
280 }
281
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700282 bool is_left() const {
283 if (!start_counts_valid_ || !hot_goal.get()) return false;
284 const uint64_t left_difference =
285 hot_goal->left_count - start_counts_.left_count;
286 const uint64_t right_difference =
287 hot_goal->right_count - start_counts_.right_count;
288 if (left_difference > kThreshold) {
289 if (right_difference > kThreshold) {
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700290 // We've seen a lot of both, so pick the one we've seen the most of.
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700291 return left_difference > right_difference;
292 } else {
293 // We've seen enough left but not enough right, so go with it.
294 return true;
295 }
296 } else {
297 // We haven't seen enough left, so it's not left.
298 return false;
299 }
300 }
301
302 bool is_right() const {
303 if (!start_counts_valid_ || !hot_goal.get()) return false;
304 const uint64_t left_difference =
305 hot_goal->left_count - start_counts_.left_count;
306 const uint64_t right_difference =
307 hot_goal->right_count - start_counts_.right_count;
308 if (right_difference > kThreshold) {
309 if (left_difference > kThreshold) {
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700310 // We've seen a lot of both, so pick the one we've seen the most of.
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700311 return right_difference > left_difference;
312 } else {
313 // We've seen enough right but not enough left, so go with it.
314 return true;
315 }
316 } else {
317 // We haven't seen enough right, so it's not right.
318 return false;
319 }
320 }
321
322 private:
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700323 static const uint64_t kThreshold = 5;
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700324
325 ::frc971::HotGoal start_counts_;
326 bool start_counts_valid_;
327};
328
Austin Schuh80ff2e12014-03-08 12:06:19 -0800329void HandleAuto() {
Brian Silverman45ceeb52014-04-17 15:15:18 -0700330 enum class AutoVersion : uint8_t {
331 kStraight,
332 kDoubleHot,
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700333 kSingleHot,
Brian Silverman45ceeb52014-04-17 15:15:18 -0700334 };
335
Austin Schuha4faacc2014-03-09 00:50:50 -0800336 // The front of the robot is 1.854 meters from the wall
Brian Silvermanad9e0002014-04-13 14:55:57 -0700337 static const double kShootDistance = 3.15;
338 static const double kPickupDistance = 0.5;
339 static const double kTurnAngle = 0.3;
Brian Silverman45ceeb52014-04-17 15:15:18 -0700340
Austin Schuh577edf62014-04-13 10:33:05 -0700341 ::aos::time::Time start_time = ::aos::time::Time::Now();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800342 LOG(INFO, "Handling auto mode\n");
Brian Silvermanb36ae1f2014-04-17 15:13:41 -0700343
Brian Silverman45ceeb52014-04-17 15:15:18 -0700344 AutoVersion auto_version;
345 ::frc971::sensors::auto_mode.FetchLatest();
346 if (!::frc971::sensors::auto_mode.get()) {
347 LOG(WARNING, "not sure which auto mode to use\n");
348 auto_version = AutoVersion::kStraight;
349 } else {
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700350 static const double kSelectorMin = 0.2, kSelectorMax = 4.4;
351
352 const double kSelectorStep = (kSelectorMax - kSelectorMin) / 3.0;
353 if (::frc971::sensors::auto_mode->voltage < kSelectorStep + kSelectorMin) {
354 auto_version = AutoVersion::kSingleHot;
355 } else if (::frc971::sensors::auto_mode->voltage <
356 2 * kSelectorStep + kSelectorMin) {
357 auto_version = AutoVersion::kStraight;
358 } else {
359 auto_version = AutoVersion::kDoubleHot;
360 }
Brian Silverman45ceeb52014-04-17 15:15:18 -0700361 }
362 LOG(INFO, "running auto %" PRIu8 "\n", auto_version);
363
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700364 const bool drive_slow_acceleration = auto_version == AutoVersion::kStraight;
365
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700366 HotGoalDecoder hot_goal_decoder;
367 // True for left, false for right.
368 bool first_shot_left, second_shot_left_default, second_shot_left;
Brian Silverman6f621542014-04-06 16:00:41 -0700369
Austin Schuh80ff2e12014-03-08 12:06:19 -0800370 ResetDrivetrain();
371
372 if (ShouldExitAuto()) return;
373 InitializeEncoders();
374
375 // Turn the claw on, keep it straight up until the ball has been grabbed.
Austin Schuh577edf62014-04-13 10:33:05 -0700376 LOG(INFO, "Claw going up at %f\n",
377 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800378 PositionClawVertically(12.0, 4.0);
Austin Schuha4faacc2014-03-09 00:50:50 -0800379 SetShotPower(115.0);
Austin Schuh80ff2e12014-03-08 12:06:19 -0800380
381 // Wait for the ball to enter the claw.
Austin Schuha4faacc2014-03-09 00:50:50 -0800382 time::SleepFor(time::Time::InSeconds(0.25));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800383 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700384 LOG(INFO, "Readying claw for shot at %f\n",
385 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800386
387 {
388 if (ShouldExitAuto()) return;
389 // Drive to the goal.
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700390 auto drivetrain_action = SetDriveGoal(-kShootDistance,
391 drive_slow_acceleration, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800392 time::SleepFor(time::Time::InSeconds(0.75));
393 PositionClawForShot();
394 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800395 WaitUntilDoneOrCanceled(drivetrain_action.get());
396 if (ShouldExitAuto()) return;
397 }
Brian Silvermanad9e0002014-04-13 14:55:57 -0700398
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700399 hot_goal_decoder.Update();
400 if (hot_goal_decoder.is_left()) {
401 LOG(INFO, "first shot left\n");
402 first_shot_left = true;
403 second_shot_left_default = false;
404 } else if (hot_goal_decoder.is_right()) {
405 LOG(INFO, "first shot right\n");
406 first_shot_left = false;
407 second_shot_left_default = true;
408 } else {
409 LOG(INFO, "first shot defaulting left\n");
410 first_shot_left = true;
411 second_shot_left_default = true;
412 }
413 if (auto_version == AutoVersion::kDoubleHot) {
Brian Silvermanad9e0002014-04-13 14:55:57 -0700414 if (ShouldExitAuto()) return;
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700415 auto drivetrain_action =
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700416 SetDriveGoal(0, drive_slow_acceleration, 2,
417 first_shot_left ? kTurnAngle : -kTurnAngle);
Brian Silvermanad9e0002014-04-13 14:55:57 -0700418 WaitUntilDoneOrCanceled(drivetrain_action.get());
419 if (ShouldExitAuto()) return;
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700420 } else if (auto_version == AutoVersion::kSingleHot) {
421 do {
Brian Silvermanaf4a5852014-04-23 22:27:59 -0500422 // TODO(brians): Wait for next message with timeout or something.
423 ::aos::time::SleepFor(::aos::time::Time::InSeconds(0.003));
424 hot_goal_decoder.Update(false);
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700425 if (ShouldExitAuto()) return;
426 } while (!hot_goal_decoder.left_triggered() &&
427 (::aos::time::Time::Now() - start_time) <
428 ::aos::time::Time::InSeconds(9));
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700429 } else if (auto_version == AutoVersion::kStraight) {
430 time::SleepFor(time::Time::InSeconds(0.4));
Brian Silvermanad9e0002014-04-13 14:55:57 -0700431 }
Austin Schuh80ff2e12014-03-08 12:06:19 -0800432
433 // Shoot.
Brian Silvermanad9e0002014-04-13 14:55:57 -0700434 LOG(INFO, "Shooting at %f\n",
435 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800436 Shoot();
Austin Schuh577edf62014-04-13 10:33:05 -0700437 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800438
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700439 if (auto_version == AutoVersion::kDoubleHot) {
Austin Schuh80ff2e12014-03-08 12:06:19 -0800440 if (ShouldExitAuto()) return;
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700441 auto drivetrain_action =
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700442 SetDriveGoal(0, drive_slow_acceleration, 2,
443 first_shot_left ? -kTurnAngle : kTurnAngle);
Brian Silvermanad9e0002014-04-13 14:55:57 -0700444 WaitUntilDoneOrCanceled(drivetrain_action.get());
445 if (ShouldExitAuto()) return;
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700446 } else if (auto_version == AutoVersion::kSingleHot) {
447 LOG(INFO, "auto done at %f\n",
448 (::aos::time::Time::Now() - start_time).ToSeconds());
449 PositionClawVertically(0.0, 0.0);
450 return;
Brian Silvermanad9e0002014-04-13 14:55:57 -0700451 }
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700452
Brian Silvermanad9e0002014-04-13 14:55:57 -0700453 {
454 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800455 // Intake the new ball.
Austin Schuh577edf62014-04-13 10:33:05 -0700456 LOG(INFO, "Claw ready for intake at %f\n",
457 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800458 PositionClawBackIntake();
Brian Silvermanb94069c2014-04-17 14:34:24 -0700459 auto drivetrain_action =
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700460 SetDriveGoal(kShootDistance + kPickupDistance,
461 drive_slow_acceleration, 2.5);
Austin Schuha4faacc2014-03-09 00:50:50 -0800462 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800463 WaitUntilDoneOrCanceled(drivetrain_action.get());
464 if (ShouldExitAuto()) return;
Austin Schuh577edf62014-04-13 10:33:05 -0700465 LOG(INFO, "Wait for the claw at %f\n",
466 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuha4faacc2014-03-09 00:50:50 -0800467 WaitUntilClawDone();
468 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800469 }
470
471 // Drive back.
472 {
Austin Schuh577edf62014-04-13 10:33:05 -0700473 LOG(INFO, "Driving back at %f\n",
474 (::aos::time::Time::Now() - start_time).ToSeconds());
Brian Silvermanb94069c2014-04-17 14:34:24 -0700475 auto drivetrain_action =
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700476 SetDriveGoal(-(kShootDistance + kPickupDistance),
477 drive_slow_acceleration, 2.5);
Austin Schuh577edf62014-04-13 10:33:05 -0700478 time::SleepFor(time::Time::InSeconds(0.3));
Brian Silverman38ea9bf2014-04-19 22:57:54 -0700479 hot_goal_decoder.ResetCounts();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800480 if (ShouldExitAuto()) return;
Brian Silverman2bd5a062014-04-26 07:35:56 -0500481 PositionClawUpClosed();
482 WaitUntilClawDone();
483 if (ShouldExitAuto()) return;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800484 PositionClawForShot();
Austin Schuha4faacc2014-03-09 00:50:50 -0800485 LOG(INFO, "Waiting until drivetrain is finished\n");
Austin Schuh80ff2e12014-03-08 12:06:19 -0800486 WaitUntilDoneOrCanceled(drivetrain_action.get());
Brian Silverman2bd5a062014-04-26 07:35:56 -0500487 if (ShouldExitAuto()) return;
Austin Schuha4faacc2014-03-09 00:50:50 -0800488 WaitUntilClawDone();
Austin Schuh80ff2e12014-03-08 12:06:19 -0800489 if (ShouldExitAuto()) return;
490 }
491
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700492 hot_goal_decoder.Update();
493 if (hot_goal_decoder.is_left()) {
494 LOG(INFO, "second shot left\n");
495 second_shot_left = true;
496 } else if (hot_goal_decoder.is_right()) {
497 LOG(INFO, "second shot right\n");
498 second_shot_left = false;
499 } else {
500 LOG(INFO, "second shot defaulting %s\n",
501 second_shot_left_default ? "left" : "right");
502 second_shot_left = second_shot_left_default;
503 }
504 if (auto_version == AutoVersion::kDoubleHot) {
Brian Silvermanad9e0002014-04-13 14:55:57 -0700505 if (ShouldExitAuto()) return;
Brian Silverman4ac1cb82014-04-17 16:00:06 -0700506 auto drivetrain_action =
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700507 SetDriveGoal(0, drive_slow_acceleration, 2,
508 second_shot_left ? kTurnAngle : -kTurnAngle);
Brian Silvermanad9e0002014-04-13 14:55:57 -0700509 WaitUntilDoneOrCanceled(drivetrain_action.get());
510 if (ShouldExitAuto()) return;
Natalia Frumkind1fa52f2014-06-21 15:24:25 -0700511 } else if (auto_version == AutoVersion::kStraight) {
512 time::SleepFor(time::Time::InSeconds(0.4));
Brian Silvermanad9e0002014-04-13 14:55:57 -0700513 }
514
Austin Schuh577edf62014-04-13 10:33:05 -0700515 LOG(INFO, "Shooting at %f\n",
516 (::aos::time::Time::Now() - start_time).ToSeconds());
Austin Schuh80ff2e12014-03-08 12:06:19 -0800517 // Shoot
518 Shoot();
519 if (ShouldExitAuto()) return;
520
521 // Get ready to zero when we come back up.
Austin Schuh577edf62014-04-13 10:33:05 -0700522 time::SleepFor(time::Time::InSeconds(0.05));
Austin Schuh80ff2e12014-03-08 12:06:19 -0800523 PositionClawVertically(0.0, 0.0);
Austin Schuh47017412013-03-10 11:50:46 -0700524}
525
526} // namespace autonomous
527} // namespace frc971