blob: 9a703e324ee01c48e433090603e8061473d672aa [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 Sohmersafc51fe2024-01-29 17:48:35 -080034 intake_pivot_(
35 robot_constants_->common()->intake_pivot(),
36 robot_constants_->robot()->intake_constants()->intake_pivot_zero()) {
Niko Sohmers3860f8a2024-01-12 21:05:19 -080037 event_loop->SetRuntimeRealtimePriority(30);
38}
39
40void Superstructure::RunIteration(const Goal *unsafe_goal,
41 const Position *position,
42 aos::Sender<Output>::Builder *output,
43 aos::Sender<Status>::Builder *status) {
44 const monotonic_clock::time_point timestamp =
45 event_loop()->context().monotonic_event_time;
46
47 (void)timestamp;
Niko Sohmers3860f8a2024-01-12 21:05:19 -080048 (void)position;
49
50 if (WasReset()) {
51 AOS_LOG(ERROR, "WPILib reset, restarting\n");
Niko Sohmersafc51fe2024-01-29 17:48:35 -080052 intake_pivot_.Reset();
Niko Sohmers3860f8a2024-01-12 21:05:19 -080053 }
54
55 OutputT output_struct;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080056
57 double intake_pivot_position =
58 robot_constants_->common()->intake_pivot_set_points()->retracted();
59
60 if (unsafe_goal != nullptr &&
61 unsafe_goal->intake_pivot_goal() == IntakePivotGoal::EXTENDED) {
62 intake_pivot_position =
63 robot_constants_->common()->intake_pivot_set_points()->extended();
64 }
65
66 IntakeRollerState intake_roller_state = IntakeRollerState::NONE;
67
68 switch (unsafe_goal != nullptr ? unsafe_goal->intake_roller_goal()
69 : IntakeRollerGoal::NONE) {
70 case IntakeRollerGoal::NONE:
71 output_struct.intake_roller_voltage = 0.0;
72 break;
73 case IntakeRollerGoal::SPIT:
Niko Sohmerse735fa82024-02-02 16:49:02 -080074 transfer_goal_ = TransferRollerGoal::TRANSFER_OUT;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080075 intake_roller_state = IntakeRollerState::SPITTING;
76 output_struct.intake_roller_voltage =
77 robot_constants_->common()->intake_roller_voltages()->spitting();
78 break;
79 case IntakeRollerGoal::INTAKE:
Niko Sohmerse735fa82024-02-02 16:49:02 -080080 transfer_goal_ = TransferRollerGoal::TRANSFER_IN;
Niko Sohmersafc51fe2024-01-29 17:48:35 -080081 intake_roller_state = IntakeRollerState::INTAKING;
82 output_struct.intake_roller_voltage =
83 robot_constants_->common()->intake_roller_voltages()->intaking();
84 break;
85 }
86
Niko Sohmerse735fa82024-02-02 16:49:02 -080087 TransferRollerState transfer_roller_state = TransferRollerState::NONE;
88
89 switch (unsafe_goal != nullptr ? transfer_goal_ : TransferRollerGoal::NONE) {
90 case TransferRollerGoal::NONE:
91 output_struct.transfer_roller_voltage = 0.0;
92 break;
93 case TransferRollerGoal::TRANSFER_IN:
94 if (position->transfer_beambreak()) {
95 transfer_goal_ = TransferRollerGoal::NONE;
96 transfer_roller_state = TransferRollerState::NONE;
97 output_struct.transfer_roller_voltage = 0.0;
98 break;
99 }
100 transfer_roller_state = TransferRollerState::TRANSFERING_IN;
101 output_struct.transfer_roller_voltage =
102 robot_constants_->common()->transfer_roller_voltages()->transfer_in();
103 break;
104 case TransferRollerGoal::TRANSFER_OUT:
105 transfer_roller_state = TransferRollerState::TRANSFERING_OUT;
106 output_struct.transfer_roller_voltage = robot_constants_->common()
107 ->transfer_roller_voltages()
108 ->transfer_out();
109 break;
110 }
111
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800112 if (joystick_state_fetcher_.Fetch() &&
113 joystick_state_fetcher_->has_alliance()) {
114 alliance_ = joystick_state_fetcher_->alliance();
115 }
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800116
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800117 drivetrain_status_fetcher_.Fetch();
118
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800119 aos::FlatbufferFixedAllocatorArray<
120 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal, 512>
121 intake_pivot_goal_buffer;
122
123 intake_pivot_goal_buffer.Finish(
124 frc971::control_loops::CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
125 *intake_pivot_goal_buffer.fbb(), intake_pivot_position));
126
127 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
128 *intake_pivot_goal = &intake_pivot_goal_buffer.message();
129
130 const flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
131 intake_pivot_status_offset = intake_pivot_.Iterate(
132 intake_pivot_goal, position->intake_pivot(),
133 output != nullptr ? &output_struct.intake_pivot_voltage : nullptr,
134 status->fbb());
135
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800136 if (output) {
137 output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
138 }
139
140 Status::Builder status_builder = status->MakeBuilder<Status>();
Niko Sohmersafc51fe2024-01-29 17:48:35 -0800141
142 const bool zeroed = intake_pivot_.zeroed();
143 const bool estopped = intake_pivot_.estopped();
144
145 status_builder.add_zeroed(zeroed);
146 status_builder.add_estopped(estopped);
147 status_builder.add_intake_roller_state(intake_roller_state);
148 status_builder.add_intake_pivot_state(intake_pivot_status_offset);
Niko Sohmerse735fa82024-02-02 16:49:02 -0800149 status_builder.add_transfer_roller_state(transfer_roller_state);
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800150
151 (void)status->Send(status_builder.Finish());
152}
153
154double Superstructure::robot_velocity() const {
155 return (drivetrain_status_fetcher_.get() != nullptr
156 ? drivetrain_status_fetcher_->robot_speed()
157 : 0.0);
158}
159
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800160} // namespace y2024::control_loops::superstructure