blob: 5ac705b42a84a675db609b7e39dcef6944f854f2 [file] [log] [blame]
Niko Sohmers3860f8a2024-01-12 21:05:19 -08001#include "y2024/control_loops/superstructure/superstructure.h"
2
3#include "aos/events/event_loop.h"
4#include "aos/flatbuffer_merge.h"
5#include "aos/network/team_number.h"
6#include "frc971/shooter_interpolation/interpolation.h"
7#include "frc971/zeroing/wrap.h"
8
9DEFINE_bool(ignore_distance, false,
10 "If true, ignore distance when shooting and obay joystick_reader");
11
Stephan Pleinesf63bde82024-01-13 15:59:33 -080012namespace y2024::control_loops::superstructure {
Niko Sohmers3860f8a2024-01-12 21:05:19 -080013
14using ::aos::monotonic_clock;
15
16using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
17using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
18using frc971::control_loops::RelativeEncoderProfiledJointStatus;
19
20Superstructure::Superstructure(::aos::EventLoop *event_loop,
21 std::shared_ptr<const constants::Values> values,
22 const ::std::string &name)
23 : frc971::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
24 name),
25 values_(values),
26 constants_fetcher_(event_loop),
Niko Sohmersafc51fe2024-01-29 17:48:35 -080027 robot_constants_(CHECK_NOTNULL(&constants_fetcher_.constants())),
Niko Sohmers3860f8a2024-01-12 21:05:19 -080028 drivetrain_status_fetcher_(
29 event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
30 "/drivetrain")),
31 joystick_state_fetcher_(
Niko Sohmersafc51fe2024-01-29 17:48:35 -080032 event_loop->MakeFetcher<aos::JoystickState>("/aos")),
Niko Sohmerse735fa82024-02-02 16:49:02 -080033 transfer_goal_(TransferRollerGoal::NONE),
Niko Sohmers74b0ad52024-02-03 18:00:31 -080034 intake_pivot_(robot_constants_->common()->intake_pivot(),
35 robot_constants_->robot()->intake_constants()),
Filip Kujawa6d717632024-02-01 11:40:55 -080036 climber_(
37 robot_constants_->common()->climber(),
Niko Sohmersc4d2c502024-02-19 19:35:35 -080038 robot_constants_->robot()->climber_constants()->zeroing_constants()),
39 shooter_(event_loop, robot_constants_) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -080040 event_loop->SetRuntimeRealtimePriority(30);
41}
42
43void Superstructure::RunIteration(const Goal *unsafe_goal,
44 const Position *position,
45 aos::Sender<Output>::Builder *output,
46 aos::Sender<Status>::Builder *status) {
47 const monotonic_clock::time_point timestamp =
48 event_loop()->context().monotonic_event_time;
49
Niko Sohmers3860f8a2024-01-12 21:05:19 -080050 if (WasReset()) {
51 AOS_LOG(ERROR, "WPILib reset, restarting\n");
Niko Sohmersafc51fe2024-01-29 17:48:35 -080052 intake_pivot_.Reset();
Filip Kujawa6d717632024-02-01 11:40:55 -080053 climber_.Reset();
Niko Sohmersc4d2c502024-02-19 19:35:35 -080054 shooter_.Reset();
Niko Sohmers3860f8a2024-01-12 21:05:19 -080055 }
56
57 OutputT output_struct;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080058
59 double intake_pivot_position =
60 robot_constants_->common()->intake_pivot_set_points()->retracted();
61
62 if (unsafe_goal != nullptr &&
63 unsafe_goal->intake_pivot_goal() == IntakePivotGoal::EXTENDED) {
64 intake_pivot_position =
65 robot_constants_->common()->intake_pivot_set_points()->extended();
66 }
67
Filip Kujawa102a9b22024-02-18 09:40:23 -080068 IntakeRollerStatus intake_roller_state = IntakeRollerStatus::NONE;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080069
70 switch (unsafe_goal != nullptr ? unsafe_goal->intake_roller_goal()
71 : IntakeRollerGoal::NONE) {
72 case IntakeRollerGoal::NONE:
73 output_struct.intake_roller_voltage = 0.0;
74 break;
75 case IntakeRollerGoal::SPIT:
Niko Sohmerse735fa82024-02-02 16:49:02 -080076 transfer_goal_ = TransferRollerGoal::TRANSFER_OUT;
Filip Kujawa102a9b22024-02-18 09:40:23 -080077 intake_roller_state = IntakeRollerStatus::SPITTING;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080078 output_struct.intake_roller_voltage =
79 robot_constants_->common()->intake_roller_voltages()->spitting();
80 break;
81 case IntakeRollerGoal::INTAKE:
Niko Sohmerse735fa82024-02-02 16:49:02 -080082 transfer_goal_ = TransferRollerGoal::TRANSFER_IN;
Filip Kujawa102a9b22024-02-18 09:40:23 -080083 intake_roller_state = IntakeRollerStatus::INTAKING;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080084 output_struct.intake_roller_voltage =
85 robot_constants_->common()->intake_roller_voltages()->intaking();
86 break;
87 }
88
Filip Kujawa102a9b22024-02-18 09:40:23 -080089 TransferRollerStatus transfer_roller_state = TransferRollerStatus::NONE;
Niko Sohmerse735fa82024-02-02 16:49:02 -080090
91 switch (unsafe_goal != nullptr ? transfer_goal_ : TransferRollerGoal::NONE) {
92 case TransferRollerGoal::NONE:
93 output_struct.transfer_roller_voltage = 0.0;
94 break;
95 case TransferRollerGoal::TRANSFER_IN:
96 if (position->transfer_beambreak()) {
97 transfer_goal_ = TransferRollerGoal::NONE;
Filip Kujawa102a9b22024-02-18 09:40:23 -080098 transfer_roller_state = TransferRollerStatus::NONE;
Niko Sohmerse735fa82024-02-02 16:49:02 -080099 output_struct.transfer_roller_voltage = 0.0;
100 break;
101 }
Filip Kujawa102a9b22024-02-18 09:40:23 -0800102 transfer_roller_state = TransferRollerStatus::TRANSFERING_IN;
Niko Sohmerse735fa82024-02-02 16:49:02 -0800103 output_struct.transfer_roller_voltage =
104 robot_constants_->common()->transfer_roller_voltages()->transfer_in();
105 break;
106 case TransferRollerGoal::TRANSFER_OUT:
Filip Kujawa102a9b22024-02-18 09:40:23 -0800107 transfer_roller_state = TransferRollerStatus::TRANSFERING_OUT;
Niko Sohmerse735fa82024-02-02 16:49:02 -0800108 output_struct.transfer_roller_voltage = robot_constants_->common()
109 ->transfer_roller_voltages()
110 ->transfer_out();
111 break;
112 }
113
Filip Kujawa6d717632024-02-01 11:40:55 -0800114 double climber_position =
115 robot_constants_->common()->climber_set_points()->retract();
116
117 if (unsafe_goal != nullptr) {
118 switch (unsafe_goal->climber_goal()) {
119 case ClimberGoal::FULL_EXTEND:
120 climber_position =
121 robot_constants_->common()->climber_set_points()->full_extend();
122 break;
123 case ClimberGoal::HALF_EXTEND:
124 climber_position =
125 robot_constants_->common()->climber_set_points()->half_extend();
126 break;
127 case ClimberGoal::RETRACT:
128 climber_position =
129 robot_constants_->common()->climber_set_points()->retract();
130 break;
131 default:
132 break;
133 }
134 }
135
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800136 if (joystick_state_fetcher_.Fetch() &&
137 joystick_state_fetcher_->has_alliance()) {
138 alliance_ = joystick_state_fetcher_->alliance();
139 }
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800140
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800141 drivetrain_status_fetcher_.Fetch();
142
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800143 aos::FlatbufferFixedAllocatorArray<
144 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal, 512>
145 intake_pivot_goal_buffer;
146
147 intake_pivot_goal_buffer.Finish(
148 frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
149 *intake_pivot_goal_buffer.fbb(), intake_pivot_position));
150
151 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
152 *intake_pivot_goal = &intake_pivot_goal_buffer.message();
153
Niko Sohmers74b0ad52024-02-03 18:00:31 -0800154 const flatbuffers::Offset<AbsoluteEncoderProfiledJointStatus>
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800155 intake_pivot_status_offset = intake_pivot_.Iterate(
156 intake_pivot_goal, position->intake_pivot(),
157 output != nullptr ? &output_struct.intake_pivot_voltage : nullptr,
158 status->fbb());
159
Filip Kujawa6d717632024-02-01 11:40:55 -0800160 aos::FlatbufferFixedAllocatorArray<
161 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal, 512>
162 climber_goal_buffer;
163
164 climber_goal_buffer.Finish(
165 frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
166 *climber_goal_buffer.fbb(), climber_position));
167
168 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
169 *climber_goal = &climber_goal_buffer.message();
170
171 const flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
172 climber_status_offset = climber_.Iterate(
173 climber_goal, position->climber(),
174 output != nullptr ? &output_struct.climber_voltage : nullptr,
175 status->fbb());
176
Niko Sohmersc4d2c502024-02-19 19:35:35 -0800177 const flatbuffers::Offset<ShooterStatus> shooter_status_offset =
178 shooter_.Iterate(
179 position,
180 unsafe_goal != nullptr ? unsafe_goal->shooter_goal() : nullptr,
181 output != nullptr ? &output_struct.catapult_voltage : nullptr,
182 output != nullptr ? &output_struct.altitude_voltage : nullptr,
183 output != nullptr ? &output_struct.turret_voltage : nullptr,
184 output != nullptr ? &output_struct.retention_roller_voltage : nullptr,
185 robot_state().voltage_battery(), timestamp, status->fbb());
186
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800187 if (output) {
188 output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
189 }
190
191 Status::Builder status_builder = status->MakeBuilder<Status>();
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800192
Niko Sohmersc4d2c502024-02-19 19:35:35 -0800193 const bool zeroed =
194 intake_pivot_.zeroed() && climber_.zeroed() && shooter_.zeroed();
195 const bool estopped =
196 intake_pivot_.estopped() || climber_.estopped() || shooter_.estopped();
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800197
198 status_builder.add_zeroed(zeroed);
199 status_builder.add_estopped(estopped);
Filip Kujawa102a9b22024-02-18 09:40:23 -0800200 status_builder.add_intake_roller(intake_roller_state);
201 status_builder.add_intake_pivot(intake_pivot_status_offset);
202 status_builder.add_transfer_roller(transfer_roller_state);
203 status_builder.add_climber(climber_status_offset);
Niko Sohmersc4d2c502024-02-19 19:35:35 -0800204 status_builder.add_shooter(shooter_status_offset);
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800205
206 (void)status->Send(status_builder.Finish());
207}
208
209double Superstructure::robot_velocity() const {
210 return (drivetrain_status_fetcher_.get() != nullptr
211 ? drivetrain_status_fetcher_->robot_speed()
212 : 0.0);
213}
214
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800215} // namespace y2024::control_loops::superstructure