9#include <unordered_map>
12#include <wpi/datalog/DataLog.hpp>
13#include <wpi/nt/BooleanTopic.hpp>
14#include <wpi/nt/DoubleTopic.hpp>
15#include <wpi/nt/NetworkTable.hpp>
16#include <wpi/system/DataLogManager.hpp>
17#include <wpi/util/json.hpp>
25class SmartMotorController;
108 std::optional<std::vector<BooleanTelemetryField>>
boolFields;
139 DoubleTelemetry(std::string key,
double defaultVal, F field,
bool tunable, std::string unit)
141 m_key{std::move(key)},
143 m_unit{std::move(unit)},
144 m_defaultValue{defaultVal},
145 m_cachedValue{defaultVal} {}
161 std::shared_ptr<wpi::nt::NetworkTable> tuningTable) {
162 m_dataTable = dataTable;
163 m_tuningTable = tuningTable;
164 if (!m_enabled)
return;
166 if (tuningTable && m_tunable) {
167 auto topic = tuningTable->GetDoubleTopic(m_key);
168 if (m_unit !=
"none") {
169 topic.SetProperties(wpi::util::json{{
"units", m_unit}});
171 m_subPublisher = topic.Publish();
172 m_subPublisher->SetDefault(m_defaultValue);
173 m_subscriber = topic.Subscribe(m_defaultValue);
174 }
else if (dataTable) {
175 auto topic = dataTable->GetDoubleTopic(m_key);
176 if (m_unit !=
"none") {
177 topic.SetProperties(wpi::util::json{{
"units", m_unit}});
179 m_publisher = topic.Publish();
180 m_publisher->SetDefault(m_defaultValue);
199 if (m_tunable)
return;
200 std::string path = prefix;
201 if (!path.empty() && path.back() !=
'/') path +=
'/';
202 path += m_unit +
'/' + m_key;
203 m_dataLogEntry = wpi::log::DoubleLogEntry{wpi::DataLogManager::GetLog(), path};
214 if (m_unit ==
"tunable_position") {
215 m_unit = linear ?
"meter" :
"degrees";
216 }
else if (m_unit ==
"position") {
217 m_unit = linear ?
"meter" :
"rotations";
218 }
else if (m_unit ==
"tunable_velocity") {
219 m_unit = linear ?
"meter_per_second" :
"rotations_per_minute";
220 }
else if (m_unit ==
"velocity") {
221 m_unit = linear ?
"meter_per_second" :
"rotation_per_second";
222 }
else if (m_unit ==
"tunable_acceleration") {
223 m_unit = linear ?
"meter_per_second_per_second" :
"rotations_per_minute_per_second";
224 }
else if (m_unit ==
"acceleration") {
225 m_unit = linear ?
"meter_per_second_per_second" :
"rotation_per_second_per_second";
237 if (m_subPublisher) {
238 m_subPublisher->Set(value);
239 }
else if (m_publisher) {
240 m_publisher->Set(value);
251 if (!m_enabled)
return false;
252 if (m_dataLogEntry) {
253 m_dataLogEntry->Append(value);
256 double tuningValue = m_subscriber->Get(m_defaultValue);
257 if (tuningValue != value)
return false;
260 m_publisher->Set(value);
271 if (!m_enabled)
return m_defaultValue;
273 return m_subscriber->Get(m_defaultValue);
275 throw std::runtime_error(
"Tuning table not configured for " + m_key +
"!");
284 if (m_subscriber && m_tunable && m_enabled) {
285 double current = m_subscriber->Get(m_defaultValue);
286 if (current != m_cachedValue) {
287 m_cachedValue = current;
303 void Display(
bool state) { m_enabled = state; }
311 m_subscriber.reset();
312 m_subPublisher.reset();
315 m_dataTable->GetEntry(m_key).Unpublish();
318 m_tuningTable->GetEntry(m_key).Unpublish();
326 bool m_enabled{
false};
328 double m_defaultValue;
329 double m_cachedValue;
331 std::optional<wpi::nt::DoublePublisher> m_publisher;
332 std::optional<wpi::nt::DoubleSubscriber> m_subscriber;
333 std::optional<wpi::nt::DoublePublisher> m_subPublisher;
334 std::optional<wpi::log::DoubleLogEntry> m_dataLogEntry;
336 std::shared_ptr<wpi::nt::NetworkTable> m_tuningTable;
337 std::shared_ptr<wpi::nt::NetworkTable> m_dataTable;
365 m_key{std::move(key)},
367 m_defaultValue{defaultVal},
368 m_cachedValue{defaultVal} {}
384 std::shared_ptr<wpi::nt::NetworkTable> tuningTable) {
385 m_dataTable = dataTable;
386 m_tuningTable = tuningTable;
387 if (!m_enabled)
return;
389 if (tuningTable && m_tunable) {
390 auto topic = tuningTable->GetBooleanTopic(m_key);
391 m_pubSub = topic.Publish();
392 m_pubSub->SetDefault(m_defaultValue);
393 m_subscriber = topic.Subscribe(m_defaultValue);
394 }
else if (dataTable) {
395 auto topic = dataTable->GetBooleanTopic(m_key);
396 m_publisher = topic.Publish();
397 m_publisher->SetDefault(m_defaultValue);
416 if (m_tunable)
return;
417 std::string path = prefix;
418 if (!path.empty() && path.back() !=
'/') path +=
'/';
420 m_dataLogEntry = wpi::log::BooleanLogEntry{wpi::DataLogManager::GetLog(), path};
430 if (!m_enabled)
return false;
431 if (m_dataLogEntry) {
432 m_dataLogEntry->Append(value);
435 bool tuningValue = m_subscriber->Get(m_defaultValue);
436 if (tuningValue != value)
return false;
439 m_publisher->Set(value);
450 if (!m_enabled)
return m_defaultValue;
452 return m_subscriber->Get(m_defaultValue);
454 throw std::runtime_error(
"Tuning table not configured for " + m_key +
"!");
467 m_pubSub->Set(value);
468 }
else if (m_publisher) {
469 m_publisher->Set(value);
479 if (m_subscriber && m_tunable && m_enabled) {
480 bool current = m_subscriber->Get(m_defaultValue);
481 if (current != m_cachedValue) {
482 m_cachedValue = current;
498 void Display(
bool state) { m_enabled = state; }
506 m_subscriber.reset();
510 m_dataTable->GetEntry(m_key).Unpublish();
513 m_tuningTable->GetEntry(m_key).Unpublish();
521 bool m_enabled{
false};
525 std::optional<wpi::nt::BooleanPublisher> m_publisher;
526 std::optional<wpi::nt::BooleanSubscriber> m_subscriber;
527 std::optional<wpi::nt::BooleanPublisher> m_pubSub;
528 std::optional<wpi::log::BooleanLogEntry> m_dataLogEntry;
530 std::shared_ptr<wpi::nt::NetworkTable> m_tuningTable;
531 std::shared_ptr<wpi::nt::NetworkTable> m_dataTable;
558 std::shared_ptr<wpi::nt::NetworkTable> publishTable,
559 std::shared_ptr<wpi::nt::NetworkTable> tuningTable,
563 bool nt4Enabled, std::optional<std::string> dataLogName);
595 std::shared_ptr<wpi::nt::NetworkTable> m_dataTable;
596 std::shared_ptr<wpi::nt::NetworkTable> m_tuningTable;
598 std::unordered_map<DoubleTelemetryField, DoubleTelemetry<DoubleTelemetryField>>* m_doubleFields{
600 std::unordered_map<BooleanTelemetryField, BooleanTelemetry<BooleanTelemetryField>>* m_boolFields{
Definition SmartMotorControllerConfig.hpp:65
bool GetLinearClosedLoopControllerUse() const
Definition SmartMotorController.hpp:48
Definition SmartMotorControllerTelemetry.hpp:353
void SetDefaultValue(bool value)
Definition SmartMotorControllerTelemetry.hpp:375
void ForceSet(bool value)
Definition SmartMotorControllerTelemetry.hpp:465
bool Get() const
Definition SmartMotorControllerTelemetry.hpp:449
bool Set(bool value)
Definition SmartMotorControllerTelemetry.hpp:429
void SetupDataLog(const std::string &prefix)
Definition SmartMotorControllerTelemetry.hpp:415
void Close()
Definition SmartMotorControllerTelemetry.hpp:505
bool IsEnabled() const
Definition SmartMotorControllerTelemetry.hpp:502
F GetField() const
Definition SmartMotorControllerTelemetry.hpp:500
void Enable()
Definition SmartMotorControllerTelemetry.hpp:490
void SetupNetworkTables(std::shared_ptr< wpi::nt::NetworkTable > dataTable, std::shared_ptr< wpi::nt::NetworkTable > tuningTable)
Definition SmartMotorControllerTelemetry.hpp:383
void Disable()
Definition SmartMotorControllerTelemetry.hpp:492
void Display(bool state)
Definition SmartMotorControllerTelemetry.hpp:498
bool IsTunable()
Definition SmartMotorControllerTelemetry.hpp:478
void SetupNetworkTable(std::shared_ptr< wpi::nt::NetworkTable > dataTable)
Definition SmartMotorControllerTelemetry.hpp:406
BooleanTelemetry(std::string key, bool defaultVal, F field, bool tunable)
Definition SmartMotorControllerTelemetry.hpp:363
Definition SmartMotorControllerTelemetry.hpp:128
void SetupDataLog(const std::string &prefix)
Definition SmartMotorControllerTelemetry.hpp:198
double Get() const
Definition SmartMotorControllerTelemetry.hpp:270
bool IsTunable()
Definition SmartMotorControllerTelemetry.hpp:283
F GetField() const
Definition SmartMotorControllerTelemetry.hpp:305
void TransformUnit(const motorcontrollers::SmartMotorControllerConfig &cfg)
Definition SmartMotorControllerTelemetry.hpp:212
void Enable()
Definition SmartMotorControllerTelemetry.hpp:295
void SetDefaultValue(double value)
Definition SmartMotorControllerTelemetry.hpp:152
void SetupNetworkTables(std::shared_ptr< wpi::nt::NetworkTable > dataTable, std::shared_ptr< wpi::nt::NetworkTable > tuningTable)
Definition SmartMotorControllerTelemetry.hpp:160
void Disable()
Definition SmartMotorControllerTelemetry.hpp:297
bool Set(double value)
Definition SmartMotorControllerTelemetry.hpp:250
void Display(bool state)
Definition SmartMotorControllerTelemetry.hpp:303
DoubleTelemetry(std::string key, double defaultVal, F field, bool tunable, std::string unit)
Definition SmartMotorControllerTelemetry.hpp:139
void SetupNetworkTable(std::shared_ptr< wpi::nt::NetworkTable > dataTable)
Definition SmartMotorControllerTelemetry.hpp:189
void ForceSet(double value)
Definition SmartMotorControllerTelemetry.hpp:236
bool IsEnabled() const
Definition SmartMotorControllerTelemetry.hpp:307
void Close()
Definition SmartMotorControllerTelemetry.hpp:310
Definition SmartMotorControllerTelemetry.hpp:543
void Publish(motorcontrollers::SmartMotorController &smc)
void SetupTelemetry(motorcontrollers::SmartMotorController &smc, std::shared_ptr< wpi::nt::NetworkTable > publishTable, std::shared_ptr< wpi::nt::NetworkTable > tuningTable, std::unordered_map< DoubleTelemetryField, DoubleTelemetry< DoubleTelemetryField > > &doubleFields, std::unordered_map< BooleanTelemetryField, BooleanTelemetry< BooleanTelemetryField > > &boolFields, bool nt4Enabled, std::optional< std::string > dataLogName)
void StopTuning(motorcontrollers::SmartMotorController &smc)
void ApplyTuningValues(motorcontrollers::SmartMotorController &smc)
bool TuningEnabled() const
Definition SimSensorConfig.hpp:15
Definition SwerveDrive.hpp:864
DoubleTelemetryField
Definition SmartMotorControllerTelemetry.hpp:33
@ TrapezoidalProfileMaxAcceleration
@ kG
Gravity feedforward gain kG (tunable).
@ kI
Integral feedback gain kI (tunable).
@ MechanismUpperLimit
Configured upper angular soft limit (degrees, tunable).
@ MechanismAcceleration
Mechanism acceleration in rotations per second squared.
@ ExternalEncoderVelocity
External encoder's mechanism velocity in rotations per second, only with an external encoder.
@ kA
Acceleration feedforward gain kA (tunable).
@ TunableClosedLoopControllerSlot
Live-tunable closed-loop gain slot selector.
@ kP
Proportional feedback gain kP (tunable).
@ SupplyCurrent
Supply (input) current draw (A).
@ StatorCurrent
Stator (output) current draw (A).
@ OutputVoltage
Voltage currently applied to the motor (V).
@ VelocityMeasurementDelay
How far behind the measured velocity is, when known (s).
@ ExponentialProfileKV
Exponential profile kV constant (tunable).
@ SetpointForce
Feedforward force applied on the velocity setpoint (N).
@ SupplyCurrentLimit
Configured supply current limit (A, tunable).
@ MeasurementVelocity
Linear measurement velocity (m/s).
@ kV
Velocity feedforward gain kV (tunable).
@ kD
Derivative feedback gain kD (tunable).
@ SetpointPosition
Read-only position setpoint rotations or meters.
@ MeasurementUpperLimit
Configured upper linear soft limit (m, tunable).
@ ClosedLoopPeriod
Period the closed-loop controller runs at (s).
@ ExternalEncoderPosition
External encoder's mechanism position in rotations, only with an external encoder.
@ TunableSetpointPosition
Live-tunable position setpoint degrees or meters.
@ MechanismPosition
Mechanism position in rotations.
@ RotorVelocity
Raw rotor velocity in rotations per second.
@ MeasurementPosition
Linear measurement position (m).
@ MeasurementAcceleration
Linear measurement acceleration (m/s²).
@ OpenloopRampRate
Open-loop duty-cycle ramp rate (s, tunable).
@ TrapezoidalProfileMaxVelocity
Trapezoidal profile max velocity RPM or m/s (tunable).
@ ExponentialProfileKA
Exponential profile kA constant (tunable).
@ TunableSetpointVelocity
Live-tunable velocity setpoint RPM or m/s.
@ MeasurementLowerLimit
Configured lower linear soft limit (m, tunable).
@ SetpointVelocity
Read-only velocity setpoint RPS or m/s.
@ ClosedloopRampRate
Closed-loop duty-cycle ramp rate (s, tunable).
@ kS
Static friction feedforward gain kS (tunable).
@ StatorCurrentLimit
Configured stator current limit (A, tunable).
@ ExponentialProfileMaxInput
Exponential profile maximum input voltage (tunable).
@ ActiveClosedLoopControllerSlot
Currently active closed-loop gain slot (read-only).
@ MotorTemperature
Motor controller temperature (°F).
@ MechanismLowerLimit
Configured lower angular soft limit (degrees, tunable).
@ RotorPosition
Raw rotor position in rotations.
@ TrapezoidalProfileMaxJerk
Trapezoidal profile max jerk RPM/s² (tunable).
@ MechanismVelocity
Mechanism velocity in rotations per second.
BooleanTelemetryField
Definition SmartMotorControllerTelemetry.hpp:84
@ EncoderInversion
true when the encoder count direction is inverted (tunable).
@ TemperatureLimit
true when the motor temperature has reached the cutoff threshold.
@ SimpleMotorFeedForward
true when a simple motor feedforward model is configured.
@ MotorInversion
true when the motor output direction is inverted (tunable).
@ ElevatorFeedForward
true when an elevator feedforward model is configured.
@ MotionProfile
true when a motion profile (trapezoidal or exponential) is active.
@ VelocityControl
true when a velocity setpoint is active.
@ ArmFeedForward
true when an arm feedforward model is configured.
Definition SmartMotorControllerTelemetry.hpp:107
std::optional< std::vector< DoubleTelemetryField > > doubleFields
Unsupported double fields.
Definition SmartMotorControllerTelemetry.hpp:109
std::optional< std::vector< BooleanTelemetryField > > boolFields
Unsupported boolean fields.
Definition SmartMotorControllerTelemetry.hpp:108