CTRE Phoenix 6 C++ 26.0.0-beta-1
Loading...
Searching...
No Matches
StatusSignal.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) Cross The Road Electronics.  All rights reserved.
3 * License information can be found in CTRE_LICENSE.txt
4 * For support and suggestions contact support@ctr-electronics.com or file
5 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
6 */
7#pragma once
8
14#include <array>
15#include <functional>
16#include <map>
17#include <ostream>
18#include <span>
19#include <sstream>
20#include <string>
21#include <units/frequency.h>
22#include <units/math.h>
23#include <units/time.h>
24
25namespace ctre {
26namespace phoenix6 {
27
28 namespace hardware {
29 class ParentDevice;
30 }
31
32 template <typename T>
33 class StatusSignal;
34
35 /**
36 * \brief Class that provides operations to
37 * retrieve information about a status signal.
38 */
40 private:
41 hardware::DeviceIdentifier deviceIdentifier;
42 uint16_t spn;
43 std::string name;
44 std::function<void()> _checkFirmVersFunction;
45
46 std::map<uint16_t, std::string> _unitStrings{};
47 uint16_t _unitsKey;
48
49 units::time::second_t _lastTimestamp{0_s};
50
51 protected:
52 std::string units;
53 double baseValue = 0;
56
58 hardware::DeviceIdentifier deviceIdentifier,
59 uint16_t spn,
60 std::string signalName,
61 std::function<void()> checkFirmVersFunction
62 ) :
63 deviceIdentifier{std::move(deviceIdentifier)},
64 spn{spn},
65 name{std::move(signalName)},
66 _checkFirmVersFunction{std::move(checkFirmVersFunction)},
67 _unitsKey{spn},
69 {
70 }
71
73 hardware::DeviceIdentifier deviceIdentifier,
74 uint16_t spn,
75 std::string signalName,
76 std::function<void()> checkFirmVersFunction,
77 std::function<std::map<uint16_t, std::string>()> const &unitsGenerator
78 ) :
79 deviceIdentifier{std::move(deviceIdentifier)},
80 spn{spn},
81 name{std::move(signalName)},
82 _checkFirmVersFunction{std::move(checkFirmVersFunction)},
83 _unitStrings{unitsGenerator()},
84 _unitsKey{spn},
86 {
87 for (auto &unitString : _unitStrings) {
88 unitString.second = Status_GetUnits(unitString.first);
89 }
90 }
91
92 /* Constructor for an invalid BaseStatusSignal */
94 deviceIdentifier{hardware::DeviceIdentifier{}},
95 spn{0},
96 name{"Invalid"},
97 _checkFirmVersFunction{[] {}},
98 _unitsKey{spn},
99 error{error}
100 {
101 }
102
103 static std::string Status_GetUnits(uint32_t signal);
104
106 BaseStatusSignal &signal,
107 char const *network,
108 bool bWaitForUpdate,
109 double timeoutSeconds);
111 std::span<BaseStatusSignal* const> signals,
112 char const *network,
113 double timeoutSeconds);
114
116 char const *canbus,
117 uint32_t deviceHash,
118 uint16_t spn,
119 double frequencyHz,
120 double timeoutSeconds);
122 std::span<BaseStatusSignal* const> signals,
123 double frequencyHz,
124 double timeoutSeconds);
125 static double Status_GetAppliedUpdateFrequency(char const *canbus, uint32_t deviceHash, uint16_t spn);
126
128 char const *location,
129 units::time::second_t timeoutSeconds,
130 std::span<BaseStatusSignal* const> signals);
131
132 void RefreshValue(bool waitForUpdate, units::time::second_t timeout, bool ReportOnError);
133 void UpdateUnits(uint16_t unitsKey);
134
135 public:
136 virtual ~BaseStatusSignal() = 0; // Declare virtual destructor to make this class abstract
137
138 /**
139 * \brief Gets the name of this signal.
140 *
141 * \returns Name of this signal
142 */
143 std::string const &GetName() const { return name; }
144 /**
145 * \brief Gets the units for this signal.
146 *
147 * \returns String representation of units for this signal
148 */
149 std::string const &GetUnits() const { return units; }
150 /**
151 * \brief Gets the value of this signal as a double.
152 *
153 * \return Value of this signal as a double instead of the generic type
154 */
155 double GetValueAsDouble() const { return baseValue; }
156 /**
157 * \brief Gets the timestamps of this signals.
158 *
159 * \returns All timestamps for this signal
160 */
161 AllTimestamps const &GetAllTimestamps() const { return timestamps; }
162 /**
163 * \brief Gets the most accurate timestamp available for this signal.
164 *
165 * \details The timestamp sources from most to least accurate are:
166 *
167 * - Timestamp#TimestampSource#Device
168 * - Timestamp#TimestampSource#CANivore
169 * - Timestamp#TimestampSource#System
170 *
171 * Note that some of these sources may not be available.
172 *
173 * \returns The most accurate timestamp available for this signal
174 */
175 Timestamp const &GetTimestamp() const { return timestamps.GetBestTimestamp(); }
176 /**
177 * \brief Gets the error code from when we last received this signal.
178 *
179 * \returns Last cached Error Code
180 */
181 ctre::phoenix::StatusCode GetStatus() const { return error; }
182
183 /**
184 * \brief Checks whether the signal has been updated since the last check.
185 *
186 * Note that the signal must be refreshed before calling this routine.
187 *
188 * \returns true if the signal has updated since the previous call of this routine
189 */
191 {
192 bool retval = false;
193 /* did we receive an update */
194 auto const &timestamp = GetAllTimestamps().GetSystemTimestamp();
195 if (timestamp.IsValid()) {
196 /* if the update timestamp is new, then a new frame was sent */
197 if (_lastTimestamp != timestamp.GetTime()) {
198 _lastTimestamp = timestamp.GetTime();
199 retval = true;
200 }
201 }
202 return retval;
203 }
204
205 /**
206 * \brief Sets the rate at which the device will publish this signal.
207 *
208 * A frequency of 0 Hz will turn off the signal. Otherwise, the minimum supported signal
209 * frequency is 4 Hz, and the maximum is 1000 Hz. Additionally, some update frequencies are
210 * not supported and will be promoted up to the next highest supported frequency.
211 *
212 * If other StatusSignals in the same status frame have been set to an update frequency,
213 * the fastest requested update frequency will be applied to the frame.
214 *
215 * \param frequencyHz Rate to publish the signal in Hz.
216 * \param timeoutSeconds Maximum amount of time to wait when performing the action
217 * \returns Status code of setting the update frequency
218 */
219 ctre::phoenix::StatusCode SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds = 100_ms)
220 {
221 return Status_SetUpdateFrequency(
222 this->deviceIdentifier.network.c_str(),
223 this->deviceIdentifier.deviceHash,
224 this->spn,
225 frequencyHz.to<double>(),
226 timeoutSeconds.to<double>()
227 );
228 }
229
230 /**
231 * \brief Gets the rate at which the device will publish this signal.
232 *
233 * This is typically the last value passed into #SetUpdateFrequency. The returned value
234 * may be higher if another StatusSignal in the same status frame has been set to a higher
235 * update frequency.
236 *
237 * \returns Applied update frequency of the signal in Hz
238 */
239 units::frequency::hertz_t GetAppliedUpdateFrequency() const
240 {
241 return units::frequency::hertz_t{
242 Status_GetAppliedUpdateFrequency(
243 this->deviceIdentifier.network.c_str(),
244 this->deviceIdentifier.deviceHash,
245 this->spn
246 )
247 };
248 }
249
250 /**
251 * \brief Performs latency compensation on signal using the signalSlope and signal's latency to determine
252 * the magnitude of compensation. The caller must refresh these StatusSignals beforehand;
253 * this function only does the math required for latency compensation.
254 *
255 * \details Example usage:
256 * \code
257 * units::turn_t compensatedTurns = BaseStatusSignal::GetLatencyCompensatedValue(fx.GetPosition(), fx.GetVelocity());
258 * \endcode
259 *
260 * \tparam U Type of signal's underlying type. This is the type that the function will return.
261 * \tparam U_PER_SEC Type of signalSlope's underlying type. This must be the derivative of U.
262 * \param signal Signal to be latency compensated. Caller must make sure this signal is up to date
263 * either by calling \c Refresh() or \c WaitForUpdate().
264 * \param signalSlope Derivative of signal that informs compensation magnitude. Caller must make sure this
265 * signal is up to date either by calling \c Refresh() or \c WaitForUpdate().
266 * \param maxLatencySeconds The maximum amount of latency to compensate for in seconds. A negative or zero
267 * value disables the max latency cap. This is used to cap the contribution of
268 * latency compensation for stale signals, such as after the device has been
269 * disconnected from the CAN bus.
270 * \returns Latency compensated value from the signal StatusSignal.
271 */
272 template <typename U, typename U_PER_SEC>
273 requires units::traits::is_unit_t_v<U> && units::traits::is_unit_t_v<U_PER_SEC> &&
274 units::traits::is_convertible_unit_v<
275 typename units::traits::unit_t_traits<U>::unit_type,
276 units::compound_unit<typename units::traits::unit_t_traits<U_PER_SEC>::unit_type, units::seconds>
277 >
278 static U GetLatencyCompensatedValue(StatusSignal<U> const &signal, StatusSignal<U_PER_SEC> const &signalSlope, units::time::second_t maxLatencySeconds = 0.300_s)
279 {
280 U const nonCompensatedSignal = signal.GetValue();
281 U_PER_SEC const changeInSignal = signalSlope.GetValue();
282 units::second_t latency = signal.GetTimestamp().GetLatency();
283 if (maxLatencySeconds > 0_s && latency > maxLatencySeconds) {
284 latency = maxLatencySeconds;
285 }
286 return nonCompensatedSignal + (changeInSignal * latency);
287 }
288
289 /**
290 * \brief Waits for new data on all provided signals up to timeout.
291 * This API is typically used with CANivore Bus signals as they will be synced using the
292 * CANivore Timesync feature and arrive simultaneously. Signals on a roboRIO bus cannot
293 * be synced and may require a significantly longer blocking call to receive all signals.
294 *
295 * Note that CANivore Timesync requires Phoenix Pro.
296 *
297 * This can also be used with a timeout of zero to refresh many signals at once, which
298 * is faster than calling Refresh() on every signal. This is equivalent to calling #RefreshAll.
299 *
300 * If a signal arrives multiple times while waiting, such as when *not* using CANivore
301 * Timesync, the newest signal data is fetched. Additionally, if this function times out,
302 * the newest signal data is fetched for all signals (when possible). We recommend checking
303 * the individual status codes using GetStatus() when this happens.
304 *
305 * \param timeoutSeconds Maximum time to wait for all the signals to arrive.
306 * Pass zero to refresh all signals without blocking.
307 * \param signals Signals to wait on, passed as a comma-separated list of signal references.
308 * \return An InvalidParamValue if signals array is empty,
309 * InvalidNetwork if signals are on different CAN bus networks,
310 * RxTimeout if it took longer than timeoutSeconds to receive all the signals,
311 * MultiSignalNotSupported if using the roboRIO bus with more than one signal and a non-zero timeout.
312 * An OK status code means that all signals arrived within timeoutSeconds and they are all OK.
313 *
314 * Any other value represents the StatusCode of the first failed signal.
315 * Call GetStatus() on each signal to determine which ones failed.
316 */
317 template <std::derived_from<BaseStatusSignal>... Signals>
318 static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, Signals &... signals)
319 {
320 return WaitForAll(
321 timeoutSeconds,
322 std::array<BaseStatusSignal *, sizeof...(Signals)>{(&signals)...}
323 );
324 }
325 /**
326 * \brief Waits for new data on all provided signals up to timeout.
327 * This API is typically used with CANivore Bus signals as they will be synced using the
328 * CANivore Timesync feature and arrive simultaneously. Signals on a roboRIO bus cannot
329 * be synced and may require a significantly longer blocking call to receive all signals.
330 *
331 * Note that CANivore Timesync requires Phoenix Pro.
332 *
333 * This can also be used with a timeout of zero to refresh many signals at once, which
334 * is faster than calling Refresh() on every signal. This is equivalent to calling #RefreshAll.
335 *
336 * If a signal arrives multiple times while waiting, such as when *not* using CANivore
337 * Timesync, the newest signal data is fetched. Additionally, if this function times out,
338 * the newest signal data is fetched for all signals (when possible). We recommend checking
339 * the individual status codes using GetStatus() when this happens.
340 *
341 * \param timeoutSeconds Maximum time to wait for all the signals to arrive.
342 * Pass zero to refresh all signals without blocking.
343 * \param signals Signals to wait on, passed as a span of signal pointers.
344 * \return An InvalidParamValue if signals array is empty,
345 * InvalidNetwork if signals are on different CAN bus networks,
346 * RxTimeout if it took longer than timeoutSeconds to receive all the signals,
347 * MultiSignalNotSupported if using the roboRIO bus with more than one signal and a non-zero timeout.
348 * An OK status code means that all signals arrived within timeoutSeconds and they are all OK.
349 *
350 * Any other value represents the StatusCode of the first failed signal.
351 * Call GetStatus() on each signal to determine which ones failed.
352 */
353 static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, std::span<BaseStatusSignal* const> signals)
354 {
355 /* static string for location */
356 constexpr char kLocation[] = "ctre::phoenix6::BaseStatusSignal::WaitForAll";
357 return WaitForAllImpl(kLocation, timeoutSeconds, signals);
358 }
359
360 /**
361 * \brief Performs a non-blocking refresh on all provided signals.
362 *
363 * This provides a performance improvement over separately calling Refresh() on each signal.
364 *
365 * \param signals Signals to refresh, passed as a comma-separated list of signal references.
366 * \return An InvalidParamValue if signals array is empty,
367 * InvalidNetwork if signals are on different CAN bus networks.
368 * An OK status code means that all signals are OK.
369 *
370 * Any other value represents the StatusCode of the first failed signal.
371 * Call GetStatus() on each signal to determine which ones failed.
372 */
373 template <std::derived_from<BaseStatusSignal>... Signals>
374 static ctre::phoenix::StatusCode RefreshAll(Signals &... signals)
375 {
376 return RefreshAll(std::array<BaseStatusSignal *, sizeof...(Signals)>{(&signals)...});
377 }
378 /**
379 * \brief Performs a non-blocking refresh on all provided signals.
380 *
381 * This provides a performance improvement over separately calling Refresh() on each signal.
382 *
383 * \param signals Signals to refresh, passed as a span of signal pointers.
384 * \return An InvalidParamValue if signals array is empty,
385 * InvalidNetwork if signals are on different CAN bus networks.
386 * An OK status code means that all signals are OK.
387 *
388 * Any other value represents the StatusCode of the first failed signal.
389 * Call GetStatus() on each signal to determine which ones failed.
390 */
391 static ctre::phoenix::StatusCode RefreshAll(std::span<BaseStatusSignal* const> signals)
392 {
393 /* static string for location */
394 constexpr char kLocation[] = "ctre::phoenix6::BaseStatusSignal::RefreshAll";
395 return WaitForAllImpl(kLocation, 0_s, signals);
396 }
397
398 /**
399 * \brief Checks if all signals have an OK error code.
400 *
401 * \param signals Signals to check error code of, passed as a comma-separated list of signal references.
402 * \returns True if all signals are OK, false otherwise
403 */
404 template <std::derived_from<BaseStatusSignal>... Signals>
405 static bool IsAllGood(Signals const &... signals)
406 {
407 return IsAllGood(std::array<BaseStatusSignal const *, sizeof...(Signals)>{(&signals)...});
408 }
409 /**
410 * \brief Checks if all signals have an OK error code.
411 *
412 * \param signals Signals to check error code of, passed as a span of signal pointers.
413 * \returns True if all signals are OK, false otherwise
414 */
415 static bool IsAllGood(std::span<BaseStatusSignal const *const> signals)
416 {
417 for (auto signal : signals) {
418 if (!signal->GetStatus().IsOK()) {
419 return false;
420 }
421 }
422 return true;
423 }
424
425 /**
426 * \brief Sets the update frequency of all specified status signals to the provided common frequency.
427 *
428 * A frequency of 0 Hz will turn off the signal. Otherwise, the minimum supported signal frequency
429 * is 4 Hz, and the maximum is 1000 Hz. Additionally, some update frequencies are not supported and
430 * will be promoted up to the next highest supported frequency.
431 *
432 * If other StatusSignals in the same status frame have been set to an update frequency,
433 * the fastest requested update frequency will be applied to the frame.
434 *
435 * This will wait up to 0.100 seconds (100ms) for each signal.
436 *
437 * \param frequencyHz Rate to publish the signal in Hz.
438 * \param signals Signals to apply the update frequency to, passed as a comma-separated list of signal references.
439 * \returns Status code of the first failed update frequency set call, or OK if all succeeded
440 */
441 template <std::derived_from<BaseStatusSignal>... Signals>
442 static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, Signals &... signals)
443 {
444 return SetUpdateFrequencyForAll(frequencyHz, std::array<BaseStatusSignal *, sizeof...(Signals)>{(&signals)...});
445 }
446 /**
447 * \brief Sets the update frequency of all specified status signals to the provided common frequency.
448 *
449 * A frequency of 0 Hz will turn off the signal. Otherwise, the minimum supported signal frequency
450 * is 4 Hz, and the maximum is 1000 Hz. Additionally, some update frequencies are not supported and
451 * will be promoted up to the next highest supported frequency.
452 *
453 * If other StatusSignals in the same status frame have been set to an update frequency,
454 * the fastest requested update frequency will be applied to the frame.
455 *
456 * This will wait up to 0.100 seconds (100ms) for each signal.
457 *
458 * \param frequencyHz Rate to publish the signal in Hz.
459 * \param signals Signals to apply the update frequency to, passed as a span of signal pointers.
460 * \returns Status code of the first failed update frequency set call, or OK if all succeeded
461 */
462 static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, std::span<BaseStatusSignal* const> signals)
463 {
464 return Status_SetUpdateFrequencyForAll(signals, frequencyHz.to<double>(), 0.100);
465 }
466 };
467
468 /**
469 * \brief Represents a status signal with data of type T,
470 * and operations available to retrieve information about
471 * the signal.
472 */
473 template <typename T>
476
478 hardware::DeviceIdentifier deviceIdentifier,
479 uint16_t spn,
480 std::string signalName,
481 std::function<void()> checkFirmVersFunction
482 ) :
484 std::move(deviceIdentifier),
485 spn, std::move(signalName),
486 std::move(checkFirmVersFunction)
487 }
488 {
489 }
490
492 hardware::DeviceIdentifier deviceIdentifier,
493 uint16_t spn,
494 std::string signalName,
495 std::function<void()> checkFirmVersFunction,
496 std::function<std::map<uint16_t, std::string>()> const &unitsGenerator
497 ) :
499 std::move(deviceIdentifier),
500 spn, std::move(signalName),
501 std::move(checkFirmVersFunction),
502 unitsGenerator
503 }
504 {
505 }
506
507 /* Constructor for an invalid StatusSignal */
508 StatusSignal(ctre::phoenix::StatusCode error) :
509 BaseStatusSignal{error}
510 {
511 }
512
513 public:
514 /**
515 * \brief Gets the cached value from this status signal.
516 *
517 * \details Gets the cached value. To make sure the value is up-to-date
518 * call \c Refresh() or \c WaitForUpdate()
519 *
520 * \returns Cached value
521 */
522 T GetValue() const
523 {
524 if constexpr(units::traits::is_unit_t_v<T>) {
525 return units::make_unit<T>(this->baseValue);
526 } else {
527 return static_cast<T>(this->baseValue);
528 }
529 }
530
531 /**
532 * \brief Refreshes the value of this status signal.
533 *
534 * If the user application caches this StatusSignal object
535 * instead of periodically fetching it from the hardware device,
536 * this function must be called to fetch fresh data.
537 *
538 * \details This performs a non-blocking refresh operation. If
539 * you want to wait until you receive the signal, call
540 * \c WaitForUpdate() instead.
541 *
542 * \param ReportOnError Whether to report any errors to the Driver Station/stderr.
543 *
544 * \returns Reference to itself
545 */
546 StatusSignal<T> &Refresh(bool ReportOnError = true)
547 {
548 RefreshValue(false, 0_s, ReportOnError); // Don't block and error if signal is older than a default timeout
549 return *this;
550 }
551 /**
552 * \brief Waits up to timeoutSec to get the up-to-date status signal value.
553 *
554 * \details This performs a blocking refresh operation. If
555 * you want to non-blocking refresh the signal, call
556 * \c Refresh() instead.
557 *
558 * \param timeoutSec Maximum time to wait for the signal to update
559 * \param ReportOnError Whether to report any errors to the Driver Station/stderr.
560 *
561 * \returns Reference to itself
562 */
563 StatusSignal<T> &WaitForUpdate(units::time::second_t timeoutSec, bool ReportOnError = true)
564 {
565 RefreshValue(true, timeoutSec, ReportOnError);
566 return *this;
567 }
568
569 /**
570 * \brief Checks whether the signal is near a target value within the
571 * given tolerance.
572 *
573 * \param target The target value of the signal
574 * \param tolerance The error tolerance between the target and measured values
575 * \returns Whether the signal is near the target value
576 */
577 bool IsNear(T target, T tolerance) const
578 requires (std::same_as<T, double>)
579 {
580 return fabs(GetValue() - target) <= tolerance;
581 }
582
583 /**
584 * \brief Checks whether the signal is near a target value within the
585 * given tolerance.
586 *
587 * \param target The target value of the signal
588 * \param tolerance The error tolerance between the target and measured values
589 * \returns Whether the signal is near the target value
590 */
591 bool IsNear(T target, T tolerance) const
592 requires (units::traits::is_unit_t_v<T>)
593 {
594 return units::math::abs(GetValue() - target) <= tolerance;
595 }
596
597 /**
598 * \brief Get a basic data-only container with a copy of the current signal data.
599 *
600 * If looking for Phoenix 6 logging features, see the SignalLogger class instead.
601 *
602 * \returns Basic structure with all relevant information
603 */
605 {
607 toRet.name = GetName();
608 toRet.value = GetValue();
609 toRet.timestamp = GetTimestamp().GetTime();
610 toRet.units = GetUnits();
611 toRet.status = GetStatus();
612 return toRet;
613 }
614
615 /**
616 * \brief Returns a lambda that calls #Refresh and #GetValue on this object. This is useful for command-based programming.
617 *
618 * \returns std::function<T()> that calls #Refresh and returns this signal's value.
619 */
620 std::function<T()> AsSupplier()
621 {
622 return [this]() { return Refresh().GetValue(); };
623 }
624
625 friend std::ostream &operator<<(std::ostream &os, StatusSignal<T> const &data)
626 {
627 /* Units may contain UTF-8 characters */
629
630 if constexpr(units::traits::is_unit_t_v<T>) {
631 os << data.GetValue().value() << " " << data.GetUnits();
632 } else {
633 os << data.GetValue() << " " << data.GetUnits();
634 }
635 return os;
636 }
637 std::string ToString() const
638 {
639 std::stringstream ss;
640 ss << *this;
641 return ss.str();
642 }
643 };
644
645}
646}
A collection of timestamps for a received signal.
Definition Timestamp.hpp:125
Class that provides operations to retrieve information about a status signal.
Definition StatusSignal.hpp:39
AllTimestamps timestamps
Definition StatusSignal.hpp:54
AllTimestamps const & GetAllTimestamps() const
Gets the timestamps of this signals.
Definition StatusSignal.hpp:161
ctre::phoenix::StatusCode error
Definition StatusSignal.hpp:55
static std::string Status_GetUnits(uint32_t signal)
static double Status_GetAppliedUpdateFrequency(char const *canbus, uint32_t deviceHash, uint16_t spn)
static ctre::phoenix::StatusCode RefreshAll(std::span< BaseStatusSignal *const > signals)
Performs a non-blocking refresh on all provided signals.
Definition StatusSignal.hpp:391
static ctre::phoenix::StatusCode Status_SetUpdateFrequency(char const *canbus, uint32_t deviceHash, uint16_t spn, double frequencyHz, double timeoutSeconds)
std::string units
Definition StatusSignal.hpp:52
static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, std::span< BaseStatusSignal *const > signals)
Sets the update frequency of all specified status signals to the provided common frequency.
Definition StatusSignal.hpp:462
std::string const & GetName() const
Gets the name of this signal.
Definition StatusSignal.hpp:143
BaseStatusSignal(hardware::DeviceIdentifier deviceIdentifier, uint16_t spn, std::string signalName, std::function< void()> checkFirmVersFunction, std::function< std::map< uint16_t, std::string >()> const &unitsGenerator)
Definition StatusSignal.hpp:72
ctre::phoenix::StatusCode SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds=100_ms)
Sets the rate at which the device will publish this signal.
Definition StatusSignal.hpp:219
ctre::phoenix::StatusCode GetStatus() const
Gets the error code from when we last received this signal.
Definition StatusSignal.hpp:181
void RefreshValue(bool waitForUpdate, units::time::second_t timeout, bool ReportOnError)
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, std::span< BaseStatusSignal *const > signals)
Waits for new data on all provided signals up to timeout.
Definition StatusSignal.hpp:353
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, Signals &... signals)
Waits for new data on all provided signals up to timeout.
Definition StatusSignal.hpp:318
static ctre::phoenix::StatusCode Status_Get(BaseStatusSignal &signal, char const *network, bool bWaitForUpdate, double timeoutSeconds)
static bool IsAllGood(Signals const &... signals)
Checks if all signals have an OK error code.
Definition StatusSignal.hpp:405
bool HasUpdated()
Checks whether the signal has been updated since the last check.
Definition StatusSignal.hpp:190
BaseStatusSignal(ctre::phoenix::StatusCode error)
Definition StatusSignal.hpp:93
units::frequency::hertz_t GetAppliedUpdateFrequency() const
Gets the rate at which the device will publish this signal.
Definition StatusSignal.hpp:239
double baseValue
Definition StatusSignal.hpp:53
std::string const & GetUnits() const
Gets the units for this signal.
Definition StatusSignal.hpp:149
static U GetLatencyCompensatedValue(StatusSignal< U > const &signal, StatusSignal< U_PER_SEC > const &signalSlope, units::time::second_t maxLatencySeconds=0.300_s)
Performs latency compensation on signal using the signalSlope and signal's latency to determine the m...
Definition StatusSignal.hpp:278
static ctre::phoenix::StatusCode Status_WaitForAll(std::span< BaseStatusSignal *const > signals, char const *network, double timeoutSeconds)
static ctre::phoenix::StatusCode RefreshAll(Signals &... signals)
Performs a non-blocking refresh on all provided signals.
Definition StatusSignal.hpp:374
static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, Signals &... signals)
Sets the update frequency of all specified status signals to the provided common frequency.
Definition StatusSignal.hpp:442
double GetValueAsDouble() const
Gets the value of this signal as a double.
Definition StatusSignal.hpp:155
static bool IsAllGood(std::span< BaseStatusSignal const *const > signals)
Checks if all signals have an OK error code.
Definition StatusSignal.hpp:415
Timestamp const & GetTimestamp() const
Gets the most accurate timestamp available for this signal.
Definition StatusSignal.hpp:175
BaseStatusSignal(hardware::DeviceIdentifier deviceIdentifier, uint16_t spn, std::string signalName, std::function< void()> checkFirmVersFunction)
Definition StatusSignal.hpp:57
void UpdateUnits(uint16_t unitsKey)
static ctre::phoenix::StatusCode Status_SetUpdateFrequencyForAll(std::span< BaseStatusSignal *const > signals, double frequencyHz, double timeoutSeconds)
static ctre::phoenix::StatusCode WaitForAllImpl(char const *location, units::time::second_t timeoutSeconds, std::span< BaseStatusSignal *const > signals)
Represents a status signal with data of type T, and operations available to retrieve information abou...
Definition StatusSignal.hpp:474
std::string ToString() const
Definition StatusSignal.hpp:637
T GetValue() const
Gets the cached value from this status signal.
Definition StatusSignal.hpp:522
friend std::ostream & operator<<(std::ostream &os, StatusSignal< T > const &data)
Definition StatusSignal.hpp:625
StatusSignal< T > & Refresh(bool ReportOnError=true)
Refreshes the value of this status signal.
Definition StatusSignal.hpp:546
SignalMeasurement< T > GetDataCopy() const
Get a basic data-only container with a copy of the current signal data.
Definition StatusSignal.hpp:604
bool IsNear(T target, T tolerance) const
Checks whether the signal is near a target value within the given tolerance.
Definition StatusSignal.hpp:591
std::function< T()> AsSupplier()
Returns a lambda that calls Refresh and GetValue on this object.
Definition StatusSignal.hpp:620
StatusSignal< T > & WaitForUpdate(units::time::second_t timeoutSec, bool ReportOnError=true)
Waits up to timeoutSec to get the up-to-date status signal value.
Definition StatusSignal.hpp:563
bool IsNear(T target, T tolerance) const
Checks whether the signal is near a target value within the given tolerance.
Definition StatusSignal.hpp:577
Information about the timestamp of a signal.
Definition Timestamp.hpp:17
units::time::second_t GetLatency() const
Get the latency of this timestamp compared to now.
Definition Timestamp.hpp:107
Definition DeviceIdentifier.hpp:16
std::string network
Definition DeviceIdentifier.hpp:18
Parent class for all devices.
Definition ParentDevice.hpp:23
Status codes reported by APIs, including OK, warnings, and errors.
Definition StatusCodes.h:28
static constexpr int SigNotUpdated
No new response to update signal.
Definition StatusCodes.h:419
CTREXPORT void EnableConsoleUTF8Output()
Enables UTF-8 console output.
Definition motor_constants.h:14
Information from a single measurement of a status signal.
Definition SignalMeasurement.hpp:20
T value
The value of the signal.
Definition SignalMeasurement.hpp:28
std::string units
The units of the signal measurement.
Definition SignalMeasurement.hpp:36
ctre::phoenix::StatusCode status
Status code response of getting the data.
Definition SignalMeasurement.hpp:40
units::time::second_t timestamp
Timestamp of when the data point was taken.
Definition SignalMeasurement.hpp:32
std::string_view name
The name of the signal.
Definition SignalMeasurement.hpp:24