blob: 8891223917e4d59e2c643342148fff72d6a3d1bc [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 Kuszmaul6fc7ee22023-09-30 10:23:31 -070018DEFINE_bool(do_balance, true, "If true run the balance.");
James Kuszmaul713c5ce2023-03-04 18:23:24 -080019
Maxwell Hendersonad312342023-01-10 12:07:47 -080020namespace y2023 {
Maxwell Henderson64f37452023-03-11 13:39:21 -080021namespace autonomous {
Maxwell Hendersonad312342023-01-10 12:07:47 -080022
Maxwell Hendersonad312342023-01-10 12:07:47 -080023using ::frc971::ProfileParametersT;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070024
25ProfileParametersT MakeProfileParameters(float max_velocity,
26 float max_acceleration) {
27 ProfileParametersT result;
28 result.max_velocity = max_velocity;
29 result.max_acceleration = max_acceleration;
30 return result;
31}
32
33using ::aos::monotonic_clock;
34using frc971::CreateProfileParameters;
35using ::frc971::ProfileParametersT;
36using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
37using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
Maxwell Hendersonad312342023-01-10 12:07:47 -080038using frc971::control_loops::drivetrain::LocalizerControl;
39namespace chrono = ::std::chrono;
40
41AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
42 : frc971::autonomous::BaseAutonomousActor(
James Kuszmaul713c5ce2023-03-04 18:23:24 -080043 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
44 localizer_control_sender_(
45 event_loop->MakeSender<
46 ::frc971::control_loops::drivetrain::LocalizerControl>(
47 "/drivetrain")),
48 joystick_state_fetcher_(
49 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
50 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
Maxwell Henderson64f37452023-03-11 13:39:21 -080051 auto_splines_(),
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070052 arm_goal_position_(control_loops::superstructure::arm::StartingIndex()),
53 superstructure_goal_sender_(
54 event_loop->MakeSender<::y2023::control_loops::superstructure::Goal>(
55 "/superstructure")),
56 superstructure_status_fetcher_(
57 event_loop
58 ->MakeFetcher<::y2023::control_loops::superstructure::Status>(
59 "/superstructure")),
Maxwell Henderson64f37452023-03-11 13:39:21 -080060 points_(control_loops::superstructure::arm::PointList()) {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -070061 drivetrain_status_fetcher_.Fetch();
James Kuszmaul713c5ce2023-03-04 18:23:24 -080062 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
63
64 event_loop->OnRun([this, event_loop]() {
Philipp Schradera6712522023-07-05 20:25:11 -070065 replan_timer_->Schedule(event_loop->monotonic_now());
66 button_poll_->Schedule(event_loop->monotonic_now(),
67 chrono::milliseconds(50));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080068 });
69
70 // TODO(james): Really need to refactor this code since we keep using it.
71 button_poll_ = event_loop->AddTimer([this]() {
72 const aos::monotonic_clock::time_point now =
73 this->event_loop()->context().monotonic_event_time;
74 if (robot_state_fetcher_.Fetch()) {
75 if (robot_state_fetcher_->user_button()) {
76 user_indicated_safe_to_reset_ = true;
77 MaybeSendStartingPosition();
78 }
79 }
80 if (joystick_state_fetcher_.Fetch()) {
81 if (joystick_state_fetcher_->has_alliance() &&
82 (joystick_state_fetcher_->alliance() != alliance_)) {
83 alliance_ = joystick_state_fetcher_->alliance();
84 is_planned_ = false;
Maxwell Henderson64f37452023-03-11 13:39:21 -080085 // Only kick the planning out by 2 seconds. If we end up enabled in
86 // that second, then we will kick it out further based on the code
87 // below.
Philipp Schradera6712522023-07-05 20:25:11 -070088 replan_timer_->Schedule(now + std::chrono::seconds(2));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080089 }
90 if (joystick_state_fetcher_->enabled()) {
91 if (!is_planned_) {
92 // Only replan once we've been disabled for 5 seconds.
Philipp Schradera6712522023-07-05 20:25:11 -070093 replan_timer_->Schedule(now + std::chrono::seconds(5));
James Kuszmaul713c5ce2023-03-04 18:23:24 -080094 }
95 }
96 }
97 });
98}
99
100void AutonomousActor::Replan() {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700101 if (!drivetrain_status_fetcher_.Fetch()) {
Philipp Schradera6712522023-07-05 20:25:11 -0700102 replan_timer_->Schedule(event_loop()->monotonic_now() + chrono::seconds(1));
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700103 AOS_LOG(INFO, "Drivetrain not up, replanning in 1 second");
104 return;
105 }
106
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800107 if (alliance_ == aos::Alliance::kInvalid) {
108 return;
109 }
110 sent_starting_position_ = false;
111 if (FLAGS_spline_auto) {
112 test_spline_ =
113 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
114 std::placeholders::_1, alliance_),
115 SplineDirection::kForward);
116
117 starting_position_ = test_spline_->starting_position();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800118 } else if (FLAGS_charged_up) {
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700119 AOS_LOG(INFO, "Charged up replanning!");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800120 charged_up_splines_ = {
121 PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
122 std::placeholders::_1, alliance_),
123 SplineDirection::kBackward),
124 PlanSpline(std::bind(&AutonomousSplines::Spline2, &auto_splines_,
125 std::placeholders::_1, alliance_),
126 SplineDirection::kForward),
127 PlanSpline(std::bind(&AutonomousSplines::Spline3, &auto_splines_,
128 std::placeholders::_1, alliance_),
129 SplineDirection::kBackward),
130 PlanSpline(std::bind(&AutonomousSplines::Spline4, &auto_splines_,
131 std::placeholders::_1, alliance_),
Maxwell Henderson25378832023-04-07 14:37:41 -0700132 SplineDirection::kForward)};
Maxwell Henderson64f37452023-03-11 13:39:21 -0800133
134 starting_position_ = charged_up_splines_.value()[0].starting_position();
135 CHECK(starting_position_);
Maxwell Henderson25378832023-04-07 14:37:41 -0700136 } else if (FLAGS_charged_up_cable) {
137 charged_up_cable_splines_ = {
138 PlanSpline(std::bind(&AutonomousSplines::SplineCable1, &auto_splines_,
139 std::placeholders::_1, alliance_),
140 SplineDirection::kBackward),
141 PlanSpline(std::bind(&AutonomousSplines::SplineCable2, &auto_splines_,
142 std::placeholders::_1, alliance_),
143 SplineDirection::kForward),
144 PlanSpline(std::bind(&AutonomousSplines::SplineCable3, &auto_splines_,
145 std::placeholders::_1, alliance_),
146 SplineDirection::kBackward),
147 PlanSpline(std::bind(&AutonomousSplines::SplineCable4, &auto_splines_,
148 std::placeholders::_1, alliance_),
149 SplineDirection::kForward)};
150
151 starting_position_ =
152 charged_up_cable_splines_.value()[0].starting_position();
153 CHECK(starting_position_);
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800154 }
155
156 is_planned_ = true;
157
158 MaybeSendStartingPosition();
159}
160
161void AutonomousActor::MaybeSendStartingPosition() {
162 if (is_planned_ && user_indicated_safe_to_reset_ &&
163 !sent_starting_position_) {
164 CHECK(starting_position_);
165 SendStartingPosition(starting_position_.value());
166 }
167}
Maxwell Hendersonad312342023-01-10 12:07:47 -0800168
169void AutonomousActor::Reset() {
170 InitializeEncoders();
171 ResetDrivetrain();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800172
173 joystick_state_fetcher_.Fetch();
174 CHECK(joystick_state_fetcher_.get() != nullptr)
175 << "Expect at least one JoystickState message before running auto...";
176 alliance_ = joystick_state_fetcher_->alliance();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700177
178 wrist_goal_ = 0.0;
179 roller_goal_ = control_loops::superstructure::RollerGoal::IDLE;
180 arm_goal_position_ = control_loops::superstructure::arm::StartingIndex();
181 preloaded_ = false;
182 SendSuperstructureGoal();
Maxwell Hendersonad312342023-01-10 12:07:47 -0800183}
184
185bool AutonomousActor::RunAction(
186 const ::frc971::autonomous::AutonomousActionParams *params) {
187 Reset();
188
189 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800190
191 if (!user_indicated_safe_to_reset_) {
192 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
193 CHECK(starting_position_);
194 SendStartingPosition(starting_position_.value());
195 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800196 // Clear this so that we don't accidentally resend things as soon as we
197 // replan later.
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800198 user_indicated_safe_to_reset_ = false;
199 is_planned_ = false;
200 starting_position_.reset();
201
202 AOS_LOG(INFO, "Params are %d\n", params->mode());
203 if (alliance_ == aos::Alliance::kInvalid) {
204 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
205 return false;
206 }
207 if (FLAGS_spline_auto) {
208 SplineAuto();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700209 } else if (FLAGS_charged_up) {
210 ChargedUp();
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700211 } else if (FLAGS_charged_up_cable) {
212 ChargedUpCableSide();
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800213 } else {
214 AOS_LOG(WARNING, "No auto mode selected.");
215 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800216 return true;
217}
218
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800219void AutonomousActor::SplineAuto() {
220 CHECK(test_spline_);
221
222 if (!test_spline_->WaitForPlan()) return;
223 test_spline_->Start();
224
225 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
226}
227
228void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
229 // Set up the starting position for the blue alliance.
230
231 auto builder = localizer_control_sender_.MakeBuilder();
232
233 LocalizerControl::Builder localizer_control_builder =
234 builder.MakeBuilder<LocalizerControl>();
235 localizer_control_builder.add_x(start(0));
236 localizer_control_builder.add_y(start(1));
237 localizer_control_builder.add_theta(start(2));
238 localizer_control_builder.add_theta_uncertainty(0.00001);
239 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
240 start(1), start(2));
241 if (builder.Send(localizer_control_builder.Finish()) !=
242 aos::RawSender::Error::kOk) {
243 AOS_LOG(ERROR, "Failed to reset localizer.\n");
244 }
245}
246
Maxwell Henderson25378832023-04-07 14:37:41 -0700247// Charged Up 3 Game Object Autonomous (non-cable side)
Maxwell Henderson64f37452023-03-11 13:39:21 -0800248void AutonomousActor::ChargedUp() {
249 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
250
251 CHECK(charged_up_splines_);
252
253 auto &splines = *charged_up_splines_;
254
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700255 AOS_LOG(INFO, "Going to preload");
256
Maxwell Henderson64f37452023-03-11 13:39:21 -0800257 // Tell the superstructure a cone was preloaded
258 if (!WaitForPreloaded()) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700259 AOS_LOG(INFO, "Moving arm");
Maxwell Henderson64f37452023-03-11 13:39:21 -0800260
261 // Place first cone on mid level
262 MidConeScore();
263
264 // Wait until the arm is at the goal to spit
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700265 if (!WaitForArmGoal(0.10)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800266 Spit();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700267 if (!WaitForArmGoal(0.01)) return;
268
269 std::this_thread::sleep_for(chrono::milliseconds(100));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800270
271 AOS_LOG(
272 INFO, "Placed first cone %lf s\n",
273 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
274
275 // Drive and intake the cube nearest to the starting zone
276 if (!splines[0].WaitForPlan()) return;
277 splines[0].Start();
278
279 // Move arm into position to pickup a cube and start cube intake
280 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700281
282 std::this_thread::sleep_for(chrono::milliseconds(500));
283
Maxwell Henderson64f37452023-03-11 13:39:21 -0800284 IntakeCube();
285
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700286 AOS_LOG(
287 INFO, "Turning on rollers %lf s\n",
288 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
289
Maxwell Henderson64f37452023-03-11 13:39:21 -0800290 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
291
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700292 AOS_LOG(
293 INFO, "Got there %lf s\n",
294 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
295
Maxwell Henderson64f37452023-03-11 13:39:21 -0800296 // Drive back to grid and place cube on high level
297 if (!splines[1].WaitForPlan()) return;
298 splines[1].Start();
299
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700300 std::this_thread::sleep_for(chrono::milliseconds(300));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800301 HighCubeScore();
302
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700303 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
304 AOS_LOG(
305 INFO, "Back for first cube %lf s\n",
306 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800307
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700308 if (!WaitForArmGoal(0.10)) return;
309
310 AOS_LOG(
311 INFO, "Arm in place for first cube %lf s\n",
312 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
313
Maxwell Henderson64f37452023-03-11 13:39:21 -0800314 Spit();
315
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700316 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
317
318 AOS_LOG(
319 INFO, "Finished spline back %lf s\n",
320 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
321
322 if (!WaitForArmGoal(0.05)) return;
323
Austin Schuha7c3bc62023-04-16 19:46:23 -0700324 std::this_thread::sleep_for(chrono::milliseconds(100));
325
Maxwell Henderson64f37452023-03-11 13:39:21 -0800326 AOS_LOG(
327 INFO, "Placed first cube %lf s\n",
328 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
329
330 // Drive and intake the cube second nearest to the starting zone
331 if (!splines[2].WaitForPlan()) return;
332 splines[2].Start();
333
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700334 std::this_thread::sleep_for(chrono::milliseconds(200));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800335 PickupCube();
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700336
337 std::this_thread::sleep_for(chrono::milliseconds(500));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800338 IntakeCube();
339
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700340 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
341 AOS_LOG(
342 INFO, "Picked up second cube %lf s\n",
343 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800344
345 // Drive back to grid and place object on mid level
346 if (!splines[3].WaitForPlan()) return;
347 splines[3].Start();
348
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700349 AOS_LOG(
350 INFO, "Driving back %lf s\n",
351 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
352
Maxwell Henderson64f37452023-03-11 13:39:21 -0800353 MidCubeScore();
354
Austin Schuh700bfff2023-04-05 19:45:55 -0700355 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700356 AOS_LOG(
357 INFO, "Got back from second cube at %lf s\n",
358 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson64f37452023-03-11 13:39:21 -0800359
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700360 if (!WaitForArmGoal(0.05)) return;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800361 Spit();
362
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700363 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
364
Maxwell Henderson64f37452023-03-11 13:39:21 -0800365 AOS_LOG(
366 INFO, "Placed second cube %lf s\n",
367 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
James Kuszmaul6fc7ee22023-09-30 10:23:31 -0700368
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700369 InitializeEncoders();
Maxwell Henderson64f37452023-03-11 13:39:21 -0800370
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700371 const ProfileParametersT kDrive = MakeProfileParameters(2.0, 4.0);
372 const ProfileParametersT kTurn = MakeProfileParameters(3.0, 4.5);
373 StartDrive(0.0, 0.0, kDrive, kTurn);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800374
Austin Schuh700bfff2023-04-05 19:45:55 -0700375 std::this_thread::sleep_for(chrono::milliseconds(100));
376
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700377 {
378 double side_scalar = (alliance_ == aos::Alliance::kRed) ? 1.0 : -1.0;
379 StartDrive(6.33 - std::abs(X()), 0.0, kDrive, kTurn);
380 if (!WaitForDriveProfileNear(0.01)) return;
381
382 AOS_LOG(
383 INFO, "Done backing up %lf s\n",
384 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
385
James Kuszmaul6fc7ee22023-09-30 10:23:31 -0700386 if (!FLAGS_do_balance) {
387 StopSpitting();
388 return;
389 }
390
Austin Schuha7c3bc62023-04-16 19:46:23 -0700391 const ProfileParametersT kInPlaceTurn = MakeProfileParameters(2.7, 8.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700392 StartDrive(0.0, aos::math::NormalizeAngle(M_PI / 2.0 - Theta()), kDrive,
393 kInPlaceTurn);
394
395 std::this_thread::sleep_for(chrono::milliseconds(400));
396 StopSpitting();
397
398 AOS_LOG(
399 INFO, "Roller off %lf s\n",
400 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
401
Austin Schuh700bfff2023-04-05 19:45:55 -0700402 if (!WaitForTurnProfileNear(0.6)) return;
403 AOS_LOG(
404 INFO, "Balance arm %lf s\n",
405 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
406
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700407 Balance();
Austin Schuh700bfff2023-04-05 19:45:55 -0700408 if (!WaitForTurnProfileNear(0.001)) return;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700409
410 AOS_LOG(
411 INFO, "Done turning %lf s\n",
412 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
413
414 const ProfileParametersT kDrive = MakeProfileParameters(1.4, 3.0);
415 const ProfileParametersT kFinalTurn = MakeProfileParameters(3.0, 4.5);
Austin Schuh700bfff2023-04-05 19:45:55 -0700416 const double kDriveDistance = 3.11;
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700417 StartDrive(-kDriveDistance, 0.0, kDrive, kFinalTurn);
418
419 const ProfileParametersT kFastTurn = MakeProfileParameters(5.0, 8.0);
420 if (!WaitForDriveProfileNear(kDriveDistance - 0.4)) return;
421
422 AOS_LOG(
423 INFO, "Turning %lf s\n",
424 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
425 StartDrive(0.0, -side_scalar * M_PI / 2.0, kDrive, kFastTurn);
426 if (!WaitForDriveProfileDone()) return;
427 if (!WaitForTurnProfileDone()) return;
428 AOS_LOG(
429 INFO, "Done %lf s\n",
430 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
431 }
Maxwell Henderson64f37452023-03-11 13:39:21 -0800432}
433
Maxwell Henderson25378832023-04-07 14:37:41 -0700434// Charged Up 3 Game Object Autonomous (cable side)
435void AutonomousActor::ChargedUpCableSide() {
436 aos::monotonic_clock::time_point start_time = aos::monotonic_clock::now();
437
438 CHECK(charged_up_cable_splines_);
439
440 auto &splines = *charged_up_cable_splines_;
441
442 AOS_LOG(INFO, "Going to preload");
443
444 // Tell the superstructure a cone was preloaded
445 if (!WaitForPreloaded()) return;
446 AOS_LOG(INFO, "Moving arm");
447
448 // Place first cone on mid level
449 MidConeScore();
450
451 // Wait until the arm is at the goal to spit
452 if (!WaitForArmGoal(0.10)) return;
453 Spit();
454 if (!WaitForArmGoal(0.01)) return;
455
456 std::this_thread::sleep_for(chrono::milliseconds(100));
457
458 AOS_LOG(
459 INFO, "Placed first cone %lf s\n",
460 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
461
462 // Drive and intake the cube nearest to the starting zone
463 if (!splines[0].WaitForPlan()) return;
464 splines[0].Start();
465
466 // Move arm into position to pickup a cube and start cube intake
467 PickupCube();
468
469 std::this_thread::sleep_for(chrono::milliseconds(500));
470
471 IntakeCube();
472
473 AOS_LOG(
474 INFO, "Turning on rollers %lf s\n",
475 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
476
477 if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
478
479 AOS_LOG(
480 INFO, "Got there %lf s\n",
481 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
482
483 // Drive back to grid and place cube on high level
484 if (!splines[1].WaitForPlan()) return;
485 splines[1].Start();
486
487 std::this_thread::sleep_for(chrono::milliseconds(300));
Austin Schuhdd128822023-04-09 22:19:06 -0700488 Neutral();
489
490 if (!splines[1].WaitForSplineDistanceTraveled(3.2)) return;
Maxwell Henderson25378832023-04-07 14:37:41 -0700491 HighCubeScore();
Austin Schuhdd128822023-04-09 22:19:06 -0700492 AOS_LOG(
493 INFO, "Extending arm %lf s\n",
494 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700495
496 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
497 AOS_LOG(
498 INFO, "Back for first cube %lf s\n",
499 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
500
501 if (!WaitForArmGoal(0.10)) return;
502
503 AOS_LOG(
504 INFO, "Arm in place for first cube %lf s\n",
505 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
506
507 Spit();
508
509 if (!splines[1].WaitForSplineDistanceRemaining(0.08)) return;
510
511 AOS_LOG(
512 INFO, "Finished spline back %lf s\n",
513 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
514
515 if (!WaitForArmGoal(0.05)) return;
516
517 AOS_LOG(
518 INFO, "Placed first cube %lf s\n",
519 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
520
521 // Drive and intake the cube second nearest to the starting zone
522 if (!splines[2].WaitForPlan()) return;
523 splines[2].Start();
524
525 std::this_thread::sleep_for(chrono::milliseconds(200));
526 PickupCube();
527
528 std::this_thread::sleep_for(chrono::milliseconds(500));
529 IntakeCube();
530
531 if (!splines[2].WaitForSplineDistanceRemaining(0.05)) return;
532 AOS_LOG(
533 INFO, "Picked up second cube %lf s\n",
534 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
535
536 // Drive back to grid and place object on mid level
537 if (!splines[3].WaitForPlan()) return;
538 splines[3].Start();
539
Austin Schuhdd128822023-04-09 22:19:06 -0700540 std::this_thread::sleep_for(chrono::milliseconds(400));
541 Neutral();
542
Maxwell Henderson25378832023-04-07 14:37:41 -0700543 AOS_LOG(
544 INFO, "Driving back %lf s\n",
545 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
546
Austin Schuhdd128822023-04-09 22:19:06 -0700547 if (!splines[3].WaitForSplineDistanceTraveled(3.5)) return;
548 AOS_LOG(
549 INFO, "Extending arm %lf s\n",
550 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700551 MidCubeScore();
552
553 if (!splines[3].WaitForSplineDistanceRemaining(0.07)) return;
554 AOS_LOG(
555 INFO, "Got back from second cube at %lf s\n",
556 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
557
558 if (!WaitForArmGoal(0.05)) return;
559 Spit();
560
561 if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
562
563 AOS_LOG(
564 INFO, "Placed second cube %lf s\n",
565 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Austin Schuh8c9d2d02023-04-09 20:05:42 -0700566
567 std::this_thread::sleep_for(chrono::milliseconds(200));
568 Neutral();
Austin Schuha7c3bc62023-04-16 19:46:23 -0700569 AOS_LOG(
570 INFO, "Going to neutral %lf s\n",
571 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
572
573 if (!WaitForArmGoal(0.05)) return;
574 AOS_LOG(
575 INFO, "Done at neutral %lf s\n",
576 aos::time::DurationInSeconds(aos::monotonic_clock::now() - start_time));
Maxwell Henderson25378832023-04-07 14:37:41 -0700577}
578
Maxwell Henderson64f37452023-03-11 13:39:21 -0800579void AutonomousActor::SendSuperstructureGoal() {
580 auto builder = superstructure_goal_sender_.MakeBuilder();
581
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700582 flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
583 wrist_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
584 *builder.fbb(), wrist_goal_,
585 CreateProfileParameters(*builder.fbb(), 12.0, 90.0));
586
Maxwell Henderson64f37452023-03-11 13:39:21 -0800587 control_loops::superstructure::Goal::Builder superstructure_builder =
588 builder.MakeBuilder<control_loops::superstructure::Goal>();
589
590 superstructure_builder.add_arm_goal_position(arm_goal_position_);
591 superstructure_builder.add_preloaded_with_cone(preloaded_);
592 superstructure_builder.add_roller_goal(roller_goal_);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700593 superstructure_builder.add_wrist(wrist_offset);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800594
595 if (builder.Send(superstructure_builder.Finish()) !=
596 aos::RawSender::Error::kOk) {
597 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
598 }
599}
600
601[[nodiscard]] bool AutonomousActor::WaitForPreloaded() {
602 set_preloaded(true);
603 SendSuperstructureGoal();
604
605 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
606 event_loop()->monotonic_now(),
607 ActorBase::kLoopOffset);
608
609 bool loaded = false;
610 while (!loaded) {
611 if (ShouldCancel()) {
612 return false;
613 }
614
615 phased_loop.SleepUntilNext();
616 superstructure_status_fetcher_.Fetch();
617 CHECK(superstructure_status_fetcher_.get() != nullptr);
618
619 loaded = (superstructure_status_fetcher_->end_effector_state() ==
620 control_loops::superstructure::EndEffectorState::LOADED);
621 }
622
623 set_preloaded(false);
624 SendSuperstructureGoal();
625
626 return true;
627}
628
629void AutonomousActor::MidConeScore() {
630 set_arm_goal_position(
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700631 control_loops::superstructure::arm::ScoreFrontMidConeUpAutoIndex());
632 set_wrist_goal(0.0);
633 SendSuperstructureGoal();
634}
635
636void AutonomousActor::Neutral() {
637 set_arm_goal_position(control_loops::superstructure::arm::NeutralIndex());
Austin Schuha7c3bc62023-04-16 19:46:23 -0700638 set_wrist_goal(1.0);
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700639 SendSuperstructureGoal();
640}
641
642void AutonomousActor::Balance() {
643 set_arm_goal_position(
Austin Schuh700bfff2023-04-05 19:45:55 -0700644 control_loops::superstructure::arm::ScoreFrontLowCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700645 set_wrist_goal(0.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800646 SendSuperstructureGoal();
647}
648
649void AutonomousActor::HighCubeScore() {
650 set_arm_goal_position(
651 control_loops::superstructure::arm::ScoreFrontHighCubeIndex());
Austin Schuha7c3bc62023-04-16 19:46:23 -0700652 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800653 SendSuperstructureGoal();
654}
655
656void AutonomousActor::MidCubeScore() {
657 set_arm_goal_position(
658 control_loops::superstructure::arm::ScoreFrontMidCubeIndex());
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::PickupCube() {
664 set_arm_goal_position(
665 control_loops::superstructure::arm::GroundPickupBackCubeIndex());
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700666 set_wrist_goal(1.0);
Maxwell Henderson64f37452023-03-11 13:39:21 -0800667 SendSuperstructureGoal();
668}
669
670void AutonomousActor::Spit() {
671 set_roller_goal(control_loops::superstructure::RollerGoal::SPIT);
672 SendSuperstructureGoal();
673}
674
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700675void AutonomousActor::StopSpitting() {
676 set_roller_goal(control_loops::superstructure::RollerGoal::IDLE);
677 SendSuperstructureGoal();
678}
679
Maxwell Henderson64f37452023-03-11 13:39:21 -0800680void AutonomousActor::IntakeCube() {
681 set_roller_goal(control_loops::superstructure::RollerGoal::INTAKE_CUBE);
682 SendSuperstructureGoal();
683}
684
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700685[[nodiscard]] bool AutonomousActor::WaitForArmGoal(double distance_to_go) {
686 constexpr double kEpsTheta = 0.10;
Maxwell Henderson64f37452023-03-11 13:39:21 -0800687
688 ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
689 event_loop()->monotonic_now(),
690 ActorBase::kLoopOffset);
691
692 bool at_goal = false;
693 while (!at_goal) {
694 if (ShouldCancel()) {
695 return false;
696 }
697
698 phased_loop.SleepUntilNext();
699 superstructure_status_fetcher_.Fetch();
700 CHECK(superstructure_status_fetcher_.get() != nullptr);
701
Maxwell Henderson3d0beaf2023-03-23 11:32:44 -0700702 at_goal = (arm_goal_position_ ==
703 superstructure_status_fetcher_->arm()->current_node() &&
704 superstructure_status_fetcher_->arm()->path_distance_to_go() <
705 distance_to_go) &&
Maxwell Henderson64f37452023-03-11 13:39:21 -0800706 (std::abs(wrist_goal_ -
707 superstructure_status_fetcher_->wrist()->position()) <
708 kEpsTheta);
709 }
710
Maxwell Henderson64f37452023-03-11 13:39:21 -0800711 return true;
712}
713
714} // namespace autonomous
Maxwell Hendersonad312342023-01-10 12:07:47 -0800715} // namespace y2023