blob: 4c02a18a4461cf1048ce8ca93319c500008d5424 [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
9using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
10using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
11
12Superstructure::Superstructure(::aos::EventLoop *event_loop,
13 const ::std::string &name)
14 : aos::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
Sabina Daviscf08b152020-01-31 22:12:09 -080015 name),
Sabina Davis0f2d38c2020-02-08 17:01:21 -080016 hood_(constants::GetValues().hood),
Kai Tinkessfb460372020-02-08 14:05:48 -080017 intake_joint_(constants::GetValues().intake),
Sabina Davis0f31d3f2020-02-20 20:41:00 -080018 turret_(constants::GetValues().turret.subsystem_params),
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080019 drivetrain_status_fetcher_(
20 event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
James Kuszmaula53c3ac2020-02-22 19:36:01 -080021 "/drivetrain")),
22 joystick_state_fetcher_(
23 event_loop->MakeFetcher<aos::JoystickState>("/aos")) {
Sabina Daviscf08b152020-01-31 22:12:09 -080024 event_loop->SetRuntimeRealtimePriority(30);
Stephan Massaltd021f972020-01-05 20:41:23 -080025}
26
milind upadhyayaec1aee2020-10-13 13:44:33 -070027double Superstructure::robot_speed() const {
28 return (drivetrain_status_fetcher_.get() != nullptr
29 ? drivetrain_status_fetcher_->robot_speed()
30 : 0.0);
31}
32
Sabina Daviscf08b152020-01-31 22:12:09 -080033void Superstructure::RunIteration(const Goal *unsafe_goal,
34 const Position *position,
Stephan Massaltd021f972020-01-05 20:41:23 -080035 aos::Sender<Output>::Builder *output,
36 aos::Sender<Status>::Builder *status) {
37 if (WasReset()) {
38 AOS_LOG(ERROR, "WPILib reset, restarting\n");
Sabina Daviscf08b152020-01-31 22:12:09 -080039 hood_.Reset();
Sabina Davis0f2d38c2020-02-08 17:01:21 -080040 intake_joint_.Reset();
Kai Tinkessfb460372020-02-08 14:05:48 -080041 turret_.Reset();
Stephan Massaltd021f972020-01-05 20:41:23 -080042 }
43
Sabina Davis0f31d3f2020-02-20 20:41:00 -080044 const aos::monotonic_clock::time_point position_timestamp =
45 event_loop()->context().monotonic_event_time;
46
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080047 if (drivetrain_status_fetcher_.Fetch()) {
James Kuszmaula53c3ac2020-02-22 19:36:01 -080048 aos::Alliance alliance = aos::Alliance::kInvalid;
James Kuszmaul519585d2020-03-08 22:32:48 -070049 joystick_state_fetcher_.Fetch();
50 if (joystick_state_fetcher_.get() != nullptr) {
James Kuszmaula53c3ac2020-02-22 19:36:01 -080051 alliance = joystick_state_fetcher_->alliance();
52 }
James Kuszmaul3b393d72020-02-26 19:43:51 -080053 const turret::Aimer::WrapMode mode =
James Kuszmaulb83d6e12020-02-22 20:44:48 -080054 (unsafe_goal != nullptr && unsafe_goal->shooting())
James Kuszmaul3b393d72020-02-26 19:43:51 -080055 ? turret::Aimer::WrapMode::kAvoidWrapping
56 : turret::Aimer::WrapMode::kAvoidEdges;
57 aimer_.Update(drivetrain_status_fetcher_.get(), alliance, mode,
58 turret::Aimer::ShotMode::kShootOnTheFly);
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080059 }
60
milind upadhyayaec1aee2020-10-13 13:44:33 -070061 const float velocity = robot_speed();
62
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -080063 const flatbuffers::Offset<AimerStatus> aimer_status_offset =
64 aimer_.PopulateStatus(status->fbb());
65
Sabina Daviscf08b152020-01-31 22:12:09 -080066 OutputT output_struct;
67
68 flatbuffers::Offset<AbsoluteEncoderProfiledJointStatus> hood_status_offset =
69 hood_.Iterate(unsafe_goal != nullptr ? unsafe_goal->hood() : nullptr,
70 position->hood(),
71 output != nullptr ? &(output_struct.hood_voltage) : nullptr,
72 status->fbb());
73
Austin Schuh13e55522020-02-29 23:11:17 -080074 if (unsafe_goal != nullptr) {
75 if (unsafe_goal->shooting() &&
76 shooting_start_time_ == aos::monotonic_clock::min_time) {
77 shooting_start_time_ = position_timestamp;
78 }
79
80 if (unsafe_goal->shooting()) {
81 constexpr std::chrono::milliseconds kPeriod =
82 std::chrono::milliseconds(250);
83 if ((position_timestamp - shooting_start_time_) % (kPeriod * 2) <
84 kPeriod) {
85 intake_joint_.set_min_position(-0.25);
86 } else {
87 intake_joint_.set_min_position(-0.75);
88 }
89 } else {
90 intake_joint_.clear_min_position();
91 }
92
93 if (!unsafe_goal->shooting()) {
94 shooting_start_time_ = aos::monotonic_clock::min_time;
95 }
96 }
97
Sabina Davis0f2d38c2020-02-08 17:01:21 -080098 flatbuffers::Offset<AbsoluteEncoderProfiledJointStatus> intake_status_offset =
99 intake_joint_.Iterate(
100 unsafe_goal != nullptr ? unsafe_goal->intake() : nullptr,
101 position->intake_joint(),
102 output != nullptr ? &(output_struct.intake_joint_voltage) : nullptr,
103 status->fbb());
104
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800105 const frc971::control_loops::StaticZeroingSingleDOFProfiledSubsystemGoal
106 *turret_goal = unsafe_goal != nullptr ? (unsafe_goal->turret_tracking()
107 ? aimer_.TurretGoal()
108 : unsafe_goal->turret())
109 : nullptr;
Kai Tinkessfb460372020-02-08 14:05:48 -0800110 flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
111 turret_status_offset = turret_.Iterate(
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800112 turret_goal, position->turret(),
Kai Tinkessfb460372020-02-08 14:05:48 -0800113 output != nullptr ? &(output_struct.turret_voltage) : nullptr,
114 status->fbb());
115
Sabina Davis0f31d3f2020-02-20 20:41:00 -0800116 flatbuffers::Offset<ShooterStatus> shooter_status_offset =
117 shooter_.RunIteration(
118 unsafe_goal != nullptr ? unsafe_goal->shooter() : nullptr,
119 position->shooter(), status->fbb(),
120 output != nullptr ? &(output_struct) : nullptr, position_timestamp);
121
John Park0a245a02020-02-02 14:10:15 -0800122 climber_.Iterate(unsafe_goal, output != nullptr ? &(output_struct) : nullptr);
123
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800124 const AbsoluteEncoderProfiledJointStatus *const hood_status =
125 GetMutableTemporaryPointer(*status->fbb(), hood_status_offset);
126
Austin Schuh2fb23642020-02-29 15:10:51 -0800127 const PotAndAbsoluteEncoderProfiledJointStatus *const turret_status =
128 GetMutableTemporaryPointer(*status->fbb(), turret_status_offset);
129
130 if (output != nullptr) {
131 // Friction is a pain and putting a really high burden on the integrator.
James Kuszmaul519585d2020-03-08 22:32:48 -0700132 const double turret_velocity_sign =
133 turret_status->velocity() * kTurretFrictionGain;
Austin Schuh2fb23642020-02-29 15:10:51 -0800134 output_struct.turret_voltage +=
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800135 std::clamp(turret_velocity_sign, -kTurretFrictionVoltageLimit,
Austin Schuh2fb23642020-02-29 15:10:51 -0800136 kTurretFrictionVoltageLimit);
James Kuszmaulb7fe49e2020-03-05 08:24:44 -0800137 output_struct.turret_voltage =
138 std::clamp(output_struct.turret_voltage, -turret_.operating_voltage(),
139 turret_.operating_voltage());
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800140
141 // Friction is a pain and putting a really high burden on the integrator.
milind upadhyayaec1aee2020-10-13 13:44:33 -0700142 const double hood_velocity_sign =
143 hood_status->velocity() * kHoodFrictionGain;
Austin Schuh78f0bfd2020-02-29 23:04:21 -0800144 output_struct.hood_voltage +=
145 std::clamp(hood_velocity_sign, -kHoodFrictionVoltageLimit,
146 kHoodFrictionVoltageLimit);
147
148 // And dither the output.
149 time_ += 0.00505;
150 output_struct.hood_voltage += 1.3 * std::sin(time_ * 2.0 * M_PI * 30.0);
Austin Schuh2fb23642020-02-29 15:10:51 -0800151 }
152
Sabina Daviscf08b152020-01-31 22:12:09 -0800153 bool zeroed;
154 bool estopped;
155
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800156 {
Kai Tinkessfb460372020-02-08 14:05:48 -0800157 const AbsoluteEncoderProfiledJointStatus *const intake_status =
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800158 GetMutableTemporaryPointer(*status->fbb(), intake_status_offset);
159
Kai Tinkessfb460372020-02-08 14:05:48 -0800160 zeroed = hood_status->zeroed() && intake_status->zeroed() &&
161 turret_status->zeroed();
162 estopped = hood_status->estopped() || intake_status->estopped() ||
163 turret_status->estopped();
Stephan Massaltd021f972020-01-05 20:41:23 -0800164 }
165
166 Status::Builder status_builder = status->MakeBuilder<Status>();
167
Sabina Daviscf08b152020-01-31 22:12:09 -0800168 status_builder.add_zeroed(zeroed);
169 status_builder.add_estopped(estopped);
170
171 status_builder.add_hood(hood_status_offset);
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800172 status_builder.add_intake(intake_status_offset);
Kai Tinkessfb460372020-02-08 14:05:48 -0800173 status_builder.add_turret(turret_status_offset);
Sabina Davis0f31d3f2020-02-20 20:41:00 -0800174 status_builder.add_shooter(shooter_status_offset);
James Kuszmaulb1b2d8e2020-02-21 21:11:46 -0800175 status_builder.add_aimer(aimer_status_offset);
Stephan Massaltd021f972020-01-05 20:41:23 -0800176
177 status->Send(status_builder.Finish());
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800178
179 if (output != nullptr) {
180 if (unsafe_goal) {
Austin Schuh13e55522020-02-29 23:11:17 -0800181 output_struct.washing_machine_spinner_voltage = 0.0;
Austin Schuh43a220f2020-02-26 22:02:34 -0800182 if (unsafe_goal->shooting()) {
Austin Schuh13e55522020-02-29 23:11:17 -0800183 if (shooter_.ready() &&
184 unsafe_goal->shooter()->velocity_accelerator() > 10.0 &&
185 unsafe_goal->shooter()->velocity_finisher() > 10.0) {
Austin Schuh93109a52020-03-04 21:37:33 -0800186 output_struct.feeder_voltage = 12.0;
Austin Schuh13e55522020-02-29 23:11:17 -0800187 } else {
188 output_struct.feeder_voltage = 0.0;
189 }
190 output_struct.washing_machine_spinner_voltage = 5.0;
191 output_struct.intake_roller_voltage = 3.0;
Austin Schuh43a220f2020-02-26 22:02:34 -0800192 } else {
193 output_struct.feeder_voltage = 0.0;
milind upadhyayaec1aee2020-10-13 13:44:33 -0700194 output_struct.intake_roller_voltage =
195 unsafe_goal->roller_voltage() +
196 std::max(velocity * unsafe_goal->roller_speed_compensation(), 0.0f);
Austin Schuh43a220f2020-02-26 22:02:34 -0800197 }
Sabina Davis0f2d38c2020-02-08 17:01:21 -0800198 } else {
199 output_struct.intake_roller_voltage = 0.0;
200 }
201 output->Send(Output::Pack(*output->fbb(), &output_struct));
202 }
Stephan Massaltd021f972020-01-05 20:41:23 -0800203}
204
Sabina Daviscf08b152020-01-31 22:12:09 -0800205} // namespace superstructure
Stephan Massaltd021f972020-01-05 20:41:23 -0800206} // namespace control_loops
207} // namespace y2020