blob: cd4d4f1c79361694030e5d5d3d26b8d0b6396a7e [file] [log] [blame]
Maxwell Hendersonad312342023-01-10 12:07:47 -08001#include "y2023/autonomous/autonomous_actor.h"
2
3#include <chrono>
4#include <cinttypes>
5#include <cmath>
6
7#include "aos/logging/logging.h"
Maxwell Henderson64f37452023-03-11 13:39:21 -08008#include "aos/util/math.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -08009#include "frc971/control_loops/drivetrain/localizer_generated.h"
Maxwell Henderson64f37452023-03-11 13:39:21 -080010#include "y2023/autonomous/auto_splines.h"
11#include "y2023/constants.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080012#include "y2023/control_loops/drivetrain/drivetrain_base.h"
Maxwell Henderson64f37452023-03-11 13:39:21 -080013#include "y2023/control_loops/superstructure/arm/generated_graph.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080014
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070015DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
Maxwell Henderson64f37452023-03-11 13:39:21 -080016DEFINE_bool(charged_up, true, "If true run charged up autonomous mode");
Maxwell Henderson25378832023-04-07 14:37:41 -070017DEFINE_bool(charged_up_cable, false, "If true run cable side autonomous mode");
James Kuszmaul713c5ce2023-03-04 18:23:24 -080018
Maxwell Hendersonad312342023-01-10 12:07:47 -080019namespace y2023 {
Maxwell Henderson64f37452023-03-11 13:39:21 -080020namespace autonomous {
Maxwell Hendersonad312342023-01-10 12:07:47 -080021
Maxwell Hendersonad312342023-01-10 12:07:47 -080022using ::frc971::ProfileParametersT;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070023
24ProfileParametersT MakeProfileParameters(float max_velocity,
25 float max_acceleration) {
26 ProfileParametersT result;
27 result.max_velocity = max_velocity;
28 result.max_acceleration = max_acceleration;
29 return result;
30}
31
32using ::aos::monotonic_clock;
33using frc971::CreateProfileParameters;
34using ::frc971::ProfileParametersT;
35using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
36using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
Maxwell Hendersonad312342023-01-10 12:07:47 -080037using frc971::control_loops::drivetrain::LocalizerControl;
38namespace chrono = ::std::chrono;
39
40AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
41 : frc971::autonomous::BaseAutonomousActor(
James Kuszmaul713c5ce2023-03-04 18:23:24 -080042 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
43 localizer_control_sender_(
44 event_loop->MakeSender<
45 ::frc971::control_loops::drivetrain::LocalizerControl>(
46 "/drivetrain")),
47 joystick_state_fetcher_(
48 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
49 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
Maxwell Henderson64f37452023-03-11 13:39:21 -080050 auto_splines_(),
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070051 arm_goal_position_(control_loops::superstructure::arm::StartingIndex()),
52 superstructure_goal_sender_(
53 event_loop->MakeSender<::y2023::control_loops::superstructure::Goal>(
54 "/superstructure")),
55 superstructure_status_fetcher_(
56 event_loop
57 ->MakeFetcher<::y2023::control_loops::superstructure::Status>(
58 "/superstructure")),
Maxwell Henderson64f37452023-03-11 13:39:21 -080059 points_(control_loops::superstructure::arm::PointList()) {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070060 drivetrain_status_fetcher_.Fetch();
James Kuszmaul713c5ce2023-03-04 18:23:24 -080061 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
62
63 event_loop->OnRun([this, event_loop]() {
64 replan_timer_->Setup(event_loop->monotonic_now());
65 button_poll_->Setup(event_loop->monotonic_now(), chrono::milliseconds(50));
66 });
67
68 // TODO(james): Really need to refactor this code since we keep using it.
69 button_poll_ = event_loop->AddTimer([this]() {
70 const aos::monotonic_clock::time_point now =
71 this->event_loop()->context().monotonic_event_time;
72 if (robot_state_fetcher_.Fetch()) {
73 if (robot_state_fetcher_->user_button()) {
74 user_indicated_safe_to_reset_ = true;
75 MaybeSendStartingPosition();
76 }
77 }
78 if (joystick_state_fetcher_.Fetch()) {
79 if (joystick_state_fetcher_->has_alliance() &&
80 (joystick_state_fetcher_->alliance() != alliance_)) {
81 alliance_ = joystick_state_fetcher_->alliance();
82 is_planned_ = false;
Maxwell Henderson64f37452023-03-11 13:39:21 -080083 // Only kick the planning out by 2 seconds. If we end up enabled in
84 // that second, then we will kick it out further based on the code
85 // below.
James Kuszmaul713c5ce2023-03-04 18:23:24 -080086 replan_timer_->Setup(now + std::chrono::seconds(2));
87 }
88 if (joystick_state_fetcher_->enabled()) {
89 if (!is_planned_) {
90 // Only replan once we've been disabled for 5 seconds.
91 replan_timer_->Setup(now + std::chrono::seconds(5));
92 }
93 }
94 }
95 });
96}
97
98void AutonomousActor::Replan() {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070099 if (!drivetrain_status_fetcher_.Fetch()) {
100 replan_timer_->Setup(event_loop()->monotonic_now() + chrono::seconds(1));
101 AOS_LOG(INFO, "Drivetrain not up, replanning in 1 second");
102 return;
103 }
104
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800105 if (alliance_ == aos::Alliance::kInvalid) {
106 return;
107 }
108 sent_starting_position_ = false;
109 if (FLAGS_spline_auto) {
110 test_spline_ =
111 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
112 std::placeholders::_1, alliance_),
113 SplineDirection::kForward);
114
115 starting_position_ = test_spline_->starting_position();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800116 } else if (FLAGS_charged_up) {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700117 AOS_LOG(INFO, "Charged up replanning!");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800118 charged_up_splines_ = {
119 PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
120 std::placeholders::_1, alliance_),
121 SplineDirection::kBackward),
122 PlanSpline(std::bind(&AutonomousSplines::Spline2, &auto_splines_,
123 std::placeholders::_1, alliance_),
124 SplineDirection::kForward),
125 PlanSpline(std::bind(&AutonomousSplines::Spline3, &auto_splines_,
126 std::placeholders::_1, alliance_),
127 SplineDirection::kBackward),
128 PlanSpline(std::bind(&AutonomousSplines::Spline4, &auto_splines_,
129 std::placeholders::_1, alliance_),
Maxwell Henderson25378832023-04-07 14:37:41 -0700130 SplineDirection::kForward)};
Maxwell Henderson64f37452023-03-11 13:39:21 -0800131
132 starting_position_ = charged_up_splines_.value()[0].starting_position();
133 CHECK(starting_position_);
Maxwell Henderson25378832023-04-07 14:37:41 -0700134 } else if (FLAGS_charged_up_cable) {
135 charged_up_cable_splines_ = {
136 PlanSpline(std::bind(&AutonomousSplines::SplineCable1, &auto_splines_,
137 std::placeholders::_1, alliance_),
138 SplineDirection::kBackward),
139 PlanSpline(std::bind(&AutonomousSplines::SplineCable2, &auto_splines_,
140 std::placeholders::_1, alliance_),
141 SplineDirection::kForward),
142 PlanSpline(std::bind(&AutonomousSplines::SplineCable3, &auto_splines_,
143 std::placeholders::_1, alliance_),
144 SplineDirection::kBackward),
145 PlanSpline(std::bind(&AutonomousSplines::SplineCable4, &auto_splines_,
146 std::placeholders::_1, alliance_),
147 SplineDirection::kForward)};
148
149 starting_position_ =
150 charged_up_cable_splines_.value()[0].starting_position();
151 CHECK(starting_position_);
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800152 }
153
154 is_planned_ = true;
155
156 MaybeSendStartingPosition();
157}
158
159void AutonomousActor::MaybeSendStartingPosition() {
160 if (is_planned_ && user_indicated_safe_to_reset_ &&
161 !sent_starting_position_) {
162 CHECK(starting_position_);
163 SendStartingPosition(starting_position_.value());
164 }
165}
Maxwell Hendersonad312342023-01-10 12:07:47 -0800166
167void AutonomousActor::Reset() {
168 InitializeEncoders();
169 ResetDrivetrain();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800170
171 joystick_state_fetcher_.Fetch();
172 CHECK(joystick_state_fetcher_.get() != nullptr)
173 << "Expect at least one JoystickState message before running auto...";
174 alliance_ = joystick_state_fetcher_->alliance();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700175
176 wrist_goal_ = 0.0;
177 roller_goal_ = control_loops::superstructure::RollerGoal::IDLE;
178 arm_goal_position_ = control_loops::superstructure::arm::StartingIndex();
179 preloaded_ = false;
180 SendSuperstructureGoal();
Maxwell Hendersonad312342023-01-10 12:07:47 -0800181}
182
183bool AutonomousActor::RunAction(
184 const ::frc971::autonomous::AutonomousActionParams *params) {
185 Reset();
186
187 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800188
189 if (!user_indicated_safe_to_reset_) {
190 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
191 CHECK(starting_position_);
192 SendStartingPosition(starting_position_.value());
193 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800194 // Clear this so that we don't accidentally resend things as soon as we
195 // replan later.
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800196 user_indicated_safe_to_reset_ = false;
197 is_planned_ = false;
198 starting_position_.reset();
199
200 AOS_LOG(INFO, "Params are %d\n", params->mode());
201 if (alliance_ == aos::Alliance::kInvalid) {
202 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
203 return false;
204 }
205 if (FLAGS_spline_auto) {
206 SplineAuto();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700207 } else if (FLAGS_charged_up) {
208 ChargedUp();
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700209 } else if (FLAGS_charged_up_cable) {
210 ChargedUpCableSide();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800211 } else {
212 AOS_LOG(WARNING, "No auto mode selected.");
213 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800214 return true;
215}
216
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800217void AutonomousActor::SplineAuto() {
218 CHECK(test_spline_);
219
220 if (!test_spline_->WaitForPlan()) return;
221 test_spline_->Start();
222
223 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
224}
225
226void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
227 // Set up the starting position for the blue alliance.
228
229 auto builder = localizer_control_sender_.MakeBuilder();
230
231 LocalizerControl::Builder localizer_control_builder =
232 builder.MakeBuilder<LocalizerControl>();
233 localizer_control_builder.add_x(start(0));
234 localizer_control_builder.add_y(start(1));
235 localizer_control_builder.add_theta(start(2));
236 localizer_control_builder.add_theta_uncertainty(0.00001);
237 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
238 start(1), start(2));
239 if (builder.Send(localizer_control_builder.Finish()) !=
240 aos::RawSender::Error::kOk) {
241 AOS_LOG(ERROR, "Failed to reset localizer.\n");
242 }
243}
244
Maxwell Henderson25378832023-04-07 14:37:41 -0700245// Charged Up 3 Game Object Autonomous (non-cable side)
Maxwell Henderson64f37452023-03-11 13:39:21 -0800246void AutonomousActor::ChargedUp() {
247 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
248
249 CHECK(charged_up_splines_);
250
251 auto &splines = *charged_up_splines_;
252
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700253 AOS_LOG(INFO, "Going to preload");
254
Maxwell Henderson64f37452023-03-11 13:39:21 -0800255 // Tell the superstructure a cone was preloaded
256 if (!WaitForPreloaded()) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700257 AOS_LOG(INFO, "Moving arm");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800258
259 // Place first cone on mid level
260 MidConeScore();
261
262 // Wait until the arm is at the goal to spit
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700263 if (!WaitForArmGoal(0.10)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800264 Spit();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700265 if (!WaitForArmGoal(0.01)) return;
266
267 std::this_thread::sleep_for(chrono::milliseconds(100));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800268
269 AOS_LOG(
270 INFO, "Placed first cone %lf s\n",
271 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
272
273 // Drive and intake the cube nearest to the starting zone
274 if (!splines[0].WaitForPlan()) return;
275 splines[0].Start();
276
277 // Move arm into position to pickup a cube and start cube intake
278 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700279
280 std::this_thread::sleep_for(chrono::milliseconds(500));
281
Maxwell Henderson64f37452023-03-11 13:39:21 -0800282 IntakeCube();
283
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700284 AOS_LOG(
285 INFO, "Turning on rollers %lf s\n",
286 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
287
Maxwell Henderson64f37452023-03-11 13:39:21 -0800288 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
289
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700290 AOS_LOG(
291 INFO, "Got there %lf s\n",
292 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
293
Maxwell Henderson64f37452023-03-11 13:39:21 -0800294 // Drive back to grid and place cube on high level
295 if (!splines[1].WaitForPlan()) return;
296 splines[1].Start();
297
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700298 std::this_thread::sleep_for(chrono::milliseconds(300));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800299 HighCubeScore();
300
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700301 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
302 AOS_LOG(
303 INFO, "Back for first cube %lf s\n",
304 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800305
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700306 if (!WaitForArmGoal(0.10)) return;
307
308 AOS_LOG(
309 INFO, "Arm in place for first cube %lf s\n",
310 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
311
Maxwell Henderson64f37452023-03-11 13:39:21 -0800312 Spit();
313
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700314 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
315
316 AOS_LOG(
317 INFO, "Finished spline back %lf s\n",
318 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
319
320 if (!WaitForArmGoal(0.05)) return;
321
Maxwell Henderson64f37452023-03-11 13:39:21 -0800322 AOS_LOG(
323 INFO, "Placed first cube %lf s\n",
324 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
325
326 // Drive and intake the cube second nearest to the starting zone
327 if (!splines[2].WaitForPlan()) return;
328 splines[2].Start();
329
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700330 std::this_thread::sleep_for(chrono::milliseconds(200));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800331 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700332
333 std::this_thread::sleep_for(chrono::milliseconds(500));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800334 IntakeCube();
335
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700336 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
337 AOS_LOG(
338 INFO, "Picked up second cube %lf s\n",
339 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800340
341 // Drive back to grid and place object on mid level
342 if (!splines[3].WaitForPlan()) return;
343 splines[3].Start();
344
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700345 AOS_LOG(
346 INFO, "Driving back %lf s\n",
347 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
348
Maxwell Henderson64f37452023-03-11 13:39:21 -0800349 MidCubeScore();
350
Austin Schuh700bfff2023-04-05 19:45:55 -0700351 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700352 AOS_LOG(
353 INFO, "Got back from second cube at %lf s\n",
354 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800355
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700356 if (!WaitForArmGoal(0.05)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800357 Spit();
358
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700359 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
360
Maxwell Henderson64f37452023-03-11 13:39:21 -0800361 AOS_LOG(
362 INFO, "Placed second cube %lf s\n",
363 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700364 InitializeEncoders();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800365
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700366 const ProfileParametersT kDrive = MakeProfileParameters(2.0, 4.0);
367 const ProfileParametersT kTurn = MakeProfileParameters(3.0, 4.5);
368 StartDrive(0.0, 0.0, kDrive, kTurn);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800369
Austin Schuh700bfff2023-04-05 19:45:55 -0700370 std::this_thread::sleep_for(chrono::milliseconds(100));
371
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700372 {
373 double side_scalar = (alliance_ == aos::Alliance::kRed) ? 1.0 : -1.0;
374 StartDrive(6.33 - std::abs(X()), 0.0, kDrive, kTurn);
375 if (!WaitForDriveProfileNear(0.01)) return;
376
377 AOS_LOG(
378 INFO, "Done backing up %lf s\n",
379 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
380
Austin Schuh700bfff2023-04-05 19:45:55 -0700381 const ProfileParametersT kInPlaceTurn = MakeProfileParameters(2.5, 7.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700382 StartDrive(0.0, aos::math::NormalizeAngle(M_PI / 2.0 - Theta()), kDrive,
383 kInPlaceTurn);
384
385 std::this_thread::sleep_for(chrono::milliseconds(400));
386 StopSpitting();
387
388 AOS_LOG(
389 INFO, "Roller off %lf s\n",
390 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
391
Austin Schuh700bfff2023-04-05 19:45:55 -0700392 if (!WaitForTurnProfileNear(0.6)) return;
393 AOS_LOG(
394 INFO, "Balance arm %lf s\n",
395 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
396
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700397 Balance();
Austin Schuh700bfff2023-04-05 19:45:55 -0700398 if (!WaitForTurnProfileNear(0.001)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700399
400 AOS_LOG(
401 INFO, "Done turning %lf s\n",
402 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
403
404 const ProfileParametersT kDrive = MakeProfileParameters(1.4, 3.0);
405 const ProfileParametersT kFinalTurn = MakeProfileParameters(3.0, 4.5);
Austin Schuh700bfff2023-04-05 19:45:55 -0700406 const double kDriveDistance = 3.11;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700407 StartDrive(-kDriveDistance, 0.0, kDrive, kFinalTurn);
408
409 const ProfileParametersT kFastTurn = MakeProfileParameters(5.0, 8.0);
410 if (!WaitForDriveProfileNear(kDriveDistance - 0.4)) return;
411
412 AOS_LOG(
413 INFO, "Turning %lf s\n",
414 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
415 StartDrive(0.0, -side_scalar * M_PI / 2.0, kDrive, kFastTurn);
416 if (!WaitForDriveProfileDone()) return;
417 if (!WaitForTurnProfileDone()) return;
418 AOS_LOG(
419 INFO, "Done %lf s\n",
420 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
421 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800422}
423
Maxwell Henderson25378832023-04-07 14:37:41 -0700424// Charged Up 3 Game Object Autonomous (cable side)
425void AutonomousActor::ChargedUpCableSide() {
426 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
427
428 CHECK(charged_up_cable_splines_);
429
430 auto &splines = *charged_up_cable_splines_;
431
432 AOS_LOG(INFO, "Going to preload");
433
434 // Tell the superstructure a cone was preloaded
435 if (!WaitForPreloaded()) return;
436 AOS_LOG(INFO, "Moving arm");
437
438 // Place first cone on mid level
439 MidConeScore();
440
441 // Wait until the arm is at the goal to spit
442 if (!WaitForArmGoal(0.10)) return;
443 Spit();
444 if (!WaitForArmGoal(0.01)) return;
445
446 std::this_thread::sleep_for(chrono::milliseconds(100));
447
448 AOS_LOG(
449 INFO, "Placed first cone %lf s\n",
450 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
451
452 // Drive and intake the cube nearest to the starting zone
453 if (!splines[0].WaitForPlan()) return;
454 splines[0].Start();
455
456 // Move arm into position to pickup a cube and start cube intake
457 PickupCube();
458
459 std::this_thread::sleep_for(chrono::milliseconds(500));
460
461 IntakeCube();
462
463 AOS_LOG(
464 INFO, "Turning on rollers %lf s\n",
465 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
466
467 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
468
469 AOS_LOG(
470 INFO, "Got there %lf s\n",
471 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
472
473 // Drive back to grid and place cube on high level
474 if (!splines[1].WaitForPlan()) return;
475 splines[1].Start();
476
477 std::this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhdd128822023-04-09 22:19:06 -0700478 Neutral();
479
480 if (!splines[1].WaitForSplineDistanceTraveled(3.2)) return;
Maxwell Henderson25378832023-04-07 14:37:41 -0700481 HighCubeScore();
Austin Schuhdd128822023-04-09 22:19:06 -0700482 AOS_LOG(
483 INFO, "Extending arm %lf s\n",
484 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700485
486 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
487 AOS_LOG(
488 INFO, "Back for first cube %lf s\n",
489 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
490
491 if (!WaitForArmGoal(0.10)) return;
492
493 AOS_LOG(
494 INFO, "Arm in place for first cube %lf s\n",
495 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
496
497 Spit();
498
499 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
500
501 AOS_LOG(
502 INFO, "Finished spline back %lf s\n",
503 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
504
505 if (!WaitForArmGoal(0.05)) return;
506
507 AOS_LOG(
508 INFO, "Placed first cube %lf s\n",
509 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
510
511 // Drive and intake the cube second nearest to the starting zone
512 if (!splines[2].WaitForPlan()) return;
513 splines[2].Start();
514
515 std::this_thread::sleep_for(chrono::milliseconds(200));
516 PickupCube();
517
518 std::this_thread::sleep_for(chrono::milliseconds(500));
519 IntakeCube();
520
521 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
522 AOS_LOG(
523 INFO, "Picked up second cube %lf s\n",
524 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
525
526 // Drive back to grid and place object on mid level
527 if (!splines[3].WaitForPlan()) return;
528 splines[3].Start();
529
Austin Schuhdd128822023-04-09 22:19:06 -0700530 std::this_thread::sleep_for(chrono::milliseconds(400));
531 Neutral();
532
Maxwell Henderson25378832023-04-07 14:37:41 -0700533 AOS_LOG(
534 INFO, "Driving back %lf s\n",
535 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
536
Austin Schuhdd128822023-04-09 22:19:06 -0700537 if (!splines[3].WaitForSplineDistanceTraveled(3.5)) return;
538 AOS_LOG(
539 INFO, "Extending arm %lf s\n",
540 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700541 MidCubeScore();
542
543 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
544 AOS_LOG(
545 INFO, "Got back from second cube at %lf s\n",
546 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
547
548 if (!WaitForArmGoal(0.05)) return;
549 Spit();
550
551 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
552
553 AOS_LOG(
554 INFO, "Placed second cube %lf s\n",
555 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700556
557 std::this_thread::sleep_for(chrono::milliseconds(200));
558 Neutral();
Maxwell Henderson25378832023-04-07 14:37:41 -0700559}
560
Maxwell Henderson64f37452023-03-11 13:39:21 -0800561void AutonomousActor::SendSuperstructureGoal() {
562 auto builder = superstructure_goal_sender_.MakeBuilder();
563
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700564 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
565 wrist_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
566 *builder.fbb(), wrist_goal_,
567 CreateProfileParameters(*builder.fbb(), 12.0, 90.0));
568
Maxwell Henderson64f37452023-03-11 13:39:21 -0800569 control_loops::superstructure::Goal::Builder superstructure_builder =
570 builder.MakeBuilder<control_loops::superstructure::Goal>();
571
572 superstructure_builder.add_arm_goal_position(arm_goal_position_);
573 superstructure_builder.add_preloaded_with_cone(preloaded_);
574 superstructure_builder.add_roller_goal(roller_goal_);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700575 superstructure_builder.add_wrist(wrist_offset);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800576
577 if (builder.Send(superstructure_builder.Finish()) !=
578 aos::RawSender::Error::kOk) {
579 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
580 }
581}
582
583[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
584 set_preloaded(true);
585 SendSuperstructureGoal();
586
587 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
588 event_loop()->monotonic_now(),
589 ActorBase::kLoopOffset);
590
591 bool loaded = false;
592 while (!loaded) {
593 if (ShouldCancel()) {
594 return false;
595 }
596
597 phased_loop.SleepUntilNext();
598 superstructure_status_fetcher_.Fetch();
599 CHECK(superstructure_status_fetcher_.get() != nullptr);
600
601 loaded = (superstructure_status_fetcher_->end_effector_state() ==
602 control_loops::superstructure::EndEffectorState::LOADED);
603 }
604
605 set_preloaded(false);
606 SendSuperstructureGoal();
607
608 return true;
609}
610
611void AutonomousActor::MidConeScore() {
612 set_arm_goal_position(
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700613 control_loops::superstructure::arm::ScoreFrontMidConeUpAutoIndex());
614 set_wrist_goal(0.0);
615 SendSuperstructureGoal();
616}
617
618void AutonomousActor::Neutral() {
619 set_arm_goal_position(control_loops::superstructure::arm::NeutralIndex());
620 set_wrist_goal(0.0);
621 SendSuperstructureGoal();
622}
623
624void AutonomousActor::Balance() {
625 set_arm_goal_position(
Austin Schuh700bfff2023-04-05 19:45:55 -0700626 control_loops::superstructure::arm::ScoreFrontLowCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700627 set_wrist_goal(0.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800628 SendSuperstructureGoal();
629}
630
631void AutonomousActor::HighCubeScore() {
632 set_arm_goal_position(
633 control_loops::superstructure::arm::ScoreFrontHighCubeIndex());
634 set_wrist_goal(0.6);
635 SendSuperstructureGoal();
636}
637
638void AutonomousActor::MidCubeScore() {
639 set_arm_goal_position(
640 control_loops::superstructure::arm::ScoreFrontMidCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700641 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800642 SendSuperstructureGoal();
643}
644
645void AutonomousActor::PickupCube() {
646 set_arm_goal_position(
647 control_loops::superstructure::arm::GroundPickupBackCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700648 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800649 SendSuperstructureGoal();
650}
651
652void AutonomousActor::Spit() {
653 set_roller_goal(control_loops::superstructure::RollerGoal::SPIT);
654 SendSuperstructureGoal();
655}
656
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700657void AutonomousActor::StopSpitting() {
658 set_roller_goal(control_loops::superstructure::RollerGoal::IDLE);
659 SendSuperstructureGoal();
660}
661
Maxwell Henderson64f37452023-03-11 13:39:21 -0800662void AutonomousActor::IntakeCube() {
663 set_roller_goal(control_loops::superstructure::RollerGoal::INTAKE_CUBE);
664 SendSuperstructureGoal();
665}
666
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700667[[nodiscard]] bool AutonomousActor::WaitForArmGoal(double distance_to_go) {
668 constexpr double kEpsTheta = 0.10;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800669
670 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
671 event_loop()->monotonic_now(),
672 ActorBase::kLoopOffset);
673
674 bool at_goal = false;
675 while (!at_goal) {
676 if (ShouldCancel()) {
677 return false;
678 }
679
680 phased_loop.SleepUntilNext();
681 superstructure_status_fetcher_.Fetch();
682 CHECK(superstructure_status_fetcher_.get() != nullptr);
683
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700684 at_goal = (arm_goal_position_ ==
685 superstructure_status_fetcher_->arm()->current_node() &&
686 superstructure_status_fetcher_->arm()->path_distance_to_go() <
687 distance_to_go) &&
Maxwell Henderson64f37452023-03-11 13:39:21 -0800688 (std::abs(wrist_goal_ -
689 superstructure_status_fetcher_->wrist()->position()) <
690 kEpsTheta);
691 }
692
Maxwell Henderson64f37452023-03-11 13:39:21 -0800693 return true;
694}
695
696} // namespace autonomous
Maxwell Hendersonad312342023-01-10 12:07:47 -0800697} // namespace y2023