blob: bedbab704d70e72ceecd3b1fcc08dae20a115dc3 [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]() {
Philipp Schradera6712522023-07-05 20:25:11 -070064 replan_timer_->Schedule(event_loop->monotonic_now());
65 button_poll_->Schedule(event_loop->monotonic_now(),
66 chrono::milliseconds(50));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080067 });
68
69 // TODO(james): Really need to refactor this code since we keep using it.
70 button_poll_ = event_loop->AddTimer([this]() {
71 const aos::monotonic_clock::time_point now =
72 this->event_loop()->context().monotonic_event_time;
73 if (robot_state_fetcher_.Fetch()) {
74 if (robot_state_fetcher_->user_button()) {
75 user_indicated_safe_to_reset_ = true;
76 MaybeSendStartingPosition();
77 }
78 }
79 if (joystick_state_fetcher_.Fetch()) {
80 if (joystick_state_fetcher_->has_alliance() &&
81 (joystick_state_fetcher_->alliance() != alliance_)) {
82 alliance_ = joystick_state_fetcher_->alliance();
83 is_planned_ = false;
Maxwell Henderson64f37452023-03-11 13:39:21 -080084 // Only kick the planning out by 2 seconds. If we end up enabled in
85 // that second, then we will kick it out further based on the code
86 // below.
Philipp Schradera6712522023-07-05 20:25:11 -070087 replan_timer_->Schedule(now + std::chrono::seconds(2));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080088 }
89 if (joystick_state_fetcher_->enabled()) {
90 if (!is_planned_) {
91 // Only replan once we've been disabled for 5 seconds.
Philipp Schradera6712522023-07-05 20:25:11 -070092 replan_timer_->Schedule(now + std::chrono::seconds(5));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080093 }
94 }
95 }
96 });
97}
98
99void AutonomousActor::Replan() {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700100 if (!drivetrain_status_fetcher_.Fetch()) {
Philipp Schradera6712522023-07-05 20:25:11 -0700101 replan_timer_->Schedule(event_loop()->monotonic_now() + chrono::seconds(1));
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700102 AOS_LOG(INFO, "Drivetrain not up, replanning in 1 second");
103 return;
104 }
105
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800106 if (alliance_ == aos::Alliance::kInvalid) {
107 return;
108 }
109 sent_starting_position_ = false;
110 if (FLAGS_spline_auto) {
111 test_spline_ =
112 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
113 std::placeholders::_1, alliance_),
114 SplineDirection::kForward);
115
116 starting_position_ = test_spline_->starting_position();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800117 } else if (FLAGS_charged_up) {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700118 AOS_LOG(INFO, "Charged up replanning!");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800119 charged_up_splines_ = {
120 PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
121 std::placeholders::_1, alliance_),
122 SplineDirection::kBackward),
123 PlanSpline(std::bind(&AutonomousSplines::Spline2, &auto_splines_,
124 std::placeholders::_1, alliance_),
125 SplineDirection::kForward),
126 PlanSpline(std::bind(&AutonomousSplines::Spline3, &auto_splines_,
127 std::placeholders::_1, alliance_),
128 SplineDirection::kBackward),
129 PlanSpline(std::bind(&AutonomousSplines::Spline4, &auto_splines_,
130 std::placeholders::_1, alliance_),
Maxwell Henderson25378832023-04-07 14:37:41 -0700131 SplineDirection::kForward)};
Maxwell Henderson64f37452023-03-11 13:39:21 -0800132
133 starting_position_ = charged_up_splines_.value()[0].starting_position();
134 CHECK(starting_position_);
Maxwell Henderson25378832023-04-07 14:37:41 -0700135 } else if (FLAGS_charged_up_cable) {
136 charged_up_cable_splines_ = {
137 PlanSpline(std::bind(&AutonomousSplines::SplineCable1, &auto_splines_,
138 std::placeholders::_1, alliance_),
139 SplineDirection::kBackward),
140 PlanSpline(std::bind(&AutonomousSplines::SplineCable2, &auto_splines_,
141 std::placeholders::_1, alliance_),
142 SplineDirection::kForward),
143 PlanSpline(std::bind(&AutonomousSplines::SplineCable3, &auto_splines_,
144 std::placeholders::_1, alliance_),
145 SplineDirection::kBackward),
146 PlanSpline(std::bind(&AutonomousSplines::SplineCable4, &auto_splines_,
147 std::placeholders::_1, alliance_),
148 SplineDirection::kForward)};
149
150 starting_position_ =
151 charged_up_cable_splines_.value()[0].starting_position();
152 CHECK(starting_position_);
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800153 }
154
155 is_planned_ = true;
156
157 MaybeSendStartingPosition();
158}
159
160void AutonomousActor::MaybeSendStartingPosition() {
161 if (is_planned_ && user_indicated_safe_to_reset_ &&
162 !sent_starting_position_) {
163 CHECK(starting_position_);
164 SendStartingPosition(starting_position_.value());
165 }
166}
Maxwell Hendersonad312342023-01-10 12:07:47 -0800167
168void AutonomousActor::Reset() {
169 InitializeEncoders();
170 ResetDrivetrain();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800171
172 joystick_state_fetcher_.Fetch();
173 CHECK(joystick_state_fetcher_.get() != nullptr)
174 << "Expect at least one JoystickState message before running auto...";
175 alliance_ = joystick_state_fetcher_->alliance();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700176
177 wrist_goal_ = 0.0;
178 roller_goal_ = control_loops::superstructure::RollerGoal::IDLE;
179 arm_goal_position_ = control_loops::superstructure::arm::StartingIndex();
180 preloaded_ = false;
181 SendSuperstructureGoal();
Maxwell Hendersonad312342023-01-10 12:07:47 -0800182}
183
184bool AutonomousActor::RunAction(
185 const ::frc971::autonomous::AutonomousActionParams *params) {
186 Reset();
187
188 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800189
190 if (!user_indicated_safe_to_reset_) {
191 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
192 CHECK(starting_position_);
193 SendStartingPosition(starting_position_.value());
194 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800195 // Clear this so that we don't accidentally resend things as soon as we
196 // replan later.
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800197 user_indicated_safe_to_reset_ = false;
198 is_planned_ = false;
199 starting_position_.reset();
200
201 AOS_LOG(INFO, "Params are %d\n", params->mode());
202 if (alliance_ == aos::Alliance::kInvalid) {
203 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
204 return false;
205 }
206 if (FLAGS_spline_auto) {
207 SplineAuto();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700208 } else if (FLAGS_charged_up) {
209 ChargedUp();
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700210 } else if (FLAGS_charged_up_cable) {
211 ChargedUpCableSide();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800212 } else {
213 AOS_LOG(WARNING, "No auto mode selected.");
214 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800215 return true;
216}
217
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800218void AutonomousActor::SplineAuto() {
219 CHECK(test_spline_);
220
221 if (!test_spline_->WaitForPlan()) return;
222 test_spline_->Start();
223
224 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
225}
226
227void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
228 // Set up the starting position for the blue alliance.
229
230 auto builder = localizer_control_sender_.MakeBuilder();
231
232 LocalizerControl::Builder localizer_control_builder =
233 builder.MakeBuilder<LocalizerControl>();
234 localizer_control_builder.add_x(start(0));
235 localizer_control_builder.add_y(start(1));
236 localizer_control_builder.add_theta(start(2));
237 localizer_control_builder.add_theta_uncertainty(0.00001);
238 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
239 start(1), start(2));
240 if (builder.Send(localizer_control_builder.Finish()) !=
241 aos::RawSender::Error::kOk) {
242 AOS_LOG(ERROR, "Failed to reset localizer.\n");
243 }
244}
245
Maxwell Henderson25378832023-04-07 14:37:41 -0700246// Charged Up 3 Game Object Autonomous (non-cable side)
Maxwell Henderson64f37452023-03-11 13:39:21 -0800247void AutonomousActor::ChargedUp() {
248 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
249
250 CHECK(charged_up_splines_);
251
252 auto &splines = *charged_up_splines_;
253
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700254 AOS_LOG(INFO, "Going to preload");
255
Maxwell Henderson64f37452023-03-11 13:39:21 -0800256 // Tell the superstructure a cone was preloaded
257 if (!WaitForPreloaded()) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700258 AOS_LOG(INFO, "Moving arm");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800259
260 // Place first cone on mid level
261 MidConeScore();
262
263 // Wait until the arm is at the goal to spit
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700264 if (!WaitForArmGoal(0.10)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800265 Spit();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700266 if (!WaitForArmGoal(0.01)) return;
267
268 std::this_thread::sleep_for(chrono::milliseconds(100));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800269
270 AOS_LOG(
271 INFO, "Placed first cone %lf s\n",
272 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
273
274 // Drive and intake the cube nearest to the starting zone
275 if (!splines[0].WaitForPlan()) return;
276 splines[0].Start();
277
278 // Move arm into position to pickup a cube and start cube intake
279 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700280
281 std::this_thread::sleep_for(chrono::milliseconds(500));
282
Maxwell Henderson64f37452023-03-11 13:39:21 -0800283 IntakeCube();
284
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700285 AOS_LOG(
286 INFO, "Turning on rollers %lf s\n",
287 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
288
Maxwell Henderson64f37452023-03-11 13:39:21 -0800289 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
290
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700291 AOS_LOG(
292 INFO, "Got there %lf s\n",
293 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
294
Maxwell Henderson64f37452023-03-11 13:39:21 -0800295 // Drive back to grid and place cube on high level
296 if (!splines[1].WaitForPlan()) return;
297 splines[1].Start();
298
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700299 std::this_thread::sleep_for(chrono::milliseconds(300));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800300 HighCubeScore();
301
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700302 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
303 AOS_LOG(
304 INFO, "Back for first cube %lf s\n",
305 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800306
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700307 if (!WaitForArmGoal(0.10)) return;
308
309 AOS_LOG(
310 INFO, "Arm in place for first cube %lf s\n",
311 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
312
Maxwell Henderson64f37452023-03-11 13:39:21 -0800313 Spit();
314
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700315 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
316
317 AOS_LOG(
318 INFO, "Finished spline back %lf s\n",
319 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
320
321 if (!WaitForArmGoal(0.05)) return;
322
Austin Schuha7c3bc62023-04-16 19:46:23 -0700323 std::this_thread::sleep_for(chrono::milliseconds(100));
324
Maxwell Henderson64f37452023-03-11 13:39:21 -0800325 AOS_LOG(
326 INFO, "Placed first cube %lf s\n",
327 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
328
329 // Drive and intake the cube second nearest to the starting zone
330 if (!splines[2].WaitForPlan()) return;
331 splines[2].Start();
332
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700333 std::this_thread::sleep_for(chrono::milliseconds(200));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800334 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700335
336 std::this_thread::sleep_for(chrono::milliseconds(500));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800337 IntakeCube();
338
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700339 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
340 AOS_LOG(
341 INFO, "Picked up second cube %lf s\n",
342 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800343
344 // Drive back to grid and place object on mid level
345 if (!splines[3].WaitForPlan()) return;
346 splines[3].Start();
347
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700348 AOS_LOG(
349 INFO, "Driving back %lf s\n",
350 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
351
Maxwell Henderson64f37452023-03-11 13:39:21 -0800352 MidCubeScore();
353
Austin Schuh700bfff2023-04-05 19:45:55 -0700354 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700355 AOS_LOG(
356 INFO, "Got back from second cube at %lf s\n",
357 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800358
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700359 if (!WaitForArmGoal(0.05)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800360 Spit();
361
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700362 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
363
Maxwell Henderson64f37452023-03-11 13:39:21 -0800364 AOS_LOG(
365 INFO, "Placed second cube %lf s\n",
366 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700367 InitializeEncoders();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800368
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700369 const ProfileParametersT kDrive = MakeProfileParameters(2.0, 4.0);
370 const ProfileParametersT kTurn = MakeProfileParameters(3.0, 4.5);
371 StartDrive(0.0, 0.0, kDrive, kTurn);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800372
Austin Schuh700bfff2023-04-05 19:45:55 -0700373 std::this_thread::sleep_for(chrono::milliseconds(100));
374
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700375 {
376 double side_scalar = (alliance_ == aos::Alliance::kRed) ? 1.0 : -1.0;
377 StartDrive(6.33 - std::abs(X()), 0.0, kDrive, kTurn);
378 if (!WaitForDriveProfileNear(0.01)) return;
379
380 AOS_LOG(
381 INFO, "Done backing up %lf s\n",
382 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
383
Austin Schuha7c3bc62023-04-16 19:46:23 -0700384 const ProfileParametersT kInPlaceTurn = MakeProfileParameters(2.7, 8.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700385 StartDrive(0.0, aos::math::NormalizeAngle(M_PI / 2.0 - Theta()), kDrive,
386 kInPlaceTurn);
387
388 std::this_thread::sleep_for(chrono::milliseconds(400));
389 StopSpitting();
390
391 AOS_LOG(
392 INFO, "Roller off %lf s\n",
393 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
394
Austin Schuh700bfff2023-04-05 19:45:55 -0700395 if (!WaitForTurnProfileNear(0.6)) return;
396 AOS_LOG(
397 INFO, "Balance arm %lf s\n",
398 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
399
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700400 Balance();
Austin Schuh700bfff2023-04-05 19:45:55 -0700401 if (!WaitForTurnProfileNear(0.001)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700402
403 AOS_LOG(
404 INFO, "Done turning %lf s\n",
405 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
406
407 const ProfileParametersT kDrive = MakeProfileParameters(1.4, 3.0);
408 const ProfileParametersT kFinalTurn = MakeProfileParameters(3.0, 4.5);
Austin Schuh700bfff2023-04-05 19:45:55 -0700409 const double kDriveDistance = 3.11;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700410 StartDrive(-kDriveDistance, 0.0, kDrive, kFinalTurn);
411
412 const ProfileParametersT kFastTurn = MakeProfileParameters(5.0, 8.0);
413 if (!WaitForDriveProfileNear(kDriveDistance - 0.4)) return;
414
415 AOS_LOG(
416 INFO, "Turning %lf s\n",
417 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
418 StartDrive(0.0, -side_scalar * M_PI / 2.0, kDrive, kFastTurn);
419 if (!WaitForDriveProfileDone()) return;
420 if (!WaitForTurnProfileDone()) return;
421 AOS_LOG(
422 INFO, "Done %lf s\n",
423 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
424 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800425}
426
Maxwell Henderson25378832023-04-07 14:37:41 -0700427// Charged Up 3 Game Object Autonomous (cable side)
428void AutonomousActor::ChargedUpCableSide() {
429 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
430
431 CHECK(charged_up_cable_splines_);
432
433 auto &splines = *charged_up_cable_splines_;
434
435 AOS_LOG(INFO, "Going to preload");
436
437 // Tell the superstructure a cone was preloaded
438 if (!WaitForPreloaded()) return;
439 AOS_LOG(INFO, "Moving arm");
440
441 // Place first cone on mid level
442 MidConeScore();
443
444 // Wait until the arm is at the goal to spit
445 if (!WaitForArmGoal(0.10)) return;
446 Spit();
447 if (!WaitForArmGoal(0.01)) return;
448
449 std::this_thread::sleep_for(chrono::milliseconds(100));
450
451 AOS_LOG(
452 INFO, "Placed first cone %lf s\n",
453 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
454
455 // Drive and intake the cube nearest to the starting zone
456 if (!splines[0].WaitForPlan()) return;
457 splines[0].Start();
458
459 // Move arm into position to pickup a cube and start cube intake
460 PickupCube();
461
462 std::this_thread::sleep_for(chrono::milliseconds(500));
463
464 IntakeCube();
465
466 AOS_LOG(
467 INFO, "Turning on rollers %lf s\n",
468 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
469
470 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
471
472 AOS_LOG(
473 INFO, "Got there %lf s\n",
474 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
475
476 // Drive back to grid and place cube on high level
477 if (!splines[1].WaitForPlan()) return;
478 splines[1].Start();
479
480 std::this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhdd128822023-04-09 22:19:06 -0700481 Neutral();
482
483 if (!splines[1].WaitForSplineDistanceTraveled(3.2)) return;
Maxwell Henderson25378832023-04-07 14:37:41 -0700484 HighCubeScore();
Austin Schuhdd128822023-04-09 22:19:06 -0700485 AOS_LOG(
486 INFO, "Extending arm %lf s\n",
487 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700488
489 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
490 AOS_LOG(
491 INFO, "Back for first cube %lf s\n",
492 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
493
494 if (!WaitForArmGoal(0.10)) return;
495
496 AOS_LOG(
497 INFO, "Arm in place for first cube %lf s\n",
498 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
499
500 Spit();
501
502 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
503
504 AOS_LOG(
505 INFO, "Finished spline back %lf s\n",
506 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
507
508 if (!WaitForArmGoal(0.05)) return;
509
510 AOS_LOG(
511 INFO, "Placed first cube %lf s\n",
512 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
513
514 // Drive and intake the cube second nearest to the starting zone
515 if (!splines[2].WaitForPlan()) return;
516 splines[2].Start();
517
518 std::this_thread::sleep_for(chrono::milliseconds(200));
519 PickupCube();
520
521 std::this_thread::sleep_for(chrono::milliseconds(500));
522 IntakeCube();
523
524 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
525 AOS_LOG(
526 INFO, "Picked up second cube %lf s\n",
527 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
528
529 // Drive back to grid and place object on mid level
530 if (!splines[3].WaitForPlan()) return;
531 splines[3].Start();
532
Austin Schuhdd128822023-04-09 22:19:06 -0700533 std::this_thread::sleep_for(chrono::milliseconds(400));
534 Neutral();
535
Maxwell Henderson25378832023-04-07 14:37:41 -0700536 AOS_LOG(
537 INFO, "Driving back %lf s\n",
538 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
539
Austin Schuhdd128822023-04-09 22:19:06 -0700540 if (!splines[3].WaitForSplineDistanceTraveled(3.5)) return;
541 AOS_LOG(
542 INFO, "Extending arm %lf s\n",
543 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700544 MidCubeScore();
545
546 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
547 AOS_LOG(
548 INFO, "Got back from second cube at %lf s\n",
549 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
550
551 if (!WaitForArmGoal(0.05)) return;
552 Spit();
553
554 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
555
556 AOS_LOG(
557 INFO, "Placed second cube %lf s\n",
558 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700559
560 std::this_thread::sleep_for(chrono::milliseconds(200));
561 Neutral();
Austin Schuha7c3bc62023-04-16 19:46:23 -0700562 AOS_LOG(
563 INFO, "Going to neutral %lf s\n",
564 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
565
566 if (!WaitForArmGoal(0.05)) return;
567 AOS_LOG(
568 INFO, "Done at neutral %lf s\n",
569 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700570}
571
Maxwell Henderson64f37452023-03-11 13:39:21 -0800572void AutonomousActor::SendSuperstructureGoal() {
573 auto builder = superstructure_goal_sender_.MakeBuilder();
574
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700575 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
576 wrist_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
577 *builder.fbb(), wrist_goal_,
578 CreateProfileParameters(*builder.fbb(), 12.0, 90.0));
579
Maxwell Henderson64f37452023-03-11 13:39:21 -0800580 control_loops::superstructure::Goal::Builder superstructure_builder =
581 builder.MakeBuilder<control_loops::superstructure::Goal>();
582
583 superstructure_builder.add_arm_goal_position(arm_goal_position_);
584 superstructure_builder.add_preloaded_with_cone(preloaded_);
585 superstructure_builder.add_roller_goal(roller_goal_);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700586 superstructure_builder.add_wrist(wrist_offset);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800587
588 if (builder.Send(superstructure_builder.Finish()) !=
589 aos::RawSender::Error::kOk) {
590 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
591 }
592}
593
594[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
595 set_preloaded(true);
596 SendSuperstructureGoal();
597
598 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
599 event_loop()->monotonic_now(),
600 ActorBase::kLoopOffset);
601
602 bool loaded = false;
603 while (!loaded) {
604 if (ShouldCancel()) {
605 return false;
606 }
607
608 phased_loop.SleepUntilNext();
609 superstructure_status_fetcher_.Fetch();
610 CHECK(superstructure_status_fetcher_.get() != nullptr);
611
612 loaded = (superstructure_status_fetcher_->end_effector_state() ==
613 control_loops::superstructure::EndEffectorState::LOADED);
614 }
615
616 set_preloaded(false);
617 SendSuperstructureGoal();
618
619 return true;
620}
621
622void AutonomousActor::MidConeScore() {
623 set_arm_goal_position(
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700624 control_loops::superstructure::arm::ScoreFrontMidConeUpAutoIndex());
625 set_wrist_goal(0.0);
626 SendSuperstructureGoal();
627}
628
629void AutonomousActor::Neutral() {
630 set_arm_goal_position(control_loops::superstructure::arm::NeutralIndex());
Austin Schuha7c3bc62023-04-16 19:46:23 -0700631 set_wrist_goal(1.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700632 SendSuperstructureGoal();
633}
634
635void AutonomousActor::Balance() {
636 set_arm_goal_position(
Austin Schuh700bfff2023-04-05 19:45:55 -0700637 control_loops::superstructure::arm::ScoreFrontLowCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700638 set_wrist_goal(0.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800639 SendSuperstructureGoal();
640}
641
642void AutonomousActor::HighCubeScore() {
643 set_arm_goal_position(
644 control_loops::superstructure::arm::ScoreFrontHighCubeIndex());
Austin Schuha7c3bc62023-04-16 19:46:23 -0700645 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800646 SendSuperstructureGoal();
647}
648
649void AutonomousActor::MidCubeScore() {
650 set_arm_goal_position(
651 control_loops::superstructure::arm::ScoreFrontMidCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700652 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800653 SendSuperstructureGoal();
654}
655
656void AutonomousActor::PickupCube() {
657 set_arm_goal_position(
658 control_loops::superstructure::arm::GroundPickupBackCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700659 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800660 SendSuperstructureGoal();
661}
662
663void AutonomousActor::Spit() {
664 set_roller_goal(control_loops::superstructure::RollerGoal::SPIT);
665 SendSuperstructureGoal();
666}
667
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700668void AutonomousActor::StopSpitting() {
669 set_roller_goal(control_loops::superstructure::RollerGoal::IDLE);
670 SendSuperstructureGoal();
671}
672
Maxwell Henderson64f37452023-03-11 13:39:21 -0800673void AutonomousActor::IntakeCube() {
674 set_roller_goal(control_loops::superstructure::RollerGoal::INTAKE_CUBE);
675 SendSuperstructureGoal();
676}
677
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700678[[nodiscard]] bool AutonomousActor::WaitForArmGoal(double distance_to_go) {
679 constexpr double kEpsTheta = 0.10;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800680
681 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
682 event_loop()->monotonic_now(),
683 ActorBase::kLoopOffset);
684
685 bool at_goal = false;
686 while (!at_goal) {
687 if (ShouldCancel()) {
688 return false;
689 }
690
691 phased_loop.SleepUntilNext();
692 superstructure_status_fetcher_.Fetch();
693 CHECK(superstructure_status_fetcher_.get() != nullptr);
694
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700695 at_goal = (arm_goal_position_ ==
696 superstructure_status_fetcher_->arm()->current_node() &&
697 superstructure_status_fetcher_->arm()->path_distance_to_go() <
698 distance_to_go) &&
Maxwell Henderson64f37452023-03-11 13:39:21 -0800699 (std::abs(wrist_goal_ -
700 superstructure_status_fetcher_->wrist()->position()) <
701 kEpsTheta);
702 }
703
Maxwell Henderson64f37452023-03-11 13:39:21 -0800704 return true;
705}
706
707} // namespace autonomous
Maxwell Hendersonad312342023-01-10 12:07:47 -0800708} // namespace y2023