blob: ee7f4924e1ccdc5aa2f102093b724f8ead7056c9 [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),
33 ::std::chrono::milliseconds(5) / 2);
34
35 while (true) {
36 if (ShouldCancel()) {
37 return false;
38 }
39 phased_loop.SleepUntilNext();
40 drivetrain_queue.status.FetchLatest();
41 if (drivetrain_queue.status->x > x) {
42 LOG(INFO, "X at %f\n", drivetrain_queue.status->x);
43 return true;
44 }
45 }
46}
47
48bool AutonomousActor::WaitForDriveYCloseToZero(double y) {
49 LOG(INFO, "Waiting until |y| < %f\n", y);
50 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
51 ::std::chrono::milliseconds(5) / 2);
52
53 while (true) {
54 if (ShouldCancel()) {
55 return false;
56 }
57 phased_loop.SleepUntilNext();
58 drivetrain_queue.status.FetchLatest();
59 if (::std::abs(drivetrain_queue.status->y) < y) {
60 LOG(INFO, "Y at %f\n", drivetrain_queue.status->y);
61 return true;
62 }
63 }
64}
65
Austin Schuha9644062019-03-28 14:31:52 -070066void AutonomousActor::Reset(bool is_left) {
67 const double turn_scalar = is_left ? 1.0 : -1.0;
Austin Schuh13379ba2019-03-12 21:06:46 -070068 elevator_goal_ = 0.01;
69 wrist_goal_ = -M_PI / 2.0;
70 intake_goal_ = -1.2;
71
72 suction_on_ = false;
73 suction_gamepiece_ = 1;
74
75 elevator_max_velocity_ = 0.0;
76 elevator_max_acceleration_ = 0.0;
77 wrist_max_velocity_ = 0.0;
78 wrist_max_acceleration_ = 0.0;
79
80 InitializeEncoders();
81 SendSuperstructureGoal();
82
83 {
Austin Schuheb99d072019-05-12 21:03:38 -070084 auto localizer_resetter = localizer_control_sender_.MakeMessage();
Austin Schuh13379ba2019-03-12 21:06:46 -070085 // Start on the left l2.
86 localizer_resetter->x = 1.0;
Austin Schuhb5b79a52019-05-08 20:32:07 -070087 localizer_resetter->y = 1.35 * turn_scalar;
Austin Schuh13379ba2019-03-12 21:06:46 -070088 localizer_resetter->theta = M_PI;
Austin Schuhb5b79a52019-05-08 20:32:07 -070089 localizer_resetter->theta_uncertainty = 0.00001;
Austin Schuh13379ba2019-03-12 21:06:46 -070090 if (!localizer_resetter.Send()) {
91 LOG(ERROR, "Failed to reset localizer.\n");
92 }
93 }
94
95 // Wait for the drivetrain to run so it has time to reset the heading.
96 // Otherwise our drivetrain reset will do a 180 right at the start.
97 drivetrain_queue.status.FetchAnother();
98 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
99 InitializeEncoders();
100 ResetDrivetrain();
101 drivetrain_queue.status.FetchAnother();
102 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
103
104 ResetDrivetrain();
105 InitializeEncoders();
106}
107
108const ProfileParameters kJumpDrive = {2.0, 3.0};
109const ProfileParameters kDrive = {4.0, 3.0};
110const ProfileParameters kTurn = {5.0, 15.0};
111
Austin Schuhb5b79a52019-05-08 20:32:07 -0700112const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
113const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
114
115const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
116const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
117
118const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
119
120const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
121
Austin Schuh13379ba2019-03-12 21:06:46 -0700122bool AutonomousActor::RunAction(
123 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuhb5b79a52019-05-08 20:32:07 -0700124 const monotonic_clock::time_point start_time = monotonic_clock::now();
Austin Schuha9644062019-03-28 14:31:52 -0700125 const bool is_left = params.mode == 0;
126
127 {
128 LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
129 params.mode, is_left ? "left" : "right");
130 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700131
Austin Schuha9644062019-03-28 14:31:52 -0700132 const double turn_scalar = is_left ? 1.0 : -1.0;
133
134 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700135 enum class Mode { kTesting, kRocket, kCargoship };
136 Mode mode = Mode::kCargoship;
137 if (mode == Mode::kRocket) {
138 SplineHandle spline1 =
139 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
140 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700141
Austin Schuhb5b79a52019-05-08 20:32:07 -0700142 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
143 set_elevator_goal(0.010);
144 set_wrist_goal(-M_PI / 2.0);
145 set_intake_goal(-1.2);
146 set_suction_goal(true, 1);
147 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700148
Austin Schuhb5b79a52019-05-08 20:32:07 -0700149 // if planned start the spline and plan the next
150 if (!spline1.WaitForPlan()) return true;
151 LOG(INFO, "Planned\n");
152 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700153
Austin Schuhb5b79a52019-05-08 20:32:07 -0700154 // If suction, move the superstructure to score
155 if (!WaitForGamePiece()) return true;
156 LOG(INFO, "Has game piece\n");
157 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
158 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
159 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700160
Austin Schuhb5b79a52019-05-08 20:32:07 -0700161 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
162 set_elevator_wrist_goal(kPanelForwardMiddlePos);
163 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700164
Austin Schuhb5b79a52019-05-08 20:32:07 -0700165 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700166
Austin Schuhb5b79a52019-05-08 20:32:07 -0700167 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
168 LineFollowAtVelocity(1.3, 4);
169 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700170
Austin Schuhb5b79a52019-05-08 20:32:07 -0700171 set_suction_goal(false, 1);
172 SendSuperstructureGoal();
173 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
174 LineFollowAtVelocity(-1.0, 4);
175 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
176 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700177
Austin Schuhb5b79a52019-05-08 20:32:07 -0700178 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
179 if (!spline2.WaitForPlan()) return true;
180 LOG(INFO, "Planned\n");
181 // Drive back to hp and set the superstructure accordingly
182 spline2.Start();
183 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
184 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
185 SendSuperstructureGoal();
186 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
187 set_suction_goal(true, 1);
188 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700189
Austin Schuhb5b79a52019-05-08 20:32:07 -0700190 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
191 LineFollowAtVelocity(-1.6);
192
193 // As soon as we pick up Panel 2 go score on the back rocket
194 if (!WaitForGamePiece()) return true;
195 LineFollowAtVelocity(1.5);
196 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
197 SplineDirection::kForward);
198 if (!WaitForDriveXGreater(0.50)) return true;
199 if (!spline3.WaitForPlan()) return true;
200 spline3.Start();
201 LOG(INFO, "Has game piece\n");
202 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
203 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
204 SendSuperstructureGoal();
205 if (!WaitForDriveXGreater(7.1)) return true;
206 LineFollowAtVelocity(-1.5, 4);
207 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
208 set_elevator_wrist_goal(kPanelBackwardUpperPos);
209 SendSuperstructureGoal();
210 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
211 set_suction_goal(false, 1);
212 SendSuperstructureGoal();
213 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
214 LineFollowAtVelocity(1.0, 4);
215 SendSuperstructureGoal();
216 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
217 } else if (mode == Mode::kCargoship) {
218 SplineHandle spline1 =
219 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
220 SplineDirection::kBackward);
221 set_elevator_goal(0.01);
222 set_wrist_goal(-M_PI / 2.0);
223 set_intake_goal(-1.2);
224 set_suction_goal(true, 1);
225 SendSuperstructureGoal();
226
227 // if planned start the spline and plan the next
228 if (!spline1.WaitForPlan()) return true;
229 LOG(INFO, "Planned\n");
230 spline1.Start();
231
232 // If suction, move the superstructure to score
233 if (!WaitForGamePiece()) return true;
234 LOG(INFO, "Has game piece\n");
235 // unstick the hatch panel
236 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
237 set_elevator_goal(0.5);
238 set_wrist_goal(-M_PI / 2.0);
239 SendSuperstructureGoal();
240 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
241 set_elevator_wrist_goal(kPanelCargoBackwardPos);
242 SendSuperstructureGoal();
243
244 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
245 // Line follow in to the first disc.
246 LineFollowAtVelocity(-0.9, 2);
247 if (!WaitForDriveYCloseToZero(1.2)) return true;
248
249 set_suction_goal(false, 1);
250 SendSuperstructureGoal();
251 LOG(INFO, "Dropping disc 1 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700252 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700253
254 if (!WaitForDriveYCloseToZero(1.13)) return true;
255 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
256
257 LineFollowAtVelocity(0.9, 2);
258 SplineHandle spline2 =
259 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
260 SplineDirection::kForward);
261 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
262 if (!spline2.WaitForPlan()) return true;
263 LOG(INFO, "Planned\n");
264 // Drive back to hp and set the superstructure accordingly
265 spline2.Start();
266 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
267 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
268 SendSuperstructureGoal();
269 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
270 set_suction_goal(true, 1);
271 SendSuperstructureGoal();
272
273 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
274 LineFollowAtVelocity(1.5);
275 // As soon as we pick up Panel 2 go score on the rocket
276 if (!WaitForGamePiece()) return true;
277 LOG(INFO, "Got gamepiece %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700278 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700279 LineFollowAtVelocity(-4.0);
280 SplineHandle spline3 =
281 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
282 SplineDirection::kBackward);
283 if (!WaitForDriveXGreater(0.55)) return true;
284 if (!spline3.WaitForPlan()) return true;
285 spline3.Start();
286 // Wait until we are a bit out to lift.
287 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
288 set_elevator_wrist_goal(kPanelCargoBackwardPos);
289 SendSuperstructureGoal();
290
291 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
292 // Line follow in to the second disc.
293 LineFollowAtVelocity(-0.7, 3);
294 LOG(INFO, "Drawing in disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700295 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700296 if (!WaitForDriveYCloseToZero(1.2)) return true;
297
298 set_suction_goal(false, 1);
299 SendSuperstructureGoal();
300 LOG(INFO, "Dropping disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700301 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700302
303 if (!WaitForDriveYCloseToZero(1.13)) return true;
304 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
305 LOG(INFO, "Backing up %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700306 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700307 LineFollowAtVelocity(0.9, 3);
308 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
309 } else {
310 // Grab the disk, wait until we have vacuum, then jump
311 set_elevator_goal(0.01);
312 set_wrist_goal(-M_PI / 2.0);
313 set_intake_goal(-1.2);
314 set_suction_goal(true, 1);
315 SendSuperstructureGoal();
316
317 if (!WaitForGamePiece()) return true;
318 LOG(INFO, "Has game piece\n");
319
320 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
321 if (!WaitForDriveNear(3.3, 10.0)) return true;
322 LOG(INFO, "Lifting\n");
323 set_elevator_goal(0.30);
324 SendSuperstructureGoal();
325
326 if (!WaitForDriveNear(2.8, 10.0)) return true;
327 LOG(INFO, "Off the platform\n");
328
329 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
330 LOG(INFO, "Turn started\n");
331 if (!WaitForSuperstructureDone()) return true;
332 LOG(INFO, "Superstructure done\n");
333
334 if (!WaitForDriveNear(0.7, 10.0)) return true;
335 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
336
337 LOG(INFO, "Elevator up\n");
338 set_elevator_goal(0.78);
339 SendSuperstructureGoal();
340
341 if (!WaitForDriveDone()) return true;
342 LOG(INFO, "Done driving\n");
343
344 if (!WaitForSuperstructureDone()) return true;
345 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700346
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700347 LOG(INFO, "Done %f\n",
348 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh13379ba2019-03-12 21:06:46 -0700349
Austin Schuh13379ba2019-03-12 21:06:46 -0700350 return true;
351}
352
353} // namespace actors
354} // namespace y2019