blob: d9e239b40b169325422dc2ec58129f19deffc99e [file] [log] [blame]
James Kuszmaule3df1ed2023-02-20 16:21:17 -08001#include "frc971/control_loops/drivetrain/localization/utils.h"
James Kuszmaul9a1733a2023-02-19 16:51:47 -08002
3namespace frc971::control_loops::drivetrain {
4
5LocalizationUtils::LocalizationUtils(aos::EventLoop *event_loop)
6 : output_fetcher_(event_loop->MakeFetcher<Output>("/drivetrain")),
7 clock_offset_fetcher_(
8 event_loop->MakeFetcher<aos::message_bridge::ServerStatistics>(
9 "/aos")),
10 joystick_state_fetcher_(
11 event_loop->MakeFetcher<aos::JoystickState>("/roborio/aos")) {}
12
13Eigen::Vector2d LocalizationUtils::VoltageOrZero(
14 aos::monotonic_clock::time_point now) {
15 output_fetcher_.Fetch();
16 // Determine if the robot is likely to be disabled currently.
17 const bool disabled = (output_fetcher_.get() == nullptr) ||
18 (output_fetcher_.context().monotonic_event_time +
19 std::chrono::milliseconds(10) <
20 now);
21 return disabled ? Eigen::Vector2d::Zero()
22 : Eigen::Vector2d{output_fetcher_->left_voltage(),
23 output_fetcher_->right_voltage()};
24}
25
26bool LocalizationUtils::MaybeInAutonomous() {
27 joystick_state_fetcher_.Fetch();
28 return (joystick_state_fetcher_.get() != nullptr)
29 ? joystick_state_fetcher_->autonomous()
30 : true;
31}
32
James Kuszmaul4fe845a2023-03-26 12:57:30 -070033aos::Alliance LocalizationUtils::Alliance() {
34 joystick_state_fetcher_.Fetch();
35 return (joystick_state_fetcher_.get() != nullptr)
36 ? joystick_state_fetcher_->alliance()
37 : aos::Alliance::kInvalid;
38
39}
40
James Kuszmaul9a1733a2023-02-19 16:51:47 -080041std::optional<aos::monotonic_clock::duration> LocalizationUtils::ClockOffset(
42 std::string_view node) {
43 std::optional<aos::monotonic_clock::duration> monotonic_offset;
44 clock_offset_fetcher_.Fetch();
45 if (clock_offset_fetcher_.get() != nullptr) {
46 for (const auto connection : *clock_offset_fetcher_->connections()) {
47 if (connection->has_node() && connection->node()->has_name() &&
48 connection->node()->name()->string_view() == node) {
49 if (connection->has_monotonic_offset()) {
50 monotonic_offset =
51 std::chrono::nanoseconds(connection->monotonic_offset());
52 } else {
53 // If we don't have a monotonic offset, that means we aren't
54 // connected.
55 return std::nullopt;
56 }
57 break;
58 }
59 }
60 }
61 CHECK(monotonic_offset.has_value());
62 return monotonic_offset;
63}
64
65// Technically, this should be able to do a single memcpy, but the extra
66// verbosity here seems appropriate.
67Eigen::Matrix<double, 4, 4> FlatbufferToTransformationMatrix(
68 const frc971::vision::calibration::TransformationMatrix &flatbuffer) {
69 CHECK_EQ(16u, CHECK_NOTNULL(flatbuffer.data())->size());
70 Eigen::Matrix<double, 4, 4> result;
71 result.setIdentity();
72 for (int row = 0; row < 4; ++row) {
73 for (int col = 0; col < 4; ++col) {
74 result(row, col) = (*flatbuffer.data())[row * 4 + col];
75 }
76 }
77 return result;
78}
79
80} // namespace frc971::control_loops::drivetrain