blob: 83d431c4de51b6c3655bf31d674c3c7dad341e48 [file] [log] [blame]
Austin Schuh99f7c6a2024-06-25 22:07:44 -07001#include "absl/flags/flag.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -07002#include "ctre/phoenix/cci/Diagnostics_CCI.h"
3#include "ctre/phoenix6/TalonFX.hpp"
4
5#include "aos/events/shm_event_loop.h"
6#include "aos/init.h"
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -07007#include "frc971/constants/constants_sender_lib.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -07008#include "frc971/control_loops/control_loops_generated.h"
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -07009#include "frc971/control_loops/swerve/swerve_drivetrain_can_position_static.h"
10#include "frc971/control_loops/swerve/swerve_drivetrain_position_static.h"
James Kuszmaul6e445c42024-07-06 13:06:23 -070011#include "frc971/queues/gyro_generated.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070012#include "frc971/wpilib/can_sensor_reader.h"
James Kuszmaulf40b6772024-06-22 16:04:03 -070013#include "frc971/wpilib/joystick_sender.h"
14#include "frc971/wpilib/pdp_fetcher.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070015#include "frc971/wpilib/sensor_reader.h"
16#include "frc971/wpilib/swerve/swerve_drivetrain_writer.h"
Maxwell Henderson10ed5c32024-01-09 12:40:54 -080017#include "frc971/wpilib/talonfx.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070018#include "frc971/wpilib/wpilib_robot_base.h"
Nikolai Sohmers3cc1fc22024-05-04 12:27:58 -070019#include "y2024_swerve/constants.h"
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -070020#include "y2024_swerve/constants/constants_generated.h"
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070021
Austin Schuh99f7c6a2024-06-25 22:07:44 -070022ABSL_FLAG(bool, ctre_diag_server, false,
23 "If true, enable the diagnostics server for interacting with "
24 "devices on the CAN bus using Phoenix Tuner");
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070025
26using frc971::wpilib::CANSensorReader;
Maxwell Henderson10ed5c32024-01-09 12:40:54 -080027using frc971::wpilib::TalonFX;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070028using frc971::wpilib::swerve::DrivetrainWriter;
29using frc971::wpilib::swerve::SwerveModule;
30
31namespace drivetrain = frc971::control_loops::drivetrain;
32
Nikolai Sohmers3cc1fc22024-05-04 12:27:58 -070033namespace y2024_swerve::wpilib {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070034namespace {
35
36template <class T>
37T value_or_exit(std::optional<T> optional) {
38 CHECK(optional.has_value());
39 return optional.value();
40}
41
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070042constexpr double kMaxFastEncoderPulsesPerSecond = std::max({
43 constants::Values::kMaxDrivetrainEncoderPulsesPerSecond(),
44});
45static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
46 "fast encoders are too fast");
47} // namespace
48
49class SensorReader : public ::frc971::wpilib::SensorReader {
50 public:
51 SensorReader(aos::ShmEventLoop *event_loop,
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -070052 std::shared_ptr<const constants::Values> values,
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -070053 const Constants *robot_constants,
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -070054 frc971::wpilib::swerve::SwerveModules modules)
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070055 : ::frc971::wpilib::SensorReader(event_loop),
56 values_(values),
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -070057 robot_constants_(robot_constants),
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070058 drivetrain_position_sender_(
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -070059 event_loop
60 ->MakeSender<frc971::control_loops::swerve::PositionStatic>(
61 "/drivetrain")),
James Kuszmaul6e445c42024-07-06 13:06:23 -070062 modules_(modules),
63 gyro_sender_(event_loop->MakeSender<::frc971::sensors::GyroReading>(
64 "/drivetrain")) {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070065 UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
66 event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({0}));
67 }
68
James Kuszmaul6e445c42024-07-06 13:06:23 -070069 void Start() override { AddToDMA(&imu_yaw_rate_reader_); }
70
71 void set_yaw_rate_input(::std::unique_ptr<frc::DigitalInput> sensor) {
72 imu_yaw_rate_input_ = ::std::move(sensor);
73 imu_yaw_rate_reader_.set_input(imu_yaw_rate_input_.get());
74 }
75
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070076 void RunIteration() override {
77 {
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -070078 auto builder = drivetrain_position_sender_.MakeStaticBuilder();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070079
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -070080 auto swerve_position_constants =
81 robot_constants_->common()->swerve_positions_constants();
82
83 modules_.front_left->PopulatePosition(builder->add_front_left(),
84 swerve_position_constants);
85 modules_.front_right->PopulatePosition(builder->add_front_right(),
86 swerve_position_constants);
87 modules_.back_left->PopulatePosition(builder->add_back_left(),
88 swerve_position_constants);
89 modules_.back_right->PopulatePosition(builder->add_back_right(),
90 swerve_position_constants);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070091
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -070092 builder.CheckOk(builder.Send());
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -070093 }
James Kuszmaul6e445c42024-07-06 13:06:23 -070094
95 {
96 auto builder = gyro_sender_.MakeBuilder();
97 ::frc971::sensors::GyroReading::Builder gyro_reading_builder =
98 builder.MakeBuilder<::frc971::sensors::GyroReading>();
99 // +/- 2000 deg / sec
100 constexpr double kMaxVelocity = 4000; // degrees / second
101 constexpr double kVelocityRadiansPerSecond =
102 kMaxVelocity / 360 * (2.0 * M_PI);
103
104 // Only part of the full range is used to prevent being 100% on or off.
105 constexpr double kScaledRangeLow = 0.1;
106 constexpr double kScaledRangeHigh = 0.9;
107
108 constexpr double kPWMFrequencyHz = 200;
109 double velocity_duty_cycle =
110 imu_yaw_rate_reader_.last_width() * kPWMFrequencyHz;
111
112 constexpr double kDutyCycleScale =
113 1 / (kScaledRangeHigh - kScaledRangeLow);
114 // scale from 0.1 - 0.9 to 0 - 1
115 double rescaled_velocity_duty_cycle =
116 (velocity_duty_cycle - kScaledRangeLow) * kDutyCycleScale;
117
118 if (!std::isnan(rescaled_velocity_duty_cycle)) {
119 gyro_reading_builder.add_velocity((rescaled_velocity_duty_cycle - 0.5) *
120 kVelocityRadiansPerSecond);
121 }
122 builder.CheckOk(builder.Send(gyro_reading_builder.Finish()));
123 }
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700124 }
125
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700126 void set_front_left_encoder(std::unique_ptr<frc::Encoder> encoder,
127 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700128 fast_encoder_filter_.Add(encoder.get());
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700129 modules_.front_left->set_rotation_encoder(std::move(encoder),
130 std::move(absolute_pwm));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700131 }
132
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700133 void set_front_right_encoder(
134 std::unique_ptr<frc::Encoder> encoder,
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700135 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700136 fast_encoder_filter_.Add(encoder.get());
137 modules_.front_right->set_rotation_encoder(std::move(encoder),
138 std::move(absolute_pwm));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700139 }
140
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700141 void set_back_left_encoder(std::unique_ptr<frc::Encoder> encoder,
142 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700143 fast_encoder_filter_.Add(encoder.get());
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700144 modules_.back_left->set_rotation_encoder(std::move(encoder),
145 std::move(absolute_pwm));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700146 }
147
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700148 void set_back_right_encoder(std::unique_ptr<frc::Encoder> encoder,
149 std::unique_ptr<frc::DigitalInput> absolute_pwm) {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700150 fast_encoder_filter_.Add(encoder.get());
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700151 modules_.back_right->set_rotation_encoder(std::move(encoder),
152 std::move(absolute_pwm));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700153 }
154
155 private:
156 std::shared_ptr<const constants::Values> values_;
157
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -0700158 const Constants *robot_constants_;
159
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700160 aos::Sender<frc971::control_loops::swerve::PositionStatic>
161 drivetrain_position_sender_;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700162
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700163 frc971::wpilib::swerve::SwerveModules modules_;
James Kuszmaul6e445c42024-07-06 13:06:23 -0700164
165 std::unique_ptr<frc::DigitalInput> imu_yaw_rate_input_;
166 frc971::wpilib::DMAPulseWidthReader imu_yaw_rate_reader_;
167 ::aos::Sender<::frc971::sensors::GyroReading> gyro_sender_;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700168};
169
170class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
171 public:
172 ::std::unique_ptr<frc::Encoder> make_encoder(int index) {
173 return std::make_unique<frc::Encoder>(10 + index * 2, 11 + index * 2, false,
174 frc::Encoder::k4X);
175 }
176 void Run() override {
177 std::shared_ptr<const constants::Values> values =
178 std::make_shared<const constants::Values>(constants::MakeValues());
179
180 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
181 aos::configuration::ReadConfig("aos_config.json");
182
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -0700183 frc971::constants::WaitForConstants<y2024_swerve::Constants>(
184 &config.message());
185
186 ::aos::ShmEventLoop constant_fetcher_event_loop(&config.message());
187
188 frc971::constants::ConstantsFetcher<Constants> constants_fetcher(
189 &constant_fetcher_event_loop);
190
191 const Constants *robot_constants = &constants_fetcher.constants();
192
193 AddLoop(&constant_fetcher_event_loop);
194
James Kuszmaulf40b6772024-06-22 16:04:03 -0700195 ::aos::ShmEventLoop joystick_sender_event_loop(&config.message());
196 ::frc971::wpilib::JoystickSender joystick_sender(
197 &joystick_sender_event_loop);
198 AddLoop(&joystick_sender_event_loop);
199
200 ::aos::ShmEventLoop pdp_fetcher_event_loop(&config.message());
201 ::frc971::wpilib::PDPFetcher pdp_fetcher(&pdp_fetcher_event_loop);
202 AddLoop(&pdp_fetcher_event_loop);
203
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700204 std::vector<ctre::phoenix6::BaseStatusSignal *> signals_registry;
Maxwell Henderson10ed5c32024-01-09 12:40:54 -0800205 std::vector<std::shared_ptr<TalonFX>> falcons;
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700206
207 // TODO(max): Change the CanBus names with TalonFX software.
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700208 frc971::wpilib::swerve::SwerveModules modules{
209 .front_left = std::make_shared<SwerveModule>(
James Kuszmaul4f1a5502024-06-22 16:04:36 -0700210 frc971::wpilib::TalonFXParams{6, true},
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700211 frc971::wpilib::TalonFXParams{5, false}, "Drivetrain Bus",
212 &signals_registry,
213 constants::Values::kDrivetrainStatorCurrentLimit(),
214 constants::Values::kDrivetrainSupplyCurrentLimit()),
215 .front_right = std::make_shared<SwerveModule>(
James Kuszmaul4f1a5502024-06-22 16:04:36 -0700216 frc971::wpilib::TalonFXParams{3, true},
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700217 frc971::wpilib::TalonFXParams{4, false}, "Drivetrain Bus",
218 &signals_registry,
219 constants::Values::kDrivetrainStatorCurrentLimit(),
220 constants::Values::kDrivetrainSupplyCurrentLimit()),
221 .back_left = std::make_shared<SwerveModule>(
James Kuszmaul4f1a5502024-06-22 16:04:36 -0700222 frc971::wpilib::TalonFXParams{7, true},
223 frc971::wpilib::TalonFXParams{8, false}, "Drivetrain Bus",
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700224 &signals_registry,
225 constants::Values::kDrivetrainStatorCurrentLimit(),
226 constants::Values::kDrivetrainSupplyCurrentLimit()),
227 .back_right = std::make_shared<SwerveModule>(
James Kuszmaul4f1a5502024-06-22 16:04:36 -0700228 frc971::wpilib::TalonFXParams{2, true},
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700229 frc971::wpilib::TalonFXParams{1, false}, "Drivetrain Bus",
230 &signals_registry,
231 constants::Values::kDrivetrainStatorCurrentLimit(),
232 constants::Values::kDrivetrainSupplyCurrentLimit())};
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700233
234 // Thread 1
235 aos::ShmEventLoop can_sensor_reader_event_loop(&config.message());
236 can_sensor_reader_event_loop.set_name("CANSensorReader");
237
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700238 modules.PopulateFalconsVector(&falcons);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700239
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700240 aos::Sender<frc971::control_loops::swerve::CanPositionStatic>
241 can_position_sender =
242 can_sensor_reader_event_loop
243 .MakeSender<frc971::control_loops::swerve::CanPositionStatic>(
244 "/drivetrain");
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700245
246 CANSensorReader can_sensor_reader(
247 &can_sensor_reader_event_loop, std::move(signals_registry), falcons,
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700248 [this, falcons, modules,
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700249 &can_position_sender](ctre::phoenix::StatusCode status) {
250 // TODO(max): use status properly in the flatbuffer.
251 (void)status;
252
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700253 aos::Sender<frc971::control_loops::swerve::CanPositionStatic>::
254 StaticBuilder builder = can_position_sender.MakeStaticBuilder();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700255
256 for (auto falcon : falcons) {
257 falcon->RefreshNontimesyncedSignals();
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700258 }
259
James Kuszmaul3f1bbf52024-06-22 15:57:44 -0700260 const frc971::wpilib::swerve::SwerveModule::ModuleGearRatios
261 gear_ratios{
262 .rotation = constants::Values::kRotationModuleRatio(),
263 .translation = constants::Values::kTranslationModuleRatio()};
264 modules.front_left->PopulateCanPosition(builder->add_front_left(),
265 gear_ratios);
266 modules.front_right->PopulateCanPosition(builder->add_front_right(),
267 gear_ratios);
268 modules.back_left->PopulateCanPosition(builder->add_back_left(),
269 gear_ratios);
270 modules.back_right->PopulateCanPosition(builder->add_back_right(),
271 gear_ratios);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700272
Maxwell Hendersondfa609a2024-01-12 20:48:36 -0800273 builder.CheckOk(builder.Send());
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700274 });
275
276 AddLoop(&can_sensor_reader_event_loop);
277
278 // Thread 2
279 // Setup CAN
Austin Schuh99f7c6a2024-06-25 22:07:44 -0700280 if (!absl::GetFlag(FLAGS_ctre_diag_server)) {
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700281 c_Phoenix_Diagnostics_SetSecondsToStart(-1);
282 c_Phoenix_Diagnostics_Dispose();
283 }
284
285 ctre::phoenix::platform::can::CANComm_SetRxSchedPriority(
286 constants::Values::kDrivetrainRxPriority, true, "Drivetrain Bus");
287 ctre::phoenix::platform::can::CANComm_SetTxSchedPriority(
288 constants::Values::kDrivetrainTxPriority, true, "Drivetrain Bus");
289
290 aos::ShmEventLoop drivetrain_writer_event_loop(&config.message());
291 drivetrain_writer_event_loop.set_name("DrivetrainWriter");
292
293 DrivetrainWriter drivetrain_writer(
294 &drivetrain_writer_event_loop,
295 constants::Values::kDrivetrainWriterPriority, 12);
296
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700297 drivetrain_writer.set_talonfxs(modules);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700298
299 AddLoop(&drivetrain_writer_event_loop);
300
301 // Thread 3
302 aos::ShmEventLoop sensor_reader_event_loop(&config.message());
303 sensor_reader_event_loop.set_name("SensorReader");
Nikolai Sohmersce9ee6e2024-07-06 17:16:20 -0700304 SensorReader sensor_reader(&sensor_reader_event_loop, values,
305 robot_constants, modules);
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700306
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700307 sensor_reader.set_front_left_encoder(
James Kuszmaule4a8c6c2024-06-14 18:27:21 -0700308 make_encoder(3), std::make_unique<frc::DigitalInput>(3));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700309
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700310 sensor_reader.set_front_right_encoder(
James Kuszmaule4a8c6c2024-06-14 18:27:21 -0700311 make_encoder(1), std::make_unique<frc::DigitalInput>(1));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700312
James Kuszmaule4a8c6c2024-06-14 18:27:21 -0700313 sensor_reader.set_back_left_encoder(make_encoder(4),
314 std::make_unique<frc::DigitalInput>(4));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700315
Nikolai Sohmers3f2a5072024-06-08 14:05:59 -0700316 sensor_reader.set_back_right_encoder(
James Kuszmaule4a8c6c2024-06-14 18:27:21 -0700317 make_encoder(0), std::make_unique<frc::DigitalInput>(0));
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700318
James Kuszmaul6e445c42024-07-06 13:06:23 -0700319 sensor_reader.set_yaw_rate_input(std::make_unique<frc::DigitalInput>(25));
320
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700321 AddLoop(&sensor_reader_event_loop);
322
323 RunLoops();
324 }
325};
326
Nikolai Sohmers3cc1fc22024-05-04 12:27:58 -0700327} // namespace y2024_swerve::wpilib
Maxwell Hendersonf63a0d92023-06-24 14:49:51 -0700328
Nikolai Sohmers3cc1fc22024-05-04 12:27:58 -0700329AOS_ROBOT_CLASS(::y2024_swerve::wpilib::WPILibRobot)