blob: 0aacbd1ca707c344136c88f18e53bdb724c433ab [file] [log] [blame]
Ariv Diggi0af59c02023-10-07 13:15:39 -07001#include "y2023_bot3/autonomous/autonomous_actor.h"
2
3#include <chrono>
4#include <cinttypes>
5#include <cmath>
6
7#include "aos/logging/logging.h"
8#include "aos/util/math.h"
9#include "frc971/control_loops/drivetrain/localizer_generated.h"
10#include "y2023_bot3/autonomous/auto_splines.h"
11#include "y2023_bot3/constants.h"
12#include "y2023_bot3/control_loops/drivetrain/drivetrain_base.h"
13
14DEFINE_bool(spline_auto, false, "Run simple test S-spline auto mode.");
15
16namespace y2023_bot3 {
17namespace autonomous {
18
19using ::frc971::ProfileParametersT;
20
21ProfileParametersT MakeProfileParameters(float max_velocity,
22 float max_acceleration) {
23 ProfileParametersT result;
24 result.max_velocity = max_velocity;
25 result.max_acceleration = max_acceleration;
26 return result;
27}
28
29using ::aos::monotonic_clock;
30using frc971::CreateProfileParameters;
31using ::frc971::ProfileParametersT;
32using frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal;
33using frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal;
34using frc971::control_loops::drivetrain::LocalizerControl;
35namespace chrono = ::std::chrono;
36
37AutonomousActor::AutonomousActor(::aos::EventLoop *event_loop)
38 : frc971::autonomous::BaseAutonomousActor(
39 event_loop, control_loops::drivetrain::GetDrivetrainConfig()),
40 localizer_control_sender_(
41 event_loop->MakeSender<
42 ::frc971::control_loops::drivetrain::LocalizerControl>(
43 "/drivetrain")),
44 joystick_state_fetcher_(
45 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
46 robot_state_fetcher_(event_loop->MakeFetcher<aos::RobotState>("/aos")),
47 auto_splines_(),
48 superstructure_goal_sender_(
49 event_loop
50 ->MakeSender<::y2023_bot3::control_loops::superstructure::Goal>(
51 "/superstructure")),
52 superstructure_status_fetcher_(
53 event_loop->MakeFetcher<
54 ::y2023_bot3::control_loops::superstructure::Status>(
55 "/superstructure")) {
56 drivetrain_status_fetcher_.Fetch();
57 replan_timer_ = event_loop->AddTimer([this]() { Replan(); });
58
59 event_loop->OnRun([this, event_loop]() {
60 replan_timer_->Schedule(event_loop->monotonic_now());
61 button_poll_->Schedule(event_loop->monotonic_now(),
62 chrono::milliseconds(50));
63 });
64
65 // TODO(james): Really need to refactor this code since we keep using it.
66 button_poll_ = event_loop->AddTimer([this]() {
67 const aos::monotonic_clock::time_point now =
68 this->event_loop()->context().monotonic_event_time;
69 if (robot_state_fetcher_.Fetch()) {
70 if (robot_state_fetcher_->user_button()) {
71 user_indicated_safe_to_reset_ = true;
72 MaybeSendStartingPosition();
73 }
74 }
75 if (joystick_state_fetcher_.Fetch()) {
76 if (joystick_state_fetcher_->has_alliance() &&
77 (joystick_state_fetcher_->alliance() != alliance_)) {
78 alliance_ = joystick_state_fetcher_->alliance();
79 is_planned_ = false;
80 // Only kick the planning out by 2 seconds. If we end up enabled in
81 // that second, then we will kick it out further based on the code
82 // below.
83 replan_timer_->Schedule(now + std::chrono::seconds(2));
84 }
85 if (joystick_state_fetcher_->enabled()) {
86 if (!is_planned_) {
87 // Only replan once we've been disabled for 5 seconds.
88 replan_timer_->Schedule(now + std::chrono::seconds(5));
89 }
90 }
91 }
92 });
93}
94
95void AutonomousActor::Replan() {
96 if (!drivetrain_status_fetcher_.Fetch()) {
97 replan_timer_->Schedule(event_loop()->monotonic_now() + chrono::seconds(1));
98 AOS_LOG(INFO, "Drivetrain not up, replanning in 1 second");
99 return;
100 }
101
102 if (alliance_ == aos::Alliance::kInvalid) {
103 return;
104 }
105 sent_starting_position_ = false;
106 if (FLAGS_spline_auto) {
107 test_spline_ =
108 PlanSpline(std::bind(&AutonomousSplines::TestSpline, &auto_splines_,
109 std::placeholders::_1, alliance_),
110 SplineDirection::kForward);
111
112 starting_position_ = test_spline_->starting_position();
113 }
114 is_planned_ = true;
115
116 MaybeSendStartingPosition();
117}
118
119void AutonomousActor::MaybeSendStartingPosition() {
120 if (is_planned_ && user_indicated_safe_to_reset_ &&
121 !sent_starting_position_) {
122 CHECK(starting_position_);
123 SendStartingPosition(starting_position_.value());
124 }
125}
126
127void AutonomousActor::Reset() {
128 InitializeEncoders();
129 ResetDrivetrain();
130
131 joystick_state_fetcher_.Fetch();
132 CHECK(joystick_state_fetcher_.get() != nullptr)
133 << "Expect at least one JoystickState message before running auto...";
134 alliance_ = joystick_state_fetcher_->alliance();
135
136 preloaded_ = false;
137 SendSuperstructureGoal();
138}
139
140bool AutonomousActor::RunAction(
141 const ::frc971::autonomous::AutonomousActionParams *params) {
142 Reset();
143
144 AOS_LOG(INFO, "Params are %d\n", params->mode());
145
146 if (!user_indicated_safe_to_reset_) {
147 AOS_LOG(WARNING, "Didn't send starting position prior to starting auto.");
148 CHECK(starting_position_);
149 SendStartingPosition(starting_position_.value());
150 }
151 // Clear this so that we don't accidentally resend things as soon as we
152 // replan later.
153 user_indicated_safe_to_reset_ = false;
154 is_planned_ = false;
155 starting_position_.reset();
156
157 AOS_LOG(INFO, "Params are %d\n", params->mode());
158 if (alliance_ == aos::Alliance::kInvalid) {
159 AOS_LOG(INFO, "Aborting autonomous due to invalid alliance selection.");
160 return false;
161 }
162
163 return true;
164}
165
166void AutonomousActor::SendStartingPosition(const Eigen::Vector3d &start) {
167 // Set up the starting position for the blue alliance.
168
169 auto builder = localizer_control_sender_.MakeBuilder();
170
171 LocalizerControl::Builder localizer_control_builder =
172 builder.MakeBuilder<LocalizerControl>();
173 localizer_control_builder.add_x(start(0));
174 localizer_control_builder.add_y(start(1));
175 localizer_control_builder.add_theta(start(2));
176 localizer_control_builder.add_theta_uncertainty(0.00001);
177 AOS_LOG(INFO, "User button pressed, x: %f y: %f theta: %f", start(0),
178 start(1), start(2));
179 if (builder.Send(localizer_control_builder.Finish()) !=
180 aos::RawSender::Error::kOk) {
181 AOS_LOG(ERROR, "Failed to reset localizer.\n");
182 }
183}
184
185void AutonomousActor::SendSuperstructureGoal() {
186 auto builder = superstructure_goal_sender_.MakeBuilder();
187
188 control_loops::superstructure::Goal::Builder superstructure_builder =
189 builder.MakeBuilder<control_loops::superstructure::Goal>();
190
191 if (builder.Send(superstructure_builder.Finish()) !=
192 aos::RawSender::Error::kOk) {
193 AOS_LOG(ERROR, "Sending superstructure goal failed.\n");
194 }
195}
196
197} // namespace autonomous
198} // namespace y2023_bot3