blob: abf11da1cfe96b51cdfb986ee4d0fded4a2395dd [file] [log] [blame]
Maxwell Hendersonad312342023-01-10 12:07:47 -08001#include <unistd.h>
2
3#include <array>
4#include <chrono>
5#include <cinttypes>
6#include <cmath>
7#include <cstdio>
8#include <cstring>
9#include <functional>
10#include <memory>
11#include <mutex>
12#include <thread>
13
14#include "ctre/phoenix/CANifier.h"
Philipp Schrader790cb542023-07-05 21:06:52 -070015
Maxwell Hendersonad312342023-01-10 12:07:47 -080016#include "frc971/wpilib/ahal/AnalogInput.h"
17#include "frc971/wpilib/ahal/Counter.h"
18#include "frc971/wpilib/ahal/DigitalGlitchFilter.h"
19#include "frc971/wpilib/ahal/DriverStation.h"
20#include "frc971/wpilib/ahal/Encoder.h"
21#include "frc971/wpilib/ahal/Servo.h"
22#include "frc971/wpilib/ahal/TalonFX.h"
23#include "frc971/wpilib/ahal/VictorSP.h"
24#undef ERROR
25
Philipp Schrader790cb542023-07-05 21:06:52 -070026#include "ctre/phoenix/cci/Diagnostics_CCI.h"
27#include "ctre/phoenix/motorcontrol/can/TalonFX.h"
28#include "ctre/phoenix/motorcontrol/can/TalonSRX.h"
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -070029#include "ctre/phoenix6/TalonFX.hpp"
Philipp Schrader790cb542023-07-05 21:06:52 -070030
Maxwell Hendersonad312342023-01-10 12:07:47 -080031#include "aos/commonmath.h"
Ravago Jones2060ee62023-02-03 18:12:24 -080032#include "aos/containers/sized_array.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080033#include "aos/events/event_loop.h"
34#include "aos/events/shm_event_loop.h"
35#include "aos/init.h"
36#include "aos/logging/logging.h"
37#include "aos/realtime.h"
38#include "aos/time/time.h"
39#include "aos/util/log_interval.h"
40#include "aos/util/phased_loop.h"
41#include "aos/util/wrapping_counter.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080042#include "frc971/autonomous/auto_mode_generated.h"
Maxwell Hendersonf8c96892023-06-28 19:55:59 -070043#include "frc971/can_configuration_generated.h"
Maxwell Hendersoncef6f042023-05-26 14:38:09 -070044#include "frc971/control_loops/drivetrain/drivetrain_can_position_generated.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080045#include "frc971/control_loops/drivetrain/drivetrain_position_generated.h"
46#include "frc971/input/robot_state_generated.h"
47#include "frc971/queues/gyro_generated.h"
48#include "frc971/wpilib/ADIS16448.h"
49#include "frc971/wpilib/buffered_pcm.h"
50#include "frc971/wpilib/buffered_solenoid.h"
51#include "frc971/wpilib/dma.h"
52#include "frc971/wpilib/drivetrain_writer.h"
53#include "frc971/wpilib/encoder_and_potentiometer.h"
54#include "frc971/wpilib/joystick_sender.h"
55#include "frc971/wpilib/logging_generated.h"
56#include "frc971/wpilib/loop_output_handler.h"
57#include "frc971/wpilib/pdp_fetcher.h"
58#include "frc971/wpilib/sensor_reader.h"
59#include "frc971/wpilib/wpilib_robot_base.h"
60#include "y2023/constants.h"
Maxwell Henderson2a2faa62023-03-11 15:05:46 -080061#include "y2023/control_loops/superstructure/led_indicator.h"
Maxwell Hendersonad312342023-01-10 12:07:47 -080062#include "y2023/control_loops/superstructure/superstructure_output_generated.h"
63#include "y2023/control_loops/superstructure/superstructure_position_generated.h"
64
Ravago Jones2060ee62023-02-03 18:12:24 -080065DEFINE_bool(ctre_diag_server, false,
66 "If true, enable the diagnostics server for interacting with "
67 "devices on the CAN bus using Phoenix Tuner");
68
Maxwell Hendersonad312342023-01-10 12:07:47 -080069using ::aos::monotonic_clock;
Maxwell Hendersonf8c96892023-06-28 19:55:59 -070070using ::frc971::CANConfiguration;
Maxwell Hendersonad312342023-01-10 12:07:47 -080071using ::y2023::constants::Values;
72namespace superstructure = ::y2023::control_loops::superstructure;
Ravago Jones2060ee62023-02-03 18:12:24 -080073namespace drivetrain = ::y2023::control_loops::drivetrain;
Maxwell Hendersonad312342023-01-10 12:07:47 -080074namespace chrono = ::std::chrono;
75using std::make_unique;
76
77namespace y2023 {
78namespace wpilib {
79namespace {
80
81constexpr double kMaxBringupPower = 12.0;
82
83// TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
84// DMA stuff and then removing the * 2.0 in *_translate.
85// The low bit is direction.
86
87double drivetrain_velocity_translate(double in) {
88 return (((1.0 / in) / Values::kDrivetrainCyclesPerRevolution()) *
89 (2.0 * M_PI)) *
90 Values::kDrivetrainEncoderRatio() *
91 control_loops::drivetrain::kWheelRadius;
92}
93
milind-u18934eb2023-02-20 16:28:58 -080094double proximal_pot_translate(double voltage) {
95 return voltage * Values::kProximalPotRadiansPerVolt();
96}
97
98double distal_pot_translate(double voltage) {
99 return voltage * Values::kDistalPotRadiansPerVolt();
100}
101
102double roll_joint_pot_translate(double voltage) {
103 return voltage * Values::kRollJointPotRadiansPerVolt();
104}
105
106constexpr double kMaxFastEncoderPulsesPerSecond = std::max({
107 Values::kMaxDrivetrainEncoderPulsesPerSecond(),
108 Values::kMaxProximalEncoderPulsesPerSecond(),
109 Values::kMaxDistalEncoderPulsesPerSecond(),
110 Values::kMaxRollJointEncoderPulsesPerSecond(),
Austin Schuhe5248cd2023-03-05 12:46:16 -0800111 Values::kMaxCompWristEncoderPulsesPerSecond(),
112 Values::kMaxPracticeWristEncoderPulsesPerSecond(),
milind-u18934eb2023-02-20 16:28:58 -0800113});
114static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
115 "fast encoders are too fast");
Maxwell Hendersonad312342023-01-10 12:07:47 -0800116
117} // namespace
118
milind-u738832d2023-02-24 19:55:54 -0800119static constexpr int kCANFalconCount = 6;
milind-u738832d2023-02-24 19:55:54 -0800120static constexpr units::frequency::hertz_t kCANUpdateFreqHz = 200_Hz;
121
122class Falcon {
123 public:
124 Falcon(int device_id, std::string canbus,
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700125 std::vector<ctre::phoenix6::BaseStatusSignal *> *signals)
milind-u738832d2023-02-24 19:55:54 -0800126 : talon_(device_id, canbus),
127 device_id_(device_id),
128 device_temp_(talon_.GetDeviceTemp()),
129 supply_voltage_(talon_.GetSupplyVoltage()),
130 supply_current_(talon_.GetSupplyCurrent()),
131 torque_current_(talon_.GetTorqueCurrent()),
Ravago Jones088ca772023-03-25 22:14:24 -0700132 position_(talon_.GetPosition()),
133 duty_cycle_(talon_.GetDutyCycle()) {
milind-u738832d2023-02-24 19:55:54 -0800134 // device temp is not timesynced so don't add it to the list of signals
135 device_temp_.SetUpdateFrequency(kCANUpdateFreqHz);
136
milind-u738832d2023-02-24 19:55:54 -0800137 CHECK_NOTNULL(signals);
milind-u738832d2023-02-24 19:55:54 -0800138
139 supply_voltage_.SetUpdateFrequency(kCANUpdateFreqHz);
140 signals->push_back(&supply_voltage_);
141
142 supply_current_.SetUpdateFrequency(kCANUpdateFreqHz);
143 signals->push_back(&supply_current_);
144
145 torque_current_.SetUpdateFrequency(kCANUpdateFreqHz);
146 signals->push_back(&torque_current_);
147
148 position_.SetUpdateFrequency(kCANUpdateFreqHz);
149 signals->push_back(&position_);
Ravago Jones088ca772023-03-25 22:14:24 -0700150
151 duty_cycle_.SetUpdateFrequency(kCANUpdateFreqHz);
152 signals->push_back(&duty_cycle_);
milind-u738832d2023-02-24 19:55:54 -0800153 }
154
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800155 void PrintConfigs() {
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700156 ctre::phoenix6::configs::TalonFXConfiguration configuration;
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800157 ctre::phoenix::StatusCode status =
158 talon_.GetConfigurator().Refresh(configuration);
159 if (!status.IsOK()) {
160 AOS_LOG(ERROR, "Failed to get falcon configuration: %s: %s",
161 status.GetName(), status.GetDescription());
162 }
163 AOS_LOG(INFO, "configuration: %s", configuration.ToString().c_str());
164 }
165
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700166 void WriteConfigs(ctre::phoenix6::signals::InvertedValue invert) {
milind-u738832d2023-02-24 19:55:54 -0800167 inverted_ = invert;
168
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700169 ctre::phoenix6::configs::CurrentLimitsConfigs current_limits;
milind-u738832d2023-02-24 19:55:54 -0800170 current_limits.StatorCurrentLimit =
171 constants::Values::kDrivetrainStatorCurrentLimit();
172 current_limits.StatorCurrentLimitEnable = true;
173 current_limits.SupplyCurrentLimit =
174 constants::Values::kDrivetrainSupplyCurrentLimit();
175 current_limits.SupplyCurrentLimitEnable = true;
176
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700177 ctre::phoenix6::configs::MotorOutputConfigs output_configs;
milind-u738832d2023-02-24 19:55:54 -0800178 output_configs.NeutralMode =
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700179 ctre::phoenix6::signals::NeutralModeValue::Brake;
milind-u738832d2023-02-24 19:55:54 -0800180 output_configs.DutyCycleNeutralDeadband = 0;
181
182 output_configs.Inverted = inverted_;
183
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700184 ctre::phoenix6::configs::TalonFXConfiguration configuration;
milind-u738832d2023-02-24 19:55:54 -0800185 configuration.CurrentLimits = current_limits;
186 configuration.MotorOutput = output_configs;
187
188 ctre::phoenix::StatusCode status =
189 talon_.GetConfigurator().Apply(configuration);
190 if (!status.IsOK()) {
191 AOS_LOG(ERROR, "Failed to set falcon configuration: %s: %s",
192 status.GetName(), status.GetDescription());
193 }
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800194
195 PrintConfigs();
milind-u738832d2023-02-24 19:55:54 -0800196 }
197
198 void WriteRollerConfigs() {
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700199 ctre::phoenix6::configs::CurrentLimitsConfigs current_limits;
milind-u738832d2023-02-24 19:55:54 -0800200 current_limits.StatorCurrentLimit =
201 constants::Values::kRollerStatorCurrentLimit();
202 current_limits.StatorCurrentLimitEnable = true;
203 current_limits.SupplyCurrentLimit =
204 constants::Values::kRollerSupplyCurrentLimit();
205 current_limits.SupplyCurrentLimitEnable = true;
206
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700207 ctre::phoenix6::configs::MotorOutputConfigs output_configs;
milind-u738832d2023-02-24 19:55:54 -0800208 output_configs.NeutralMode =
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700209 ctre::phoenix6::signals::NeutralModeValue::Brake;
milind-u738832d2023-02-24 19:55:54 -0800210 output_configs.DutyCycleNeutralDeadband = 0;
211
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700212 ctre::phoenix6::configs::TalonFXConfiguration configuration;
milind-u738832d2023-02-24 19:55:54 -0800213 configuration.CurrentLimits = current_limits;
214 configuration.MotorOutput = output_configs;
215
216 ctre::phoenix::StatusCode status =
217 talon_.GetConfigurator().Apply(configuration);
218 if (!status.IsOK()) {
219 AOS_LOG(ERROR, "Failed to set falcon configuration: %s: %s",
220 status.GetName(), status.GetDescription());
221 }
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800222
223 PrintConfigs();
milind-u738832d2023-02-24 19:55:54 -0800224 }
225
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700226 ctre::phoenix6::hardware::TalonFX *talon() { return &talon_; }
milind-u738832d2023-02-24 19:55:54 -0800227
Maxwell Hendersonca1d18f2023-07-26 21:06:14 -0700228 flatbuffers::Offset<frc971::control_loops::CANFalcon> WritePosition(
229 flatbuffers::FlatBufferBuilder *fbb) {
230 frc971::control_loops::CANFalcon::Builder builder(*fbb);
milind-u738832d2023-02-24 19:55:54 -0800231 builder.add_id(device_id_);
232 builder.add_device_temp(device_temp());
233 builder.add_supply_voltage(supply_voltage());
234 builder.add_supply_current(supply_current());
235 builder.add_torque_current(torque_current());
Ravago Jones088ca772023-03-25 22:14:24 -0700236 builder.add_duty_cycle(duty_cycle());
milind-u738832d2023-02-24 19:55:54 -0800237
238 double invert =
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700239 (inverted_ == ctre::phoenix6::signals::InvertedValue::Clockwise_Positive
milind-u738832d2023-02-24 19:55:54 -0800240 ? 1
241 : -1);
242
243 builder.add_position(
244 constants::Values::DrivetrainCANEncoderToMeters(position()) * invert);
245
246 return builder.Finish();
247 }
248
249 int device_id() const { return device_id_; }
250 float device_temp() const { return device_temp_.GetValue().value(); }
251 float supply_voltage() const { return supply_voltage_.GetValue().value(); }
252 float supply_current() const { return supply_current_.GetValue().value(); }
253 float torque_current() const { return torque_current_.GetValue().value(); }
Ravago Jones088ca772023-03-25 22:14:24 -0700254 float duty_cycle() const { return duty_cycle_.GetValue().value(); }
milind-u738832d2023-02-24 19:55:54 -0800255 float position() const { return position_.GetValue().value(); }
256
257 // returns the monotonic timestamp of the latest timesynced reading in the
258 // timebase of the the syncronized CAN bus clock.
259 int64_t GetTimestamp() {
260 std::chrono::nanoseconds latest_timestamp =
261 torque_current_.GetTimestamp().GetTime();
262
263 return latest_timestamp.count();
264 }
265
266 void RefreshNontimesyncedSignals() { device_temp_.Refresh(); };
267
268 private:
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700269 ctre::phoenix6::hardware::TalonFX talon_;
milind-u738832d2023-02-24 19:55:54 -0800270 int device_id_;
271
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700272 ctre::phoenix6::signals::InvertedValue inverted_;
milind-u738832d2023-02-24 19:55:54 -0800273
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700274 ctre::phoenix6::StatusSignal<units::temperature::celsius_t> device_temp_;
275 ctre::phoenix6::StatusSignal<units::voltage::volt_t> supply_voltage_;
276 ctre::phoenix6::StatusSignal<units::current::ampere_t> supply_current_,
milind-u738832d2023-02-24 19:55:54 -0800277 torque_current_;
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700278 ctre::phoenix6::StatusSignal<units::angle::turn_t> position_;
279 ctre::phoenix6::StatusSignal<units::dimensionless::scalar_t> duty_cycle_;
milind-u738832d2023-02-24 19:55:54 -0800280};
281
282class CANSensorReader {
283 public:
Ravago Jones2bfcecd2023-03-14 13:13:26 -0700284 CANSensorReader(
285 aos::EventLoop *event_loop,
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700286 std::vector<ctre::phoenix6::BaseStatusSignal *> signals_registry)
milind-u738832d2023-02-24 19:55:54 -0800287 : event_loop_(event_loop),
Ravago Jones2bfcecd2023-03-14 13:13:26 -0700288 signals_(signals_registry.begin(), signals_registry.end()),
milind-u738832d2023-02-24 19:55:54 -0800289 can_position_sender_(
Maxwell Hendersoncef6f042023-05-26 14:38:09 -0700290 event_loop
291 ->MakeSender<frc971::control_loops::drivetrain::CANPosition>(
292 "/drivetrain")),
milind-u738832d2023-02-24 19:55:54 -0800293 roller_falcon_data_(std::nullopt) {
294 event_loop->SetRuntimeRealtimePriority(40);
295 event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({1}));
296 timer_handler_ = event_loop->AddTimer([this]() { Loop(); });
297 timer_handler_->set_name("CANSensorReader Loop");
298
299 event_loop->OnRun([this]() {
Philipp Schradera6712522023-07-05 20:25:11 -0700300 timer_handler_->Schedule(event_loop_->monotonic_now(),
301 1 / kCANUpdateFreqHz);
milind-u738832d2023-02-24 19:55:54 -0800302 });
303 }
304
milind-u738832d2023-02-24 19:55:54 -0800305 void set_falcons(std::shared_ptr<Falcon> right_front,
306 std::shared_ptr<Falcon> right_back,
307 std::shared_ptr<Falcon> right_under,
308 std::shared_ptr<Falcon> left_front,
309 std::shared_ptr<Falcon> left_back,
310 std::shared_ptr<Falcon> left_under,
311 std::shared_ptr<Falcon> roller_falcon) {
312 right_front_ = std::move(right_front);
313 right_back_ = std::move(right_back);
314 right_under_ = std::move(right_under);
315 left_front_ = std::move(left_front);
316 left_back_ = std::move(left_back);
317 left_under_ = std::move(left_under);
318 roller_falcon_ = std::move(roller_falcon);
319 }
320
321 std::optional<superstructure::CANFalconT> roller_falcon_data() {
322 std::unique_lock<aos::stl_mutex> lock(roller_mutex_);
323 return roller_falcon_data_;
324 }
325
326 private:
327 void Loop() {
milind-u738832d2023-02-24 19:55:54 -0800328 ctre::phoenix::StatusCode status =
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700329 ctre::phoenix6::BaseStatusSignal::WaitForAll(2000_ms, signals_);
milind-u738832d2023-02-24 19:55:54 -0800330
331 if (!status.IsOK()) {
332 AOS_LOG(ERROR, "Failed to read signals from falcons: %s: %s",
333 status.GetName(), status.GetDescription());
334 }
335
336 auto builder = can_position_sender_.MakeBuilder();
337
338 for (auto falcon : {right_front_, right_back_, right_under_, left_front_,
339 left_back_, left_under_, roller_falcon_}) {
340 falcon->RefreshNontimesyncedSignals();
341 }
342
Maxwell Hendersonca1d18f2023-07-26 21:06:14 -0700343 aos::SizedArray<flatbuffers::Offset<frc971::control_loops::CANFalcon>,
344 kCANFalconCount>
milind-u738832d2023-02-24 19:55:54 -0800345 falcons;
346
347 for (auto falcon : {right_front_, right_back_, right_under_, left_front_,
348 left_back_, left_under_}) {
349 falcons.push_back(falcon->WritePosition(builder.fbb()));
350 }
351
352 auto falcons_list =
Maxwell Hendersoncef6f042023-05-26 14:38:09 -0700353 builder.fbb()
Maxwell Hendersonca1d18f2023-07-26 21:06:14 -0700354 ->CreateVector<
355 flatbuffers::Offset<frc971::control_loops::CANFalcon>>(falcons);
milind-u738832d2023-02-24 19:55:54 -0800356
Maxwell Hendersoncef6f042023-05-26 14:38:09 -0700357 frc971::control_loops::drivetrain::CANPosition::Builder
358 can_position_builder =
359 builder
360 .MakeBuilder<frc971::control_loops::drivetrain::CANPosition>();
milind-u738832d2023-02-24 19:55:54 -0800361
362 can_position_builder.add_falcons(falcons_list);
363 can_position_builder.add_timestamp(right_front_->GetTimestamp());
364 can_position_builder.add_status(static_cast<int>(status));
365
366 builder.CheckOk(builder.Send(can_position_builder.Finish()));
367
368 {
369 std::unique_lock<aos::stl_mutex> lock(roller_mutex_);
370 superstructure::CANFalconT roller_falcon_data;
371 roller_falcon_data.id = roller_falcon_->device_id();
372 roller_falcon_data.supply_current = roller_falcon_->supply_current();
Austin Schuh23a90022023-02-24 22:13:39 -0800373 roller_falcon_data.torque_current = -roller_falcon_->torque_current();
milind-u738832d2023-02-24 19:55:54 -0800374 roller_falcon_data.supply_voltage = roller_falcon_->supply_voltage();
375 roller_falcon_data.device_temp = roller_falcon_->device_temp();
Austin Schuh23a90022023-02-24 22:13:39 -0800376 roller_falcon_data.position = -roller_falcon_->position();
Ravago Jones088ca772023-03-25 22:14:24 -0700377 roller_falcon_data.duty_cycle = roller_falcon_->duty_cycle();
milind-u738832d2023-02-24 19:55:54 -0800378 roller_falcon_data_ =
379 std::make_optional<superstructure::CANFalconT>(roller_falcon_data);
380 }
381 }
382
383 aos::EventLoop *event_loop_;
384
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700385 const std::vector<ctre::phoenix6::BaseStatusSignal *> signals_;
Maxwell Hendersoncef6f042023-05-26 14:38:09 -0700386 aos::Sender<frc971::control_loops::drivetrain::CANPosition>
387 can_position_sender_;
milind-u738832d2023-02-24 19:55:54 -0800388
389 std::shared_ptr<Falcon> right_front_, right_back_, right_under_, left_front_,
390 left_back_, left_under_, roller_falcon_;
391
392 std::optional<superstructure::CANFalconT> roller_falcon_data_;
393
394 aos::stl_mutex roller_mutex_;
395
396 // Pointer to the timer handler used to modify the wakeup.
397 ::aos::TimerHandler *timer_handler_;
398};
399
Maxwell Hendersonad312342023-01-10 12:07:47 -0800400// Class to send position messages with sensor readings to our loops.
401class SensorReader : public ::frc971::wpilib::SensorReader {
402 public:
403 SensorReader(::aos::ShmEventLoop *event_loop,
milind-u738832d2023-02-24 19:55:54 -0800404 std::shared_ptr<const Values> values,
405 CANSensorReader *can_sensor_reader)
Maxwell Hendersonad312342023-01-10 12:07:47 -0800406 : ::frc971::wpilib::SensorReader(event_loop),
407 values_(std::move(values)),
408 auto_mode_sender_(
409 event_loop->MakeSender<::frc971::autonomous::AutonomousMode>(
410 "/autonomous")),
411 superstructure_position_sender_(
412 event_loop->MakeSender<superstructure::Position>(
413 "/superstructure")),
414 drivetrain_position_sender_(
415 event_loop
416 ->MakeSender<::frc971::control_loops::drivetrain::Position>(
417 "/drivetrain")),
418 gyro_sender_(event_loop->MakeSender<::frc971::sensors::GyroReading>(
milind-u738832d2023-02-24 19:55:54 -0800419 "/drivetrain")),
420 can_sensor_reader_(can_sensor_reader) {
Maxwell Hendersonad312342023-01-10 12:07:47 -0800421 // Set to filter out anything shorter than 1/4 of the minimum pulse width
422 // we should ever see.
423 UpdateFastEncoderFilterHz(kMaxFastEncoderPulsesPerSecond);
Austin Schuh595ffc72023-02-24 16:24:37 -0800424 event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({0}));
Maxwell Hendersonad312342023-01-10 12:07:47 -0800425 }
426
427 void Start() override {
Maxwell Hendersonad312342023-01-10 12:07:47 -0800428 AddToDMA(&imu_yaw_rate_reader_);
milind-u3a7f9212023-02-24 20:46:59 -0800429 AddToDMA(&cone_position_sensor_);
Maxwell Hendersonad312342023-01-10 12:07:47 -0800430 }
431
432 // Auto mode switches.
433 void set_autonomous_mode(int i, ::std::unique_ptr<frc::DigitalInput> sensor) {
434 autonomous_modes_.at(i) = ::std::move(sensor);
435 }
436
Ravago Jones2060ee62023-02-03 18:12:24 -0800437 void set_yaw_rate_input(::std::unique_ptr<frc::DigitalInput> sensor) {
438 imu_yaw_rate_input_ = ::std::move(sensor);
439 imu_yaw_rate_reader_.set_input(imu_yaw_rate_input_.get());
440 }
441
Maxwell Hendersonad312342023-01-10 12:07:47 -0800442 void RunIteration() override {
443 superstructure_reading_->Set(true);
milind-u18934eb2023-02-20 16:28:58 -0800444 {
445 auto builder = superstructure_position_sender_.MakeBuilder();
446 frc971::PotAndAbsolutePositionT proximal;
447 CopyPosition(proximal_encoder_, &proximal,
448 Values::kProximalEncoderCountsPerRevolution(),
449 Values::kProximalEncoderRatio(), proximal_pot_translate,
Austin Schuh7dcc49b2023-02-21 17:35:10 -0800450 true, values_->arm_proximal.potentiometer_offset);
milind-u18934eb2023-02-20 16:28:58 -0800451 frc971::PotAndAbsolutePositionT distal;
Maxwell Hendersonce816122023-03-27 20:12:38 -0700452 CopyPosition(
453 distal_encoder_, &distal, Values::kDistalEncoderCountsPerRevolution(),
454 values_->arm_distal.zeroing.one_revolution_distance / (M_PI * 2.0),
455 distal_pot_translate, true, values_->arm_distal.potentiometer_offset);
milind-u18934eb2023-02-20 16:28:58 -0800456 frc971::PotAndAbsolutePositionT roll_joint;
457 CopyPosition(roll_joint_encoder_, &roll_joint,
458 Values::kRollJointEncoderCountsPerRevolution(),
459 Values::kRollJointEncoderRatio(), roll_joint_pot_translate,
Austin Schuh29d025c2023-03-03 21:41:04 -0800460 false, values_->roll_joint.potentiometer_offset);
milind-u18934eb2023-02-20 16:28:58 -0800461 frc971::AbsolutePositionT wrist;
462 CopyPosition(wrist_encoder_, &wrist,
463 Values::kWristEncoderCountsPerRevolution(),
Austin Schuhe5248cd2023-03-05 12:46:16 -0800464 values_->wrist.subsystem_params.zeroing_constants
465 .one_revolution_distance /
466 (M_PI * 2.0),
467 values_->wrist_flipped);
milind-u18934eb2023-02-20 16:28:58 -0800468
469 flatbuffers::Offset<frc971::PotAndAbsolutePosition> proximal_offset =
470 frc971::PotAndAbsolutePosition::Pack(*builder.fbb(), &proximal);
471 flatbuffers::Offset<frc971::PotAndAbsolutePosition> distal_offset =
472 frc971::PotAndAbsolutePosition::Pack(*builder.fbb(), &distal);
milind-u18934eb2023-02-20 16:28:58 -0800473 flatbuffers::Offset<frc971::PotAndAbsolutePosition> roll_joint_offset =
474 frc971::PotAndAbsolutePosition::Pack(*builder.fbb(), &roll_joint);
milind-u18a901d2023-02-17 21:51:55 -0800475 flatbuffers::Offset<superstructure::ArmPosition> arm_offset =
476 superstructure::CreateArmPosition(*builder.fbb(), proximal_offset,
477 distal_offset, roll_joint_offset);
milind-u18934eb2023-02-20 16:28:58 -0800478 flatbuffers::Offset<frc971::AbsolutePosition> wrist_offset =
479 frc971::AbsolutePosition::Pack(*builder.fbb(), &wrist);
480
milind-u738832d2023-02-24 19:55:54 -0800481 flatbuffers::Offset<superstructure::CANFalcon> roller_falcon_offset;
482 auto optional_roller_falcon = can_sensor_reader_->roller_falcon_data();
483 if (optional_roller_falcon.has_value()) {
484 roller_falcon_offset = superstructure::CANFalcon::Pack(
485 *builder.fbb(), &optional_roller_falcon.value());
486 }
487
milind-u18934eb2023-02-20 16:28:58 -0800488 superstructure::Position::Builder position_builder =
489 builder.MakeBuilder<superstructure::Position>();
490
491 position_builder.add_arm(arm_offset);
milind-u18934eb2023-02-20 16:28:58 -0800492 position_builder.add_wrist(wrist_offset);
Maxwell Henderson6c7e61f2023-02-22 16:43:43 -0800493 position_builder.add_end_effector_cube_beam_break(
494 end_effector_cube_beam_break_->Get());
milind-u3a7f9212023-02-24 20:46:59 -0800495 position_builder.add_cone_position(cone_position_sensor_.last_width() /
496 cone_position_sensor_.last_period());
milind-u738832d2023-02-24 19:55:54 -0800497 if (!roller_falcon_offset.IsNull()) {
498 position_builder.add_roller_falcon(roller_falcon_offset);
499 }
Henry Speisere139f802023-02-21 14:14:48 -0800500 builder.CheckOk(builder.Send(position_builder.Finish()));
milind-u18934eb2023-02-20 16:28:58 -0800501 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800502
503 {
504 auto builder = drivetrain_position_sender_.MakeBuilder();
505 frc971::control_loops::drivetrain::Position::Builder drivetrain_builder =
506 builder.MakeBuilder<frc971::control_loops::drivetrain::Position>();
507 drivetrain_builder.add_left_encoder(
508 constants::Values::DrivetrainEncoderToMeters(
509 drivetrain_left_encoder_->GetRaw()));
510 drivetrain_builder.add_left_speed(
511 drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod()));
512
513 drivetrain_builder.add_right_encoder(
514 -constants::Values::DrivetrainEncoderToMeters(
515 drivetrain_right_encoder_->GetRaw()));
516 drivetrain_builder.add_right_speed(-drivetrain_velocity_translate(
517 drivetrain_right_encoder_->GetPeriod()));
518
519 builder.CheckOk(builder.Send(drivetrain_builder.Finish()));
520 }
521
522 {
523 auto builder = gyro_sender_.MakeBuilder();
524 ::frc971::sensors::GyroReading::Builder gyro_reading_builder =
525 builder.MakeBuilder<::frc971::sensors::GyroReading>();
526 // +/- 2000 deg / sec
527 constexpr double kMaxVelocity = 4000; // degrees / second
528 constexpr double kVelocityRadiansPerSecond =
529 kMaxVelocity / 360 * (2.0 * M_PI);
530
531 // Only part of the full range is used to prevent being 100% on or off.
532 constexpr double kScaledRangeLow = 0.1;
533 constexpr double kScaledRangeHigh = 0.9;
534
535 constexpr double kPWMFrequencyHz = 200;
Maxwell Hendersonad312342023-01-10 12:07:47 -0800536 double velocity_duty_cycle =
537 imu_yaw_rate_reader_.last_width() * kPWMFrequencyHz;
538
539 constexpr double kDutyCycleScale =
540 1 / (kScaledRangeHigh - kScaledRangeLow);
541 // scale from 0.1 - 0.9 to 0 - 1
Maxwell Hendersonad312342023-01-10 12:07:47 -0800542 double rescaled_velocity_duty_cycle =
543 (velocity_duty_cycle - kScaledRangeLow) * kDutyCycleScale;
544
Maxwell Hendersonad312342023-01-10 12:07:47 -0800545 if (!std::isnan(rescaled_velocity_duty_cycle)) {
546 gyro_reading_builder.add_velocity((rescaled_velocity_duty_cycle - 0.5) *
547 kVelocityRadiansPerSecond);
548 }
549 builder.CheckOk(builder.Send(gyro_reading_builder.Finish()));
550 }
551
552 {
553 auto builder = auto_mode_sender_.MakeBuilder();
554
555 uint32_t mode = 0;
556 for (size_t i = 0; i < autonomous_modes_.size(); ++i) {
557 if (autonomous_modes_[i] && autonomous_modes_[i]->Get()) {
558 mode |= 1 << i;
559 }
560 }
561
562 auto auto_mode_builder =
563 builder.MakeBuilder<frc971::autonomous::AutonomousMode>();
564
565 auto_mode_builder.add_mode(mode);
566
567 builder.CheckOk(builder.Send(auto_mode_builder.Finish()));
568 }
569 }
570
571 std::shared_ptr<frc::DigitalOutput> superstructure_reading_;
572
573 void set_superstructure_reading(
574 std::shared_ptr<frc::DigitalOutput> superstructure_reading) {
575 superstructure_reading_ = superstructure_reading;
576 }
577
milind-u18934eb2023-02-20 16:28:58 -0800578 void set_proximal_encoder(::std::unique_ptr<frc::Encoder> encoder) {
579 fast_encoder_filter_.Add(encoder.get());
580 proximal_encoder_.set_encoder(::std::move(encoder));
581 }
582
583 void set_proximal_absolute_pwm(
584 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
585 proximal_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
586 }
587
588 void set_proximal_potentiometer(
589 ::std::unique_ptr<frc::AnalogInput> potentiometer) {
590 proximal_encoder_.set_potentiometer(::std::move(potentiometer));
591 }
592
593 void set_distal_encoder(::std::unique_ptr<frc::Encoder> encoder) {
594 fast_encoder_filter_.Add(encoder.get());
595 distal_encoder_.set_encoder(::std::move(encoder));
596 }
597
598 void set_distal_absolute_pwm(
599 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
600 distal_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
601 }
602
603 void set_distal_potentiometer(
604 ::std::unique_ptr<frc::AnalogInput> potentiometer) {
605 distal_encoder_.set_potentiometer(::std::move(potentiometer));
606 }
607
608 void set_roll_joint_encoder(::std::unique_ptr<frc::Encoder> encoder) {
609 fast_encoder_filter_.Add(encoder.get());
610 roll_joint_encoder_.set_encoder(::std::move(encoder));
611 }
612
613 void set_roll_joint_absolute_pwm(
614 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
615 roll_joint_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
616 }
617
618 void set_roll_joint_potentiometer(
619 ::std::unique_ptr<frc::AnalogInput> potentiometer) {
620 roll_joint_encoder_.set_potentiometer(::std::move(potentiometer));
621 }
622
623 void set_wrist_encoder(::std::unique_ptr<frc::Encoder> encoder) {
624 fast_encoder_filter_.Add(encoder.get());
625 wrist_encoder_.set_encoder(::std::move(encoder));
626 }
627
628 void set_wrist_absolute_pwm(
629 ::std::unique_ptr<frc::DigitalInput> absolute_pwm) {
630 wrist_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
631 }
632
Maxwell Henderson6c7e61f2023-02-22 16:43:43 -0800633 void set_end_effector_cube_beam_break(
634 ::std::unique_ptr<frc::DigitalInput> sensor) {
635 end_effector_cube_beam_break_ = ::std::move(sensor);
636 }
637
milind-u3a7f9212023-02-24 20:46:59 -0800638 void set_cone_position_sensor(::std::unique_ptr<frc::DigitalInput> sensor) {
639 cone_position_input_ = ::std::move(sensor);
640 cone_position_sensor_.set_input(cone_position_input_.get());
641 }
642
Maxwell Hendersonad312342023-01-10 12:07:47 -0800643 private:
644 std::shared_ptr<const Values> values_;
645
646 aos::Sender<frc971::autonomous::AutonomousMode> auto_mode_sender_;
647 aos::Sender<superstructure::Position> superstructure_position_sender_;
648 aos::Sender<frc971::control_loops::drivetrain::Position>
649 drivetrain_position_sender_;
650 ::aos::Sender<::frc971::sensors::GyroReading> gyro_sender_;
651
652 std::array<std::unique_ptr<frc::DigitalInput>, 2> autonomous_modes_;
653
Ravago Jones2544ad82023-03-04 22:24:49 -0800654 std::unique_ptr<frc::DigitalInput> imu_yaw_rate_input_,
milind-u3a7f9212023-02-24 20:46:59 -0800655 end_effector_cube_beam_break_;
Ravago Jones2060ee62023-02-03 18:12:24 -0800656
Ravago Jones2544ad82023-03-04 22:24:49 -0800657 frc971::wpilib::DMAPulseWidthReader imu_yaw_rate_reader_;
milind-u18934eb2023-02-20 16:28:58 -0800658
659 frc971::wpilib::AbsoluteEncoderAndPotentiometer proximal_encoder_,
660 distal_encoder_, roll_joint_encoder_;
661 frc971::wpilib::AbsoluteEncoder wrist_encoder_;
milind-u3a7f9212023-02-24 20:46:59 -0800662
663 frc971::wpilib::DMAPulseWidthReader cone_position_sensor_;
664 std::unique_ptr<frc::DigitalInput> cone_position_input_;
milind-u738832d2023-02-24 19:55:54 -0800665
666 CANSensorReader *can_sensor_reader_;
Maxwell Hendersonad312342023-01-10 12:07:47 -0800667};
668
669class SuperstructureWriter
670 : public ::frc971::wpilib::LoopOutputHandler<superstructure::Output> {
671 public:
672 SuperstructureWriter(aos::EventLoop *event_loop)
673 : frc971::wpilib::LoopOutputHandler<superstructure::Output>(
milind-u32d29d32023-02-24 21:11:51 -0800674 event_loop, "/superstructure") {
675 event_loop->SetRuntimeRealtimePriority(
676 constants::Values::kDrivetrainWriterPriority);
677 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800678
679 std::shared_ptr<frc::DigitalOutput> superstructure_reading_;
680
681 void set_superstructure_reading(
682 std::shared_ptr<frc::DigitalOutput> superstructure_reading) {
683 superstructure_reading_ = superstructure_reading;
684 }
685
milind-u18934eb2023-02-20 16:28:58 -0800686 void set_proximal_falcon(::std::unique_ptr<::frc::TalonFX> t) {
687 proximal_falcon_ = ::std::move(t);
688 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800689
milind-u18934eb2023-02-20 16:28:58 -0800690 void set_distal_falcon(::std::unique_ptr<::frc::TalonFX> t) {
691 distal_falcon_ = ::std::move(t);
692 }
693
694 void set_roll_joint_victor(::std::unique_ptr<::frc::VictorSP> t) {
695 roll_joint_victor_ = ::std::move(t);
696 }
697
698 void set_wrist_victor(::std::unique_ptr<::frc::VictorSP> t) {
699 wrist_victor_ = ::std::move(t);
700 }
701
milind-u18934eb2023-02-20 16:28:58 -0800702 private:
703 void Stop() override {
704 AOS_LOG(WARNING, "Superstructure output too old.\n");
705 proximal_falcon_->SetDisabled();
706 distal_falcon_->SetDisabled();
707 roll_joint_victor_->SetDisabled();
708 wrist_victor_->SetDisabled();
milind-u18934eb2023-02-20 16:28:58 -0800709 }
710
711 void Write(const superstructure::Output &output) override {
712 WritePwm(output.proximal_voltage(), proximal_falcon_.get());
713 WritePwm(output.distal_voltage(), distal_falcon_.get());
Austin Schuh3fd5f0e2023-02-22 11:10:37 -0800714 WritePwm(-output.roll_joint_voltage(), roll_joint_victor_.get());
milind-u18934eb2023-02-20 16:28:58 -0800715 WritePwm(output.wrist_voltage(), wrist_victor_.get());
milind-u18934eb2023-02-20 16:28:58 -0800716 }
Maxwell Hendersonad312342023-01-10 12:07:47 -0800717
718 static void WriteCan(const double voltage,
719 ::ctre::phoenix::motorcontrol::can::TalonFX *falcon) {
720 falcon->Set(
721 ctre::phoenix::motorcontrol::ControlMode::PercentOutput,
722 std::clamp(voltage, -kMaxBringupPower, kMaxBringupPower) / 12.0);
723 }
724
725 template <typename T>
726 static void WritePwm(const double voltage, T *motor) {
727 motor->SetSpeed(std::clamp(voltage, -kMaxBringupPower, kMaxBringupPower) /
728 12.0);
729 }
milind-u18934eb2023-02-20 16:28:58 -0800730
731 ::std::unique_ptr<::frc::TalonFX> proximal_falcon_, distal_falcon_;
732 ::std::unique_ptr<::frc::VictorSP> roll_joint_victor_, wrist_victor_;
Maxwell Hendersonad312342023-01-10 12:07:47 -0800733};
734
milind-u32d29d32023-02-24 21:11:51 -0800735class SuperstructureCANWriter
736 : public ::frc971::wpilib::LoopOutputHandler<superstructure::Output> {
737 public:
738 SuperstructureCANWriter(::aos::EventLoop *event_loop)
739 : ::frc971::wpilib::LoopOutputHandler<superstructure::Output>(
740 event_loop, "/superstructure") {
741 event_loop->SetRuntimeRealtimePriority(
742 constants::Values::kSuperstructureCANWriterPriority);
743
744 event_loop->OnRun([this]() { WriteConfigs(); });
745 };
746
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800747 void HandleCANConfiguration(const CANConfiguration &configuration) {
748 roller_falcon_->PrintConfigs();
749 if (configuration.reapply()) {
750 WriteConfigs();
751 }
752 }
753
milind-u32d29d32023-02-24 21:11:51 -0800754 void set_roller_falcon(std::shared_ptr<Falcon> roller_falcon) {
755 roller_falcon_ = std::move(roller_falcon);
756 }
757
758 private:
759 void WriteConfigs() { roller_falcon_->WriteRollerConfigs(); }
760
761 void Write(const superstructure::Output &output) override {
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700762 ctre::phoenix6::controls::DutyCycleOut roller_control(
milind-u32d29d32023-02-24 21:11:51 -0800763 SafeSpeed(-output.roller_voltage()));
764 roller_control.UpdateFreqHz = 0_Hz;
765 roller_control.EnableFOC = true;
766
767 ctre::phoenix::StatusCode status =
768 roller_falcon_->talon()->SetControl(roller_control);
769
770 if (!status.IsOK()) {
771 AOS_LOG(ERROR, "Failed to write control to falcon: %s: %s",
772 status.GetName(), status.GetDescription());
773 }
774 }
775
776 void Stop() override {
777 AOS_LOG(WARNING, "Superstructure CAN output too old.\n");
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700778 ctre::phoenix6::controls::DutyCycleOut stop_command(0.0);
Austin Schuh1780e002023-03-03 21:39:26 -0800779 stop_command.UpdateFreqHz = 0_Hz;
780 stop_command.EnableFOC = true;
milind-u32d29d32023-02-24 21:11:51 -0800781
782 roller_falcon_->talon()->SetControl(stop_command);
783 }
784
785 double SafeSpeed(double voltage) {
786 return (::aos::Clip(voltage, -kMaxBringupPower, kMaxBringupPower) / 12.0);
787 }
788
789 std::shared_ptr<Falcon> roller_falcon_;
790};
791
Ravago Jones2060ee62023-02-03 18:12:24 -0800792class DrivetrainWriter : public ::frc971::wpilib::LoopOutputHandler<
793 ::frc971::control_loops::drivetrain::Output> {
794 public:
795 DrivetrainWriter(::aos::EventLoop *event_loop)
796 : ::frc971::wpilib::LoopOutputHandler<
797 ::frc971::control_loops::drivetrain::Output>(event_loop,
798 "/drivetrain") {
799 event_loop->SetRuntimeRealtimePriority(
800 constants::Values::kDrivetrainWriterPriority);
801
Ravago Jones2060ee62023-02-03 18:12:24 -0800802 event_loop->OnRun([this]() { WriteConfigs(); });
803 }
804
805 void set_falcons(std::shared_ptr<Falcon> right_front,
806 std::shared_ptr<Falcon> right_back,
807 std::shared_ptr<Falcon> right_under,
808 std::shared_ptr<Falcon> left_front,
809 std::shared_ptr<Falcon> left_back,
810 std::shared_ptr<Falcon> left_under) {
811 right_front_ = std::move(right_front);
812 right_back_ = std::move(right_back);
813 right_under_ = std::move(right_under);
814 left_front_ = std::move(left_front);
815 left_back_ = std::move(left_back);
816 left_under_ = std::move(left_under);
817 }
818
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700819 void set_right_inverted(ctre::phoenix6::signals::InvertedValue invert) {
Ravago Jones2060ee62023-02-03 18:12:24 -0800820 right_inverted_ = invert;
821 }
822
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700823 void set_left_inverted(ctre::phoenix6::signals::InvertedValue invert) {
Ravago Jones2060ee62023-02-03 18:12:24 -0800824 left_inverted_ = invert;
825 }
826
Austin Schuhbb4c9ac2023-02-28 22:04:20 -0800827 void HandleCANConfiguration(const CANConfiguration &configuration) {
828 for (auto falcon : {right_front_, right_back_, right_under_, left_front_,
829 left_back_, left_under_}) {
830 falcon->PrintConfigs();
831 }
832 if (configuration.reapply()) {
833 WriteConfigs();
834 }
835 }
836
Ravago Jones2060ee62023-02-03 18:12:24 -0800837 private:
838 void WriteConfigs() {
839 for (auto falcon :
840 {right_front_.get(), right_back_.get(), right_under_.get()}) {
841 falcon->WriteConfigs(right_inverted_);
842 }
843
844 for (auto falcon :
845 {left_front_.get(), left_back_.get(), left_under_.get()}) {
846 falcon->WriteConfigs(left_inverted_);
847 }
848 }
849
850 void Write(
851 const ::frc971::control_loops::drivetrain::Output &output) override {
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700852 ctre::phoenix6::controls::DutyCycleOut left_control(
Ravago Jones2060ee62023-02-03 18:12:24 -0800853 SafeSpeed(output.left_voltage()));
854 left_control.UpdateFreqHz = 0_Hz;
855 left_control.EnableFOC = true;
856
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700857 ctre::phoenix6::controls::DutyCycleOut right_control(
Ravago Jones2060ee62023-02-03 18:12:24 -0800858 SafeSpeed(output.right_voltage()));
859 right_control.UpdateFreqHz = 0_Hz;
860 right_control.EnableFOC = true;
861
862 for (auto falcon :
863 {left_front_.get(), left_back_.get(), left_under_.get()}) {
864 ctre::phoenix::StatusCode status =
865 falcon->talon()->SetControl(left_control);
866
867 if (!status.IsOK()) {
868 AOS_LOG(ERROR, "Failed to write control to falcon: %s: %s",
869 status.GetName(), status.GetDescription());
870 }
871 }
872
873 for (auto falcon :
874 {right_front_.get(), right_back_.get(), right_under_.get()}) {
875 ctre::phoenix::StatusCode status =
876 falcon->talon()->SetControl(right_control);
877
878 if (!status.IsOK()) {
879 AOS_LOG(ERROR, "Failed to write control to falcon: %s: %s",
880 status.GetName(), status.GetDescription());
881 }
882 }
883 }
884
885 void Stop() override {
886 AOS_LOG(WARNING, "drivetrain output too old\n");
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700887 ctre::phoenix6::controls::DutyCycleOut stop_command(0.0);
Austin Schuh1780e002023-03-03 21:39:26 -0800888 stop_command.UpdateFreqHz = 0_Hz;
889 stop_command.EnableFOC = true;
890
Ravago Jones2060ee62023-02-03 18:12:24 -0800891 for (auto falcon :
892 {right_front_.get(), right_back_.get(), right_under_.get(),
893 left_front_.get(), left_back_.get(), left_under_.get()}) {
894 falcon->talon()->SetControl(stop_command);
895 }
896 }
897
898 double SafeSpeed(double voltage) {
899 return (::aos::Clip(voltage, -kMaxBringupPower, kMaxBringupPower) / 12.0);
900 }
901
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700902 ctre::phoenix6::signals::InvertedValue left_inverted_, right_inverted_;
Ravago Jones2060ee62023-02-03 18:12:24 -0800903 std::shared_ptr<Falcon> right_front_, right_back_, right_under_, left_front_,
904 left_back_, left_under_;
905};
Maxwell Hendersonad312342023-01-10 12:07:47 -0800906
907class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
908 public:
909 ::std::unique_ptr<frc::Encoder> make_encoder(int index) {
910 return make_unique<frc::Encoder>(10 + index * 2, 11 + index * 2, false,
911 frc::Encoder::k4X);
912 }
913
914 void Run() override {
915 std::shared_ptr<const Values> values =
916 std::make_shared<const Values>(constants::MakeValues());
917
918 aos::FlatbufferDetachedBuffer<aos::Configuration> config =
919 aos::configuration::ReadConfig("aos_config.json");
920
921 // Thread 1.
Ravago Jones2060ee62023-02-03 18:12:24 -0800922 ::aos::ShmEventLoop joystick_sender_event_loop(&config.message());
923 ::frc971::wpilib::JoystickSender joystick_sender(
924 &joystick_sender_event_loop);
925 AddLoop(&joystick_sender_event_loop);
926
Maxwell Hendersonad312342023-01-10 12:07:47 -0800927 // Thread 2.
928 ::aos::ShmEventLoop pdp_fetcher_event_loop(&config.message());
929 ::frc971::wpilib::PDPFetcher pdp_fetcher(&pdp_fetcher_event_loop);
930 AddLoop(&pdp_fetcher_event_loop);
931
932 std::shared_ptr<frc::DigitalOutput> superstructure_reading =
933 make_unique<frc::DigitalOutput>(25);
934
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -0700935 std::vector<ctre::phoenix6::BaseStatusSignal *> signals_registry;
Ravago Jones2bfcecd2023-03-14 13:13:26 -0700936 std::shared_ptr<Falcon> right_front =
937 std::make_shared<Falcon>(1, "Drivetrain Bus", &signals_registry);
938 std::shared_ptr<Falcon> right_back =
939 std::make_shared<Falcon>(2, "Drivetrain Bus", &signals_registry);
940 std::shared_ptr<Falcon> right_under =
941 std::make_shared<Falcon>(3, "Drivetrain Bus", &signals_registry);
942 std::shared_ptr<Falcon> left_front =
943 std::make_shared<Falcon>(4, "Drivetrain Bus", &signals_registry);
944 std::shared_ptr<Falcon> left_back =
945 std::make_shared<Falcon>(5, "Drivetrain Bus", &signals_registry);
946 std::shared_ptr<Falcon> left_under =
947 std::make_shared<Falcon>(6, "Drivetrain Bus", &signals_registry);
948 std::shared_ptr<Falcon> roller =
949 std::make_shared<Falcon>(13, "Drivetrain Bus", &signals_registry);
950
Maxwell Hendersonad312342023-01-10 12:07:47 -0800951 // Thread 3.
milind-u738832d2023-02-24 19:55:54 -0800952 ::aos::ShmEventLoop can_sensor_reader_event_loop(&config.message());
953 can_sensor_reader_event_loop.set_name("CANSensorReader");
Ravago Jones2bfcecd2023-03-14 13:13:26 -0700954 CANSensorReader can_sensor_reader(&can_sensor_reader_event_loop,
955 std::move(signals_registry));
milind-u738832d2023-02-24 19:55:54 -0800956
957 can_sensor_reader.set_falcons(right_front, right_back, right_under,
958 left_front, left_back, left_under, roller);
959
960 AddLoop(&can_sensor_reader_event_loop);
961
962 // Thread 4.
Maxwell Hendersonad312342023-01-10 12:07:47 -0800963 ::aos::ShmEventLoop sensor_reader_event_loop(&config.message());
milind-u738832d2023-02-24 19:55:54 -0800964 SensorReader sensor_reader(&sensor_reader_event_loop, values,
965 &can_sensor_reader);
Maxwell Hendersonad312342023-01-10 12:07:47 -0800966 sensor_reader.set_pwm_trigger(true);
967 sensor_reader.set_drivetrain_left_encoder(make_encoder(1));
968 sensor_reader.set_drivetrain_right_encoder(make_encoder(0));
969 sensor_reader.set_superstructure_reading(superstructure_reading);
Henry Speisere139f802023-02-21 14:14:48 -0800970 sensor_reader.set_yaw_rate_input(make_unique<frc::DigitalInput>(0));
Ravago Jones2060ee62023-02-03 18:12:24 -0800971
milind-u18934eb2023-02-20 16:28:58 -0800972 sensor_reader.set_proximal_encoder(make_encoder(3));
973 sensor_reader.set_proximal_absolute_pwm(make_unique<frc::DigitalInput>(3));
974 sensor_reader.set_proximal_potentiometer(make_unique<frc::AnalogInput>(3));
975
Henry Speisere139f802023-02-21 14:14:48 -0800976 sensor_reader.set_distal_encoder(make_encoder(2));
977 sensor_reader.set_distal_absolute_pwm(make_unique<frc::DigitalInput>(2));
978 sensor_reader.set_distal_potentiometer(make_unique<frc::AnalogInput>(2));
milind-u18934eb2023-02-20 16:28:58 -0800979
Henry Speisere139f802023-02-21 14:14:48 -0800980 sensor_reader.set_roll_joint_encoder(make_encoder(5));
milind-u18934eb2023-02-20 16:28:58 -0800981 sensor_reader.set_roll_joint_absolute_pwm(
Henry Speisere139f802023-02-21 14:14:48 -0800982 make_unique<frc::DigitalInput>(5));
milind-u18934eb2023-02-20 16:28:58 -0800983 sensor_reader.set_roll_joint_potentiometer(
Henry Speisere139f802023-02-21 14:14:48 -0800984 make_unique<frc::AnalogInput>(5));
milind-u18934eb2023-02-20 16:28:58 -0800985
Henry Speisere139f802023-02-21 14:14:48 -0800986 sensor_reader.set_wrist_encoder(make_encoder(4));
987 sensor_reader.set_wrist_absolute_pwm(make_unique<frc::DigitalInput>(4));
milind-u18934eb2023-02-20 16:28:58 -0800988
Maxwell Henderson6c7e61f2023-02-22 16:43:43 -0800989 sensor_reader.set_end_effector_cube_beam_break(
990 make_unique<frc::DigitalInput>(7));
milind-u3a7f9212023-02-24 20:46:59 -0800991 sensor_reader.set_cone_position_sensor(make_unique<frc::DigitalInput>(8));
Maxwell Henderson6c7e61f2023-02-22 16:43:43 -0800992
Maxwell Hendersonad312342023-01-10 12:07:47 -0800993 AddLoop(&sensor_reader_event_loop);
994
Ravago Jones2060ee62023-02-03 18:12:24 -0800995 // Thread 5.
Philipp Schradera6712522023-07-05 20:25:11 -0700996 // Set up CAN.
milind-u32d29d32023-02-24 21:11:51 -0800997 if (!FLAGS_ctre_diag_server) {
998 c_Phoenix_Diagnostics_SetSecondsToStart(-1);
999 c_Phoenix_Diagnostics_Dispose();
1000 }
1001
1002 ctre::phoenix::platform::can::CANComm_SetRxSchedPriority(
1003 constants::Values::kDrivetrainRxPriority, true, "Drivetrain Bus");
1004 ctre::phoenix::platform::can::CANComm_SetTxSchedPriority(
1005 constants::Values::kDrivetrainTxPriority, true, "Drivetrain Bus");
1006
1007 ::aos::ShmEventLoop can_output_event_loop(&config.message());
1008 can_output_event_loop.set_name("CANOutputWriter");
1009 DrivetrainWriter drivetrain_writer(&can_output_event_loop);
Ravago Jones2060ee62023-02-03 18:12:24 -08001010
1011 drivetrain_writer.set_falcons(right_front, right_back, right_under,
1012 left_front, left_back, left_under);
1013 drivetrain_writer.set_right_inverted(
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -07001014 ctre::phoenix6::signals::InvertedValue::Clockwise_Positive);
Ravago Jones2060ee62023-02-03 18:12:24 -08001015 drivetrain_writer.set_left_inverted(
Maxwell Hendersonfcc0d122023-08-05 17:03:34 -07001016 ctre::phoenix6::signals::InvertedValue::CounterClockwise_Positive);
milind-u32d29d32023-02-24 21:11:51 -08001017
1018 SuperstructureCANWriter superstructure_can_writer(&can_output_event_loop);
1019 superstructure_can_writer.set_roller_falcon(roller);
1020
Austin Schuhbb4c9ac2023-02-28 22:04:20 -08001021 can_output_event_loop.MakeWatcher(
1022 "/roborio", [&drivetrain_writer, &superstructure_can_writer](
1023 const CANConfiguration &configuration) {
1024 drivetrain_writer.HandleCANConfiguration(configuration);
1025 superstructure_can_writer.HandleCANConfiguration(configuration);
1026 });
1027
milind-u32d29d32023-02-24 21:11:51 -08001028 AddLoop(&can_output_event_loop);
1029
Maxwell Henderson2a2faa62023-03-11 15:05:46 -08001030 // Thread 6
Philipp Schradera6712522023-07-05 20:25:11 -07001031 // Set up superstructure output.
milind-u32d29d32023-02-24 21:11:51 -08001032 ::aos::ShmEventLoop output_event_loop(&config.message());
1033 output_event_loop.set_name("PWMOutputWriter");
Maxwell Hendersonad312342023-01-10 12:07:47 -08001034 SuperstructureWriter superstructure_writer(&output_event_loop);
1035
Henry Speisere139f802023-02-21 14:14:48 -08001036 superstructure_writer.set_proximal_falcon(make_unique<::frc::TalonFX>(1));
1037 superstructure_writer.set_distal_falcon(make_unique<::frc::TalonFX>(0));
milind-u18934eb2023-02-20 16:28:58 -08001038
1039 superstructure_writer.set_roll_joint_victor(
Henry Speisere139f802023-02-21 14:14:48 -08001040 make_unique<::frc::VictorSP>(3));
1041 superstructure_writer.set_wrist_victor(make_unique<::frc::VictorSP>(2));
1042
Maxwell Hendersonad312342023-01-10 12:07:47 -08001043 superstructure_writer.set_superstructure_reading(superstructure_reading);
1044
1045 AddLoop(&output_event_loop);
1046
Maxwell Henderson2a2faa62023-03-11 15:05:46 -08001047 // Thread 7
Philipp Schradera6712522023-07-05 20:25:11 -07001048 // Set up led_indicator.
Maxwell Henderson2a2faa62023-03-11 15:05:46 -08001049 ::aos::ShmEventLoop led_indicator_event_loop(&config.message());
1050 led_indicator_event_loop.set_name("LedIndicator");
1051 control_loops::superstructure::LedIndicator led_indicator(
1052 &led_indicator_event_loop);
1053 AddLoop(&led_indicator_event_loop);
1054
Maxwell Hendersonad312342023-01-10 12:07:47 -08001055 RunLoops();
1056 }
1057};
1058
1059} // namespace wpilib
1060} // namespace y2023
1061
1062AOS_ROBOT_CLASS(::y2023::wpilib::WPILibRobot);