Maxwell Henderson | f29e318 | 2023-05-25 06:51:24 -0700 | [diff] [blame^] | 1 | #include "frc971/wpilib/can_sensor_reader.h" |
| 2 | |
| 3 | using frc971::wpilib::CANSensorReader; |
| 4 | using frc971::wpilib::kCANUpdateFreqHz; |
| 5 | |
| 6 | CANSensorReader::CANSensorReader( |
| 7 | aos::EventLoop *event_loop, |
| 8 | std::vector<ctre::phoenixpro::BaseStatusSignalValue *> signals_registry, |
| 9 | std::vector<std::shared_ptr<Falcon>> falcons) |
| 10 | : event_loop_(event_loop), |
| 11 | signals_(signals_registry.begin(), signals_registry.end()), |
| 12 | can_position_sender_( |
| 13 | event_loop->MakeSender<control_loops::drivetrain::CANPosition>( |
| 14 | "/drivetrain")), |
| 15 | falcons_(falcons) { |
| 16 | event_loop->SetRuntimeRealtimePriority(40); |
| 17 | |
| 18 | // TODO(max): Decide if we want to keep this on this core. |
| 19 | event_loop->SetRuntimeAffinity(aos::MakeCpusetFromCpus({1})); |
| 20 | timer_handler_ = event_loop->AddTimer([this]() { Loop(); }); |
| 21 | timer_handler_->set_name("CANSensorReader Loop"); |
| 22 | |
| 23 | event_loop->OnRun([this]() { |
| 24 | timer_handler_->Schedule(event_loop_->monotonic_now(), |
| 25 | 1 / kCANUpdateFreqHz); |
| 26 | }); |
| 27 | } |
| 28 | |
| 29 | void CANSensorReader::Loop() { |
| 30 | ctre::phoenix::StatusCode status = |
| 31 | ctre::phoenixpro::BaseStatusSignalValue::WaitForAll(20_ms, signals_); |
| 32 | |
| 33 | if (!status.IsOK()) { |
| 34 | AOS_LOG(ERROR, "Failed to read signals from falcons: %s: %s", |
| 35 | status.GetName(), status.GetDescription()); |
| 36 | } |
| 37 | |
| 38 | auto builder = can_position_sender_.MakeBuilder(); |
| 39 | |
| 40 | for (auto falcon : falcons_) { |
| 41 | falcon->RefreshNontimesyncedSignals(); |
| 42 | falcon->SerializePosition(builder.fbb()); |
| 43 | } |
| 44 | |
| 45 | auto falcon_offsets = |
| 46 | builder.fbb() |
| 47 | ->CreateVector<flatbuffers::Offset<control_loops::CANFalcon>>( |
| 48 | falcons_.size(), [this](size_t index) { |
| 49 | auto offset = falcons_.at(index)->TakeOffset(); |
| 50 | CHECK(offset.has_value()); |
| 51 | return offset.value(); |
| 52 | }); |
| 53 | |
| 54 | control_loops::drivetrain::CANPosition::Builder can_position_builder = |
| 55 | builder.MakeBuilder<control_loops::drivetrain::CANPosition>(); |
| 56 | |
| 57 | can_position_builder.add_falcons(falcon_offsets); |
| 58 | if (!falcons_.empty()) { |
| 59 | can_position_builder.add_timestamp(falcons_.at(0)->GetTimestamp()); |
| 60 | } |
| 61 | can_position_builder.add_status(static_cast<int>(status)); |
| 62 | |
| 63 | builder.CheckOk(builder.Send(can_position_builder.Finish())); |
| 64 | } |