16#include <initializer_list>
21#include <units/base.h>
22#include <units/frequency.h>
23#include <units/time.h>
25#if defined(_WIN32) || defined(_WIN64)
37 class StatusSignalValue;
58 this->units = other.
units;
62 this->error = other.
error;
91 std::initializer_list<BaseStatusSignalValue *> signals,
93 units::time::second_t timeoutSeconds);
104 const std::vector<BaseStatusSignalValue *> &signals,
106 units::time::second_t timeoutSeconds);
108 ctre::phoenix::StatusCode
SetUpdateFrequency(
const char *canbus, uint32_t deviceHash, uint16_t
spn, units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds);
130 bool bWaitForUpdate, units::time::second_t timeoutSeconds,
131 double *outValue, std::string *
units,
132 double *hwtimestamp,
double *swtimestamp,
double *ecutimestamp, int32_t *
timestampType);
157 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds, std::initializer_list<BaseStatusSignalValue *> signals)
160 std::vector<BaseStatusSignalValue*>(signals.begin(), signals.end()));
182 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds,
const std::vector<BaseStatusSignalValue *> &signals)
185 const char kLocation[] =
"ctre::phoenixpro::BaseStatusSignalValue::WaitForAll";
187 if (signals.size() < 1)
192 retval.GetDescription(),
199 for (
auto signal : signals)
202 if (network != signal->deviceIdentifier.network)
207 retval.GetDescription(),
214 ctre::phoenix::StatusCode retval =
Status_WaitForAll(signals, network.c_str(), timeoutSeconds);
217 if (
false == retval.IsOK())
220 retval.GetDescription(),
241 template <
typename U,
typename U_PER_SEC>
244 static_assert(units::traits::is_unit_t_v<U>,
"signal must be a unit signal");
245 static_assert(units::traits::is_unit_t_v<U_PER_SEC>,
"signalSlope must be a unit signal");
246 using lhs =
typename units::traits::unit_t_traits<U>::unit_type;
247 using rhs =
typename units::traits::unit_t_traits<U_PER_SEC>::unit_type;
248 static_assert(units::traits::is_convertible_unit_v<lhs, units::compound_unit<rhs, units::seconds>>,
249 "Compensation can only be performed on a signal with its derivative");
250 U nonCompensatedSignal = signal.
GetValue();
251 U_PER_SEC changeInSignal = signalSlope.
GetValue();
253 return nonCompensatedSignal + (changeInSignal * latency);
261 static ctre::phoenix::StatusCode
IsAllGood(std::initializer_list<BaseStatusSignalValue *> signals)
263 for (
auto signal : signals)
297 template <
typename L>
318 template <
typename T>
321 bool _containsUnderlyingTypes;
322 std::map<int, StatusSignalValue<T>> _basicTypeMap;
323 std::function<void()> _checkFirmVersFunction;
326 void RefreshSwitch(
bool block, units::time::second_t timeout)
329 if (!_containsUnderlyingTypes)
334 ctre::phoenix::StatusCode outputError =
Status_Get(
336 this->deviceIdentifier.deviceHash,
339 &switchValue,
nullptr,
340 nullptr,
nullptr,
nullptr,
nullptr);
344 this->
error = outputError;
348 auto foundValue = _basicTypeMap.find(
static_cast<int>(switchValue));
349 if (foundValue != _basicTypeMap.end())
352 foundValue->second.RefreshValue(block, timeout,
false);
356 std::lock_guard<std::mutex> lock{_copyLck};
367 void RefreshNoSwitch(
bool block, units::time::second_t timeout)
370 if (_containsUnderlyingTypes)
374 std::string outUnits;
375 double outHwTimestamp;
376 double outSwTimestamp;
377 double outEcuTimestamp;
378 int32_t outTimestampType;
380 ctre::phoenix::StatusCode outputError =
Status_Get(
382 this->deviceIdentifier.deviceHash,
385 &this->baseValue, &outUnits,
386 &outHwTimestamp, &outSwTimestamp, &outEcuTimestamp, &outTimestampType);
389 if (outputError >= 0)
395 this->
units = outUnits;
396 this->
error = outputError;
399 void RefreshValue(
bool block, units::time::second_t timeout,
bool ReportOnError)
401 _checkFirmVersFunction();
402 if (_containsUnderlyingTypes)
404 RefreshSwitch(block, timeout);
408 RefreshNoSwitch(block, timeout);
411 if (ReportOnError && !(this->
error.IsOK()))
413 std::stringstream location;
422 _containsUnderlyingTypes{false},
424 _checkFirmVersFunction{[] {}}
429 StatusSignalValue(hardware::DeviceIdentifier deviceIdentifier,
431 std::function<
void()> checkFirmVersFunction,
432 std::string signalName) : BaseStatusSignalValue{std::move(deviceIdentifier), spn, std::move(signalName)},
433 _containsUnderlyingTypes{false},
435 _checkFirmVersFunction{checkFirmVersFunction}
439 StatusSignalValue(hardware::DeviceIdentifier deviceIdentifier,
441 std::function<
void()> checkFirmVersFunction,
442 std::function<std::map<
int, StatusSignalValue<T>>()> map_filler,
443 std::string signalName) : BaseStatusSignalValue{std::move(deviceIdentifier), spn, std::move(signalName)},
444 _containsUnderlyingTypes{true},
445 _basicTypeMap{map_filler()},
446 _checkFirmVersFunction{checkFirmVersFunction}
451 StatusSignalValue(ctre::phoenix::StatusCode error) : BaseStatusSignalValue{error},
452 _containsUnderlyingTypes{false},
454 _checkFirmVersFunction{[] {}}
461 #if defined(_WIN32) || defined(_WIN64)
463 SetConsoleOutputCP(CP_UTF8);
465 if constexpr(units::traits::is_unit_t_v<T>)
477 std::stringstream ss;
492 if constexpr(units::traits::is_unit_t_v<T>)
494 return units::make_unit<T>(this->baseValue);
498 return static_cast<T
>(this->baseValue);
519 RefreshValue(
false, 0.300_s, ReportOnError);
536 RefreshValue(
true, timeoutSec, ReportOnError);
548 toRet.
value = GetValue();
549 toRet.
error = GetError();
550 toRet.
units = GetUnits();
551 toRet.
timestamp = GetTimestamp().GetTime();
564 ctre::phoenix::StatusCode
SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds = 50_ms)
567 return BaseStatusSignalValue::SetUpdateFrequency(this->deviceIdentifier.network.c_str(),
568 this->deviceIdentifier.deviceHash,
582 {
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:1101
@ InvalidModeToGetSignal
The current mode of the device is invalid for getting this signal.
Definition: StatusCodes.h:1740
@ InvalidNetwork
InvalidNetwork.
Definition: StatusCodes.h:1688
@ InvalidParamValue
Incorrect argument passed into function/VI.
Definition: StatusCodes.h:1425
@ SigNotUpdated
No new response to update signal.
Definition: StatusCodes.h:1474
A collection of timestamps for a received signal.
Definition: Timestamp.hpp:131
void Update(const Timestamp &newSystemTimestamp, const Timestamp &newCanivoreTimestamp, const Timestamp &newDeviceTimestamp)
Definition: Timestamp.hpp:137
const Timestamp & GetBestTimestamp() const
Get the best timestamp available.
Definition: Timestamp.hpp:147
Definition: StatusSignalValue.hpp:40
static ctre::phoenix::StatusCode Status_WaitForAll(std::initializer_list< BaseStatusSignalValue * > signals, const char *network, units::time::second_t timeoutSeconds)
Wait for multiple signals to arrive.
void CopyFrom(const BaseStatusSignalValue &other)
Definition: StatusSignalValue.hpp:56
static U GetLatencyCompensatedValue(StatusSignalValue< U > &signal, StatusSignalValue< U_PER_SEC > &signalSlope)
Definition: StatusSignalValue.hpp:242
int timestampType
Definition: StatusSignalValue.hpp:48
static ctre::phoenix::StatusCode IsAllGood(std::initializer_list< BaseStatusSignalValue * > signals)
Check if all signals have an OK error code.
Definition: StatusSignalValue.hpp:261
ctre::phoenix::StatusCode SetUpdateFrequency(const char *canbus, uint32_t deviceHash, uint16_t spn, units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds)
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, std::initializer_list< BaseStatusSignalValue * > signals)
Wait for all provided signals up to timeout.
Definition: StatusSignalValue.hpp:157
AllTimestamps timestamps
Definition: StatusSignalValue.hpp:47
const std::string & GetUnits() const
Gets the units for this signal.
Definition: StatusSignalValue.hpp:276
uint16_t spn
Definition: StatusSignalValue.hpp:45
virtual ~BaseStatusSignalValue()=0
BaseStatusSignalValue(ctre::phoenix::StatusCode error)
Definition: StatusSignalValue.hpp:75
static ctre::phoenix::StatusCode Status_WaitForAll(const std::vector< BaseStatusSignalValue * > &signals, const char *network, units::time::second_t timeoutSeconds)
Wait for multiple signals to arrive.
hardware::DeviceIdentifier deviceIdentifier
Definition: StatusSignalValue.hpp:44
const AllTimestamps & GetAllTimestamps() const
Get the timestamps of this signals.
Definition: StatusSignalValue.hpp:282
static ctre::phoenix::StatusCode Status_Get(const char *network, int deviceHash, uint32_t signal, bool bWaitForUpdate, units::time::second_t timeoutSeconds, double *outValue, std::string *units, double *hwtimestamp, double *swtimestamp, double *ecutimestamp, int32_t *timestampType)
Get signal update.
std::string units
Definition: StatusSignalValue.hpp:46
std::string signalName
Definition: StatusSignalValue.hpp:51
BaseStatusSignalValue(hardware::DeviceIdentifier deviceIdentifier, uint16_t spn, std::string signalName)
Definition: StatusSignalValue.hpp:66
const Timestamp & GetTimestamp() const
Get the best timestamp available to this signal.
Definition: StatusSignalValue.hpp:288
ctre::phoenix::StatusCode error
Definition: StatusSignalValue.hpp:50
static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, const std::vector< BaseStatusSignalValue * > &signals)
Wait for all provided signals up to timeout.
Definition: StatusSignalValue.hpp:182
double baseValue
Definition: StatusSignalValue.hpp:49
ctre::phoenix::StatusCode GetError() const
Get the error code from when we last received this signal.
Definition: StatusSignalValue.hpp:294
friend class StatusSignalValue
Definition: StatusSignalValue.hpp:54
Definition: StatusSignalValue.hpp:320
StatusSignalValue< T > & Refresh(bool ReportOnError=true)
Refreshes this status signal value.
Definition: StatusSignalValue.hpp:517
StatusSignalValue< T > & WaitForUpdate(units::time::second_t timeoutSec, bool ReportOnError=true)
Waits up to timeoutSec to get the up-to-date status signal value.
Definition: StatusSignalValue.hpp:534
std::function< T()> AsSupplier()
Returns a lambda that calls Refresh and GetValue on this object.
Definition: StatusSignalValue.hpp:579
T GetValue() const
Gets the cached value from this status signal value.
Definition: StatusSignalValue.hpp:490
friend std::ostream & operator<<(std::ostream &os, const StatusSignalValue< T > &data)
Definition: StatusSignalValue.hpp:459
std::string ToString() const
Definition: StatusSignalValue.hpp:475
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: StatusSignalValue.hpp:564
SignalMeasurement< T > GetDataCopy() const
Get a basic data-only container with this information, to be used for things such as data logging.
Definition: StatusSignalValue.hpp:545
Information about the timestamp of a signal.
Definition: Timestamp.hpp:20
units::time::second_t GetLatency() const
Get the latency of this timestamp compared to now.
Definition: Timestamp.hpp:113
@ CANivore
Timestamp as reported by the CANivore.
@ System
Timestamp as reported by the system.
Definition: DeviceIdentifier.hpp:19
std::string network
Definition: DeviceIdentifier.hpp:21
std::string ToString() const
Definition: DeviceIdentifier.hpp:34
Parent class for all devices.
Definition: ParentDevice.hpp:30
Definition: string_util.hpp:14
Definition: StatusSignalValue.hpp:299
ctre::phoenix::StatusCode error
Code response of getting the data.
Definition: StatusSignalValue.hpp:311
units::time::second_t timestamp
Timestamp of when the data point was taken.
Definition: StatusSignalValue.hpp:307
std::string units
Units that correspond to this point.
Definition: StatusSignalValue.hpp:315
L value
The value of the signal, this may be an enum so it is stored as a string.
Definition: StatusSignalValue.hpp:303