blob: ce816a0d92723b318f647d9bb73ac6274761cbba [file] [log] [blame]
Stephan Massaltd021f972020-01-05 20:41:23 -08001#include "y2020/control_loops/superstructure/superstructure.h"
2
3#include "aos/events/event_loop.h"
4
5namespace y2020 {
6namespace control_loops {
7namespace superstructure {
8
Ravago Jones937587c2020-12-26 17:21:09 -08009using frc971::control_loops::AbsoluteAndAbsoluteEncoderProfiledJointStatus;
Stephan Massaltd021f972020-01-05 20:41:23 -080010using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
11using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
12
13Superstructure::Superstructure(::aos::EventLoop *event_loop,
14 const ::std::string &name)
James Kuszmaul61750662021-06-21 21:32:33 -070015 : frc971::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
16 name),
Sabina Davis0f2d38c2020-02-08 17:01:21 -080017 hood_(constants::GetValues().hood),
Kai Tinkessfb460372020-02-08 14:05:48 -080018 intake_joint_(constants::GetValues().intake),
Sabina Davis0f31d3f2020-02-20 20:41:00 -080019 turret_(constants::GetValues().turret.subsystem_params),
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080020 drivetrain_status_fetcher_(
21 event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
James Kuszmaula53c3ac2020-02-22 19:36:01 -080022 "/drivetrain")),
23 joystick_state_fetcher_(
24 event_loop->MakeFetcher<aos::JoystickState>("/aos")) {
Sabina Daviscf08b152020-01-31 22:12:09 -080025 event_loop->SetRuntimeRealtimePriority(30);
Stephan Massaltd021f972020-01-05 20:41:23 -080026}
27
milind upadhyayaec1aee2020-10-13 13:44:33 -070028double Superstructure::robot_speed() const {
29 return (drivetrain_status_fetcher_.get() != nullptr
30 ? drivetrain_status_fetcher_->robot_speed()
31 : 0.0);
32}
33
Sabina Daviscf08b152020-01-31 22:12:09 -080034void Superstructure::RunIteration(const Goal *unsafe_goal,
35 const Position *position,
Stephan Massaltd021f972020-01-05 20:41:23 -080036 aos::Sender<Output>::Builder *output,
37 aos::Sender<Status>::Builder *status) {
38 if (WasReset()) {
39 AOS_LOG(ERROR, "WPILib reset, restarting\n");
Sabina Daviscf08b152020-01-31 22:12:09 -080040 hood_.Reset();
Sabina Davis0f2d38c2020-02-08 17:01:21 -080041 intake_joint_.Reset();
Kai Tinkessfb460372020-02-08 14:05:48 -080042 turret_.Reset();
Stephan Massaltd021f972020-01-05 20:41:23 -080043 }
44
Sabina Davis0f31d3f2020-02-20 20:41:00 -080045 const aos::monotonic_clock::time_point position_timestamp =
46 event_loop()->context().monotonic_event_time;
47
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080048 if (drivetrain_status_fetcher_.Fetch()) {
James Kuszmaula53c3ac2020-02-22 19:36:01 -080049 aos::Alliance alliance = aos::Alliance::kInvalid;
James Kuszmaul519585d2020-03-08 22:32:48 -070050 joystick_state_fetcher_.Fetch();
51 if (joystick_state_fetcher_.get() != nullptr) {
James Kuszmaula53c3ac2020-02-22 19:36:01 -080052 alliance = joystick_state_fetcher_->alliance();
53 }
James Kuszmaul3b393d72020-02-26 19:43:51 -080054 const turret::Aimer::WrapMode mode =
James Kuszmaulb83d6e12020-02-22 20:44:48 -080055 (unsafe_goal != nullptr && unsafe_goal->shooting())
James Kuszmaul3b393d72020-02-26 19:43:51 -080056 ? turret::Aimer::WrapMode::kAvoidWrapping
57 : turret::Aimer::WrapMode::kAvoidEdges;
58 aimer_.Update(drivetrain_status_fetcher_.get(), alliance, mode,
59 turret::Aimer::ShotMode::kShootOnTheFly);
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080060 }
61
milind upadhyayaec1aee2020-10-13 13:44:33 -070062 const float velocity = robot_speed();
63
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080064 const flatbuffers::Offset<AimerStatus> aimer_status_offset =
65 aimer_.PopulateStatus(status->fbb());
66
James Kuszmaul98154a22021-04-03 16:09:29 -070067 const double distance_to_goal = aimer_.DistanceToGoal();
68
69 aos::FlatbufferFixedAllocatorArray<
70 frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal, 64>
71 hood_goal;
72 aos::FlatbufferFixedAllocatorArray<ShooterGoal, 64> shooter_goal;
73
74 constants::Values::ShotParams shot_params;
75 if (constants::GetValues().shot_interpolation_table.GetInRange(
76 distance_to_goal, &shot_params)) {
77 hood_goal.Finish(frc971::control_loops::
78 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
79 *hood_goal.fbb(), shot_params.hood_angle));
80
81 shooter_goal.Finish(CreateShooterGoal(*shooter_goal.fbb(),
82 shot_params.accelerator_power,
83 shot_params.finisher_power));
84 } else {
85 hood_goal.Finish(
86 frc971::control_loops::
87 CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
88 *hood_goal.fbb(), constants::GetValues().hood.range.upper));
89
90 shooter_goal.Finish(CreateShooterGoal(*shooter_goal.fbb(), 0.0, 0.0));
91 }
92
Sabina Daviscf08b152020-01-31 22:12:09 -080093 OutputT output_struct;
94
Ravago Jones937587c2020-12-26 17:21:09 -080095 flatbuffers::Offset<AbsoluteAndAbsoluteEncoderProfiledJointStatus>
96 hood_status_offset = hood_.Iterate(
James Kuszmaul98154a22021-04-03 16:09:29 -070097 unsafe_goal != nullptr
98 ? (unsafe_goal->hood_tracking() ? &hood_goal.message()
99 : unsafe_goal->hood())
100 : nullptr,
Ravago Jones937587c2020-12-26 17:21:09 -0800101 position->hood(),
102 output != nullptr ? &(output_struct.hood_voltage) : nullptr,
103 status->fbb());
Sabina Daviscf08b152020-01-31 22:12:09 -0800104
Austin Schuh13e55522020-02-29 23:11:17 -0800105 if (unsafe_goal != nullptr) {
106 if (unsafe_goal->shooting() &&
107 shooting_start_time_ == aos::monotonic_clock::min_time) {
108 shooting_start_time_ = position_timestamp;
109 }
110
111 if (unsafe_goal->shooting()) {
112 constexpr std::chrono::milliseconds kPeriod =
113 std::chrono::milliseconds(250);
114 if ((position_timestamp - shooting_start_time_) % (kPeriod * 2) <
115 kPeriod) {
116 intake_joint_.set_min_position(-0.25);
117 } else {
118 intake_joint_.set_min_position(-0.75);
119 }
120 } else {
121 intake_joint_.clear_min_position();
122 }
123
124 if (!unsafe_goal->shooting()) {
125 shooting_start_time_ = aos::monotonic_clock::min_time;
126 }
127 }
128
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800129 flatbuffers::Offset<AbsoluteEncoderProfiledJointStatus> intake_status_offset =
130 intake_joint_.Iterate(
131 unsafe_goal != nullptr ? unsafe_goal->intake() : nullptr,
132 position->intake_joint(),
133 output != nullptr ? &(output_struct.intake_joint_voltage) : nullptr,
134 status->fbb());
135
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800136 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
137 *turret_goal = unsafe_goal != nullptr ? (unsafe_goal->turret_tracking()
138 ? aimer_.TurretGoal()
139 : unsafe_goal->turret())
140 : nullptr;
James Kuszmaul98154a22021-04-03 16:09:29 -0700141
Kai Tinkessfb460372020-02-08 14:05:48 -0800142 flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
143 turret_status_offset = turret_.Iterate(
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800144 turret_goal, position->turret(),
Kai Tinkessfb460372020-02-08 14:05:48 -0800145 output != nullptr ? &(output_struct.turret_voltage) : nullptr,
146 status->fbb());
147
Sabina Davis0f31d3f2020-02-20 20:41:00 -0800148 flatbuffers::Offset<ShooterStatus> shooter_status_offset =
149 shooter_.RunIteration(
James Kuszmaul98154a22021-04-03 16:09:29 -0700150 unsafe_goal != nullptr
151 ? (unsafe_goal->shooter_tracking() ? &shooter_goal.message()
152 : unsafe_goal->shooter())
153 : nullptr,
Sabina Davis0f31d3f2020-02-20 20:41:00 -0800154 position->shooter(), status->fbb(),
155 output != nullptr ? &(output_struct) : nullptr, position_timestamp);
156
John Park0a245a02020-02-02 14:10:15 -0800157 climber_.Iterate(unsafe_goal, output != nullptr ? &(output_struct) : nullptr);
158
Ravago Jones937587c2020-12-26 17:21:09 -0800159 const AbsoluteAndAbsoluteEncoderProfiledJointStatus *const hood_status =
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800160 GetMutableTemporaryPointer(*status->fbb(), hood_status_offset);
161
Austin Schuh2fb23642020-02-29 15:10:51 -0800162 const PotAndAbsoluteEncoderProfiledJointStatus *const turret_status =
163 GetMutableTemporaryPointer(*status->fbb(), turret_status_offset);
164
165 if (output != nullptr) {
166 // Friction is a pain and putting a really high burden on the integrator.
James Kuszmaul519585d2020-03-08 22:32:48 -0700167 const double turret_velocity_sign =
168 turret_status->velocity() * kTurretFrictionGain;
Austin Schuh2fb23642020-02-29 15:10:51 -0800169 output_struct.turret_voltage +=
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800170 std::clamp(turret_velocity_sign, -kTurretFrictionVoltageLimit,
Austin Schuh2fb23642020-02-29 15:10:51 -0800171 kTurretFrictionVoltageLimit);
James Kuszmaulb7fe49e2020-03-05 08:24:44 -0800172 output_struct.turret_voltage =
173 std::clamp(output_struct.turret_voltage, -turret_.operating_voltage(),
174 turret_.operating_voltage());
Austin Schuh2fb23642020-02-29 15:10:51 -0800175 }
176
Sabina Daviscf08b152020-01-31 22:12:09 -0800177 bool zeroed;
178 bool estopped;
179
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800180 {
Kai Tinkessfb460372020-02-08 14:05:48 -0800181 const AbsoluteEncoderProfiledJointStatus *const intake_status =
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800182 GetMutableTemporaryPointer(*status->fbb(), intake_status_offset);
183
Kai Tinkessfb460372020-02-08 14:05:48 -0800184 zeroed = hood_status->zeroed() && intake_status->zeroed() &&
185 turret_status->zeroed();
186 estopped = hood_status->estopped() || intake_status->estopped() ||
187 turret_status->estopped();
Stephan Massaltd021f972020-01-05 20:41:23 -0800188 }
189
190 Status::Builder status_builder = status->MakeBuilder<Status>();
191
Sabina Daviscf08b152020-01-31 22:12:09 -0800192 status_builder.add_zeroed(zeroed);
193 status_builder.add_estopped(estopped);
194
195 status_builder.add_hood(hood_status_offset);
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800196 status_builder.add_intake(intake_status_offset);
Kai Tinkessfb460372020-02-08 14:05:48 -0800197 status_builder.add_turret(turret_status_offset);
Sabina Davis0f31d3f2020-02-20 20:41:00 -0800198 status_builder.add_shooter(shooter_status_offset);
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800199 status_builder.add_aimer(aimer_status_offset);
Stephan Massaltd021f972020-01-05 20:41:23 -0800200
201 status->Send(status_builder.Finish());
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800202
203 if (output != nullptr) {
204 if (unsafe_goal) {
Austin Schuh13e55522020-02-29 23:11:17 -0800205 output_struct.washing_machine_spinner_voltage = 0.0;
Austin Schuh43a220f2020-02-26 22:02:34 -0800206 if (unsafe_goal->shooting()) {
Austin Schuh263dead2021-04-04 21:19:19 -0700207 if (shooter_.ready() && shooter_.finisher_goal() > 10.0 &&
208 shooter_.accelerator_goal() > 10.0) {
Austin Schuh93109a52020-03-04 21:37:33 -0800209 output_struct.feeder_voltage = 12.0;
Austin Schuh13e55522020-02-29 23:11:17 -0800210 } else {
211 output_struct.feeder_voltage = 0.0;
212 }
213 output_struct.washing_machine_spinner_voltage = 5.0;
214 output_struct.intake_roller_voltage = 3.0;
Austin Schuh43a220f2020-02-26 22:02:34 -0800215 } else {
216 output_struct.feeder_voltage = 0.0;
milind upadhyayaec1aee2020-10-13 13:44:33 -0700217 output_struct.intake_roller_voltage =
218 unsafe_goal->roller_voltage() +
219 std::max(velocity * unsafe_goal->roller_speed_compensation(), 0.0f);
Austin Schuh43a220f2020-02-26 22:02:34 -0800220 }
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800221 } else {
222 output_struct.intake_roller_voltage = 0.0;
223 }
224 output->Send(Output::Pack(*output->fbb(), &output_struct));
225 }
Stephan Massaltd021f972020-01-05 20:41:23 -0800226}
227
Sabina Daviscf08b152020-01-31 22:12:09 -0800228} // namespace superstructure
Stephan Massaltd021f972020-01-05 20:41:23 -0800229} // namespace control_loops
230} // namespace y2020