17#include <initializer_list>
22#include <units/base.h>
23#include <units/frequency.h>
24#include <units/time.h>
26#if defined(_WIN32) || defined(_WIN64)
65 this->units = other.
units;
69 this->error = other.
error;
103 double timeoutSeconds);
105 static ctre::phoenix::StatusCode
Status_SetUpdateFrequency(
const char *canbus, uint32_t deviceHash, uint16_t
spn,
double frequencyHz,
double timeoutSeconds);
136 bool bWaitForUpdate,
double timeoutSeconds,
138 double *hwtimestamp,
double *swtimestamp,
double *ecutimestamp, int32_t *
timestampType);
149 template <
typename Arr>
150 static ctre::phoenix::StatusCode
WaitForAllImpl(
const char *location, units::time::second_t timeoutSeconds,
const Arr &signals)
152 if (signals.size() < 1)
157 retval.GetDescription(),
162 const std::string &network = signals[0]->deviceIdentifier.network;
164 for (
auto signal : signals)
167 if (network != signal->deviceIdentifier.network)
172 retval.GetDescription(),
179 ctre::phoenix::StatusCode retval =
Status_WaitForAll(signals.data(), signals.size(), network.c_str(), timeoutSeconds.to<
double>());
182 if (
false == retval.IsOK())
185 retval.GetDescription(),
195 template <
typename... Signals>
197 std::conjunction<std::is_convertible<Signals &, BaseStatusSignal &>...>
203 template <
typename... Signals>
233 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds, Signals &... signals)
261 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds,
const std::vector<BaseStatusSignal *> &signals)
264 constexpr char kLocation[] =
"ctre::phoenix6::BaseStatusSignal::WaitForAll";
291 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds,
const std::array<BaseStatusSignal *, N> &signals)
294 constexpr char kLocation[] =
"ctre::phoenix6::BaseStatusSignal::WaitForAll";
312 static ctre::phoenix::StatusCode
RefreshAll(Signals &... signals)
329 static ctre::phoenix::StatusCode
RefreshAll(
const std::vector<BaseStatusSignal *> &signals)
332 constexpr char kLocation[] =
"ctre::phoenix6::BaseStatusSignal::RefreshAll";
349 static ctre::phoenix::StatusCode
RefreshAll(
const std::array<BaseStatusSignal *, N> &signals)
352 constexpr char kLocation[] =
"ctre::phoenix6::BaseStatusSignal::RefreshAll";
374 template <
typename U,
typename U_PER_SEC>
377 static_assert(units::traits::is_unit_t_v<U>,
"signal must be a unit signal");
378 static_assert(units::traits::is_unit_t_v<U_PER_SEC>,
"signalSlope must be a unit signal");
379 using lhs =
typename units::traits::unit_t_traits<U>::unit_type;
380 using rhs =
typename units::traits::unit_t_traits<U_PER_SEC>::unit_type;
381 static_assert(units::traits::is_convertible_unit_v<lhs, units::compound_unit<rhs, units::seconds>>,
382 "Compensation can only be performed on a signal with its derivative");
383 U nonCompensatedSignal = signal.
GetValue();
384 U_PER_SEC changeInSignal = signalSlope.
GetValue();
386 return nonCompensatedSignal + (changeInSignal * latency);
406 static bool IsAllGood(
const std::vector<BaseStatusSignal *> &signals)
408 for (
auto signal : signals)
410 if (!signal->GetStatus().IsOK()) {
423 static bool IsAllGood(
const std::array<BaseStatusSignal *, N> &signals)
425 for (
auto signal : signals)
427 if (!signal->GetStatus().IsOK()) {
469 static ctre::phoenix::StatusCode
SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz,
const std::vector<BaseStatusSignal *> &signals)
489 static ctre::phoenix::StatusCode
SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz,
const std::array<BaseStatusSignal *, N> &signals)
507 ctre::phoenix::StatusCode
SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds = 50_ms)
510 this->deviceIdentifier.deviceHash,
512 frequencyHz.to<
double>(),
513 timeoutSeconds.to<
double>());
527 return units::frequency::hertz_t{
529 this->deviceIdentifier.deviceHash,
582 if (timestamp.IsValid())
598 template <
typename L>
624 template <
typename T>
627 bool _containsUnderlyingTypes;
628 std::map<int, StatusSignal<T>> _basicTypeMap;
629 std::function<void()> _checkFirmVersFunction;
632 void RefreshSwitch(
bool block, units::time::second_t timeout)
635 if (!_containsUnderlyingTypes)
640 ctre::phoenix::StatusCode outputError = Status_Get(
641 this->deviceIdentifier.network.c_str(),
642 this->deviceIdentifier.deviceHash,
644 block, timeout.to<
double>(),
646 nullptr,
nullptr,
nullptr,
nullptr);
650 this->error = outputError;
654 auto foundValue = _basicTypeMap.find(
static_cast<int>(switchValue));
655 if (foundValue != _basicTypeMap.end())
658 foundValue->second.RefreshValue(block, timeout,
false);
662 std::lock_guard<std::mutex> lock{_copyLck};
663 CopyFrom(foundValue->second);
673 void RefreshNoSwitch(
bool block, units::time::second_t timeout)
676 if (_containsUnderlyingTypes)
680 double outHwTimestamp;
681 double outSwTimestamp;
682 double outEcuTimestamp;
683 int32_t outTimestampType;
685 ctre::phoenix::StatusCode outputError = Status_Get(
686 this->deviceIdentifier.network.c_str(),
687 this->deviceIdentifier.deviceHash,
689 block, timeout.to<
double>(),
691 &outHwTimestamp, &outSwTimestamp, &outEcuTimestamp, &outTimestampType);
694 if (outputError >= 0)
700 this->error = outputError;
703 void RefreshValue(
bool block, units::time::second_t timeout,
bool ReportOnError)
705 _checkFirmVersFunction();
706 if (_containsUnderlyingTypes)
708 RefreshSwitch(block, timeout);
712 RefreshNoSwitch(block, timeout);
715 if (ReportOnError && !(this->error.IsOK()))
717 std::stringstream location;
718 location << this->deviceIdentifier.ToString() <<
" Status Signal " << this->signalName;
726 _containsUnderlyingTypes{false},
728 _checkFirmVersFunction{[] {}}
733 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
735 std::function<
void()> checkFirmVersFunction,
736 std::string signalName) : BaseStatusSignal{std::move(deviceIdentifier), spn, std::move(signalName)},
737 _containsUnderlyingTypes{false},
739 _checkFirmVersFunction{checkFirmVersFunction}
743 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
745 std::function<
void()> checkFirmVersFunction,
746 std::function<std::map<
int, StatusSignal<T>>()> map_filler,
747 std::string signalName) : BaseStatusSignal{std::move(deviceIdentifier), spn, std::move(signalName)},
748 _containsUnderlyingTypes{true},
749 _basicTypeMap{map_filler()},
750 _checkFirmVersFunction{checkFirmVersFunction}
755 StatusSignal(ctre::phoenix::StatusCode error) : BaseStatusSignal{error},
756 _containsUnderlyingTypes{false},
758 _checkFirmVersFunction{[] {}}
765 #if defined(_WIN32) || defined(_WIN64)
767 SetConsoleOutputCP(CP_UTF8);
769 if constexpr(units::traits::is_unit_t_v<T>)
781 std::stringstream ss;
796 if constexpr(units::traits::is_unit_t_v<T>)
798 return units::make_unit<T>(this->baseValue);
802 return static_cast<T
>(this->baseValue);
823 RefreshValue(
false, 0_s, ReportOnError);
840 RefreshValue(
true, timeoutSec, ReportOnError);
853 toRet.
value = GetValue();
854 toRet.
status = GetStatus();
855 toRet.
units = GetUnits();
856 toRet.
timestamp = GetTimestamp().GetTime();
868 {
return this->Refresh().GetValue(); };
CTREXPORT void c_ctre_phoenix_report_error(int isError, int32_t errorCode, int isLVCode, const char *details, const char *location, const char *callStack)
@ OK
No Error.
Definition: StatusCodes.h:1169
@ InvalidModeToGetSignal
The current mode of the device is invalid for getting this signal.
Definition: StatusCodes.h:1815
@ InvalidNetwork
InvalidNetwork.
Definition: StatusCodes.h:1764
@ InvalidParamValue
Incorrect argument passed into function/VI.
Definition: StatusCodes.h:1501
@ SigNotUpdated
No new response to update signal.
Definition: StatusCodes.h:1550
A collection of timestamps for a received signal.
Definition: Timestamp.hpp:131
const Timestamp & GetSystemTimestamp() const
Get the timestamp as reported by the system.
Definition: Timestamp.hpp:158
const Timestamp & GetBestTimestamp() const
Get the best timestamp available.
Definition: Timestamp.hpp:147
Class that provides operations to retrieve information about a status signal.
Definition: StatusSignal.hpp:45
std::string signalName
Definition: StatusSignal.hpp:56
void CopyFrom(const BaseStatusSignal &other)
Definition: StatusSignal.hpp:63
static constexpr bool is_all_status_signal_v
Whether all types passed in are convertible to BaseStatusSignal references.
Definition: StatusSignal.hpp:204
units::time::second_t _lastTimestamp
Definition: StatusSignal.hpp:58
const AllTimestamps & GetAllTimestamps() const
Get the timestamps of this signals.
Definition: StatusSignal.hpp:556
AllTimestamps timestamps
Definition: StatusSignal.hpp:52
ctre::phoenix::StatusCode error
Definition: StatusSignal.hpp:55
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, const std::vector< BaseStatusSignal * > &signals)
Waits for new data on all provided signals up to timeout.
Definition: StatusSignal.hpp:261
static ctre::phoenix::StatusCode Status_WaitForAll(BaseStatusSignal *const *signals, size_t count, const char *network, double timeoutSeconds)
Wait for multiple signals to arrive.
uint16_t spn
Definition: StatusSignal.hpp:50
static ctre::phoenix::StatusCode Status_Get(const char *network, int deviceHash, uint32_t signal, bool bWaitForUpdate, double timeoutSeconds, double *outValue, double *hwtimestamp, double *swtimestamp, double *ecutimestamp, int32_t *timestampType)
Get signal update.
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:450
static std::string Status_GetUnits(uint32_t signal)
Gets signal units.
static bool IsAllGood(Signals &... signals)
Checks if all signals have an OK error code.
Definition: StatusSignal.hpp:396
static ctre::phoenix::StatusCode RefreshAll(const std::array< BaseStatusSignal *, N > &signals)
Performs a non-blocking refresh on all provided signals.
Definition: StatusSignal.hpp:349
static ctre::phoenix::StatusCode RefreshAll(Signals &... signals)
Performs a non-blocking refresh on all provided signals.
Definition: StatusSignal.hpp:312
int timestampType
Definition: StatusSignal.hpp:53
std::string units
Definition: StatusSignal.hpp:51
static bool IsAllGood(const std::vector< BaseStatusSignal * > &signals)
Checks if all signals have an OK error code.
Definition: StatusSignal.hpp:406
static double Status_GetAppliedUpdateFrequency(const char *canbus, uint32_t deviceHash, uint16_t spn)
ctre::phoenix::StatusCode GetStatus() const
Get the error code from when we last received this signal.
Definition: StatusSignal.hpp:568
BaseStatusSignal(hardware::DeviceIdentifier deviceIdentifier, uint16_t spn, std::string signalName)
Definition: StatusSignal.hpp:73
static ctre::phoenix::StatusCode WaitForAllImpl(const char *location, units::time::second_t timeoutSeconds, const Arr &signals)
Implementation of the WaitForAll API.
Definition: StatusSignal.hpp:150
static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, const std::array< BaseStatusSignal *, N > &signals)
Sets the update frequency of all specified status signals to the provided common frequency.
Definition: StatusSignal.hpp:489
ctre::phoenix::StatusCode SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds=50_ms)
Sets the rate at which the device will publish this signal.
Definition: StatusSignal.hpp:507
bool HasUpdated()
Check whether the signal has been updated since the last check.
Definition: StatusSignal.hpp:577
static ctre::phoenix::StatusCode SetUpdateFrequencyForAll(units::frequency::hertz_t frequencyHz, const std::vector< BaseStatusSignal * > &signals)
Sets the update frequency of all specified status signals to the provided common frequency.
Definition: StatusSignal.hpp:469
BaseStatusSignal(ctre::phoenix::StatusCode error)
Definition: StatusSignal.hpp:83
const std::string & GetUnits() const
Gets the units for this signal.
Definition: StatusSignal.hpp:544
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:233
static ctre::phoenix::StatusCode Status_SetUpdateFrequency(const char *canbus, uint32_t deviceHash, uint16_t spn, double frequencyHz, double timeoutSeconds)
units::frequency::hertz_t GetAppliedUpdateFrequency() const
Gets the rate at which the device will publish this signal.
Definition: StatusSignal.hpp:525
static bool IsAllGood(const std::array< BaseStatusSignal *, N > &signals)
Checks if all signals have an OK error code.
Definition: StatusSignal.hpp:423
static U GetLatencyCompensatedValue(StatusSignal< U > &signal, StatusSignal< U_PER_SEC > &signalSlope)
Performs latency compensation on signal using the signalSlope and signal's latency to determine the m...
Definition: StatusSignal.hpp:375
double baseValue
Definition: StatusSignal.hpp:54
const std::string & GetName() const
Gets the name of this signal.
Definition: StatusSignal.hpp:538
virtual ~BaseStatusSignal()=0
double GetValueAsDouble() const
Gets the value of this signal as a double.
Definition: StatusSignal.hpp:550
hardware::DeviceIdentifier deviceIdentifier
Definition: StatusSignal.hpp:49
static ctre::phoenix::StatusCode Status_SetUpdateFrequencyForAll(BaseStatusSignal *const *signals, size_t count, double frequencyHz, double timeoutSeconds)
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, const std::array< BaseStatusSignal *, N > &signals)
Waits for new data on all provided signals up to timeout.
Definition: StatusSignal.hpp:291
const Timestamp & GetTimestamp() const
Get the best timestamp available to this signal.
Definition: StatusSignal.hpp:562
static ctre::phoenix::StatusCode RefreshAll(const std::vector< BaseStatusSignal * > &signals)
Performs a non-blocking refresh on all provided signals.
Definition: StatusSignal.hpp:329
Represents a status signal with data of type T, and operations available to retrieve information abou...
Definition: StatusSignal.hpp:626
friend std::ostream & operator<<(std::ostream &os, const StatusSignal< T > &data)
Definition: StatusSignal.hpp:763
std::string ToString() const
Definition: StatusSignal.hpp:779
T GetValue() const
Gets the cached value from this status signal.
Definition: StatusSignal.hpp:794
StatusSignal< T > & Refresh(bool ReportOnError=true)
Refreshes the value of this status signal.
Definition: StatusSignal.hpp:821
SignalMeasurement< T > GetDataCopy() const
Get a basic data-only container with this information, to be used for things such as data logging.
Definition: StatusSignal.hpp:850
std::function< T()> AsSupplier()
Returns a lambda that calls Refresh and GetValue on this object.
Definition: StatusSignal.hpp:865
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:838
Information about the timestamp of a signal.
Definition: Timestamp.hpp:20
@ CANivore
Timestamp as reported by the CANivore.
@ System
Timestamp as reported by the system.
units::time::second_t GetLatency() const
Get the latency of this timestamp compared to now.
Definition: Timestamp.hpp:113
Definition: DeviceIdentifier.hpp:19
std::string network
Definition: DeviceIdentifier.hpp:21
Parent class for all devices.
Definition: ParentDevice.hpp:30
Definition: ManualEvent.hpp:12
Type trait to verify that all types passed in are convertible to BaseStatusSignal references.
Definition: StatusSignal.hpp:198
Information from a single measurement of a status signal.
Definition: StatusSignal.hpp:600
std::string units
Units that correspond to this point.
Definition: StatusSignal.hpp:616
units::time::second_t timestamp
Timestamp of when the data point was taken.
Definition: StatusSignal.hpp:608
L value
The value of the signal, this may be an enum so it is stored as a string.
Definition: StatusSignal.hpp:604
ctre::phoenix::StatusCode status
Status code response of getting the data.
Definition: StatusSignal.hpp:612