blob: c933181234f6251df52fd4cd72399a636cadf441 [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 {
Austin Schuh13379ba2019-03-12 21:06:46 -070018using ::aos::monotonic_clock;
James Kuszmaul651fc3f2019-05-15 21:14:25 -070019using ::frc971::control_loops::drivetrain_queue;
Austin Schuh13379ba2019-03-12 21:06:46 -070020namespace chrono = ::std::chrono;
21
Austin Schuh1bf8a212019-05-26 22:13:14 -070022AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
Austin Schuh13379ba2019-03-12 21:06:46 -070023 : frc971::autonomous::BaseAutonomousActor(
Austin Schuh1bf8a212019-05-26 22:13:14 -070024 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
Austin Schuheb99d072019-05-12 21:03:38 -070025 localizer_control_sender_(
26 event_loop->MakeSender<
27 ::frc971::control_loops::drivetrain::LocalizerControl>(
28 ".frc971.control_loops.drivetrain.localizer_control")) {}
Austin Schuh13379ba2019-03-12 21:06:46 -070029
Austin Schuhb5b79a52019-05-08 20:32:07 -070030bool AutonomousActor::WaitForDriveXGreater(double x) {
31 LOG(INFO, "Waiting until x > %f\n", x);
32 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070033 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070034 ::std::chrono::milliseconds(5) / 2);
35
36 while (true) {
37 if (ShouldCancel()) {
38 return false;
39 }
40 phased_loop.SleepUntilNext();
41 drivetrain_queue.status.FetchLatest();
42 if (drivetrain_queue.status->x > x) {
43 LOG(INFO, "X at %f\n", drivetrain_queue.status->x);
44 return true;
45 }
46 }
47}
48
49bool AutonomousActor::WaitForDriveYCloseToZero(double y) {
50 LOG(INFO, "Waiting until |y| < %f\n", y);
51 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070052 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070053 ::std::chrono::milliseconds(5) / 2);
54
55 while (true) {
56 if (ShouldCancel()) {
57 return false;
58 }
59 phased_loop.SleepUntilNext();
60 drivetrain_queue.status.FetchLatest();
61 if (::std::abs(drivetrain_queue.status->y) < y) {
62 LOG(INFO, "Y at %f\n", drivetrain_queue.status->y);
63 return true;
64 }
65 }
66}
67
Austin Schuha9644062019-03-28 14:31:52 -070068void AutonomousActor::Reset(bool is_left) {
69 const double turn_scalar = is_left ? 1.0 : -1.0;
Austin Schuh13379ba2019-03-12 21:06:46 -070070 elevator_goal_ = 0.01;
71 wrist_goal_ = -M_PI / 2.0;
72 intake_goal_ = -1.2;
73
74 suction_on_ = false;
75 suction_gamepiece_ = 1;
76
77 elevator_max_velocity_ = 0.0;
78 elevator_max_acceleration_ = 0.0;
79 wrist_max_velocity_ = 0.0;
80 wrist_max_acceleration_ = 0.0;
81
82 InitializeEncoders();
83 SendSuperstructureGoal();
84
85 {
Austin Schuheb99d072019-05-12 21:03:38 -070086 auto localizer_resetter = localizer_control_sender_.MakeMessage();
Austin Schuh13379ba2019-03-12 21:06:46 -070087 // Start on the left l2.
88 localizer_resetter->x = 1.0;
Austin Schuhb5b79a52019-05-08 20:32:07 -070089 localizer_resetter->y = 1.35 * turn_scalar;
Austin Schuh13379ba2019-03-12 21:06:46 -070090 localizer_resetter->theta = M_PI;
Austin Schuhb5b79a52019-05-08 20:32:07 -070091 localizer_resetter->theta_uncertainty = 0.00001;
Austin Schuh13379ba2019-03-12 21:06:46 -070092 if (!localizer_resetter.Send()) {
93 LOG(ERROR, "Failed to reset localizer.\n");
94 }
95 }
96
97 // Wait for the drivetrain to run so it has time to reset the heading.
98 // Otherwise our drivetrain reset will do a 180 right at the start.
99 drivetrain_queue.status.FetchAnother();
100 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
101 InitializeEncoders();
102 ResetDrivetrain();
103 drivetrain_queue.status.FetchAnother();
104 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
105
106 ResetDrivetrain();
107 InitializeEncoders();
108}
109
110const ProfileParameters kJumpDrive = {2.0, 3.0};
111const ProfileParameters kDrive = {4.0, 3.0};
112const ProfileParameters kTurn = {5.0, 15.0};
113
Austin Schuhb5b79a52019-05-08 20:32:07 -0700114const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
115const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
116
117const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
118const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
119
120const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
121
122const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
123
Austin Schuh13379ba2019-03-12 21:06:46 -0700124bool AutonomousActor::RunAction(
125 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuhb5b79a52019-05-08 20:32:07 -0700126 const monotonic_clock::time_point start_time = monotonic_clock::now();
Austin Schuha9644062019-03-28 14:31:52 -0700127 const bool is_left = params.mode == 0;
128
129 {
130 LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
131 params.mode, is_left ? "left" : "right");
132 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700133
Austin Schuha9644062019-03-28 14:31:52 -0700134 const double turn_scalar = is_left ? 1.0 : -1.0;
135
136 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700137 enum class Mode { kTesting, kRocket, kCargoship };
138 Mode mode = Mode::kCargoship;
139 if (mode == Mode::kRocket) {
140 SplineHandle spline1 =
141 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
142 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700143
Austin Schuhb5b79a52019-05-08 20:32:07 -0700144 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
145 set_elevator_goal(0.010);
146 set_wrist_goal(-M_PI / 2.0);
147 set_intake_goal(-1.2);
148 set_suction_goal(true, 1);
149 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700150
Austin Schuhb5b79a52019-05-08 20:32:07 -0700151 // if planned start the spline and plan the next
152 if (!spline1.WaitForPlan()) return true;
153 LOG(INFO, "Planned\n");
154 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700155
Austin Schuhb5b79a52019-05-08 20:32:07 -0700156 // If suction, move the superstructure to score
157 if (!WaitForGamePiece()) return true;
158 LOG(INFO, "Has game piece\n");
159 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
160 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
161 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700162
Austin Schuhb5b79a52019-05-08 20:32:07 -0700163 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
164 set_elevator_wrist_goal(kPanelForwardMiddlePos);
165 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700166
Austin Schuhb5b79a52019-05-08 20:32:07 -0700167 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700168
Austin Schuhb5b79a52019-05-08 20:32:07 -0700169 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
170 LineFollowAtVelocity(1.3, 4);
171 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700172
Austin Schuhb5b79a52019-05-08 20:32:07 -0700173 set_suction_goal(false, 1);
174 SendSuperstructureGoal();
175 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
176 LineFollowAtVelocity(-1.0, 4);
177 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
178 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700179
Austin Schuhb5b79a52019-05-08 20:32:07 -0700180 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
181 if (!spline2.WaitForPlan()) return true;
182 LOG(INFO, "Planned\n");
183 // Drive back to hp and set the superstructure accordingly
184 spline2.Start();
185 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
186 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
187 SendSuperstructureGoal();
188 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
189 set_suction_goal(true, 1);
190 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700191
Austin Schuhb5b79a52019-05-08 20:32:07 -0700192 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
193 LineFollowAtVelocity(-1.6);
194
195 // As soon as we pick up Panel 2 go score on the back rocket
196 if (!WaitForGamePiece()) return true;
197 LineFollowAtVelocity(1.5);
198 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
199 SplineDirection::kForward);
200 if (!WaitForDriveXGreater(0.50)) return true;
201 if (!spline3.WaitForPlan()) return true;
202 spline3.Start();
203 LOG(INFO, "Has game piece\n");
204 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
205 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
206 SendSuperstructureGoal();
207 if (!WaitForDriveXGreater(7.1)) return true;
208 LineFollowAtVelocity(-1.5, 4);
209 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
210 set_elevator_wrist_goal(kPanelBackwardUpperPos);
211 SendSuperstructureGoal();
212 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
213 set_suction_goal(false, 1);
214 SendSuperstructureGoal();
215 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
216 LineFollowAtVelocity(1.0, 4);
217 SendSuperstructureGoal();
218 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
219 } else if (mode == Mode::kCargoship) {
220 SplineHandle spline1 =
221 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
222 SplineDirection::kBackward);
223 set_elevator_goal(0.01);
224 set_wrist_goal(-M_PI / 2.0);
225 set_intake_goal(-1.2);
226 set_suction_goal(true, 1);
227 SendSuperstructureGoal();
228
229 // if planned start the spline and plan the next
230 if (!spline1.WaitForPlan()) return true;
231 LOG(INFO, "Planned\n");
232 spline1.Start();
233
234 // If suction, move the superstructure to score
235 if (!WaitForGamePiece()) return true;
236 LOG(INFO, "Has game piece\n");
237 // unstick the hatch panel
238 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
239 set_elevator_goal(0.5);
240 set_wrist_goal(-M_PI / 2.0);
241 SendSuperstructureGoal();
242 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
243 set_elevator_wrist_goal(kPanelCargoBackwardPos);
244 SendSuperstructureGoal();
245
246 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
247 // Line follow in to the first disc.
248 LineFollowAtVelocity(-0.9, 2);
249 if (!WaitForDriveYCloseToZero(1.2)) return true;
250
251 set_suction_goal(false, 1);
252 SendSuperstructureGoal();
253 LOG(INFO, "Dropping disc 1 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700254 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700255
256 if (!WaitForDriveYCloseToZero(1.13)) return true;
257 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
258
259 LineFollowAtVelocity(0.9, 2);
260 SplineHandle spline2 =
261 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
262 SplineDirection::kForward);
263 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
264 if (!spline2.WaitForPlan()) return true;
265 LOG(INFO, "Planned\n");
266 // Drive back to hp and set the superstructure accordingly
267 spline2.Start();
268 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
269 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
270 SendSuperstructureGoal();
271 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
272 set_suction_goal(true, 1);
273 SendSuperstructureGoal();
274
275 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
276 LineFollowAtVelocity(1.5);
277 // As soon as we pick up Panel 2 go score on the rocket
278 if (!WaitForGamePiece()) return true;
279 LOG(INFO, "Got gamepiece %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700280 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700281 LineFollowAtVelocity(-4.0);
282 SplineHandle spline3 =
283 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
284 SplineDirection::kBackward);
285 if (!WaitForDriveXGreater(0.55)) return true;
286 if (!spline3.WaitForPlan()) return true;
287 spline3.Start();
288 // Wait until we are a bit out to lift.
289 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
290 set_elevator_wrist_goal(kPanelCargoBackwardPos);
291 SendSuperstructureGoal();
292
293 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
294 // Line follow in to the second disc.
295 LineFollowAtVelocity(-0.7, 3);
296 LOG(INFO, "Drawing in disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700297 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700298 if (!WaitForDriveYCloseToZero(1.2)) return true;
299
300 set_suction_goal(false, 1);
301 SendSuperstructureGoal();
302 LOG(INFO, "Dropping disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700303 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700304
305 if (!WaitForDriveYCloseToZero(1.13)) return true;
306 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
307 LOG(INFO, "Backing up %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700308 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700309 LineFollowAtVelocity(0.9, 3);
310 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
311 } else {
312 // Grab the disk, wait until we have vacuum, then jump
313 set_elevator_goal(0.01);
314 set_wrist_goal(-M_PI / 2.0);
315 set_intake_goal(-1.2);
316 set_suction_goal(true, 1);
317 SendSuperstructureGoal();
318
319 if (!WaitForGamePiece()) return true;
320 LOG(INFO, "Has game piece\n");
321
322 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
323 if (!WaitForDriveNear(3.3, 10.0)) return true;
324 LOG(INFO, "Lifting\n");
325 set_elevator_goal(0.30);
326 SendSuperstructureGoal();
327
328 if (!WaitForDriveNear(2.8, 10.0)) return true;
329 LOG(INFO, "Off the platform\n");
330
331 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
332 LOG(INFO, "Turn started\n");
333 if (!WaitForSuperstructureDone()) return true;
334 LOG(INFO, "Superstructure done\n");
335
336 if (!WaitForDriveNear(0.7, 10.0)) return true;
337 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
338
339 LOG(INFO, "Elevator up\n");
340 set_elevator_goal(0.78);
341 SendSuperstructureGoal();
342
343 if (!WaitForDriveDone()) return true;
344 LOG(INFO, "Done driving\n");
345
346 if (!WaitForSuperstructureDone()) return true;
347 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700348
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700349 LOG(INFO, "Done %f\n",
350 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh13379ba2019-03-12 21:06:46 -0700351
Austin Schuh13379ba2019-03-12 21:06:46 -0700352 return true;
353}
354
355} // namespace actors
356} // namespace y2019