blob: ef59ba4c716f9768e0cc7933cdfc1fb89602537a [file] [log] [blame]
Brian Silverman17f503e2015-08-02 18:17:18 -07001#include <stdio.h>
2
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
Brian Silverman17f503e2015-08-02 18:17:18 -07004#include <memory>
5
John Park33858a32018-09-28 23:05:48 -07006#include "aos/util/phased_loop.h"
7#include "aos/time/time.h"
8#include "aos/util/trapezoid_profile.h"
9#include "aos/logging/logging.h"
10#include "aos/logging/queue_logging.h"
11#include "aos/actions/actions.h"
Brian Silverman17f503e2015-08-02 18:17:18 -070012
13#include "frc971/autonomous/auto.q.h"
Comran Morshed5323ecb2015-12-26 20:50:55 +000014#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040015#include "y2014/actors/drivetrain_actor.h"
Austin Schuh3130b372016-02-17 00:34:51 -080016#include "y2014/actors/shoot_actor.h"
17#include "y2014/constants.h"
18#include "y2014/control_loops/claw/claw.q.h"
19#include "y2014/control_loops/drivetrain/drivetrain_dog_motor_plant.h"
20#include "y2014/control_loops/shooter/shooter.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040021#include "y2014/queues/auto_mode.q.h"
22
Brian Silverman17f503e2015-08-02 18:17:18 -070023#include "y2014/queues/hot_goal.q.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040024#include "y2014/queues/profile_params.q.h"
Brian Silverman17f503e2015-08-02 18:17:18 -070025
Brian Silvermanb601d892015-12-20 18:24:38 -050026namespace y2014 {
Brian Silverman17f503e2015-08-02 18:17:18 -070027namespace autonomous {
Austin Schuhf2a50ba2016-12-24 16:16:26 -080028namespace chrono = ::std::chrono;
29namespace this_thread = ::std::this_thread;
30using ::aos::monotonic_clock;
Brian Silverman17f503e2015-08-02 18:17:18 -070031
Austin Schuhf2a50ba2016-12-24 16:16:26 -080032namespace {
33
34double DoubleSeconds(monotonic_clock::duration duration) {
35 return ::std::chrono::duration_cast<::std::chrono::duration<double>>(duration)
36 .count();
37}
38
39} // namespace
Brian Silverman17f503e2015-08-02 18:17:18 -070040
41static double left_initial_position, right_initial_position;
42
43bool ShouldExitAuto() {
44 ::frc971::autonomous::autonomous.FetchLatest();
45 bool ans = !::frc971::autonomous::autonomous->run_auto;
46 if (ans) {
47 LOG(INFO, "Time to exit auto mode\n");
48 }
49 return ans;
50}
51
52void StopDrivetrain() {
53 LOG(INFO, "Stopping the drivetrain\n");
Comran Morshed5323ecb2015-12-26 20:50:55 +000054 frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Austin Schuh78379ea2019-01-04 20:39:45 -080055 .controller_type(1)
Austin Schuh86f895e2015-11-08 13:40:51 -080056 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -070057 .left_goal(left_initial_position)
Brian Silverman17f503e2015-08-02 18:17:18 -070058 .right_goal(right_initial_position)
Brian Silverman17f503e2015-08-02 18:17:18 -070059 .quickturn(false)
60 .Send();
61}
62
63void ResetDrivetrain() {
64 LOG(INFO, "resetting the drivetrain\n");
Comran Morshed5323ecb2015-12-26 20:50:55 +000065 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Austin Schuh78379ea2019-01-04 20:39:45 -080066 .controller_type(0)
Austin Schuh86f895e2015-11-08 13:40:51 -080067 .highgear(true)
Austin Schuh2b1fce02018-03-02 20:05:20 -080068 .wheel(0.0)
Brian Silverman17f503e2015-08-02 18:17:18 -070069 .throttle(0.0)
70 .left_goal(left_initial_position)
Brian Silverman17f503e2015-08-02 18:17:18 -070071 .right_goal(right_initial_position)
Brian Silverman17f503e2015-08-02 18:17:18 -070072 .Send();
73}
74
75void WaitUntilDoneOrCanceled(
76 ::std::unique_ptr<aos::common::actions::Action> action) {
77 if (!action) {
78 LOG(ERROR, "No action, not waiting\n");
79 return;
80 }
Austin Schuhf2a50ba2016-12-24 16:16:26 -080081 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(10),
82 ::std::chrono::milliseconds(10) / 2);
Brian Silverman17f503e2015-08-02 18:17:18 -070083 while (true) {
84 // Poll the running bit and auto done bits.
Austin Schuhf2a50ba2016-12-24 16:16:26 -080085 phased_loop.SleepUntilNext();
Brian Silverman17f503e2015-08-02 18:17:18 -070086 if (!action->Running() || ShouldExitAuto()) {
87 return;
88 }
89 }
90}
91
92void StepDrive(double distance, double theta) {
93 double left_goal = (left_initial_position + distance -
Austin Schuh3130b372016-02-17 00:34:51 -080094 theta * control_loops::drivetrain::kRobotRadius);
Brian Silverman17f503e2015-08-02 18:17:18 -070095 double right_goal = (right_initial_position + distance +
Austin Schuh3130b372016-02-17 00:34:51 -080096 theta * control_loops::drivetrain::kRobotRadius);
Comran Morshed5323ecb2015-12-26 20:50:55 +000097 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Austin Schuh78379ea2019-01-04 20:39:45 -080098 .controller_type(1)
Austin Schuh86f895e2015-11-08 13:40:51 -080099 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -0700100 .left_goal(left_goal)
101 .right_goal(right_goal)
Brian Silverman17f503e2015-08-02 18:17:18 -0700102 .Send();
103 left_initial_position = left_goal;
104 right_initial_position = right_goal;
105}
106
Brian Silvermanbfa00602015-05-17 01:41:29 -0400107void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
108 if (!control_loops::claw_queue.goal.MakeWithBuilder()
109 .bottom_angle(0.0)
110 .separation_angle(0.0)
111 .intake(intake_power)
112 .centering(centering_power)
113 .Send()) {
114 LOG(WARNING, "sending claw goal failed\n");
115 }
116}
117
118void PositionClawBackIntake() {
119 if (!control_loops::claw_queue.goal.MakeWithBuilder()
120 .bottom_angle(-2.273474)
121 .separation_angle(0.0)
122 .intake(12.0)
123 .centering(12.0)
124 .Send()) {
125 LOG(WARNING, "sending claw goal failed\n");
126 }
127}
128
129void PositionClawUpClosed() {
130 // Move the claw to where we're going to shoot from but keep it closed until
131 // it gets there.
132 if (!control_loops::claw_queue.goal.MakeWithBuilder()
133 .bottom_angle(0.86)
134 .separation_angle(0.0)
135 .intake(4.0)
136 .centering(1.0)
137 .Send()) {
138 LOG(WARNING, "sending claw goal failed\n");
139 }
140}
141
142void PositionClawForShot() {
143 if (!control_loops::claw_queue.goal.MakeWithBuilder()
144 .bottom_angle(0.86)
145 .separation_angle(0.10)
146 .intake(4.0)
147 .centering(1.0)
148 .Send()) {
149 LOG(WARNING, "sending claw goal failed\n");
150 }
151}
152
153void SetShotPower(double power) {
154 LOG(INFO, "Setting shot power to %f\n", power);
155 if (!control_loops::shooter_queue.goal.MakeWithBuilder()
156 .shot_power(power)
157 .shot_requested(false)
158 .unload_requested(false)
159 .load_requested(false)
160 .Send()) {
161 LOG(WARNING, "sending shooter goal failed\n");
162 }
163}
164
Brian Silverman17f503e2015-08-02 18:17:18 -0700165void WaitUntilNear(double distance) {
166 while (true) {
167 if (ShouldExitAuto()) return;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000168 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700169 double left_error = ::std::abs(
170 left_initial_position -
Austin Schuh093535c2016-03-05 23:21:00 -0800171 ::frc971::control_loops::drivetrain_queue.status->estimated_left_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700172 double right_error = ::std::abs(
173 right_initial_position -
Austin Schuh093535c2016-03-05 23:21:00 -0800174 ::frc971::control_loops::drivetrain_queue.status->estimated_right_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700175 const double kPositionThreshold = 0.05 + distance;
176 if (right_error < kPositionThreshold && left_error < kPositionThreshold) {
177 LOG(INFO, "At the goal\n");
178 return;
179 }
180 }
181}
182
Brian Silvermanbfa00602015-05-17 01:41:29 -0400183const ProfileParams kFastDrive = {3.0, 2.5};
184const ProfileParams kSlowDrive = {2.5, 2.5};
185const ProfileParams kFastWithBallDrive = {3.0, 2.0};
186const ProfileParams kSlowWithBallDrive = {2.5, 2.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700187const ProfileParams kFastTurn = {3.0, 10.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700188
Brian Silvermanb601d892015-12-20 18:24:38 -0500189::std::unique_ptr<::y2014::actors::DrivetrainAction> SetDriveGoal(
Brian Silverman17f503e2015-08-02 18:17:18 -0700190 double distance, const ProfileParams drive_params, double theta = 0,
191 const ProfileParams &turn_params = kFastTurn) {
192 LOG(INFO, "Driving to %f\n", distance);
193
Brian Silvermanb601d892015-12-20 18:24:38 -0500194 ::y2014::actors::DrivetrainActionParams params;
Brian Silverman17f503e2015-08-02 18:17:18 -0700195 params.left_initial_position = left_initial_position;
196 params.right_initial_position = right_initial_position;
197 params.y_offset = distance;
198 params.theta_offset = theta;
199 params.maximum_turn_acceleration = turn_params.acceleration;
200 params.maximum_turn_velocity = turn_params.velocity;
201 params.maximum_velocity = drive_params.velocity;
202 params.maximum_acceleration = drive_params.acceleration;
203 auto drivetrain_action = actors::MakeDrivetrainAction(params);
204 drivetrain_action->Start();
205 left_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800206 distance - theta * control_loops::drivetrain::kRobotRadius;
Brian Silverman17f503e2015-08-02 18:17:18 -0700207 right_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800208 distance + theta * control_loops::drivetrain::kRobotRadius;
sabinaf5584322017-09-23 18:37:19 -0700209 return drivetrain_action;
Brian Silverman17f503e2015-08-02 18:17:18 -0700210}
211
212void Shoot() {
213 // Shoot.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400214 auto shoot_action = actors::MakeShootAction();
Brian Silverman17f503e2015-08-02 18:17:18 -0700215 shoot_action->Start();
Brian Silvermanbfa00602015-05-17 01:41:29 -0400216 WaitUntilDoneOrCanceled(::std::move(shoot_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700217}
218
219void InitializeEncoders() {
Comran Morshed5323ecb2015-12-26 20:50:55 +0000220 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700221 left_initial_position =
Austin Schuh093535c2016-03-05 23:21:00 -0800222 ::frc971::control_loops::drivetrain_queue.status->estimated_left_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700223 right_initial_position =
Austin Schuh093535c2016-03-05 23:21:00 -0800224 ::frc971::control_loops::drivetrain_queue.status->estimated_right_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700225}
226
227void WaitUntilClawDone() {
228 while (true) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800229 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(10),
230 ::std::chrono::milliseconds(10) / 2);
Brian Silverman17f503e2015-08-02 18:17:18 -0700231 // Poll the running bit and auto done bits.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800232 phased_loop.SleepUntilNext();
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400233 control_loops::claw_queue.status.FetchLatest();
234 control_loops::claw_queue.goal.FetchLatest();
Brian Silverman17f503e2015-08-02 18:17:18 -0700235 if (ShouldExitAuto()) {
236 return;
237 }
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400238 if (control_loops::claw_queue.status.get() == nullptr ||
239 control_loops::claw_queue.goal.get() == nullptr) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700240 continue;
241 }
242 bool ans =
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400243 control_loops::claw_queue.status->zeroed &&
244 (::std::abs(control_loops::claw_queue.status->bottom_velocity) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700245 1.0) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400246 (::std::abs(control_loops::claw_queue.status->bottom -
247 control_loops::claw_queue.goal->bottom_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700248 0.10) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400249 (::std::abs(control_loops::claw_queue.status->separation -
250 control_loops::claw_queue.goal->separation_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700251 0.4);
252 if (ans) {
253 return;
254 }
255 if (ShouldExitAuto()) return;
256 }
257}
258
259class HotGoalDecoder {
260 public:
261 HotGoalDecoder() {
262 ResetCounts();
263 }
264
265 void ResetCounts() {
266 hot_goal.FetchLatest();
267 if (hot_goal.get()) {
268 start_counts_ = *hot_goal;
269 LOG_STRUCT(INFO, "counts reset to", start_counts_);
270 start_counts_valid_ = true;
271 } else {
272 LOG(WARNING, "no hot goal message. ignoring\n");
273 start_counts_valid_ = false;
274 }
275 }
276
277 void Update(bool block = false) {
278 if (block) {
279 hot_goal.FetchAnother();
280 } else {
281 hot_goal.FetchLatest();
282 }
283 if (hot_goal.get()) LOG_STRUCT(INFO, "new counts", *hot_goal);
284 }
285
286 bool left_triggered() const {
287 if (!start_counts_valid_ || !hot_goal.get()) return false;
288 return (hot_goal->left_count - start_counts_.left_count) > kThreshold;
289 }
290
291 bool right_triggered() const {
292 if (!start_counts_valid_ || !hot_goal.get()) return false;
293 return (hot_goal->right_count - start_counts_.right_count) > kThreshold;
294 }
295
296 bool is_left() const {
297 if (!start_counts_valid_ || !hot_goal.get()) return false;
298 const uint64_t left_difference =
299 hot_goal->left_count - start_counts_.left_count;
300 const uint64_t right_difference =
301 hot_goal->right_count - start_counts_.right_count;
302 if (left_difference > kThreshold) {
303 if (right_difference > kThreshold) {
304 // We've seen a lot of both, so pick the one we've seen the most of.
305 return left_difference > right_difference;
306 } else {
307 // We've seen enough left but not enough right, so go with it.
308 return true;
309 }
310 } else {
311 // We haven't seen enough left, so it's not left.
312 return false;
313 }
314 }
315
316 bool is_right() const {
317 if (!start_counts_valid_ || !hot_goal.get()) return false;
318 const uint64_t left_difference =
319 hot_goal->left_count - start_counts_.left_count;
320 const uint64_t right_difference =
321 hot_goal->right_count - start_counts_.right_count;
322 if (right_difference > kThreshold) {
323 if (left_difference > kThreshold) {
324 // We've seen a lot of both, so pick the one we've seen the most of.
325 return right_difference > left_difference;
326 } else {
327 // We've seen enough right but not enough left, so go with it.
328 return true;
329 }
330 } else {
331 // We haven't seen enough right, so it's not right.
332 return false;
333 }
334 }
335
336 private:
337 static const uint64_t kThreshold = 5;
338
Brian Silvermanb601d892015-12-20 18:24:38 -0500339 ::y2014::HotGoal start_counts_;
Brian Silverman17f503e2015-08-02 18:17:18 -0700340 bool start_counts_valid_;
341};
342
343void HandleAuto() {
344 enum class AutoVersion : uint8_t {
345 kStraight,
346 kDoubleHot,
347 kSingleHot,
348 };
349
350 // The front of the robot is 1.854 meters from the wall
351 static const double kShootDistance = 3.15;
352 static const double kPickupDistance = 0.5;
353 static const double kTurnAngle = 0.3;
354
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800355 monotonic_clock::time_point start_time = monotonic_clock::now();
Brian Silverman17f503e2015-08-02 18:17:18 -0700356 LOG(INFO, "Handling auto mode\n");
357
358 AutoVersion auto_version;
Brian Silvermanb601d892015-12-20 18:24:38 -0500359 ::y2014::sensors::auto_mode.FetchLatest();
360 if (!::y2014::sensors::auto_mode.get()) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700361 LOG(WARNING, "not sure which auto mode to use\n");
362 auto_version = AutoVersion::kStraight;
363 } else {
364 static const double kSelectorMin = 0.2, kSelectorMax = 4.4;
365
366 const double kSelectorStep = (kSelectorMax - kSelectorMin) / 3.0;
Brian Silvermanb601d892015-12-20 18:24:38 -0500367 if (::y2014::sensors::auto_mode->voltage < kSelectorStep + kSelectorMin) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700368 auto_version = AutoVersion::kSingleHot;
Brian Silvermanb601d892015-12-20 18:24:38 -0500369 } else if (::y2014::sensors::auto_mode->voltage <
Brian Silverman17f503e2015-08-02 18:17:18 -0700370 2 * kSelectorStep + kSelectorMin) {
371 auto_version = AutoVersion::kStraight;
372 } else {
373 auto_version = AutoVersion::kDoubleHot;
374 }
375 }
376 LOG(INFO, "running auto %" PRIu8 "\n", static_cast<uint8_t>(auto_version));
377
Brian Silvermanbfa00602015-05-17 01:41:29 -0400378 const ProfileParams &drive_params =
379 (auto_version == AutoVersion::kStraight) ? kFastDrive : kSlowDrive;
380 const ProfileParams &drive_with_ball_params =
381 (auto_version == AutoVersion::kStraight) ? kFastWithBallDrive
382 : kSlowWithBallDrive;
Brian Silverman17f503e2015-08-02 18:17:18 -0700383
384 HotGoalDecoder hot_goal_decoder;
385 // True for left, false for right.
386 bool first_shot_left, second_shot_left_default, second_shot_left;
387
388 ResetDrivetrain();
389
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800390 this_thread::sleep_for(chrono::milliseconds(100));
Brian Silverman17f503e2015-08-02 18:17:18 -0700391 if (ShouldExitAuto()) return;
392 InitializeEncoders();
393
394 // Turn the claw on, keep it straight up until the ball has been grabbed.
395 LOG(INFO, "Claw going up at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800396 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700397 PositionClawVertically(12.0, 4.0);
398 SetShotPower(115.0);
399
400 // Wait for the ball to enter the claw.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800401 this_thread::sleep_for(chrono::milliseconds(250));
Brian Silverman17f503e2015-08-02 18:17:18 -0700402 if (ShouldExitAuto()) return;
403 LOG(INFO, "Readying claw for shot at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800404 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700405
406 {
407 if (ShouldExitAuto()) return;
408 // Drive to the goal.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400409 auto drivetrain_action = SetDriveGoal(-kShootDistance, drive_params);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800410 this_thread::sleep_for(chrono::milliseconds(750));
Brian Silverman17f503e2015-08-02 18:17:18 -0700411 PositionClawForShot();
412 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400413 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700414 if (ShouldExitAuto()) return;
415 }
416
417 hot_goal_decoder.Update();
418 if (hot_goal_decoder.is_left()) {
419 LOG(INFO, "first shot left\n");
420 first_shot_left = true;
421 second_shot_left_default = false;
422 } else if (hot_goal_decoder.is_right()) {
423 LOG(INFO, "first shot right\n");
424 first_shot_left = false;
425 second_shot_left_default = true;
426 } else {
427 LOG(INFO, "first shot defaulting left\n");
428 first_shot_left = true;
429 second_shot_left_default = true;
430 }
431 if (auto_version == AutoVersion::kDoubleHot) {
432 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400433 auto drivetrain_action = SetDriveGoal(
434 0, drive_with_ball_params, first_shot_left ? kTurnAngle : -kTurnAngle);
435 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700436 if (ShouldExitAuto()) return;
437 } else if (auto_version == AutoVersion::kSingleHot) {
438 do {
439 // TODO(brians): Wait for next message with timeout or something.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800440 this_thread::sleep_for(chrono::milliseconds(3));
Brian Silverman17f503e2015-08-02 18:17:18 -0700441 hot_goal_decoder.Update(false);
442 if (ShouldExitAuto()) return;
443 } while (!hot_goal_decoder.left_triggered() &&
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800444 (monotonic_clock::now() - start_time) < chrono::seconds(9));
Brian Silverman17f503e2015-08-02 18:17:18 -0700445 } else if (auto_version == AutoVersion::kStraight) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800446 this_thread::sleep_for(chrono::milliseconds(400));
Brian Silverman17f503e2015-08-02 18:17:18 -0700447 }
448
449 // Shoot.
450 LOG(INFO, "Shooting at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800451 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700452 Shoot();
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800453 this_thread::sleep_for(chrono::milliseconds(50));
Brian Silverman17f503e2015-08-02 18:17:18 -0700454
455 if (auto_version == AutoVersion::kDoubleHot) {
456 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400457 auto drivetrain_action = SetDriveGoal(
458 0, drive_with_ball_params, first_shot_left ? -kTurnAngle : kTurnAngle);
459 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700460 if (ShouldExitAuto()) return;
461 } else if (auto_version == AutoVersion::kSingleHot) {
462 LOG(INFO, "auto done at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800463 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700464 PositionClawVertically(0.0, 0.0);
465 return;
466 }
467
468 {
469 if (ShouldExitAuto()) return;
470 // Intake the new ball.
471 LOG(INFO, "Claw ready for intake at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800472 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700473 PositionClawBackIntake();
474 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400475 SetDriveGoal(kShootDistance + kPickupDistance, drive_params);
Brian Silverman17f503e2015-08-02 18:17:18 -0700476 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400477 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700478 if (ShouldExitAuto()) return;
479 LOG(INFO, "Wait for the claw at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800480 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700481 WaitUntilClawDone();
482 if (ShouldExitAuto()) return;
483 }
484
485 // Drive back.
486 {
487 LOG(INFO, "Driving back at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800488 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700489 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400490 SetDriveGoal(-(kShootDistance + kPickupDistance), drive_params);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800491 this_thread::sleep_for(chrono::milliseconds(300));
Brian Silverman17f503e2015-08-02 18:17:18 -0700492 hot_goal_decoder.ResetCounts();
493 if (ShouldExitAuto()) return;
494 PositionClawUpClosed();
495 WaitUntilClawDone();
496 if (ShouldExitAuto()) return;
497 PositionClawForShot();
498 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400499 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700500 if (ShouldExitAuto()) return;
501 WaitUntilClawDone();
502 if (ShouldExitAuto()) return;
503 }
504
505 hot_goal_decoder.Update();
506 if (hot_goal_decoder.is_left()) {
507 LOG(INFO, "second shot left\n");
508 second_shot_left = true;
509 } else if (hot_goal_decoder.is_right()) {
510 LOG(INFO, "second shot right\n");
511 second_shot_left = false;
512 } else {
513 LOG(INFO, "second shot defaulting %s\n",
514 second_shot_left_default ? "left" : "right");
515 second_shot_left = second_shot_left_default;
516 }
517 if (auto_version == AutoVersion::kDoubleHot) {
518 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400519 auto drivetrain_action = SetDriveGoal(
520 0, drive_params, second_shot_left ? kTurnAngle : -kTurnAngle);
521 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700522 if (ShouldExitAuto()) return;
523 } else if (auto_version == AutoVersion::kStraight) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800524 this_thread::sleep_for(chrono::milliseconds(400));
Brian Silverman17f503e2015-08-02 18:17:18 -0700525 }
526
527 LOG(INFO, "Shooting at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800528 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700529 // Shoot
530 Shoot();
531 if (ShouldExitAuto()) return;
532
533 // Get ready to zero when we come back up.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800534 this_thread::sleep_for(chrono::milliseconds(50));
Brian Silverman17f503e2015-08-02 18:17:18 -0700535 PositionClawVertically(0.0, 0.0);
536}
537
538} // namespace autonomous
Brian Silvermanb601d892015-12-20 18:24:38 -0500539} // namespace y2014