blob: 8e99af64c34f72deecda4b90987b3d09e67a6d22 [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"
8#include "frc971/control_loops/drivetrain/localizer_generated.h"
9#include "y2023/control_loops/drivetrain/drivetrain_base.h"
10
James Kuszmaul713c5ce2023-03-04 18:23:24 -080011DEFINE_bool(spline_auto, true, "Run simple test S-spline auto mode.");
12
Maxwell Hendersonad312342023-01-10 12:07:47 -080013namespace y2023 {
14namespace actors {
15
16using ::aos::monotonic_clock;
17using ::frc971::ProfileParametersT;
18using frc971::control_loops::drivetrain::LocalizerControl;
19namespace chrono = ::std::chrono;
20
21AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
22 : frc971::autonomous::BaseAutonomousActor(
James Kuszmaul713c5ce2023-03-04 18:23:24 -080023 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
24 localizer_control_sender_(
25 event_loop->MakeSender<
26 ::frc971::control_loops::drivetrain::LocalizerControl>(
27 "/drivetrain")),
28 joystick_state_fetcher_(
29 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
30 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
31 auto_splines_() {
32 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
33
34 event_loop->OnRun([this, event_loop]() {
35 replan_timer_->Setup(event_loop->monotonic_now());
36 button_poll_->Setup(event_loop->monotonic_now(), chrono::milliseconds(50));
37 });
38
39 // TODO(james): Really need to refactor this code since we keep using it.
40 button_poll_ = event_loop->AddTimer([this]() {
41 const aos::monotonic_clock::time_point now =
42 this->event_loop()->context().monotonic_event_time;
43 if (robot_state_fetcher_.Fetch()) {
44 if (robot_state_fetcher_->user_button()) {
45 user_indicated_safe_to_reset_ = true;
46 MaybeSendStartingPosition();
47 }
48 }
49 if (joystick_state_fetcher_.Fetch()) {
50 if (joystick_state_fetcher_->has_alliance() &&
51 (joystick_state_fetcher_->alliance() != alliance_)) {
52 alliance_ = joystick_state_fetcher_->alliance();
53 is_planned_ = false;
54 // Only kick the planning out by 2 seconds. If we end up enabled in that
55 // second, then we will kick it out further based on the code below.
56 replan_timer_->Setup(now + std::chrono::seconds(2));
57 }
58 if (joystick_state_fetcher_->enabled()) {
59 if (!is_planned_) {
60 // Only replan once we've been disabled for 5 seconds.
61 replan_timer_->Setup(now + std::chrono::seconds(5));
62 }
63 }
64 }
65 });
66}
67
68void AutonomousActor::Replan() {
69 if (alliance_ == aos::Alliance::kInvalid) {
70 return;
71 }
72 sent_starting_position_ = false;
73 if (FLAGS_spline_auto) {
74 test_spline_ =
75 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
76 std::placeholders::_1, alliance_),
77 SplineDirection::kForward);
78
79 starting_position_ = test_spline_->starting_position();
80 }
81
82 is_planned_ = true;
83
84 MaybeSendStartingPosition();
85}
86
87void AutonomousActor::MaybeSendStartingPosition() {
88 if (is_planned_ && user_indicated_safe_to_reset_ &&
89 !sent_starting_position_) {
90 CHECK(starting_position_);
91 SendStartingPosition(starting_position_.value());
92 }
93}
Maxwell Hendersonad312342023-01-10 12:07:47 -080094
95void AutonomousActor::Reset() {
96 InitializeEncoders();
97 ResetDrivetrain();
James Kuszmaul713c5ce2023-03-04 18:23:24 -080098
99 joystick_state_fetcher_.Fetch();
100 CHECK(joystick_state_fetcher_.get() != nullptr)
101 << "Expect at least one JoystickState message before running auto...";
102 alliance_ = joystick_state_fetcher_->alliance();
Maxwell Hendersonad312342023-01-10 12:07:47 -0800103}
104
105bool AutonomousActor::RunAction(
106 const ::frc971::autonomous::AutonomousActionParams *params) {
107 Reset();
108
109 AOS_LOG(INFO, "Params are %d\n", params->mode());
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800110
111 if (!user_indicated_safe_to_reset_) {
112 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
113 CHECK(starting_position_);
114 SendStartingPosition(starting_position_.value());
115 }
116 // Clear this so that we don't accidentally resend things as soon as we replan
117 // later.
118 user_indicated_safe_to_reset_ = false;
119 is_planned_ = false;
120 starting_position_.reset();
121
122 AOS_LOG(INFO, "Params are %d\n", params->mode());
123 if (alliance_ == aos::Alliance::kInvalid) {
124 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
125 return false;
126 }
127 if (FLAGS_spline_auto) {
128 SplineAuto();
129 } else {
130 AOS_LOG(WARNING, "No auto mode selected.");
131 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800132 return true;
133}
134
James Kuszmaul713c5ce2023-03-04 18:23:24 -0800135void AutonomousActor::SplineAuto() {
136 CHECK(test_spline_);
137
138 if (!test_spline_->WaitForPlan()) return;
139 test_spline_->Start();
140
141 if (!test_spline_->WaitForSplineDistanceRemaining(0.02)) return;
142}
143
144void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
145 // Set up the starting position for the blue alliance.
146
147 auto builder = localizer_control_sender_.MakeBuilder();
148
149 LocalizerControl::Builder localizer_control_builder =
150 builder.MakeBuilder<LocalizerControl>();
151 localizer_control_builder.add_x(start(0));
152 localizer_control_builder.add_y(start(1));
153 localizer_control_builder.add_theta(start(2));
154 localizer_control_builder.add_theta_uncertainty(0.00001);
155 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
156 start(1), start(2));
157 if (builder.Send(localizer_control_builder.Finish()) !=
158 aos::RawSender::Error::kOk) {
159 AOS_LOG(ERROR, "Failed to reset localizer.\n");
160 }
161}
162
Maxwell Hendersonad312342023-01-10 12:07:47 -0800163} // namespace actors
164} // namespace y2023