blob: 9dd3604977c56f7c5c23b396e38d860aecc7ec49 [file] [log] [blame]
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -07001#include "ctre/phoenix/cci/Diagnostics_CCI.h"
2#include "ctre/phoenix6/TalonFX.hpp"
3
4#include "aos/events/shm_event_loop.h"
5#include "aos/init.h"
6#include "frc971/control_loops/control_loops_generated.h"
7#include "frc971/wpilib/can_sensor_reader.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -07008#include "frc971/wpilib/sensor_reader.h"
9#include "frc971/wpilib/swerve/swerve_drivetrain_writer.h"
Maxwell Henderson10ed5c32024-01-09 12:40:54 -080010#include "frc971/wpilib/talonfx.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070011#include "frc971/wpilib/wpilib_robot_base.h"
12#include "y2023_bot4/constants.h"
Maxwell Hendersondfa609a2024-01-12 20:48:36 -080013#include "y2023_bot4/drivetrain_can_position_static.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070014#include "y2023_bot4/drivetrain_position_generated.h"
15
16DEFINE_bool(ctre_diag_server, false,
17 "If true, enable the diagnostics server for interacting with "
18 "devices on the CAN bus using Phoenix Tuner");
19
20using frc971::wpilib::CANSensorReader;
Maxwell Henderson10ed5c32024-01-09 12:40:54 -080021using frc971::wpilib::TalonFX;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070022using frc971::wpilib::swerve::DrivetrainWriter;
23using frc971::wpilib::swerve::SwerveModule;
24
25namespace drivetrain = frc971::control_loops::drivetrain;
26
27namespace y2023_bot4 {
28namespace wpilib {
29namespace {
30
31template <class T>
32T value_or_exit(std::optional<T> optional) {
33 CHECK(optional.has_value());
34 return optional.value();
35}
36
37flatbuffers::Offset<frc971::AbsolutePosition> module_offset(
38 frc971::AbsolutePosition::Builder builder,
39 frc971::wpilib::AbsoluteEncoder *module) {
40 builder.add_encoder(module->ReadRelativeEncoder());
41 builder.add_absolute_encoder(module->ReadAbsoluteEncoder());
42
43 return builder.Finish();
44}
45
Maxwell Hendersondfa609a2024-01-12 20:48:36 -080046void populate_can_module(SwerveModuleCANPositionStatic *can_position,
47 std::shared_ptr<SwerveModule> module) {
48 auto rotation = can_position->add_rotation();
49 module->rotation->SerializePosition(rotation, 1.0);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070050
Maxwell Hendersondfa609a2024-01-12 20:48:36 -080051 auto translation = can_position->add_translation();
52 module->translation->SerializePosition(translation, 1.0);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070053}
54
55constexpr double kMaxFastEncoderPulsesPerSecond = std::max({
56 constants::Values::kMaxDrivetrainEncoderPulsesPerSecond(),
57});
58static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
59 "fast encoders are too fast");
60} // namespace
61
62class SensorReader : public ::frc971::wpilib::SensorReader {
63 public:
64 SensorReader(aos::ShmEventLoop *event_loop,
65 std::shared_ptr<const constants::Values> values)
66 : ::frc971::wpilib::SensorReader(event_loop),
67 values_(values),
68 drivetrain_position_sender_(
69 event_loop->MakeSender<AbsoluteDrivetrainPosition>("/drivetrain")) {
70 UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
71 event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({0}));
72 }
73
74 void RunIteration() override {
75 {
76 auto builder = drivetrain_position_sender_.MakeBuilder();
77
78 auto front_left_offset =
79 module_offset(builder.MakeBuilder<frc971::AbsolutePosition>(),
80 &front_left_encoder_);
81 auto front_right_offset =
82 module_offset(builder.MakeBuilder<frc971::AbsolutePosition>(),
83 &front_right_encoder_);
84 auto back_left_offset = module_offset(
85 builder.MakeBuilder<frc971::AbsolutePosition>(), &back_left_encoder_);
86 auto back_right_offset =
87 module_offset(builder.MakeBuilder<frc971::AbsolutePosition>(),
88 &back_right_encoder_);
89
90 AbsoluteDrivetrainPosition::Builder drivetrain_position_builder =
91 builder.MakeBuilder<AbsoluteDrivetrainPosition>();
92
93 drivetrain_position_builder.add_follower_wheel_one_position(
94 follower_wheel_one_encoder_->GetRaw());
95 drivetrain_position_builder.add_follower_wheel_two_position(
96 follower_wheel_two_encoder_->GetRaw());
97
98 drivetrain_position_builder.add_front_left_position(front_left_offset);
99 drivetrain_position_builder.add_front_right_position(front_right_offset);
100 drivetrain_position_builder.add_back_left_position(back_left_offset);
101 drivetrain_position_builder.add_back_right_position(back_right_offset);
102
103 builder.CheckOk(builder.Send(drivetrain_position_builder.Finish()));
104 }
105 }
106
107 void set_follower_wheel_one_encoder(std::unique_ptr<frc::Encoder> encoder) {
108 fast_encoder_filter_.Add(encoder.get());
109 follower_wheel_one_encoder_ = std::move(encoder);
110 follower_wheel_one_encoder_->SetMaxPeriod(0.005);
111 }
112 void set_follower_wheel_two_encoder(std::unique_ptr<frc::Encoder> encoder) {
113 fast_encoder_filter_.Add(encoder.get());
114 follower_wheel_two_encoder_ = std::move(encoder);
115 follower_wheel_two_encoder_->SetMaxPeriod(0.005);
116 }
117
118 void set_front_left_encoder(std::unique_ptr<frc::Encoder> encoder) {
119 fast_encoder_filter_.Add(encoder.get());
120 front_left_encoder_.set_encoder(std::move(encoder));
121 }
122 void set_front_left_absolute_pwm(
123 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
124 front_left_encoder_.set_absolute_pwm(std::move(absolute_pwm));
125 }
126
127 void set_front_right_encoder(std::unique_ptr<frc::Encoder> encoder) {
128 fast_encoder_filter_.Add(encoder.get());
129 front_right_encoder_.set_encoder(std::move(encoder));
130 }
131 void set_front_right_absolute_pwm(
132 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
133 front_right_encoder_.set_absolute_pwm(std::move(absolute_pwm));
134 }
135
136 void set_back_left_encoder(std::unique_ptr<frc::Encoder> encoder) {
137 fast_encoder_filter_.Add(encoder.get());
138 back_left_encoder_.set_encoder(std::move(encoder));
139 }
140 void set_back_left_absolute_pwm(
141 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
142 back_left_encoder_.set_absolute_pwm(std::move(absolute_pwm));
143 }
144
145 void set_back_right_encoder(std::unique_ptr<frc::Encoder> encoder) {
146 fast_encoder_filter_.Add(encoder.get());
147 back_right_encoder_.set_encoder(std::move(encoder));
148 }
149 void set_back_right_absolute_pwm(
150 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
151 back_right_encoder_.set_absolute_pwm(std::move(absolute_pwm));
152 }
153
154 private:
155 std::shared_ptr<const constants::Values> values_;
156
157 aos::Sender<AbsoluteDrivetrainPosition> drivetrain_position_sender_;
158
159 std::unique_ptr<frc::Encoder> follower_wheel_one_encoder_,
160 follower_wheel_two_encoder_;
161
162 frc971::wpilib::AbsoluteEncoder front_left_encoder_, front_right_encoder_,
163 back_left_encoder_, back_right_encoder_;
164};
165
166class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
167 public:
168 ::std::unique_ptr<frc::Encoder> make_encoder(int index) {
169 return std::make_unique<frc::Encoder>(10 + index * 2, 11 + index * 2, false,
170 frc::Encoder::k4X);
171 }
172 void Run() override {
173 std::shared_ptr<const constants::Values> values =
174 std::make_shared<const constants::Values>(constants::MakeValues());
175
176 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
177 aos::configuration::ReadConfig("aos_config.json");
178
179 std::vector<ctre::phoenix6::BaseStatusSignal *> signals_registry;
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800180 std::vector<std::shared_ptr<TalonFX>> falcons;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700181
182 // TODO(max): Change the CanBus names with TalonFX software.
183 std::shared_ptr<SwerveModule> front_left = std::make_shared<SwerveModule>(
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800184 frc971::wpilib::TalonFXParams{6, false},
185 frc971::wpilib::TalonFXParams{5, false}, "Drivetrain Bus",
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700186 &signals_registry, constants::Values::kDrivetrainStatorCurrentLimit(),
187 constants::Values::kDrivetrainSupplyCurrentLimit());
188 std::shared_ptr<SwerveModule> front_right = std::make_shared<SwerveModule>(
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800189 frc971::wpilib::TalonFXParams{3, false},
190 frc971::wpilib::TalonFXParams{4, false}, "Drivetrain Bus",
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700191 &signals_registry, constants::Values::kDrivetrainStatorCurrentLimit(),
192 constants::Values::kDrivetrainSupplyCurrentLimit());
193 std::shared_ptr<SwerveModule> back_left = std::make_shared<SwerveModule>(
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800194 frc971::wpilib::TalonFXParams{8, false},
195 frc971::wpilib::TalonFXParams{7, false}, "Drivetrain Bus",
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700196 &signals_registry, constants::Values::kDrivetrainStatorCurrentLimit(),
197 constants::Values::kDrivetrainSupplyCurrentLimit());
198 std::shared_ptr<SwerveModule> back_right = std::make_shared<SwerveModule>(
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800199 frc971::wpilib::TalonFXParams{2, false},
200 frc971::wpilib::TalonFXParams{1, false}, "Drivetrain Bus",
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700201 &signals_registry, constants::Values::kDrivetrainStatorCurrentLimit(),
202 constants::Values::kDrivetrainSupplyCurrentLimit());
203
204 // Thread 1
205 aos::ShmEventLoop can_sensor_reader_event_loop(&config.message());
206 can_sensor_reader_event_loop.set_name("CANSensorReader");
207
208 falcons.push_back(front_left->rotation);
209 falcons.push_back(front_left->translation);
210
211 falcons.push_back(front_right->rotation);
212 falcons.push_back(front_right->translation);
213
214 falcons.push_back(back_left->rotation);
215 falcons.push_back(back_left->translation);
216
217 falcons.push_back(back_right->rotation);
218 falcons.push_back(back_right->translation);
219
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800220 aos::Sender<AbsoluteCANPositionStatic> can_position_sender =
221 can_sensor_reader_event_loop.MakeSender<AbsoluteCANPositionStatic>(
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700222 "/drivetrain");
223
224 CANSensorReader can_sensor_reader(
225 &can_sensor_reader_event_loop, std::move(signals_registry), falcons,
226 [this, falcons, front_left, front_right, back_left, back_right,
227 &can_position_sender](ctre::phoenix::StatusCode status) {
228 // TODO(max): use status properly in the flatbuffer.
229 (void)status;
230
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800231 aos::Sender<AbsoluteCANPositionStatic>::StaticBuilder builder =
232 can_position_sender.MakeStaticBuilder();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700233
234 for (auto falcon : falcons) {
235 falcon->RefreshNontimesyncedSignals();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700236 }
237
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800238 auto front_left_flatbuffer = builder->add_front_left();
239 auto front_right_flatbuffer = builder->add_front_right();
240 auto back_left_flatbuffer = builder->add_back_left();
241 auto back_right_flatbuffer = builder->add_back_right();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700242
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800243 populate_can_module(front_left_flatbuffer, front_left);
244 populate_can_module(front_right_flatbuffer, front_right);
245 populate_can_module(back_left_flatbuffer, back_left);
246 populate_can_module(back_right_flatbuffer, back_right);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700247
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800248 builder.CheckOk(builder.Send());
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700249 });
250
251 AddLoop(&can_sensor_reader_event_loop);
252
253 // Thread 2
254 // Setup CAN
255 if (!FLAGS_ctre_diag_server) {
256 c_Phoenix_Diagnostics_SetSecondsToStart(-1);
257 c_Phoenix_Diagnostics_Dispose();
258 }
259
260 ctre::phoenix::platform::can::CANComm_SetRxSchedPriority(
261 constants::Values::kDrivetrainRxPriority, true, "Drivetrain Bus");
262 ctre::phoenix::platform::can::CANComm_SetTxSchedPriority(
263 constants::Values::kDrivetrainTxPriority, true, "Drivetrain Bus");
264
265 aos::ShmEventLoop drivetrain_writer_event_loop(&config.message());
266 drivetrain_writer_event_loop.set_name("DrivetrainWriter");
267
268 DrivetrainWriter drivetrain_writer(
269 &drivetrain_writer_event_loop,
270 constants::Values::kDrivetrainWriterPriority, 12);
271
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800272 drivetrain_writer.set_talonfxs(front_left, front_right, back_left,
273 back_right);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700274
275 AddLoop(&drivetrain_writer_event_loop);
276
277 // Thread 3
278 aos::ShmEventLoop sensor_reader_event_loop(&config.message());
279 sensor_reader_event_loop.set_name("SensorReader");
280 SensorReader sensor_reader(&sensor_reader_event_loop, values);
281
282 sensor_reader.set_follower_wheel_one_encoder(make_encoder(4));
283 sensor_reader.set_follower_wheel_two_encoder(make_encoder(5));
284
285 sensor_reader.set_front_left_encoder(make_encoder(1));
286 sensor_reader.set_front_left_absolute_pwm(
287 std::make_unique<frc::DigitalInput>(1));
288
289 sensor_reader.set_front_right_encoder(make_encoder(0));
290 sensor_reader.set_front_right_absolute_pwm(
291 std::make_unique<frc::DigitalInput>(0));
292
293 sensor_reader.set_back_left_encoder(make_encoder(2));
294 sensor_reader.set_back_left_absolute_pwm(
295 std::make_unique<frc::DigitalInput>(2));
296
297 sensor_reader.set_back_right_encoder(make_encoder(3));
298 sensor_reader.set_back_right_absolute_pwm(
299 std::make_unique<frc::DigitalInput>(3));
300
301 AddLoop(&sensor_reader_event_loop);
302
303 RunLoops();
304 }
305};
306
307} // namespace wpilib
308} // namespace y2023_bot4
309
310AOS_ROBOT_CLASS(::y2023_bot4::wpilib::WPILibRobot)