blob: 317ff0cfe26d9a1599ae05513292b25bcdbbc73c [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();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800209 } else {
210 AOS_LOG(WARNING, "No auto mode selected.");
211 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800212 return true;
213}
214
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800215void AutonomousActor::SplineAuto() {
216 CHECK(test_spline_);
217
218 if (!test_spline_->WaitForPlan()) return;
219 test_spline_->Start();
220
221 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
222}
223
224void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
225 // Set up the starting position for the blue alliance.
226
227 auto builder = localizer_control_sender_.MakeBuilder();
228
229 LocalizerControl::Builder localizer_control_builder =
230 builder.MakeBuilder<LocalizerControl>();
231 localizer_control_builder.add_x(start(0));
232 localizer_control_builder.add_y(start(1));
233 localizer_control_builder.add_theta(start(2));
234 localizer_control_builder.add_theta_uncertainty(0.00001);
235 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
236 start(1), start(2));
237 if (builder.Send(localizer_control_builder.Finish()) !=
238 aos::RawSender::Error::kOk) {
239 AOS_LOG(ERROR, "Failed to reset localizer.\n");
240 }
241}
242
Maxwell Henderson25378832023-04-07 14:37:41 -0700243// Charged Up 3 Game Object Autonomous (non-cable side)
Maxwell Henderson64f37452023-03-11 13:39:21 -0800244void AutonomousActor::ChargedUp() {
245 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
246
247 CHECK(charged_up_splines_);
248
249 auto &splines = *charged_up_splines_;
250
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700251 AOS_LOG(INFO, "Going to preload");
252
Maxwell Henderson64f37452023-03-11 13:39:21 -0800253 // Tell the superstructure a cone was preloaded
254 if (!WaitForPreloaded()) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700255 AOS_LOG(INFO, "Moving arm");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800256
257 // Place first cone on mid level
258 MidConeScore();
259
260 // Wait until the arm is at the goal to spit
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700261 if (!WaitForArmGoal(0.10)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800262 Spit();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700263 if (!WaitForArmGoal(0.01)) return;
264
265 std::this_thread::sleep_for(chrono::milliseconds(100));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800266
267 AOS_LOG(
268 INFO, "Placed first cone %lf s\n",
269 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
270
271 // Drive and intake the cube nearest to the starting zone
272 if (!splines[0].WaitForPlan()) return;
273 splines[0].Start();
274
275 // Move arm into position to pickup a cube and start cube intake
276 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700277
278 std::this_thread::sleep_for(chrono::milliseconds(500));
279
Maxwell Henderson64f37452023-03-11 13:39:21 -0800280 IntakeCube();
281
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700282 AOS_LOG(
283 INFO, "Turning on rollers %lf s\n",
284 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
285
Maxwell Henderson64f37452023-03-11 13:39:21 -0800286 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
287
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700288 AOS_LOG(
289 INFO, "Got there %lf s\n",
290 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
291
Maxwell Henderson64f37452023-03-11 13:39:21 -0800292 // Drive back to grid and place cube on high level
293 if (!splines[1].WaitForPlan()) return;
294 splines[1].Start();
295
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700296 std::this_thread::sleep_for(chrono::milliseconds(300));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800297 HighCubeScore();
298
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700299 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
300 AOS_LOG(
301 INFO, "Back for first cube %lf s\n",
302 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800303
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700304 if (!WaitForArmGoal(0.10)) return;
305
306 AOS_LOG(
307 INFO, "Arm in place for first cube %lf s\n",
308 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
309
Maxwell Henderson64f37452023-03-11 13:39:21 -0800310 Spit();
311
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700312 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
313
314 AOS_LOG(
315 INFO, "Finished spline back %lf s\n",
316 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
317
318 if (!WaitForArmGoal(0.05)) return;
319
Maxwell Henderson64f37452023-03-11 13:39:21 -0800320 AOS_LOG(
321 INFO, "Placed first cube %lf s\n",
322 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
323
324 // Drive and intake the cube second nearest to the starting zone
325 if (!splines[2].WaitForPlan()) return;
326 splines[2].Start();
327
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700328 std::this_thread::sleep_for(chrono::milliseconds(200));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800329 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700330
331 std::this_thread::sleep_for(chrono::milliseconds(500));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800332 IntakeCube();
333
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700334 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
335 AOS_LOG(
336 INFO, "Picked up second cube %lf s\n",
337 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800338
339 // Drive back to grid and place object on mid level
340 if (!splines[3].WaitForPlan()) return;
341 splines[3].Start();
342
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700343 AOS_LOG(
344 INFO, "Driving back %lf s\n",
345 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
346
Maxwell Henderson64f37452023-03-11 13:39:21 -0800347 MidCubeScore();
348
Austin Schuh700bfff2023-04-05 19:45:55 -0700349 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700350 AOS_LOG(
351 INFO, "Got back from second cube at %lf s\n",
352 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800353
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700354 if (!WaitForArmGoal(0.05)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800355 Spit();
356
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700357 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
358
Maxwell Henderson64f37452023-03-11 13:39:21 -0800359 AOS_LOG(
360 INFO, "Placed second cube %lf s\n",
361 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700362 InitializeEncoders();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800363
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700364 const ProfileParametersT kDrive = MakeProfileParameters(2.0, 4.0);
365 const ProfileParametersT kTurn = MakeProfileParameters(3.0, 4.5);
366 StartDrive(0.0, 0.0, kDrive, kTurn);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800367
Austin Schuh700bfff2023-04-05 19:45:55 -0700368 std::this_thread::sleep_for(chrono::milliseconds(100));
369
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700370 {
371 double side_scalar = (alliance_ == aos::Alliance::kRed) ? 1.0 : -1.0;
372 StartDrive(6.33 - std::abs(X()), 0.0, kDrive, kTurn);
373 if (!WaitForDriveProfileNear(0.01)) return;
374
375 AOS_LOG(
376 INFO, "Done backing up %lf s\n",
377 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
378
Austin Schuh700bfff2023-04-05 19:45:55 -0700379 const ProfileParametersT kInPlaceTurn = MakeProfileParameters(2.5, 7.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700380 StartDrive(0.0, aos::math::NormalizeAngle(M_PI / 2.0 - Theta()), kDrive,
381 kInPlaceTurn);
382
383 std::this_thread::sleep_for(chrono::milliseconds(400));
384 StopSpitting();
385
386 AOS_LOG(
387 INFO, "Roller off %lf s\n",
388 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
389
Austin Schuh700bfff2023-04-05 19:45:55 -0700390 if (!WaitForTurnProfileNear(0.6)) return;
391 AOS_LOG(
392 INFO, "Balance arm %lf s\n",
393 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
394
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700395 Balance();
Austin Schuh700bfff2023-04-05 19:45:55 -0700396 if (!WaitForTurnProfileNear(0.001)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700397
398 AOS_LOG(
399 INFO, "Done turning %lf s\n",
400 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
401
402 const ProfileParametersT kDrive = MakeProfileParameters(1.4, 3.0);
403 const ProfileParametersT kFinalTurn = MakeProfileParameters(3.0, 4.5);
Austin Schuh700bfff2023-04-05 19:45:55 -0700404 const double kDriveDistance = 3.11;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700405 StartDrive(-kDriveDistance, 0.0, kDrive, kFinalTurn);
406
407 const ProfileParametersT kFastTurn = MakeProfileParameters(5.0, 8.0);
408 if (!WaitForDriveProfileNear(kDriveDistance - 0.4)) return;
409
410 AOS_LOG(
411 INFO, "Turning %lf s\n",
412 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
413 StartDrive(0.0, -side_scalar * M_PI / 2.0, kDrive, kFastTurn);
414 if (!WaitForDriveProfileDone()) return;
415 if (!WaitForTurnProfileDone()) return;
416 AOS_LOG(
417 INFO, "Done %lf s\n",
418 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
419 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800420}
421
Maxwell Henderson25378832023-04-07 14:37:41 -0700422// Charged Up 3 Game Object Autonomous (cable side)
423void AutonomousActor::ChargedUpCableSide() {
424 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
425
426 CHECK(charged_up_cable_splines_);
427
428 auto &splines = *charged_up_cable_splines_;
429
430 AOS_LOG(INFO, "Going to preload");
431
432 // Tell the superstructure a cone was preloaded
433 if (!WaitForPreloaded()) return;
434 AOS_LOG(INFO, "Moving arm");
435
436 // Place first cone on mid level
437 MidConeScore();
438
439 // Wait until the arm is at the goal to spit
440 if (!WaitForArmGoal(0.10)) return;
441 Spit();
442 if (!WaitForArmGoal(0.01)) return;
443
444 std::this_thread::sleep_for(chrono::milliseconds(100));
445
446 AOS_LOG(
447 INFO, "Placed first cone %lf s\n",
448 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
449
450 // Drive and intake the cube nearest to the starting zone
451 if (!splines[0].WaitForPlan()) return;
452 splines[0].Start();
453
454 // Move arm into position to pickup a cube and start cube intake
455 PickupCube();
456
457 std::this_thread::sleep_for(chrono::milliseconds(500));
458
459 IntakeCube();
460
461 AOS_LOG(
462 INFO, "Turning on rollers %lf s\n",
463 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
464
465 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
466
467 AOS_LOG(
468 INFO, "Got there %lf s\n",
469 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
470
471 // Drive back to grid and place cube on high level
472 if (!splines[1].WaitForPlan()) return;
473 splines[1].Start();
474
475 std::this_thread::sleep_for(chrono::milliseconds(300));
476 HighCubeScore();
477
478 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
479 AOS_LOG(
480 INFO, "Back for first cube %lf s\n",
481 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
482
483 if (!WaitForArmGoal(0.10)) return;
484
485 AOS_LOG(
486 INFO, "Arm in place for first cube %lf s\n",
487 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
488
489 Spit();
490
491 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
492
493 AOS_LOG(
494 INFO, "Finished spline back %lf s\n",
495 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
496
497 if (!WaitForArmGoal(0.05)) return;
498
499 AOS_LOG(
500 INFO, "Placed first cube %lf s\n",
501 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
502
503 // Drive and intake the cube second nearest to the starting zone
504 if (!splines[2].WaitForPlan()) return;
505 splines[2].Start();
506
507 std::this_thread::sleep_for(chrono::milliseconds(200));
508 PickupCube();
509
510 std::this_thread::sleep_for(chrono::milliseconds(500));
511 IntakeCube();
512
513 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
514 AOS_LOG(
515 INFO, "Picked up second cube %lf s\n",
516 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
517
518 // Drive back to grid and place object on mid level
519 if (!splines[3].WaitForPlan()) return;
520 splines[3].Start();
521
522 AOS_LOG(
523 INFO, "Driving back %lf s\n",
524 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
525
526 MidCubeScore();
527
528 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
529 AOS_LOG(
530 INFO, "Got back from second cube at %lf s\n",
531 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
532
533 if (!WaitForArmGoal(0.05)) return;
534 Spit();
535
536 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
537
538 AOS_LOG(
539 INFO, "Placed second cube %lf s\n",
540 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
541}
542
Maxwell Henderson64f37452023-03-11 13:39:21 -0800543void AutonomousActor::SendSuperstructureGoal() {
544 auto builder = superstructure_goal_sender_.MakeBuilder();
545
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700546 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
547 wrist_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
548 *builder.fbb(), wrist_goal_,
549 CreateProfileParameters(*builder.fbb(), 12.0, 90.0));
550
Maxwell Henderson64f37452023-03-11 13:39:21 -0800551 control_loops::superstructure::Goal::Builder superstructure_builder =
552 builder.MakeBuilder<control_loops::superstructure::Goal>();
553
554 superstructure_builder.add_arm_goal_position(arm_goal_position_);
555 superstructure_builder.add_preloaded_with_cone(preloaded_);
556 superstructure_builder.add_roller_goal(roller_goal_);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700557 superstructure_builder.add_wrist(wrist_offset);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800558
559 if (builder.Send(superstructure_builder.Finish()) !=
560 aos::RawSender::Error::kOk) {
561 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
562 }
563}
564
565[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
566 set_preloaded(true);
567 SendSuperstructureGoal();
568
569 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
570 event_loop()->monotonic_now(),
571 ActorBase::kLoopOffset);
572
573 bool loaded = false;
574 while (!loaded) {
575 if (ShouldCancel()) {
576 return false;
577 }
578
579 phased_loop.SleepUntilNext();
580 superstructure_status_fetcher_.Fetch();
581 CHECK(superstructure_status_fetcher_.get() != nullptr);
582
583 loaded = (superstructure_status_fetcher_->end_effector_state() ==
584 control_loops::superstructure::EndEffectorState::LOADED);
585 }
586
587 set_preloaded(false);
588 SendSuperstructureGoal();
589
590 return true;
591}
592
593void AutonomousActor::MidConeScore() {
594 set_arm_goal_position(
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700595 control_loops::superstructure::arm::ScoreFrontMidConeUpAutoIndex());
596 set_wrist_goal(0.0);
597 SendSuperstructureGoal();
598}
599
600void AutonomousActor::Neutral() {
601 set_arm_goal_position(control_loops::superstructure::arm::NeutralIndex());
602 set_wrist_goal(0.0);
603 SendSuperstructureGoal();
604}
605
606void AutonomousActor::Balance() {
607 set_arm_goal_position(
Austin Schuh700bfff2023-04-05 19:45:55 -0700608 control_loops::superstructure::arm::ScoreFrontLowCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700609 set_wrist_goal(0.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800610 SendSuperstructureGoal();
611}
612
613void AutonomousActor::HighCubeScore() {
614 set_arm_goal_position(
615 control_loops::superstructure::arm::ScoreFrontHighCubeIndex());
616 set_wrist_goal(0.6);
617 SendSuperstructureGoal();
618}
619
620void AutonomousActor::MidCubeScore() {
621 set_arm_goal_position(
622 control_loops::superstructure::arm::ScoreFrontMidCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700623 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800624 SendSuperstructureGoal();
625}
626
627void AutonomousActor::PickupCube() {
628 set_arm_goal_position(
629 control_loops::superstructure::arm::GroundPickupBackCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700630 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800631 SendSuperstructureGoal();
632}
633
634void AutonomousActor::Spit() {
635 set_roller_goal(control_loops::superstructure::RollerGoal::SPIT);
636 SendSuperstructureGoal();
637}
638
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700639void AutonomousActor::StopSpitting() {
640 set_roller_goal(control_loops::superstructure::RollerGoal::IDLE);
641 SendSuperstructureGoal();
642}
643
Maxwell Henderson64f37452023-03-11 13:39:21 -0800644void AutonomousActor::IntakeCube() {
645 set_roller_goal(control_loops::superstructure::RollerGoal::INTAKE_CUBE);
646 SendSuperstructureGoal();
647}
648
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700649[[nodiscard]] bool AutonomousActor::WaitForArmGoal(double distance_to_go) {
650 constexpr double kEpsTheta = 0.10;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800651
652 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
653 event_loop()->monotonic_now(),
654 ActorBase::kLoopOffset);
655
656 bool at_goal = false;
657 while (!at_goal) {
658 if (ShouldCancel()) {
659 return false;
660 }
661
662 phased_loop.SleepUntilNext();
663 superstructure_status_fetcher_.Fetch();
664 CHECK(superstructure_status_fetcher_.get() != nullptr);
665
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700666 at_goal = (arm_goal_position_ ==
667 superstructure_status_fetcher_->arm()->current_node() &&
668 superstructure_status_fetcher_->arm()->path_distance_to_go() <
669 distance_to_go) &&
Maxwell Henderson64f37452023-03-11 13:39:21 -0800670 (std::abs(wrist_goal_ -
671 superstructure_status_fetcher_->wrist()->position()) <
672 kEpsTheta);
673 }
674
Maxwell Henderson64f37452023-03-11 13:39:21 -0800675 return true;
676}
677
678} // namespace autonomous
Maxwell Hendersonad312342023-01-10 12:07:47 -0800679} // namespace y2023