blob: 96c713228a04cfec6dec1937b67b447cd0ff0c17 [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
6#include "aos/common/util/phased_loop.h"
7#include "aos/common/time.h"
8#include "aos/common/util/trapezoid_profile.h"
9#include "aos/common/logging/logging.h"
10#include "aos/common/logging/queue_logging.h"
Brian Silvermanbfa00602015-05-17 01:41:29 -040011#include "aos/common/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()
Brian Silverman17f503e2015-08-02 18:17:18 -070055 .control_loop_driving(true)
Austin Schuh86f895e2015-11-08 13:40:51 -080056 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -070057 .left_goal(left_initial_position)
58 .left_velocity_goal(0)
59 .right_goal(right_initial_position)
60 .right_velocity_goal(0)
61 .quickturn(false)
62 .Send();
63}
64
65void ResetDrivetrain() {
66 LOG(INFO, "resetting the drivetrain\n");
Comran Morshed5323ecb2015-12-26 20:50:55 +000067 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman17f503e2015-08-02 18:17:18 -070068 .control_loop_driving(false)
Austin Schuh86f895e2015-11-08 13:40:51 -080069 .highgear(true)
Austin Schuh2b1fce02018-03-02 20:05:20 -080070 .wheel(0.0)
Brian Silverman17f503e2015-08-02 18:17:18 -070071 .throttle(0.0)
72 .left_goal(left_initial_position)
73 .left_velocity_goal(0)
74 .right_goal(right_initial_position)
75 .right_velocity_goal(0)
76 .Send();
77}
78
79void WaitUntilDoneOrCanceled(
80 ::std::unique_ptr<aos::common::actions::Action> action) {
81 if (!action) {
82 LOG(ERROR, "No action, not waiting\n");
83 return;
84 }
Austin Schuhf2a50ba2016-12-24 16:16:26 -080085 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(10),
86 ::std::chrono::milliseconds(10) / 2);
Brian Silverman17f503e2015-08-02 18:17:18 -070087 while (true) {
88 // Poll the running bit and auto done bits.
Austin Schuhf2a50ba2016-12-24 16:16:26 -080089 phased_loop.SleepUntilNext();
Brian Silverman17f503e2015-08-02 18:17:18 -070090 if (!action->Running() || ShouldExitAuto()) {
91 return;
92 }
93 }
94}
95
96void StepDrive(double distance, double theta) {
97 double left_goal = (left_initial_position + distance -
Austin Schuh3130b372016-02-17 00:34:51 -080098 theta * control_loops::drivetrain::kRobotRadius);
Brian Silverman17f503e2015-08-02 18:17:18 -070099 double right_goal = (right_initial_position + distance +
Austin Schuh3130b372016-02-17 00:34:51 -0800100 theta * control_loops::drivetrain::kRobotRadius);
Comran Morshed5323ecb2015-12-26 20:50:55 +0000101 ::frc971::control_loops::drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman17f503e2015-08-02 18:17:18 -0700102 .control_loop_driving(true)
Austin Schuh86f895e2015-11-08 13:40:51 -0800103 .highgear(true)
Brian Silverman17f503e2015-08-02 18:17:18 -0700104 .left_goal(left_goal)
105 .right_goal(right_goal)
106 .left_velocity_goal(0.0)
107 .right_velocity_goal(0.0)
108 .Send();
109 left_initial_position = left_goal;
110 right_initial_position = right_goal;
111}
112
Brian Silvermanbfa00602015-05-17 01:41:29 -0400113void PositionClawVertically(double intake_power = 0.0, double centering_power = 0.0) {
114 if (!control_loops::claw_queue.goal.MakeWithBuilder()
115 .bottom_angle(0.0)
116 .separation_angle(0.0)
117 .intake(intake_power)
118 .centering(centering_power)
119 .Send()) {
120 LOG(WARNING, "sending claw goal failed\n");
121 }
122}
123
124void PositionClawBackIntake() {
125 if (!control_loops::claw_queue.goal.MakeWithBuilder()
126 .bottom_angle(-2.273474)
127 .separation_angle(0.0)
128 .intake(12.0)
129 .centering(12.0)
130 .Send()) {
131 LOG(WARNING, "sending claw goal failed\n");
132 }
133}
134
135void PositionClawUpClosed() {
136 // Move the claw to where we're going to shoot from but keep it closed until
137 // it gets there.
138 if (!control_loops::claw_queue.goal.MakeWithBuilder()
139 .bottom_angle(0.86)
140 .separation_angle(0.0)
141 .intake(4.0)
142 .centering(1.0)
143 .Send()) {
144 LOG(WARNING, "sending claw goal failed\n");
145 }
146}
147
148void PositionClawForShot() {
149 if (!control_loops::claw_queue.goal.MakeWithBuilder()
150 .bottom_angle(0.86)
151 .separation_angle(0.10)
152 .intake(4.0)
153 .centering(1.0)
154 .Send()) {
155 LOG(WARNING, "sending claw goal failed\n");
156 }
157}
158
159void SetShotPower(double power) {
160 LOG(INFO, "Setting shot power to %f\n", power);
161 if (!control_loops::shooter_queue.goal.MakeWithBuilder()
162 .shot_power(power)
163 .shot_requested(false)
164 .unload_requested(false)
165 .load_requested(false)
166 .Send()) {
167 LOG(WARNING, "sending shooter goal failed\n");
168 }
169}
170
Brian Silverman17f503e2015-08-02 18:17:18 -0700171void WaitUntilNear(double distance) {
172 while (true) {
173 if (ShouldExitAuto()) return;
Comran Morshed5323ecb2015-12-26 20:50:55 +0000174 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700175 double left_error = ::std::abs(
176 left_initial_position -
Austin Schuh093535c2016-03-05 23:21:00 -0800177 ::frc971::control_loops::drivetrain_queue.status->estimated_left_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700178 double right_error = ::std::abs(
179 right_initial_position -
Austin Schuh093535c2016-03-05 23:21:00 -0800180 ::frc971::control_loops::drivetrain_queue.status->estimated_right_position);
Brian Silverman17f503e2015-08-02 18:17:18 -0700181 const double kPositionThreshold = 0.05 + distance;
182 if (right_error < kPositionThreshold && left_error < kPositionThreshold) {
183 LOG(INFO, "At the goal\n");
184 return;
185 }
186 }
187}
188
Brian Silvermanbfa00602015-05-17 01:41:29 -0400189const ProfileParams kFastDrive = {3.0, 2.5};
190const ProfileParams kSlowDrive = {2.5, 2.5};
191const ProfileParams kFastWithBallDrive = {3.0, 2.0};
192const ProfileParams kSlowWithBallDrive = {2.5, 2.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700193const ProfileParams kFastTurn = {3.0, 10.0};
Brian Silverman17f503e2015-08-02 18:17:18 -0700194
Brian Silvermanb601d892015-12-20 18:24:38 -0500195::std::unique_ptr<::y2014::actors::DrivetrainAction> SetDriveGoal(
Brian Silverman17f503e2015-08-02 18:17:18 -0700196 double distance, const ProfileParams drive_params, double theta = 0,
197 const ProfileParams &turn_params = kFastTurn) {
198 LOG(INFO, "Driving to %f\n", distance);
199
Brian Silvermanb601d892015-12-20 18:24:38 -0500200 ::y2014::actors::DrivetrainActionParams params;
Brian Silverman17f503e2015-08-02 18:17:18 -0700201 params.left_initial_position = left_initial_position;
202 params.right_initial_position = right_initial_position;
203 params.y_offset = distance;
204 params.theta_offset = theta;
205 params.maximum_turn_acceleration = turn_params.acceleration;
206 params.maximum_turn_velocity = turn_params.velocity;
207 params.maximum_velocity = drive_params.velocity;
208 params.maximum_acceleration = drive_params.acceleration;
209 auto drivetrain_action = actors::MakeDrivetrainAction(params);
210 drivetrain_action->Start();
211 left_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800212 distance - theta * control_loops::drivetrain::kRobotRadius;
Brian Silverman17f503e2015-08-02 18:17:18 -0700213 right_initial_position +=
Austin Schuh3130b372016-02-17 00:34:51 -0800214 distance + theta * control_loops::drivetrain::kRobotRadius;
sabinaf5584322017-09-23 18:37:19 -0700215 return drivetrain_action;
Brian Silverman17f503e2015-08-02 18:17:18 -0700216}
217
218void Shoot() {
219 // Shoot.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400220 auto shoot_action = actors::MakeShootAction();
Brian Silverman17f503e2015-08-02 18:17:18 -0700221 shoot_action->Start();
Brian Silvermanbfa00602015-05-17 01:41:29 -0400222 WaitUntilDoneOrCanceled(::std::move(shoot_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700223}
224
225void InitializeEncoders() {
Comran Morshed5323ecb2015-12-26 20:50:55 +0000226 ::frc971::control_loops::drivetrain_queue.status.FetchAnother();
Brian Silverman17f503e2015-08-02 18:17:18 -0700227 left_initial_position =
Austin Schuh093535c2016-03-05 23:21:00 -0800228 ::frc971::control_loops::drivetrain_queue.status->estimated_left_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700229 right_initial_position =
Austin Schuh093535c2016-03-05 23:21:00 -0800230 ::frc971::control_loops::drivetrain_queue.status->estimated_right_position;
Brian Silverman17f503e2015-08-02 18:17:18 -0700231}
232
233void WaitUntilClawDone() {
234 while (true) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800235 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(10),
236 ::std::chrono::milliseconds(10) / 2);
Brian Silverman17f503e2015-08-02 18:17:18 -0700237 // Poll the running bit and auto done bits.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800238 phased_loop.SleepUntilNext();
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400239 control_loops::claw_queue.status.FetchLatest();
240 control_loops::claw_queue.goal.FetchLatest();
Brian Silverman17f503e2015-08-02 18:17:18 -0700241 if (ShouldExitAuto()) {
242 return;
243 }
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400244 if (control_loops::claw_queue.status.get() == nullptr ||
245 control_loops::claw_queue.goal.get() == nullptr) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700246 continue;
247 }
248 bool ans =
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400249 control_loops::claw_queue.status->zeroed &&
250 (::std::abs(control_loops::claw_queue.status->bottom_velocity) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700251 1.0) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400252 (::std::abs(control_loops::claw_queue.status->bottom -
253 control_loops::claw_queue.goal->bottom_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700254 0.10) &&
Brian Silvermanbe5ded62015-05-14 00:23:49 -0400255 (::std::abs(control_loops::claw_queue.status->separation -
256 control_loops::claw_queue.goal->separation_angle) <
Brian Silverman17f503e2015-08-02 18:17:18 -0700257 0.4);
258 if (ans) {
259 return;
260 }
261 if (ShouldExitAuto()) return;
262 }
263}
264
265class HotGoalDecoder {
266 public:
267 HotGoalDecoder() {
268 ResetCounts();
269 }
270
271 void ResetCounts() {
272 hot_goal.FetchLatest();
273 if (hot_goal.get()) {
274 start_counts_ = *hot_goal;
275 LOG_STRUCT(INFO, "counts reset to", start_counts_);
276 start_counts_valid_ = true;
277 } else {
278 LOG(WARNING, "no hot goal message. ignoring\n");
279 start_counts_valid_ = false;
280 }
281 }
282
283 void Update(bool block = false) {
284 if (block) {
285 hot_goal.FetchAnother();
286 } else {
287 hot_goal.FetchLatest();
288 }
289 if (hot_goal.get()) LOG_STRUCT(INFO, "new counts", *hot_goal);
290 }
291
292 bool left_triggered() const {
293 if (!start_counts_valid_ || !hot_goal.get()) return false;
294 return (hot_goal->left_count - start_counts_.left_count) > kThreshold;
295 }
296
297 bool right_triggered() const {
298 if (!start_counts_valid_ || !hot_goal.get()) return false;
299 return (hot_goal->right_count - start_counts_.right_count) > kThreshold;
300 }
301
302 bool is_left() 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 (left_difference > kThreshold) {
309 if (right_difference > kThreshold) {
310 // We've seen a lot of both, so pick the one we've seen the most of.
311 return left_difference > right_difference;
312 } else {
313 // We've seen enough left but not enough right, so go with it.
314 return true;
315 }
316 } else {
317 // We haven't seen enough left, so it's not left.
318 return false;
319 }
320 }
321
322 bool is_right() const {
323 if (!start_counts_valid_ || !hot_goal.get()) return false;
324 const uint64_t left_difference =
325 hot_goal->left_count - start_counts_.left_count;
326 const uint64_t right_difference =
327 hot_goal->right_count - start_counts_.right_count;
328 if (right_difference > kThreshold) {
329 if (left_difference > kThreshold) {
330 // We've seen a lot of both, so pick the one we've seen the most of.
331 return right_difference > left_difference;
332 } else {
333 // We've seen enough right but not enough left, so go with it.
334 return true;
335 }
336 } else {
337 // We haven't seen enough right, so it's not right.
338 return false;
339 }
340 }
341
342 private:
343 static const uint64_t kThreshold = 5;
344
Brian Silvermanb601d892015-12-20 18:24:38 -0500345 ::y2014::HotGoal start_counts_;
Brian Silverman17f503e2015-08-02 18:17:18 -0700346 bool start_counts_valid_;
347};
348
349void HandleAuto() {
350 enum class AutoVersion : uint8_t {
351 kStraight,
352 kDoubleHot,
353 kSingleHot,
354 };
355
356 // The front of the robot is 1.854 meters from the wall
357 static const double kShootDistance = 3.15;
358 static const double kPickupDistance = 0.5;
359 static const double kTurnAngle = 0.3;
360
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800361 monotonic_clock::time_point start_time = monotonic_clock::now();
Brian Silverman17f503e2015-08-02 18:17:18 -0700362 LOG(INFO, "Handling auto mode\n");
363
364 AutoVersion auto_version;
Brian Silvermanb601d892015-12-20 18:24:38 -0500365 ::y2014::sensors::auto_mode.FetchLatest();
366 if (!::y2014::sensors::auto_mode.get()) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700367 LOG(WARNING, "not sure which auto mode to use\n");
368 auto_version = AutoVersion::kStraight;
369 } else {
370 static const double kSelectorMin = 0.2, kSelectorMax = 4.4;
371
372 const double kSelectorStep = (kSelectorMax - kSelectorMin) / 3.0;
Brian Silvermanb601d892015-12-20 18:24:38 -0500373 if (::y2014::sensors::auto_mode->voltage < kSelectorStep + kSelectorMin) {
Brian Silverman17f503e2015-08-02 18:17:18 -0700374 auto_version = AutoVersion::kSingleHot;
Brian Silvermanb601d892015-12-20 18:24:38 -0500375 } else if (::y2014::sensors::auto_mode->voltage <
Brian Silverman17f503e2015-08-02 18:17:18 -0700376 2 * kSelectorStep + kSelectorMin) {
377 auto_version = AutoVersion::kStraight;
378 } else {
379 auto_version = AutoVersion::kDoubleHot;
380 }
381 }
382 LOG(INFO, "running auto %" PRIu8 "\n", static_cast<uint8_t>(auto_version));
383
Brian Silvermanbfa00602015-05-17 01:41:29 -0400384 const ProfileParams &drive_params =
385 (auto_version == AutoVersion::kStraight) ? kFastDrive : kSlowDrive;
386 const ProfileParams &drive_with_ball_params =
387 (auto_version == AutoVersion::kStraight) ? kFastWithBallDrive
388 : kSlowWithBallDrive;
Brian Silverman17f503e2015-08-02 18:17:18 -0700389
390 HotGoalDecoder hot_goal_decoder;
391 // True for left, false for right.
392 bool first_shot_left, second_shot_left_default, second_shot_left;
393
394 ResetDrivetrain();
395
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800396 this_thread::sleep_for(chrono::milliseconds(100));
Brian Silverman17f503e2015-08-02 18:17:18 -0700397 if (ShouldExitAuto()) return;
398 InitializeEncoders();
399
400 // Turn the claw on, keep it straight up until the ball has been grabbed.
401 LOG(INFO, "Claw going up at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800402 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700403 PositionClawVertically(12.0, 4.0);
404 SetShotPower(115.0);
405
406 // Wait for the ball to enter the claw.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800407 this_thread::sleep_for(chrono::milliseconds(250));
Brian Silverman17f503e2015-08-02 18:17:18 -0700408 if (ShouldExitAuto()) return;
409 LOG(INFO, "Readying claw for shot at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800410 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700411
412 {
413 if (ShouldExitAuto()) return;
414 // Drive to the goal.
Brian Silvermanbfa00602015-05-17 01:41:29 -0400415 auto drivetrain_action = SetDriveGoal(-kShootDistance, drive_params);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800416 this_thread::sleep_for(chrono::milliseconds(750));
Brian Silverman17f503e2015-08-02 18:17:18 -0700417 PositionClawForShot();
418 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400419 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700420 if (ShouldExitAuto()) return;
421 }
422
423 hot_goal_decoder.Update();
424 if (hot_goal_decoder.is_left()) {
425 LOG(INFO, "first shot left\n");
426 first_shot_left = true;
427 second_shot_left_default = false;
428 } else if (hot_goal_decoder.is_right()) {
429 LOG(INFO, "first shot right\n");
430 first_shot_left = false;
431 second_shot_left_default = true;
432 } else {
433 LOG(INFO, "first shot defaulting left\n");
434 first_shot_left = true;
435 second_shot_left_default = true;
436 }
437 if (auto_version == AutoVersion::kDoubleHot) {
438 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400439 auto drivetrain_action = SetDriveGoal(
440 0, drive_with_ball_params, first_shot_left ? kTurnAngle : -kTurnAngle);
441 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700442 if (ShouldExitAuto()) return;
443 } else if (auto_version == AutoVersion::kSingleHot) {
444 do {
445 // TODO(brians): Wait for next message with timeout or something.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800446 this_thread::sleep_for(chrono::milliseconds(3));
Brian Silverman17f503e2015-08-02 18:17:18 -0700447 hot_goal_decoder.Update(false);
448 if (ShouldExitAuto()) return;
449 } while (!hot_goal_decoder.left_triggered() &&
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800450 (monotonic_clock::now() - start_time) < chrono::seconds(9));
Brian Silverman17f503e2015-08-02 18:17:18 -0700451 } else if (auto_version == AutoVersion::kStraight) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800452 this_thread::sleep_for(chrono::milliseconds(400));
Brian Silverman17f503e2015-08-02 18:17:18 -0700453 }
454
455 // Shoot.
456 LOG(INFO, "Shooting at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800457 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700458 Shoot();
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800459 this_thread::sleep_for(chrono::milliseconds(50));
Brian Silverman17f503e2015-08-02 18:17:18 -0700460
461 if (auto_version == AutoVersion::kDoubleHot) {
462 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400463 auto drivetrain_action = SetDriveGoal(
464 0, drive_with_ball_params, first_shot_left ? -kTurnAngle : kTurnAngle);
465 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700466 if (ShouldExitAuto()) return;
467 } else if (auto_version == AutoVersion::kSingleHot) {
468 LOG(INFO, "auto done at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800469 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700470 PositionClawVertically(0.0, 0.0);
471 return;
472 }
473
474 {
475 if (ShouldExitAuto()) return;
476 // Intake the new ball.
477 LOG(INFO, "Claw ready for intake at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800478 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700479 PositionClawBackIntake();
480 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400481 SetDriveGoal(kShootDistance + kPickupDistance, drive_params);
Brian Silverman17f503e2015-08-02 18:17:18 -0700482 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400483 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700484 if (ShouldExitAuto()) return;
485 LOG(INFO, "Wait for the claw at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800486 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700487 WaitUntilClawDone();
488 if (ShouldExitAuto()) return;
489 }
490
491 // Drive back.
492 {
493 LOG(INFO, "Driving back at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800494 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700495 auto drivetrain_action =
Brian Silvermanbfa00602015-05-17 01:41:29 -0400496 SetDriveGoal(-(kShootDistance + kPickupDistance), drive_params);
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800497 this_thread::sleep_for(chrono::milliseconds(300));
Brian Silverman17f503e2015-08-02 18:17:18 -0700498 hot_goal_decoder.ResetCounts();
499 if (ShouldExitAuto()) return;
500 PositionClawUpClosed();
501 WaitUntilClawDone();
502 if (ShouldExitAuto()) return;
503 PositionClawForShot();
504 LOG(INFO, "Waiting until drivetrain is finished\n");
Brian Silvermanbfa00602015-05-17 01:41:29 -0400505 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700506 if (ShouldExitAuto()) return;
507 WaitUntilClawDone();
508 if (ShouldExitAuto()) return;
509 }
510
511 hot_goal_decoder.Update();
512 if (hot_goal_decoder.is_left()) {
513 LOG(INFO, "second shot left\n");
514 second_shot_left = true;
515 } else if (hot_goal_decoder.is_right()) {
516 LOG(INFO, "second shot right\n");
517 second_shot_left = false;
518 } else {
519 LOG(INFO, "second shot defaulting %s\n",
520 second_shot_left_default ? "left" : "right");
521 second_shot_left = second_shot_left_default;
522 }
523 if (auto_version == AutoVersion::kDoubleHot) {
524 if (ShouldExitAuto()) return;
Brian Silvermanbfa00602015-05-17 01:41:29 -0400525 auto drivetrain_action = SetDriveGoal(
526 0, drive_params, second_shot_left ? kTurnAngle : -kTurnAngle);
527 WaitUntilDoneOrCanceled(::std::move(drivetrain_action));
Brian Silverman17f503e2015-08-02 18:17:18 -0700528 if (ShouldExitAuto()) return;
529 } else if (auto_version == AutoVersion::kStraight) {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800530 this_thread::sleep_for(chrono::milliseconds(400));
Brian Silverman17f503e2015-08-02 18:17:18 -0700531 }
532
533 LOG(INFO, "Shooting at %f\n",
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800534 DoubleSeconds(monotonic_clock::now() - start_time));
Brian Silverman17f503e2015-08-02 18:17:18 -0700535 // Shoot
536 Shoot();
537 if (ShouldExitAuto()) return;
538
539 // Get ready to zero when we come back up.
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800540 this_thread::sleep_for(chrono::milliseconds(50));
Brian Silverman17f503e2015-08-02 18:17:18 -0700541 PositionClawVertically(0.0, 0.0);
542}
543
544} // namespace autonomous
Brian Silvermanb601d892015-12-20 18:24:38 -0500545} // namespace y2014