blob: 4df613d2f95407b130e3e2db9ce8734188b58867 [file] [log] [blame]
Austin Schuh80ff2e12014-03-08 12:06:19 -08001#include <stdio.h>
2
Austin Schuhf2a50ba2016-12-24 16:16:26 -08003#include <chrono>
Austin Schuh80ff2e12014-03-08 12:06:19 -08004#include <memory>
Austin Schuh47017412013-03-10 11:50:46 -07005
Brian Silverman598800f2013-05-09 17:08:42 -07006#include "aos/common/logging/logging.h"
Brian Silverman6f621542014-04-06 16:00:41 -07007#include "aos/common/logging/queue_logging.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -08008#include "aos/common/time.h"
9#include "aos/common/util/phased_loop.h"
10#include "aos/common/util/trapezoid_profile.h"
Brian Silverman598800f2013-05-09 17:08:42 -070011#include "frc971/autonomous/auto.q.h"
Austin Schuh70810b92016-11-26 14:55:34 -080012#include "frc971/control_loops/drivetrain/drivetrain.q.h"
Brian Silvermanb691f5e2015-08-02 11:37:55 -070013#include "y2015/actors/drivetrain_actor.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -080014#include "y2015/actors/held_to_lift_actor.h"
Brian Silvermanb691f5e2015-08-02 11:37:55 -070015#include "y2015/actors/pickup_actor.h"
16#include "y2015/actors/stack_actor.h"
Austin Schuhf2a50ba2016-12-24 16:16:26 -080017#include "y2015/autonomous/auto.q.h"
18#include "y2015/constants.h"
19#include "y2015/control_loops/claw/claw.q.h"
20#include "y2015/control_loops/fridge/fridge.q.h"
Austin Schuh47017412013-03-10 11:50:46 -070021
Brian Silverman93936f72015-03-19 23:38:30 -070022using ::frc971::control_loops::drivetrain_queue;
Austin Schuh88af0852016-12-04 20:31:32 -080023using ::y2015::control_loops::claw_queue;
24using ::y2015::control_loops::fridge::fridge_queue;
Austin Schuh47017412013-03-10 11:50:46 -070025
Austin Schuhf2a50ba2016-12-24 16:16:26 -080026namespace chrono = ::std::chrono;
27namespace this_thread = ::std::this_thread;
28using ::aos::monotonic_clock;
29
Austin Schuh88af0852016-12-04 20:31:32 -080030namespace y2015 {
Austin Schuh47017412013-03-10 11:50:46 -070031namespace autonomous {
32
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070033constexpr double kClawAutoVelocity = 3.00;
34constexpr double kClawAutoAcceleration = 6.0;
35constexpr double kAngleEpsilon = 0.10;
Austin Schuh1f3764e2015-04-18 23:00:09 -070036const double kClawTotePackAngle = 0.90;
37const double kArmRaiseLowerClearance = -0.08;
38const double kClawStackClearance = 0.55;
39const double kStackUpHeight = 0.60;
40const double kStackUpArm = 0.0;
41
42struct ProfileParams {
43 double velocity;
44 double acceleration;
45};
Ben Fredrickson0a6ad252015-03-15 18:51:42 -070046
Austin Schuh80ff2e12014-03-08 12:06:19 -080047namespace time = ::aos::time;
48
Brian Silverman3b89ed82013-03-22 18:59:16 -070049static double left_initial_position, right_initial_position;
50
Austin Schuh6be011a2013-03-19 10:07:02 +000051bool ShouldExitAuto() {
52 ::frc971::autonomous::autonomous.FetchLatest();
53 bool ans = !::frc971::autonomous::autonomous->run_auto;
54 if (ans) {
55 LOG(INFO, "Time to exit auto mode\n");
56 }
57 return ans;
58}
59
Austin Schuh6be011a2013-03-19 10:07:02 +000060void StopDrivetrain() {
61 LOG(INFO, "Stopping the drivetrain\n");
Austin Schuh88af0852016-12-04 20:31:32 -080062 drivetrain_queue.goal.MakeWithBuilder()
Brian Silverman3b89ed82013-03-22 18:59:16 -070063 .control_loop_driving(true)
Brian Silvermance86bac2013-03-31 19:07:24 -070064 .left_goal(left_initial_position)
65 .left_velocity_goal(0)
66 .right_goal(right_initial_position)
67 .right_velocity_goal(0)
68 .quickturn(false)
69 .Send();
70}
71
72void ResetDrivetrain() {
73 LOG(INFO, "resetting the drivetrain\n");
Austin Schuh88af0852016-12-04 20:31:32 -080074 drivetrain_queue.goal.MakeWithBuilder()
Brian Silvermance86bac2013-03-31 19:07:24 -070075 .control_loop_driving(false)
Brian Silverman93335ae2015-01-26 20:43:39 -050076 //.highgear(false)
Austin Schuh6be011a2013-03-19 10:07:02 +000077 .steering(0.0)
78 .throttle(0.0)
Brian Silverman38ea9bf2014-04-19 22:57:54 -070079 .left_goal(left_initial_position)
80 .left_velocity_goal(0)
81 .right_goal(right_initial_position)
82 .right_velocity_goal(0)
Austin Schuh6be011a2013-03-19 10:07:02 +000083 .Send();
84}
85
Austin Schuh1f3764e2015-04-18 23:00:09 -070086void WaitUntilDoneOrCanceled(
87 ::std::unique_ptr<aos::common::actions::Action> action) {
88 if (!action) {
89 LOG(ERROR, "No action, not waiting\n");
90 return;
Brian Silverman3b89ed82013-03-22 18:59:16 -070091 }
Austin Schuhf2a50ba2016-12-24 16:16:26 -080092 ::aos::time::PhasedLoop phased_loop(chrono::milliseconds(5),
93 chrono::microseconds(2500));
Austin Schuh80ff2e12014-03-08 12:06:19 -080094 while (true) {
95 // Poll the running bit and auto done bits.
Austin Schuhf2a50ba2016-12-24 16:16:26 -080096 phased_loop.SleepUntilNext();
Austin Schuh80ff2e12014-03-08 12:06:19 -080097 if (!action->Running() || ShouldExitAuto()) {
98 return;
99 }
100 }
101}
102
Austin Schuh1f3764e2015-04-18 23:00:09 -0700103void StepDrive(double distance, double theta) {
104 double left_goal = (left_initial_position + distance -
105 theta * constants::GetValues().turn_width / 2.0);
106 double right_goal = (right_initial_position + distance +
107 theta * constants::GetValues().turn_width / 2.0);
Austin Schuh88af0852016-12-04 20:31:32 -0800108 drivetrain_queue.goal.MakeWithBuilder()
Austin Schuh1f3764e2015-04-18 23:00:09 -0700109 .control_loop_driving(true)
110 .left_goal(left_goal)
111 .right_goal(right_goal)
112 .left_velocity_goal(0.0)
113 .right_velocity_goal(0.0)
114 .Send();
115 left_initial_position = left_goal;
116 right_initial_position = right_goal;
117}
118
119void WaitUntilNear(double distance) {
120 while (true) {
121 if (ShouldExitAuto()) return;
Austin Schuh88af0852016-12-04 20:31:32 -0800122 drivetrain_queue.status.FetchAnother();
123 double left_error =
124 ::std::abs(left_initial_position -
125 drivetrain_queue.status->estimated_left_position);
126 double right_error =
127 ::std::abs(right_initial_position -
128 drivetrain_queue.status->estimated_right_position);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700129 const double kPositionThreshold = 0.05 + distance;
130 if (right_error < kPositionThreshold && left_error < kPositionThreshold) {
131 LOG(INFO, "At the goal\n");
132 return;
133 }
134 }
135}
136
137const ProfileParams kFastDrive = {2.0, 3.5};
138const ProfileParams kFastKnockDrive = {2.0, 3.0};
Austin Schuh9c414f42015-04-19 20:01:56 -0700139const ProfileParams kStackingSecondDrive = {2.0, 1.5};
Austin Schuh1f3764e2015-04-18 23:00:09 -0700140const ProfileParams kFastTurn = {3.0, 10.0};
Austin Schuh9c414f42015-04-19 20:01:56 -0700141const ProfileParams kStackingFirstTurn = {1.0, 1.0};
142const ProfileParams kStackingSecondTurn = {2.0, 6.0};
Austin Schuh1f3764e2015-04-18 23:00:09 -0700143const ProfileParams kComboTurn = {1.2, 8.0};
144const ProfileParams kRaceTurn = {4.0, 10.0};
145const ProfileParams kRaceDrive = {2.0, 2.0};
146const ProfileParams kRaceBackupDrive = {2.0, 5.0};
147
Austin Schuh88af0852016-12-04 20:31:32 -0800148::std::unique_ptr<::y2015::actors::DrivetrainAction> SetDriveGoal(
149 double distance, const ProfileParams drive_params, double theta = 0,
150 const ProfileParams &turn_params = kFastTurn) {
Austin Schuha4faacc2014-03-09 00:50:50 -0800151 LOG(INFO, "Driving to %f\n", distance);
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800152
Austin Schuh88af0852016-12-04 20:31:32 -0800153 ::y2015::actors::DrivetrainActionParams params;
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800154 params.left_initial_position = left_initial_position;
155 params.right_initial_position = right_initial_position;
156 params.y_offset = distance;
157 params.theta_offset = theta;
Austin Schuh1f3764e2015-04-18 23:00:09 -0700158 params.maximum_turn_acceleration = turn_params.acceleration;
159 params.maximum_turn_velocity = turn_params.velocity;
160 params.maximum_velocity = drive_params.velocity;
161 params.maximum_acceleration = drive_params.acceleration;
Ben Fredrickson9fb2ab12015-02-16 16:42:08 -0800162 auto drivetrain_action = actors::MakeDrivetrainAction(params);
163
Austin Schuh80ff2e12014-03-08 12:06:19 -0800164 drivetrain_action->Start();
Brian Silvermanad9e0002014-04-13 14:55:57 -0700165 left_initial_position +=
166 distance - theta * constants::GetValues().turn_width / 2.0;
167 right_initial_position +=
Daniel Pettib0733be2014-11-14 22:44:03 -0800168 distance + theta * constants::GetValues().turn_width / 2.0;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800169 return ::std::move(drivetrain_action);
170}
171
Austin Schuh1f3764e2015-04-18 23:00:09 -0700172const ProfileParams kFridgeYProfile{1.0, 4.0};
173const ProfileParams kFridgeXProfile{1.0, 2.0};
174const ProfileParams kFridgeFastXProfile{1.2, 5.0};
175
176static double fridge_goal_x = 0.0;
177static double fridge_goal_y = 0.0;
178
179void MoveFridge(double x, double y, bool grabbers, const ProfileParams x_params,
180 const ProfileParams y_params) {
181 auto new_fridge_goal = fridge_queue.goal.MakeMessage();
182 new_fridge_goal->profiling_type = 1;
183
184 new_fridge_goal->max_y_velocity = y_params.velocity;
185 new_fridge_goal->max_y_acceleration = y_params.acceleration;
186 new_fridge_goal->y = y;
187 fridge_goal_y = y;
188 new_fridge_goal->y_velocity = 0.0;
189
190 new_fridge_goal->max_x_velocity = x_params.velocity;
191 new_fridge_goal->max_x_acceleration = x_params.acceleration;
192 new_fridge_goal->x = x;
193 fridge_goal_x = x;
194 new_fridge_goal->x_velocity = 0.0;
195
196 new_fridge_goal->grabbers.top_front = grabbers;
197 new_fridge_goal->grabbers.top_back = grabbers;
198 new_fridge_goal->grabbers.bottom_front = grabbers;
199 new_fridge_goal->grabbers.bottom_back = grabbers;
200
201 if (!new_fridge_goal.Send()) {
202 LOG(ERROR, "Sending fridge goal failed.\n");
203 return;
Brian Silverman3b89ed82013-03-22 18:59:16 -0700204 }
Austin Schuh1f3764e2015-04-18 23:00:09 -0700205}
206
207void WaitForFridge() {
208 while (true) {
209 if (ShouldExitAuto()) return;
Austin Schuh88af0852016-12-04 20:31:32 -0800210 fridge_queue.status.FetchAnother();
Austin Schuh1f3764e2015-04-18 23:00:09 -0700211
212 constexpr double kProfileError = 1e-5;
213 constexpr double kXEpsilon = 0.03, kYEpsilon = 0.03;
214
Austin Schuh88af0852016-12-04 20:31:32 -0800215 if (fridge_queue.status->state != 4) {
Austin Schuh1f3764e2015-04-18 23:00:09 -0700216 LOG(ERROR, "Fridge no longer running, aborting action\n");
217 return;
218 }
219
Austin Schuh88af0852016-12-04 20:31:32 -0800220 if (::std::abs(fridge_queue.status->goal_x - fridge_goal_x) <
Austin Schuh1f3764e2015-04-18 23:00:09 -0700221 kProfileError &&
Austin Schuh88af0852016-12-04 20:31:32 -0800222 ::std::abs(fridge_queue.status->goal_y - fridge_goal_y) <
Austin Schuh1f3764e2015-04-18 23:00:09 -0700223 kProfileError &&
Austin Schuh88af0852016-12-04 20:31:32 -0800224 ::std::abs(fridge_queue.status->goal_x_velocity) < kProfileError &&
225 ::std::abs(fridge_queue.status->goal_y_velocity) < kProfileError) {
Austin Schuh1f3764e2015-04-18 23:00:09 -0700226 LOG(INFO, "Profile done.\n");
Austin Schuh88af0852016-12-04 20:31:32 -0800227 if (::std::abs(fridge_queue.status->x - fridge_goal_x) <
Austin Schuh1f3764e2015-04-18 23:00:09 -0700228 kXEpsilon &&
Austin Schuh88af0852016-12-04 20:31:32 -0800229 ::std::abs(fridge_queue.status->y - fridge_goal_y) <
Austin Schuh1f3764e2015-04-18 23:00:09 -0700230 kYEpsilon) {
231 LOG(INFO, "Near goal, done.\n");
232 return;
233 }
234 }
235 }
236}
237
238void InitializeEncoders() {
Austin Schuh88af0852016-12-04 20:31:32 -0800239 drivetrain_queue.status.FetchAnother();
240 left_initial_position = drivetrain_queue.status->estimated_left_position;
241 right_initial_position = drivetrain_queue.status->estimated_right_position;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800242}
243
Austin Schuh1f3764e2015-04-18 23:00:09 -0700244void WaitForClawZero() {
245 LOG(INFO, "Waiting for claw to zero.\n");
246 while (true) {
247 control_loops::claw_queue.status.FetchAnother();
248 LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);
249 if (control_loops::claw_queue.status->zeroed) {
250 LOG(INFO, "Claw zeroed\n");
251 return;
252 }
253
254 if (ShouldExitAuto()) return;
255 }
256}
257
258void WaitForFridgeZero() {
259 LOG(INFO, "Waiting for claw to zero.\n");
260 while (true) {
Austin Schuh88af0852016-12-04 20:31:32 -0800261 fridge_queue.status.FetchAnother();
262 LOG_STRUCT(DEBUG, "Got fridge status", *fridge_queue.status);
263 if (fridge_queue.status->zeroed) {
Austin Schuh1f3764e2015-04-18 23:00:09 -0700264 LOG(INFO, "Fridge zeroed\n");
265 return;
266 }
267
268 if (ShouldExitAuto()) return;
269 }
270}
271
272constexpr ProfileParams kDefaultClawParams = {kClawAutoVelocity,
273 kClawAutoAcceleration};
274
275// Move the claw in a very small number of cycles.
276constexpr ProfileParams kInstantaneousClaw = {100.0, 100.0};
277constexpr ProfileParams kFastClaw = {8.0, 20.0};
278
279void SetClawStateNoWait(double angle, double intake_voltage,
280 double rollers_closed,
281 const ProfileParams &claw_params = kDefaultClawParams) {
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700282 auto message = control_loops::claw_queue.goal.MakeMessage();
283 message->angle = angle;
Austin Schuh1f3764e2015-04-18 23:00:09 -0700284 message->max_velocity = claw_params.velocity;
285 message->max_acceleration = claw_params.acceleration;
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700286 message->angular_velocity = 0.0;
287 message->intake = intake_voltage;
288 message->rollers_closed = rollers_closed;
289
290 LOG_STRUCT(DEBUG, "Sending claw goal", *message);
291 message.Send();
Austin Schuh1f3764e2015-04-18 23:00:09 -0700292}
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700293
Austin Schuh1f3764e2015-04-18 23:00:09 -0700294void SetClawState(double angle, double intake_voltage, double rollers_closed,
295 const ProfileParams &claw_params = kDefaultClawParams) {
296 SetClawStateNoWait(angle, intake_voltage, rollers_closed, claw_params);
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700297 while (true) {
298 control_loops::claw_queue.status.FetchAnother();
299 const double current_angle = control_loops::claw_queue.status->angle;
300 LOG_STRUCT(DEBUG, "Got claw status", *control_loops::claw_queue.status);
301
302 // I believe all we can care about here is the angle. Other values will
303 // either be set or not, but there is nothing we can do about it. If it
304 // never gets there we do not care, auto is over for us.
305 if (::std::abs(current_angle - angle) < kAngleEpsilon) {
306 break;
307 }
Austin Schuh1f3764e2015-04-18 23:00:09 -0700308 if (ShouldExitAuto()) return;
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700309 }
310}
311
Austin Schuhbb227f82015-09-06 15:27:52 -0700312void TripleCanAuto() {
Austin Schuh88af0852016-12-04 20:31:32 -0800313 ::std::unique_ptr<::y2015::actors::DrivetrainAction> drive;
314 ::std::unique_ptr<::y2015::actors::PickupAction> pickup;
315 ::std::unique_ptr<::y2015::actors::StackAction> stack;
316 ::std::unique_ptr<::y2015::actors::HeldToLiftAction> lift;
Austin Schuh80ff2e12014-03-08 12:06:19 -0800317
Austin Schuh9c414f42015-04-19 20:01:56 -0700318 actors::PickupParams pickup_params;
319 // Lift to here initially.
320 pickup_params.pickup_angle = 0.9;
321 // Start sucking here
322 pickup_params.suck_angle = 0.8;
323 // Go back down to here to finish sucking.
324 pickup_params.suck_angle_finish = 0.4;
325 // Pack the box back in here.
326 pickup_params.pickup_finish_angle = kClawTotePackAngle;
327 pickup_params.intake_time = 0.70;
328 pickup_params.intake_voltage = 7.0;
329
Austin Schuh80ff2e12014-03-08 12:06:19 -0800330 if (ShouldExitAuto()) return;
331 InitializeEncoders();
Austin Schuh1f3764e2015-04-18 23:00:09 -0700332 ResetDrivetrain();
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700333
Austin Schuh1f3764e2015-04-18 23:00:09 -0700334 WaitForClawZero();
335 WaitForFridgeZero();
Brian Silverman93936f72015-03-19 23:38:30 -0700336
Austin Schuh1f3764e2015-04-18 23:00:09 -0700337 // Initialize the fridge.
338 MoveFridge(0.0, 0.3, true, kFridgeXProfile, kFridgeYProfile);
Brian Silverman93936f72015-03-19 23:38:30 -0700339
Austin Schuh1f3764e2015-04-18 23:00:09 -0700340 LOG(INFO, "Lowering claw into position.\n");
341 SetClawState(0.0, 2.0, false, kInstantaneousClaw);
Austin Schuh9c414f42015-04-19 20:01:56 -0700342
Austin Schuh1f3764e2015-04-18 23:00:09 -0700343 LOG(INFO, "Sucking in tote.\n");
Austin Schuh9c414f42015-04-19 20:01:56 -0700344 SetClawState(0.0, 6.0, true, kInstantaneousClaw);
Brian Silverman93936f72015-03-19 23:38:30 -0700345
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800346 this_thread::sleep_for(chrono::milliseconds(700));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700347 LOG(INFO, "Done sucking in tote\n");
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700348
Austin Schuh1f3764e2015-04-18 23:00:09 -0700349 // Now pick it up
Austin Schuh9c414f42015-04-19 20:01:56 -0700350 pickup = actors::MakePickupAction(pickup_params);
351 pickup->Start();
Austin Schuh1f3764e2015-04-18 23:00:09 -0700352
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800353 this_thread::sleep_for(chrono::milliseconds(900));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700354 // Start turning.
355 LOG(INFO, "Turning in place\n");
Austin Schuh9c414f42015-04-19 20:01:56 -0700356 drive = SetDriveGoal(0.0, kFastDrive, -0.23, kStackingFirstTurn);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700357
358 WaitUntilDoneOrCanceled(::std::move(drive));
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700359 if (ShouldExitAuto()) return;
360
Austin Schuh1f3764e2015-04-18 23:00:09 -0700361 LOG(INFO, "Now driving next to the can\n");
362 drive = SetDriveGoal(0.60, kFastDrive);
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700363
Austin Schuh1f3764e2015-04-18 23:00:09 -0700364 WaitUntilDoneOrCanceled(::std::move(pickup));
365 if (ShouldExitAuto()) return;
366
367 // Now grab it in the fridge.
368 {
369 actors::StackParams params;
370
371 params.claw_out_angle = kClawTotePackAngle;
372 params.bottom = 0.020;
373 params.only_place = false;
374 params.arm_clearance = kArmRaiseLowerClearance;
375 params.over_box_before_place_height = 0.39;
376
377 stack = actors::MakeStackAction(params);
378 stack->Start();
379 }
380 WaitUntilDoneOrCanceled(::std::move(stack));
381 if (ShouldExitAuto()) return;
382
383 // Lower the claw to knock the tote.
384 LOG(INFO, "Lowering the claw to knock the tote\n");
385 SetClawStateNoWait(0.0, 0.0, true, kFastClaw);
386
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800387 this_thread::sleep_for(chrono::milliseconds(100));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700388 if (ShouldExitAuto()) return;
389
390 WaitUntilDoneOrCanceled(::std::move(drive));
391 if (ShouldExitAuto()) return;
392
393 LOG(INFO, "Knocking the can over\n");
Austin Schuh9c414f42015-04-19 20:01:56 -0700394 drive = SetDriveGoal(0.40, kFastKnockDrive, 1.05, kComboTurn);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700395 WaitUntilDoneOrCanceled(::std::move(drive));
396 if (ShouldExitAuto()) return;
397 {
398 actors::HeldToLiftParams params;
399 params.arm_clearance = kArmRaiseLowerClearance;
400 params.clamp_pause_time = 0.1;
401 params.before_lift_settle_time = 0.1;
402 params.bottom_height = 0.020;
403 params.claw_out_angle = kClawStackClearance;
404 params.lift_params.lift_height = kStackUpHeight;
405 params.lift_params.lift_arm = kStackUpArm;
Austin Schuh3cba3792015-04-19 20:01:22 -0700406 params.lift_params.second_lift = false;
Austin Schuh1f3764e2015-04-18 23:00:09 -0700407
408 lift = actors::MakeHeldToLiftAction(params);
409 lift->Start();
410 }
411
412 LOG(INFO, "Turning back to aim\n");
413 drive = SetDriveGoal(0.0, kFastDrive, -0.70);
414 WaitUntilDoneOrCanceled(::std::move(drive));
415 if (ShouldExitAuto()) return;
416
417 SetClawStateNoWait(0.0, 4.0, false, kFastClaw);
418 LOG(INFO, "Now driving the second tote\n");
419 drive = SetDriveGoal(1.05, kFastDrive);
420
421 // Wait until we are almost at the tote, and then start intaking.
Austin Schuh9c414f42015-04-19 20:01:56 -0700422 WaitUntilNear(0.35);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700423
424 SetClawState(0.0, 6.0, true, kFastClaw);
425 WaitUntilDoneOrCanceled(::std::move(drive));
426 if (ShouldExitAuto()) return;
427
428 if (ShouldExitAuto()) return;
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800429 this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuh9c414f42015-04-19 20:01:56 -0700430 if (ShouldExitAuto()) return;
431
432 SetClawStateNoWait(0.0, 4.0, true, kFastClaw);
433 if (ShouldExitAuto()) return;
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800434 this_thread::sleep_for(chrono::milliseconds(100));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700435
436 WaitUntilDoneOrCanceled(::std::move(lift));
437 if (ShouldExitAuto()) return;
438
439 LOG(INFO, "Done sucking in tote\n");
440 SetClawState(0.0, 0.0, true, kFastClaw);
441 if (ShouldExitAuto()) return;
442
443 // Now pick it up
Austin Schuh9c414f42015-04-19 20:01:56 -0700444 pickup = actors::MakePickupAction(pickup_params);
445 pickup->Start();
Austin Schuh1f3764e2015-04-18 23:00:09 -0700446
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800447 this_thread::sleep_for(chrono::seconds(1));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700448 if (ShouldExitAuto()) return;
449
450 // Start turning.
451 LOG(INFO, "Turning in place\n");
Austin Schuh9c414f42015-04-19 20:01:56 -0700452 drive = SetDriveGoal(0.0, kStackingSecondDrive, -0.40, kStackingSecondTurn);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700453
454 WaitUntilDoneOrCanceled(::std::move(pickup));
455 if (ShouldExitAuto()) return;
456
457 // Now grab it in the fridge.
458 {
459 actors::StackParams params;
460
461 params.claw_out_angle = kClawTotePackAngle;
462 params.bottom = 0.020;
463 params.only_place = false;
464 params.arm_clearance = kArmRaiseLowerClearance;
465 params.over_box_before_place_height = 0.39;
466
467 stack = actors::MakeStackAction(params);
468 stack->Start();
469 }
470
Austin Schuh1f3764e2015-04-18 23:00:09 -0700471 WaitUntilDoneOrCanceled(::std::move(drive));
472 if (ShouldExitAuto()) return;
Austin Schuh9c414f42015-04-19 20:01:56 -0700473 LOG(INFO, "Driving next to the can.\n");
474 drive = SetDriveGoal(0.65, kStackingSecondDrive);
475
476 WaitUntilDoneOrCanceled(::std::move(stack));
477 if (ShouldExitAuto()) return;
Austin Schuh1f3764e2015-04-18 23:00:09 -0700478
479 // Lower the claw to knock the tote.
480 LOG(INFO, "Lowering the claw to knock the tote\n");
481 SetClawStateNoWait(0.0, 0.0, true, kFastClaw);
482
483 // Lift the fridge.
484 MoveFridge(0.0, 0.3, true, kFridgeXProfile, kFridgeYProfile);
485
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800486 this_thread::sleep_for(chrono::milliseconds(100));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700487 if (ShouldExitAuto()) return;
488
Austin Schuh9c414f42015-04-19 20:01:56 -0700489 WaitUntilDoneOrCanceled(::std::move(drive));
490 if (ShouldExitAuto()) return;
491
Austin Schuh1f3764e2015-04-18 23:00:09 -0700492 LOG(INFO, "Knocking the can over\n");
Austin Schuh9c414f42015-04-19 20:01:56 -0700493 drive = SetDriveGoal(0.40, kFastKnockDrive, 1.05, kComboTurn);
Austin Schuh1f3764e2015-04-18 23:00:09 -0700494 WaitUntilDoneOrCanceled(::std::move(drive));
495 if (ShouldExitAuto()) return;
496
497 LOG(INFO, "Turning back to aim\n");
498 drive = SetDriveGoal(0.0, kFastDrive, -0.60);
499 WaitUntilDoneOrCanceled(::std::move(drive));
500 if (ShouldExitAuto()) return;
501
502
503 SetClawStateNoWait(0.0, 4.0, false, kFastClaw);
504 LOG(INFO, "Now driving to the last tote\n");
505 drive = SetDriveGoal(1.05, kFastDrive);
506 WaitUntilNear(0.05);
507
508 SetClawState(0.0, 7.0, true, kFastClaw);
509 if (ShouldExitAuto()) return;
510
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800511 this_thread::sleep_for(chrono::milliseconds(200));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700512 if (ShouldExitAuto()) return;
513
514 WaitUntilDoneOrCanceled(::std::move(drive));
515 if (ShouldExitAuto()) return;
516 SetClawState(0.0, 6.0, true, kFastClaw);
517
518 LOG(INFO, "Racing over\n");
519 //StepDrive(2.5, -1.4);
520 drive = SetDriveGoal(2.5, kRaceDrive, -1.4, kRaceTurn);
521
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800522 this_thread::sleep_for(chrono::milliseconds(500));
Austin Schuh1f3764e2015-04-18 23:00:09 -0700523
524 LOG(INFO, "Moving totes out\n");
525 MoveFridge(0.6, 0.32, true, kFridgeXProfile, kFridgeYProfile);
526
527 WaitForFridge();
528 if (ShouldExitAuto()) return;
529
530 LOG(INFO, "Lowering totes\n");
531 MoveFridge(0.6, 0.15, false, kFridgeXProfile, kFridgeYProfile);
532
533 WaitForFridge();
534 if (ShouldExitAuto()) return;
535
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800536 this_thread::sleep_for(chrono::milliseconds(100));
Brian Silverman5bfda6c2015-03-21 23:40:13 -0700537
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700538 if (ShouldExitAuto()) return;
539
Austin Schuh1f3764e2015-04-18 23:00:09 -0700540 LOG(INFO, "Retracting\n");
541 MoveFridge(0.0, 0.10, false, kFridgeFastXProfile, kFridgeYProfile);
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700542
Austin Schuh1f3764e2015-04-18 23:00:09 -0700543 SetClawState(0.0, 0.0, false, kFastClaw);
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700544
Austin Schuh1f3764e2015-04-18 23:00:09 -0700545 if (ShouldExitAuto()) return;
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700546
Austin Schuh1f3764e2015-04-18 23:00:09 -0700547 WaitUntilDoneOrCanceled(::std::move(drive));
548 if (ShouldExitAuto()) return;
Ben Fredrickson0a6ad252015-03-15 18:51:42 -0700549
Austin Schuh1f3764e2015-04-18 23:00:09 -0700550 LOG(INFO, "Backing away to let the stack ago\n");
551 drive = SetDriveGoal(-0.1, kRaceBackupDrive);
552 WaitUntilDoneOrCanceled(::std::move(drive));
Austin Schuh9c414f42015-04-19 20:01:56 -0700553
554 WaitForFridge();
555 if (ShouldExitAuto()) return;
Austin Schuh47017412013-03-10 11:50:46 -0700556}
557
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800558void GrabberForTime(double voltage, monotonic_clock::duration wait_time) {
559 monotonic_clock::time_point now = monotonic_clock::now();
560 monotonic_clock::time_point end_time = now + wait_time;
561 LOG(INFO, "Starting to grab at %f for %f seconds\n", voltage,
562 chrono::duration_cast<chrono::duration<double>>(wait_time).count());
563 ::aos::time::PhasedLoop phased_loop(chrono::milliseconds(5),
564 chrono::microseconds(2500));
Austin Schuhbb227f82015-09-06 15:27:52 -0700565 while (true) {
566 autonomous::can_control.MakeWithBuilder().can_voltage(voltage).Send();
567 // Poll the running bit and auto done bits.
568 if (ShouldExitAuto()) {
569 return;
570 }
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800571 if (monotonic_clock::now() > end_time) {
Austin Schuhbb227f82015-09-06 15:27:52 -0700572 LOG(INFO, "Done grabbing\n");
573 return;
574 }
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800575 phased_loop.SleepUntilNext();
Austin Schuhbb227f82015-09-06 15:27:52 -0700576 }
577}
578
579void CanGrabberAuto() {
580 ResetDrivetrain();
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800581 GrabberForTime(12.0, chrono::milliseconds(180));
Austin Schuhbb227f82015-09-06 15:27:52 -0700582 if (ShouldExitAuto()) return;
583
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800584 //GrabberForTime(4.0, chrono::milliseconds(100));
Austin Schuhbb227f82015-09-06 15:27:52 -0700585 if (ShouldExitAuto()) return;
586 InitializeEncoders();
587 ResetDrivetrain();
588 if (ShouldExitAuto()) return;
Austin Schuh88af0852016-12-04 20:31:32 -0800589 drivetrain_queue.goal.MakeWithBuilder()
Austin Schuhbb227f82015-09-06 15:27:52 -0700590 .control_loop_driving(true)
591 //.highgear(false)
592 .steering(0.0)
593 .throttle(0.0)
594 .left_goal(left_initial_position + 1.5)
595 .left_velocity_goal(0)
596 .right_goal(right_initial_position + 1.5)
597 .right_velocity_goal(0)
598 .Send();
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800599 GrabberForTime(12.0, chrono::milliseconds(20));
Austin Schuhbb227f82015-09-06 15:27:52 -0700600
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800601 GrabberForTime(4.0, chrono::seconds(14));
Austin Schuhbb227f82015-09-06 15:27:52 -0700602 if (ShouldExitAuto()) return;
603}
604
605void HandleAuto() {
Austin Schuhf2a50ba2016-12-24 16:16:26 -0800606 monotonic_clock::time_point start_time = monotonic_clock::now();
607 LOG(INFO, "Starting auto mode at %f\n",
608 chrono::duration_cast<chrono::duration<double>>(
609 start_time.time_since_epoch()).count());
Austin Schuhbb227f82015-09-06 15:27:52 -0700610 //TripleCanAuto();
611 CanGrabberAuto();
612}
613
Austin Schuh47017412013-03-10 11:50:46 -0700614} // namespace autonomous
Austin Schuh88af0852016-12-04 20:31:32 -0800615} // namespace y2015