YAMS
Yet Another Mechanism System
Loading...
Searching...
No Matches
StructTelemetry.hpp
Go to the documentation of this file.
1// Copyright (c) 2026 Yet Another Software Suite
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <optional>
8#include <stdexcept>
9#include <string>
10#include <utility>
11#include <wpi/datalog/DataLog.hpp>
12#include <wpi/nt/NetworkTable.hpp>
13#include <wpi/nt/StructTopic.hpp>
14#include <wpi/system/DataLogManager.hpp>
15#include <wpi/util/struct/Struct.hpp>
16
17namespace yams::telemetry {
18
30template <typename T, typename F>
32 public:
41 StructTelemetry(std::string key, T defaultVal, F field, bool tunable)
42 : m_field{field},
43 m_key{std::move(key)},
44 m_tunable{tunable},
45 m_defaultValue{std::move(defaultVal)},
46 m_cachedValue{m_defaultValue} {}
47
53 void SetDefaultValue(T value) { m_cachedValue = m_defaultValue = std::move(value); }
54
61 void SetupNetworkTables(std::shared_ptr<wpi::nt::NetworkTable> dataTable,
62 std::shared_ptr<wpi::nt::NetworkTable> tuningTable) {
63 m_dataTable = dataTable;
64 m_tuningTable = tuningTable;
65 if (!m_enabled) return;
66
67 if (tuningTable && m_tunable) {
68 auto topic = tuningTable->template GetStructTopic<T>(m_key);
69 m_subPublisher = topic.Publish();
70 m_subPublisher->SetDefault(m_defaultValue);
71 m_subscriber = topic.Subscribe(m_defaultValue);
72 } else if (dataTable) {
73 auto topic = dataTable->template GetStructTopic<T>(m_key);
74 m_publisher = topic.Publish();
75 m_publisher->SetDefault(m_defaultValue);
76 }
77 }
78
84 void SetupNetworkTable(std::shared_ptr<wpi::nt::NetworkTable> dataTable) {
85 SetupNetworkTables(dataTable, nullptr);
86 }
87
93 void SetupDataLog(const std::string& prefix) {
94 if (m_tunable) return;
95 std::string path = prefix;
96 if (!path.empty() && path.back() != '/') path += '/';
97 path += m_key;
98 m_dataLogEntry = wpi::log::StructLogEntry<T>{wpi::DataLogManager::GetLog(), path};
99 }
100
107 bool Set(const T& value) {
108 if (!m_enabled) return false;
109 if (m_dataLogEntry) {
110 m_dataLogEntry->Append(value);
111 }
112 if (m_subscriber) {
113 T tuningValue = m_subscriber->Get(m_defaultValue);
114 if (!(tuningValue == value)) return false;
115 }
116 if (m_publisher) {
117 m_publisher->Set(value);
118 }
119 return true;
120 }
121
127 T Get() const {
128 if (!m_enabled) return m_defaultValue;
129 if (m_subscriber) {
130 return m_subscriber->Get(m_defaultValue);
131 }
132 throw std::runtime_error("Tuning table not configured for " + m_key + "!");
133 }
134
140 bool IsTunable() {
141 if (m_subscriber && m_tunable && m_enabled) {
142 T current = m_subscriber->Get(m_defaultValue);
143 if (!(current == m_cachedValue)) {
144 m_cachedValue = current;
145 return true;
146 }
147 }
148 return false;
149 }
150
152 void Enable() { m_enabled = true; }
154 void Disable() { m_enabled = false; }
160 void Display(bool state) { m_enabled = state; }
162 F GetField() const { return m_field; }
164 bool IsEnabled() const { return m_enabled; }
165
167 void Close() {
168 m_subscriber.reset();
169 m_subPublisher.reset();
170 m_publisher.reset();
171 if (m_dataTable) {
172 m_dataTable->GetEntry(m_key).Unpublish();
173 }
174 if (m_tuningTable) {
175 m_tuningTable->GetEntry(m_key).Unpublish();
176 }
177 }
178
179 private:
180 F m_field;
181 std::string m_key;
182 bool m_tunable;
183 bool m_enabled{false};
184 T m_defaultValue;
185 T m_cachedValue;
186
187 std::optional<wpi::nt::StructPublisher<T>> m_publisher;
188 std::optional<wpi::nt::StructSubscriber<T>> m_subscriber;
189 std::optional<wpi::nt::StructPublisher<T>> m_subPublisher; // tunable: publish + subscribe
190 std::optional<wpi::log::StructLogEntry<T>> m_dataLogEntry;
191
192 std::shared_ptr<wpi::nt::NetworkTable> m_tuningTable;
193 std::shared_ptr<wpi::nt::NetworkTable> m_dataTable;
194};
195
196} // namespace yams::telemetry
Definition StructTelemetry.hpp:31
bool Set(const T &value)
Definition StructTelemetry.hpp:107
void Disable()
Definition StructTelemetry.hpp:154
void Enable()
Definition StructTelemetry.hpp:152
void SetDefaultValue(T value)
Definition StructTelemetry.hpp:53
StructTelemetry(std::string key, T defaultVal, F field, bool tunable)
Definition StructTelemetry.hpp:41
void Display(bool state)
Definition StructTelemetry.hpp:160
bool IsEnabled() const
Definition StructTelemetry.hpp:164
T Get() const
Definition StructTelemetry.hpp:127
void SetupDataLog(const std::string &prefix)
Definition StructTelemetry.hpp:93
void SetupNetworkTable(std::shared_ptr< wpi::nt::NetworkTable > dataTable)
Definition StructTelemetry.hpp:84
F GetField() const
Definition StructTelemetry.hpp:162
void Close()
Definition StructTelemetry.hpp:167
void SetupNetworkTables(std::shared_ptr< wpi::nt::NetworkTable > dataTable, std::shared_ptr< wpi::nt::NetworkTable > tuningTable)
Definition StructTelemetry.hpp:61
bool IsTunable()
Definition StructTelemetry.hpp:140
Definition SwerveDrive.hpp:864