blob: bf04774b1c55e6da629664da824bd2f30abfa533 [file] [log] [blame]
milind-u086d7262022-01-19 20:44:18 -08001#include "y2022/control_loops/superstructure/superstructure.h"
2
3#include "aos/events/event_loop.h"
4
5namespace y2022 {
6namespace control_loops {
7namespace superstructure {
8
9using frc971::control_loops::AbsoluteEncoderProfiledJointStatus;
10using frc971::control_loops::PotAndAbsoluteEncoderProfiledJointStatus;
Henry Speiser55aa3ba2022-02-21 23:21:12 -080011using frc971::control_loops::RelativeEncoderProfiledJointStatus;
milind-u086d7262022-01-19 20:44:18 -080012
13Superstructure::Superstructure(::aos::EventLoop *event_loop,
Henry Speiser55aa3ba2022-02-21 23:21:12 -080014 std::shared_ptr<const constants::Values> values,
milind-u086d7262022-01-19 20:44:18 -080015 const ::std::string &name)
16 : frc971::controls::ControlLoop<Goal, Position, Status, Output>(event_loop,
Siddhant Kanwar0e37f592022-02-21 19:26:50 -080017 name),
Henry Speiser55aa3ba2022-02-21 23:21:12 -080018
19 climber_(values->climber.subsystem_params),
20 intake_front_(values->intake_front.subsystem_params),
21 intake_back_(values->intake_back.subsystem_params),
22 turret_(values->turret.subsystem_params),
23 drivetrain_status_fetcher_(
24 event_loop->MakeFetcher<frc971::control_loops::drivetrain::Status>(
25 "/drivetrain")) {
milind-u086d7262022-01-19 20:44:18 -080026 event_loop->SetRuntimeRealtimePriority(30);
27}
28
29void Superstructure::RunIteration(const Goal *unsafe_goal,
Siddhant Kanwar0e37f592022-02-21 19:26:50 -080030 const Position *position,
milind-u086d7262022-01-19 20:44:18 -080031 aos::Sender<Output>::Builder *output,
32 aos::Sender<Status>::Builder *status) {
33 if (WasReset()) {
34 AOS_LOG(ERROR, "WPILib reset, restarting\n");
Henry Speiser55aa3ba2022-02-21 23:21:12 -080035 intake_front_.Reset();
36 intake_back_.Reset();
37 turret_.Reset();
38 climber_.Reset();
39 }
40
41 drivetrain_status_fetcher_.Fetch();
42 const float velocity = robot_velocity();
43
44 double roller_speed_compensated_front = 0;
45 double roller_speed_compensated_back = 0;
46 double transfer_roller_speed = 0;
47
48 if (unsafe_goal != nullptr) {
49 roller_speed_compensated_front =
50 unsafe_goal->roller_speed_front() +
51 std::max(velocity * unsafe_goal->roller_speed_compensation(), 0.0);
52
53 roller_speed_compensated_back =
54 unsafe_goal->roller_speed_back() -
55 std::min(velocity * unsafe_goal->roller_speed_compensation(), 0.0);
56
57 transfer_roller_speed = unsafe_goal->transfer_roller_speed();
milind-u086d7262022-01-19 20:44:18 -080058 }
59
Siddhant Kanwar0e37f592022-02-21 19:26:50 -080060 OutputT output_struct;
61
62 flatbuffers::Offset<RelativeEncoderProfiledJointStatus>
63 climber_status_offset = climber_.Iterate(
64 unsafe_goal != nullptr ? unsafe_goal->climber() : nullptr,
65 position->climber(),
66 output != nullptr ? &(output_struct.climber_voltage) : nullptr,
67 status->fbb());
68
Henry Speiser55aa3ba2022-02-21 23:21:12 -080069 flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
70 intake_status_offset_front = intake_front_.Iterate(
71 unsafe_goal != nullptr ? unsafe_goal->intake_front() : nullptr,
72 position->intake_front(),
73 output != nullptr ? &(output_struct.intake_voltage_front) : nullptr,
74 status->fbb());
75
76 flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
77 intake_status_offset_back = intake_back_.Iterate(
78 unsafe_goal != nullptr ? unsafe_goal->intake_back() : nullptr,
79 position->intake_back(),
80 output != nullptr ? &(output_struct.intake_voltage_back) : nullptr,
81 status->fbb());
82
83 flatbuffers::Offset<PotAndAbsoluteEncoderProfiledJointStatus>
84 turret_status_offset = turret_.Iterate(
85 unsafe_goal != nullptr ? unsafe_goal->turret() : nullptr,
86 position->turret(),
87 output != nullptr ? &(output_struct.turret_voltage) : nullptr,
88 status->fbb());
89
Siddhant Kanwar0e37f592022-02-21 19:26:50 -080090 if (output != nullptr) {
Henry Speiser55aa3ba2022-02-21 23:21:12 -080091 output_struct.roller_voltage_front = roller_speed_compensated_front;
92 output_struct.roller_voltage_back = roller_speed_compensated_back;
93 output_struct.transfer_roller_voltage = transfer_roller_speed;
94
milind-u086d7262022-01-19 20:44:18 -080095 output->CheckOk(output->Send(Output::Pack(*output->fbb(), &output_struct)));
96 }
97
98 Status::Builder status_builder = status->MakeBuilder<Status>();
99
Henry Speiser55aa3ba2022-02-21 23:21:12 -0800100 const bool zeroed = intake_front_.zeroed() && intake_back_.zeroed() &&
101 turret_.zeroed() && climber_.zeroed();
102 const bool estopped = intake_front_.estopped() || intake_back_.estopped() ||
103 turret_.estopped() || climber_.zeroed();
104
105 status_builder.add_zeroed(zeroed);
106 status_builder.add_estopped(estopped);
107
108 status_builder.add_intake_front(intake_status_offset_front);
109 status_builder.add_intake_back(intake_status_offset_back);
110 status_builder.add_turret(turret_status_offset);
Siddhant Kanwar0e37f592022-02-21 19:26:50 -0800111 status_builder.add_climber(climber_status_offset);
milind-u086d7262022-01-19 20:44:18 -0800112
milind-u086d7262022-01-19 20:44:18 -0800113 (void)status->Send(status_builder.Finish());
114}
115
Henry Speiser55aa3ba2022-02-21 23:21:12 -0800116double Superstructure::robot_velocity() const {
117 return (drivetrain_status_fetcher_.get() != nullptr
118 ? drivetrain_status_fetcher_->robot_speed()
119 : 0.0);
120}
121
milind-u086d7262022-01-19 20:44:18 -0800122} // namespace superstructure
123} // namespace control_loops
124} // namespace y2022