blob: 0f2b04e76566d807bb78cc84ffa7bdee2ce99a5d [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>(
Austin Schuh170f4952019-06-29 18:58:30 -070028 ".frc971.control_loops.drivetrain.localizer_control")),
29 superstructure_goal_sender_(
30 event_loop->MakeSender<::y2019::control_loops::superstructure::
31 SuperstructureQueue::Goal>(
32 ".y2019.control_loops.superstructure.superstructure_queue.goal")),
33 superstructure_status_fetcher_(event_loop->MakeFetcher<
34 ::y2019::control_loops::superstructure::
35 SuperstructureQueue::Status>(
36 ".y2019.control_loops.superstructure.superstructure_queue.status")) {}
Austin Schuh13379ba2019-03-12 21:06:46 -070037
Austin Schuhb5b79a52019-05-08 20:32:07 -070038bool AutonomousActor::WaitForDriveXGreater(double x) {
39 LOG(INFO, "Waiting until x > %f\n", x);
40 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070041 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070042 ::std::chrono::milliseconds(5) / 2);
43
44 while (true) {
45 if (ShouldCancel()) {
46 return false;
47 }
48 phased_loop.SleepUntilNext();
49 drivetrain_queue.status.FetchLatest();
50 if (drivetrain_queue.status->x > x) {
51 LOG(INFO, "X at %f\n", drivetrain_queue.status->x);
52 return true;
53 }
54 }
55}
56
57bool AutonomousActor::WaitForDriveYCloseToZero(double y) {
58 LOG(INFO, "Waiting until |y| < %f\n", y);
59 ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(5),
Austin Schuhd32b3622019-06-23 18:49:06 -070060 event_loop()->monotonic_now(),
Austin Schuhb5b79a52019-05-08 20:32:07 -070061 ::std::chrono::milliseconds(5) / 2);
62
63 while (true) {
64 if (ShouldCancel()) {
65 return false;
66 }
67 phased_loop.SleepUntilNext();
68 drivetrain_queue.status.FetchLatest();
69 if (::std::abs(drivetrain_queue.status->y) < y) {
70 LOG(INFO, "Y at %f\n", drivetrain_queue.status->y);
71 return true;
72 }
73 }
74}
75
Austin Schuha9644062019-03-28 14:31:52 -070076void AutonomousActor::Reset(bool is_left) {
77 const double turn_scalar = is_left ? 1.0 : -1.0;
Austin Schuh13379ba2019-03-12 21:06:46 -070078 elevator_goal_ = 0.01;
79 wrist_goal_ = -M_PI / 2.0;
80 intake_goal_ = -1.2;
81
82 suction_on_ = false;
83 suction_gamepiece_ = 1;
84
85 elevator_max_velocity_ = 0.0;
86 elevator_max_acceleration_ = 0.0;
87 wrist_max_velocity_ = 0.0;
88 wrist_max_acceleration_ = 0.0;
89
90 InitializeEncoders();
91 SendSuperstructureGoal();
92
93 {
Austin Schuheb99d072019-05-12 21:03:38 -070094 auto localizer_resetter = localizer_control_sender_.MakeMessage();
Austin Schuh13379ba2019-03-12 21:06:46 -070095 // Start on the left l2.
96 localizer_resetter->x = 1.0;
Austin Schuhb5b79a52019-05-08 20:32:07 -070097 localizer_resetter->y = 1.35 * turn_scalar;
Austin Schuh13379ba2019-03-12 21:06:46 -070098 localizer_resetter->theta = M_PI;
Austin Schuhb5b79a52019-05-08 20:32:07 -070099 localizer_resetter->theta_uncertainty = 0.00001;
Austin Schuh13379ba2019-03-12 21:06:46 -0700100 if (!localizer_resetter.Send()) {
101 LOG(ERROR, "Failed to reset localizer.\n");
102 }
103 }
104
105 // Wait for the drivetrain to run so it has time to reset the heading.
106 // Otherwise our drivetrain reset will do a 180 right at the start.
107 drivetrain_queue.status.FetchAnother();
108 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
109 InitializeEncoders();
110 ResetDrivetrain();
111 drivetrain_queue.status.FetchAnother();
112 LOG(INFO, "Heading is %f\n", drivetrain_queue.status->estimated_heading);
113
114 ResetDrivetrain();
115 InitializeEncoders();
116}
117
118const ProfileParameters kJumpDrive = {2.0, 3.0};
119const ProfileParameters kDrive = {4.0, 3.0};
120const ProfileParameters kTurn = {5.0, 15.0};
121
Austin Schuhb5b79a52019-05-08 20:32:07 -0700122const ElevatorWristPosition kPanelHPIntakeForwrdPos{0.01, M_PI / 2.0};
123const ElevatorWristPosition kPanelHPIntakeBackwardPos{0.015, -M_PI / 2.0};
124
125const ElevatorWristPosition kPanelForwardMiddlePos{0.75, M_PI / 2.0};
126const ElevatorWristPosition kPanelBackwardMiddlePos{0.78, -M_PI / 2.0};
127
128const ElevatorWristPosition kPanelBackwardUpperPos{1.50, -M_PI / 2.0};
129
130const ElevatorWristPosition kPanelCargoBackwardPos{0.0, -M_PI / 2.0};
131
Austin Schuh13379ba2019-03-12 21:06:46 -0700132bool AutonomousActor::RunAction(
133 const ::frc971::autonomous::AutonomousActionParams &params) {
Austin Schuhb5b79a52019-05-08 20:32:07 -0700134 const monotonic_clock::time_point start_time = monotonic_clock::now();
Austin Schuha9644062019-03-28 14:31:52 -0700135 const bool is_left = params.mode == 0;
136
137 {
138 LOG(INFO, "Starting autonomous action with mode %" PRId32 " %s\n",
139 params.mode, is_left ? "left" : "right");
140 }
Austin Schuhb5b79a52019-05-08 20:32:07 -0700141
Austin Schuha9644062019-03-28 14:31:52 -0700142 const double turn_scalar = is_left ? 1.0 : -1.0;
143
144 Reset(is_left);
Austin Schuhb5b79a52019-05-08 20:32:07 -0700145 enum class Mode { kTesting, kRocket, kCargoship };
146 Mode mode = Mode::kCargoship;
147 if (mode == Mode::kRocket) {
148 SplineHandle spline1 =
149 PlanSpline(AutonomousSplines::HabToFarRocketTest(is_left),
150 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700151
Austin Schuhb5b79a52019-05-08 20:32:07 -0700152 // Grab the disk, jump, wait until we have vacuum, then raise the elevator
153 set_elevator_goal(0.010);
154 set_wrist_goal(-M_PI / 2.0);
155 set_intake_goal(-1.2);
156 set_suction_goal(true, 1);
157 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700158
Austin Schuhb5b79a52019-05-08 20:32:07 -0700159 // if planned start the spline and plan the next
160 if (!spline1.WaitForPlan()) return true;
161 LOG(INFO, "Planned\n");
162 spline1.Start();
Austin Schuh13379ba2019-03-12 21:06:46 -0700163
Austin Schuhb5b79a52019-05-08 20:32:07 -0700164 // If suction, move the superstructure to score
165 if (!WaitForGamePiece()) return true;
166 LOG(INFO, "Has game piece\n");
167 if (!spline1.WaitForSplineDistanceRemaining(3.5)) return true;
168 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
169 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700170
Austin Schuhb5b79a52019-05-08 20:32:07 -0700171 if (!spline1.WaitForSplineDistanceRemaining(2.0)) return true;
172 set_elevator_wrist_goal(kPanelForwardMiddlePos);
173 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700174
Austin Schuhb5b79a52019-05-08 20:32:07 -0700175 // END SPLINE 1
Austin Schuh13379ba2019-03-12 21:06:46 -0700176
Austin Schuhb5b79a52019-05-08 20:32:07 -0700177 if (!spline1.WaitForSplineDistanceRemaining(0.2)) return true;
178 LineFollowAtVelocity(1.3, 4);
179 if (!WaitForMilliseconds(::std::chrono::milliseconds(1200))) return true;
Austin Schuh13379ba2019-03-12 21:06:46 -0700180
Austin Schuhb5b79a52019-05-08 20:32:07 -0700181 set_suction_goal(false, 1);
182 SendSuperstructureGoal();
183 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
184 LineFollowAtVelocity(-1.0, 4);
185 SplineHandle spline2 = PlanSpline(AutonomousSplines::FarRocketToHP(is_left),
186 SplineDirection::kBackward);
Austin Schuh13379ba2019-03-12 21:06:46 -0700187
Austin Schuhb5b79a52019-05-08 20:32:07 -0700188 if (!WaitForMilliseconds(::std::chrono::milliseconds(150))) return true;
189 if (!spline2.WaitForPlan()) return true;
190 LOG(INFO, "Planned\n");
191 // Drive back to hp and set the superstructure accordingly
192 spline2.Start();
193 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
194 set_elevator_wrist_goal(kPanelHPIntakeBackwardPos);
195 SendSuperstructureGoal();
196 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
197 set_suction_goal(true, 1);
198 SendSuperstructureGoal();
Austin Schuh13379ba2019-03-12 21:06:46 -0700199
Austin Schuhb5b79a52019-05-08 20:32:07 -0700200 if (!spline2.WaitForSplineDistanceRemaining(1.6)) return true;
201 LineFollowAtVelocity(-1.6);
202
203 // As soon as we pick up Panel 2 go score on the back rocket
204 if (!WaitForGamePiece()) return true;
205 LineFollowAtVelocity(1.5);
206 SplineHandle spline3 = PlanSpline(AutonomousSplines::HPToFarRocket(is_left),
207 SplineDirection::kForward);
208 if (!WaitForDriveXGreater(0.50)) return true;
209 if (!spline3.WaitForPlan()) return true;
210 spline3.Start();
211 LOG(INFO, "Has game piece\n");
212 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
213 set_elevator_wrist_goal(kPanelBackwardMiddlePos);
214 SendSuperstructureGoal();
215 if (!WaitForDriveXGreater(7.1)) return true;
216 LineFollowAtVelocity(-1.5, 4);
217 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
218 set_elevator_wrist_goal(kPanelBackwardUpperPos);
219 SendSuperstructureGoal();
220 if (!WaitForMilliseconds(::std::chrono::milliseconds(1500))) return true;
221 set_suction_goal(false, 1);
222 SendSuperstructureGoal();
223 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
224 LineFollowAtVelocity(1.0, 4);
225 SendSuperstructureGoal();
226 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
227 } else if (mode == Mode::kCargoship) {
228 SplineHandle spline1 =
229 PlanSpline(AutonomousSplines::HABToSecondCargoShipBay(is_left),
230 SplineDirection::kBackward);
231 set_elevator_goal(0.01);
232 set_wrist_goal(-M_PI / 2.0);
233 set_intake_goal(-1.2);
234 set_suction_goal(true, 1);
235 SendSuperstructureGoal();
236
237 // if planned start the spline and plan the next
238 if (!spline1.WaitForPlan()) return true;
239 LOG(INFO, "Planned\n");
240 spline1.Start();
241
242 // If suction, move the superstructure to score
243 if (!WaitForGamePiece()) return true;
244 LOG(INFO, "Has game piece\n");
245 // unstick the hatch panel
246 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
247 set_elevator_goal(0.5);
248 set_wrist_goal(-M_PI / 2.0);
249 SendSuperstructureGoal();
250 if (!WaitForMilliseconds(::std::chrono::milliseconds(500))) return true;
251 set_elevator_wrist_goal(kPanelCargoBackwardPos);
252 SendSuperstructureGoal();
253
254 if (!spline1.WaitForSplineDistanceRemaining(0.8)) return true;
255 // Line follow in to the first disc.
256 LineFollowAtVelocity(-0.9, 2);
257 if (!WaitForDriveYCloseToZero(1.2)) return true;
258
259 set_suction_goal(false, 1);
260 SendSuperstructureGoal();
261 LOG(INFO, "Dropping disc 1 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700262 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700263
264 if (!WaitForDriveYCloseToZero(1.13)) return true;
265 if (!WaitForMilliseconds(::std::chrono::milliseconds(300))) return true;
266
267 LineFollowAtVelocity(0.9, 2);
268 SplineHandle spline2 =
269 PlanSpline(AutonomousSplines::SecondCargoShipBayToHP(is_left),
270 SplineDirection::kForward);
271 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
272 if (!spline2.WaitForPlan()) return true;
273 LOG(INFO, "Planned\n");
274 // Drive back to hp and set the superstructure accordingly
275 spline2.Start();
276 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
277 set_elevator_wrist_goal(kPanelHPIntakeForwrdPos);
278 SendSuperstructureGoal();
279 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
280 set_suction_goal(true, 1);
281 SendSuperstructureGoal();
282
283 if (!spline2.WaitForSplineDistanceRemaining(1.75)) return true;
284 LineFollowAtVelocity(1.5);
285 // As soon as we pick up Panel 2 go score on the rocket
286 if (!WaitForGamePiece()) return true;
287 LOG(INFO, "Got gamepiece %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700288 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700289 LineFollowAtVelocity(-4.0);
290 SplineHandle spline3 =
291 PlanSpline(AutonomousSplines::HPToThirdCargoShipBay(is_left),
292 SplineDirection::kBackward);
293 if (!WaitForDriveXGreater(0.55)) return true;
294 if (!spline3.WaitForPlan()) return true;
295 spline3.Start();
296 // Wait until we are a bit out to lift.
297 if (!WaitForMilliseconds(::std::chrono::milliseconds(1000))) return true;
298 set_elevator_wrist_goal(kPanelCargoBackwardPos);
299 SendSuperstructureGoal();
300
301 if (!spline3.WaitForSplineDistanceRemaining(0.7)) return true;
302 // Line follow in to the second disc.
303 LineFollowAtVelocity(-0.7, 3);
304 LOG(INFO, "Drawing in disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700305 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700306 if (!WaitForDriveYCloseToZero(1.2)) return true;
307
308 set_suction_goal(false, 1);
309 SendSuperstructureGoal();
310 LOG(INFO, "Dropping disc 2 %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700311 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700312
313 if (!WaitForDriveYCloseToZero(1.13)) return true;
314 if (!WaitForMilliseconds(::std::chrono::milliseconds(200))) return true;
315 LOG(INFO, "Backing up %f\n",
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700316 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuhb5b79a52019-05-08 20:32:07 -0700317 LineFollowAtVelocity(0.9, 3);
318 if (!WaitForMilliseconds(::std::chrono::milliseconds(400))) return true;
319 } else {
320 // Grab the disk, wait until we have vacuum, then jump
321 set_elevator_goal(0.01);
322 set_wrist_goal(-M_PI / 2.0);
323 set_intake_goal(-1.2);
324 set_suction_goal(true, 1);
325 SendSuperstructureGoal();
326
327 if (!WaitForGamePiece()) return true;
328 LOG(INFO, "Has game piece\n");
329
330 StartDrive(-4.0, 0.0, kJumpDrive, kTurn);
331 if (!WaitForDriveNear(3.3, 10.0)) return true;
332 LOG(INFO, "Lifting\n");
333 set_elevator_goal(0.30);
334 SendSuperstructureGoal();
335
336 if (!WaitForDriveNear(2.8, 10.0)) return true;
337 LOG(INFO, "Off the platform\n");
338
339 StartDrive(0.0, 1.00 * turn_scalar, kDrive, kTurn);
340 LOG(INFO, "Turn started\n");
341 if (!WaitForSuperstructureDone()) return true;
342 LOG(INFO, "Superstructure done\n");
343
344 if (!WaitForDriveNear(0.7, 10.0)) return true;
345 StartDrive(0.0, -0.35 * turn_scalar, kDrive, kTurn);
346
347 LOG(INFO, "Elevator up\n");
348 set_elevator_goal(0.78);
349 SendSuperstructureGoal();
350
351 if (!WaitForDriveDone()) return true;
352 LOG(INFO, "Done driving\n");
353
354 if (!WaitForSuperstructureDone()) return true;
355 }
Austin Schuh13379ba2019-03-12 21:06:46 -0700356
James Kuszmaul651fc3f2019-05-15 21:14:25 -0700357 LOG(INFO, "Done %f\n",
358 ::aos::time::DurationInSeconds(monotonic_clock::now() - start_time));
Austin Schuh13379ba2019-03-12 21:06:46 -0700359
Austin Schuh13379ba2019-03-12 21:06:46 -0700360 return true;
361}
362
363} // namespace actors
364} // namespace y2019