blob: 5a19e8ff96ae1bf8f53b1d2c09fb11b0ae9cfa4f [file] [log] [blame]
Maxwell Hendersonf29e3182023-05-25 06:51:24 -07001#include "frc971/wpilib/can_sensor_reader.h"
2
3using frc971::wpilib::CANSensorReader;
4using frc971::wpilib::kCANUpdateFreqHz;
5
6CANSensorReader::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
29void 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}