blob: a565764dd3505e050c1480a14fd57b850e0ee7df [file] [log] [blame]
Austin Schuh13379ba2019-03-12 21:06:46 -07001#include "y2019/actors/autonomous_actor.h"
2
3#include <inttypes.h>
4
5#include <chrono>
6#include <cmath>
7
8#include "aos/logging/logging.h"
9#include "aos/util/phased_loop.h"
10
11#include "frc971/control_loops/drivetrain/drivetrain.q.h"
12#include "frc971/control_loops/drivetrain/localizer.q.h"
Austin Schuh6bcc2302019-03-23 22:28:06 -070013#include "y2019/actors/auto_splines.h"
Austin Schuh13379ba2019-03-12 21:06:46 -070014#include "y2019/control_loops/drivetrain/drivetrain_base.h"
15
16namespace y2019 {
17namespace actors {
18using ::frc971::control_loops::drivetrain_queue;
19using ::frc971::control_loops::drivetrain::localizer_control;
20using ::aos::monotonic_clock;
21namespace chrono = ::std::chrono;
22
23namespace {
24
25double DoubleSeconds(monotonic_clock::duration duration) {
26 return ::std::chrono::duration_cast<::std::chrono::duration<double>>(duration)
27 .count();
28}
29
30} // namespace
31
32AutonomousActor::AutonomousActor(
33 ::frc971::autonomous::AutonomousActionQueueGroup *s)
34 : frc971::autonomous::BaseAutonomousActor(
35 s, control_loops::drivetrain::GetDrivetrainConfig()) {}
36
Austin Schuhb5b79a52019-05-08 20:32:07 -070037bool AutonomousActor::WaitForDriveXGreater(double x) {
38 LOG(INFO, "Waiting until x > %f\n", x);
39 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
40 ::std::chrono::milliseconds(5) / 2);
41
42 while (true) {
43 if (ShouldCancel()) {
44 return false;
45 }
46 phased_loop.SleepUntilNext();
47 drivetrain_queue.status.FetchLatest();
48 if (drivetrain_queue.status->x > x) {
49 LOG(INFO, "X at %f\n", drivetrain_queue.status->x);
50 return true;
51 }
52 }
53}
54
55bool AutonomousActor::WaitForDriveYCloseToZero(double y) {
56 LOG(INFO, "Waiting until |y| < %f\n", y);
57 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
58 ::std::chrono::milliseconds(5) / 2);
59
60 while (true) {
61 if (ShouldCancel()) {
62 return false;
63 }
64 phased_loop.SleepUntilNext();
65 drivetrain_queue.status.FetchLatest();
66 if (::std::abs(drivetrain_queue.status->y) < y) {
67 LOG(INFO, "Y at %f\n", drivetrain_queue.status->y);
68 return true;
69 }
70 }
71}
72
Austin Schuha9644062019-03-28 14:31:52 -070073void AutonomousActor::Reset(bool is_left) {
74 const double turn_scalar = is_left ? 1.0 : -1.0;
Austin Schuh13379ba2019-03-12 21:06:46 -070075 elevator_goal_ = 0.01;
76 wrist_goal_ = -M_PI / 2.0;
77 intake_goal_ = -1.2;
78
79 suction_on_ = false;
80 suction_gamepiece_ = 1;
81
82 elevator_max_velocity_ = 0.0;
83 elevator_max_acceleration_ = 0.0;
84 wrist_max_velocity_ = 0.0;
85 wrist_max_acceleration_ = 0.0;
86
87 InitializeEncoders();
88 SendSuperstructureGoal();
89
90 {
91 auto localizer_resetter = localizer_control.MakeMessage();
92 // Start on the left l2.
93 localizer_resetter->x = 1.0;
Austin Schuhb5b79a52019-05-08 20:32:07 -070094 localizer_resetter->y = 1.35 * turn_scalar;
Austin Schuh13379ba2019-03-12 21:06:46 -070095 localizer_resetter->theta = M_PI;
Austin Schuhb5b79a52019-05-08 20:32:07 -070096 localizer_resetter->theta_uncertainty = 0.00001;
Austin Schuh13379ba2019-03-12 21:06:46 -070097 if (!localizer_resetter.Send()) {
98 LOG(ERROR, "Failed to reset localizer.\n");
99 }
100 }
101
102 // Wait for the drivetrain to run so it has time to reset the heading.
103 // Otherwise our drivetrain reset will do a 180 right at the start.
104 drivetrain_queue.status.FetchAnother();
105 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
106 InitializeEncoders();
107 ResetDrivetrain();
108 drivetrain_queue.status.FetchAnother();
109 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
110
111 ResetDrivetrain();
112 InitializeEncoders();
113}
114
115const ProfileParameters kJumpDrive = {2.0, 3.0};
116const ProfileParameters kDrive = {4.0, 3.0};
117const ProfileParameters kTurn = {5.0, 15.0};
118
Austin Schuhb5b79a52019-05-08 20:32:07 -0700119const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
120const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
121
122const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
123const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
124
125const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
126
127const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
128
Austin Schuh13379ba2019-03-12 21:06:46 -0700129bool AutonomousActor::RunAction(
130 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuhb5b79a52019-05-08 20:32:07 -0700131 const monotonic_clock::time_point start_time = monotonic_clock::now();
Austin Schuha9644062019-03-28 14:31:52 -0700132 const bool is_left = params.mode == 0;
133
134 {
135 LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
136 params.mode, is_left ? "left" : "right");
137 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700138
Austin Schuha9644062019-03-28 14:31:52 -0700139 const double turn_scalar = is_left ? 1.0 : -1.0;
140
141 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700142 enum class Mode { kTesting, kRocket, kCargoship };
143 Mode mode = Mode::kCargoship;
144 if (mode == Mode::kRocket) {
145 SplineHandle spline1 =
146 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
147 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700148
Austin Schuhb5b79a52019-05-08 20:32:07 -0700149 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
150 set_elevator_goal(0.010);
151 set_wrist_goal(-M_PI / 2.0);
152 set_intake_goal(-1.2);
153 set_suction_goal(true, 1);
154 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700155
Austin Schuhb5b79a52019-05-08 20:32:07 -0700156 // if planned start the spline and plan the next
157 if (!spline1.WaitForPlan()) return true;
158 LOG(INFO, "Planned\n");
159 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700160
Austin Schuhb5b79a52019-05-08 20:32:07 -0700161 // If suction, move the superstructure to score
162 if (!WaitForGamePiece()) return true;
163 LOG(INFO, "Has game piece\n");
164 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
165 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
166 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700167
Austin Schuhb5b79a52019-05-08 20:32:07 -0700168 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
169 set_elevator_wrist_goal(kPanelForwardMiddlePos);
170 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700171
Austin Schuhb5b79a52019-05-08 20:32:07 -0700172 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700173
Austin Schuhb5b79a52019-05-08 20:32:07 -0700174 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
175 LineFollowAtVelocity(1.3, 4);
176 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700177
Austin Schuhb5b79a52019-05-08 20:32:07 -0700178 set_suction_goal(false, 1);
179 SendSuperstructureGoal();
180 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
181 LineFollowAtVelocity(-1.0, 4);
182 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
183 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700184
Austin Schuhb5b79a52019-05-08 20:32:07 -0700185 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
186 if (!spline2.WaitForPlan()) return true;
187 LOG(INFO, "Planned\n");
188 // Drive back to hp and set the superstructure accordingly
189 spline2.Start();
190 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
191 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
192 SendSuperstructureGoal();
193 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
194 set_suction_goal(true, 1);
195 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700196
Austin Schuhb5b79a52019-05-08 20:32:07 -0700197 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
198 LineFollowAtVelocity(-1.6);
199
200 // As soon as we pick up Panel 2 go score on the back rocket
201 if (!WaitForGamePiece()) return true;
202 LineFollowAtVelocity(1.5);
203 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
204 SplineDirection::kForward);
205 if (!WaitForDriveXGreater(0.50)) return true;
206 if (!spline3.WaitForPlan()) return true;
207 spline3.Start();
208 LOG(INFO, "Has game piece\n");
209 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
210 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
211 SendSuperstructureGoal();
212 if (!WaitForDriveXGreater(7.1)) return true;
213 LineFollowAtVelocity(-1.5, 4);
214 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
215 set_elevator_wrist_goal(kPanelBackwardUpperPos);
216 SendSuperstructureGoal();
217 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
218 set_suction_goal(false, 1);
219 SendSuperstructureGoal();
220 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
221 LineFollowAtVelocity(1.0, 4);
222 SendSuperstructureGoal();
223 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
224 } else if (mode == Mode::kCargoship) {
225 SplineHandle spline1 =
226 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
227 SplineDirection::kBackward);
228 set_elevator_goal(0.01);
229 set_wrist_goal(-M_PI / 2.0);
230 set_intake_goal(-1.2);
231 set_suction_goal(true, 1);
232 SendSuperstructureGoal();
233
234 // if planned start the spline and plan the next
235 if (!spline1.WaitForPlan()) return true;
236 LOG(INFO, "Planned\n");
237 spline1.Start();
238
239 // If suction, move the superstructure to score
240 if (!WaitForGamePiece()) return true;
241 LOG(INFO, "Has game piece\n");
242 // unstick the hatch panel
243 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
244 set_elevator_goal(0.5);
245 set_wrist_goal(-M_PI / 2.0);
246 SendSuperstructureGoal();
247 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
248 set_elevator_wrist_goal(kPanelCargoBackwardPos);
249 SendSuperstructureGoal();
250
251 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
252 // Line follow in to the first disc.
253 LineFollowAtVelocity(-0.9, 2);
254 if (!WaitForDriveYCloseToZero(1.2)) return true;
255
256 set_suction_goal(false, 1);
257 SendSuperstructureGoal();
258 LOG(INFO, "Dropping disc 1 %f\n",
259 DoubleSeconds(monotonic_clock::now() - start_time));
260
261 if (!WaitForDriveYCloseToZero(1.13)) return true;
262 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
263
264 LineFollowAtVelocity(0.9, 2);
265 SplineHandle spline2 =
266 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
267 SplineDirection::kForward);
268 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
269 if (!spline2.WaitForPlan()) return true;
270 LOG(INFO, "Planned\n");
271 // Drive back to hp and set the superstructure accordingly
272 spline2.Start();
273 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
274 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
275 SendSuperstructureGoal();
276 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
277 set_suction_goal(true, 1);
278 SendSuperstructureGoal();
279
280 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
281 LineFollowAtVelocity(1.5);
282 // As soon as we pick up Panel 2 go score on the rocket
283 if (!WaitForGamePiece()) return true;
284 LOG(INFO, "Got gamepiece %f\n",
285 DoubleSeconds(monotonic_clock::now() - start_time));
286 LineFollowAtVelocity(-4.0);
287 SplineHandle spline3 =
288 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
289 SplineDirection::kBackward);
290 if (!WaitForDriveXGreater(0.55)) return true;
291 if (!spline3.WaitForPlan()) return true;
292 spline3.Start();
293 // Wait until we are a bit out to lift.
294 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
295 set_elevator_wrist_goal(kPanelCargoBackwardPos);
296 SendSuperstructureGoal();
297
298 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
299 // Line follow in to the second disc.
300 LineFollowAtVelocity(-0.7, 3);
301 LOG(INFO, "Drawing in disc 2 %f\n",
302 DoubleSeconds(monotonic_clock::now() - start_time));
303 if (!WaitForDriveYCloseToZero(1.2)) return true;
304
305 set_suction_goal(false, 1);
306 SendSuperstructureGoal();
307 LOG(INFO, "Dropping disc 2 %f\n",
308 DoubleSeconds(monotonic_clock::now() - start_time));
309
310 if (!WaitForDriveYCloseToZero(1.13)) return true;
311 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
312 LOG(INFO, "Backing up %f\n",
313 DoubleSeconds(monotonic_clock::now() - start_time));
314 LineFollowAtVelocity(0.9, 3);
315 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
316 } else {
317 // Grab the disk, wait until we have vacuum, then jump
318 set_elevator_goal(0.01);
319 set_wrist_goal(-M_PI / 2.0);
320 set_intake_goal(-1.2);
321 set_suction_goal(true, 1);
322 SendSuperstructureGoal();
323
324 if (!WaitForGamePiece()) return true;
325 LOG(INFO, "Has game piece\n");
326
327 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
328 if (!WaitForDriveNear(3.3, 10.0)) return true;
329 LOG(INFO, "Lifting\n");
330 set_elevator_goal(0.30);
331 SendSuperstructureGoal();
332
333 if (!WaitForDriveNear(2.8, 10.0)) return true;
334 LOG(INFO, "Off the platform\n");
335
336 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
337 LOG(INFO, "Turn started\n");
338 if (!WaitForSuperstructureDone()) return true;
339 LOG(INFO, "Superstructure done\n");
340
341 if (!WaitForDriveNear(0.7, 10.0)) return true;
342 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
343
344 LOG(INFO, "Elevator up\n");
345 set_elevator_goal(0.78);
346 SendSuperstructureGoal();
347
348 if (!WaitForDriveDone()) return true;
349 LOG(INFO, "Done driving\n");
350
351 if (!WaitForSuperstructureDone()) return true;
352 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700353
354 LOG(INFO, "Done %f\n", DoubleSeconds(monotonic_clock::now() - start_time));
355
Austin Schuh13379ba2019-03-12 21:06:46 -0700356 return true;
357}
358
359} // namespace actors
360} // namespace y2019