blob: ff027d070e68696c8c694a9c1020e20563cbf596 [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
33std::optional<aos::monotonic_clock::duration> LocalizationUtils::ClockOffset(
34 std::string_view node) {
35 std::optional<aos::monotonic_clock::duration> monotonic_offset;
36 clock_offset_fetcher_.Fetch();
37 if (clock_offset_fetcher_.get() != nullptr) {
38 for (const auto connection : *clock_offset_fetcher_->connections()) {
39 if (connection->has_node() && connection->node()->has_name() &&
40 connection->node()->name()->string_view() == node) {
41 if (connection->has_monotonic_offset()) {
42 monotonic_offset =
43 std::chrono::nanoseconds(connection->monotonic_offset());
44 } else {
45 // If we don't have a monotonic offset, that means we aren't
46 // connected.
47 return std::nullopt;
48 }
49 break;
50 }
51 }
52 }
53 CHECK(monotonic_offset.has_value());
54 return monotonic_offset;
55}
56
57// Technically, this should be able to do a single memcpy, but the extra
58// verbosity here seems appropriate.
59Eigen::Matrix<double, 4, 4> FlatbufferToTransformationMatrix(
60 const frc971::vision::calibration::TransformationMatrix &flatbuffer) {
61 CHECK_EQ(16u, CHECK_NOTNULL(flatbuffer.data())->size());
62 Eigen::Matrix<double, 4, 4> result;
63 result.setIdentity();
64 for (int row = 0; row < 4; ++row) {
65 for (int col = 0; col < 4; ++col) {
66 result(row, col) = (*flatbuffer.data())[row * 4 + col];
67 }
68 }
69 return result;
70}
71
72} // namespace frc971::control_loops::drivetrain