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)
62 this->units = other.
units;
66 this->error = other.
error;
96 std::initializer_list<BaseStatusSignal *> signals,
98 units::time::second_t timeoutSeconds);
109 const std::vector<BaseStatusSignal *> &signals,
111 units::time::second_t timeoutSeconds);
113 ctre::phoenix::StatusCode
SetUpdateFrequency(
const char *canbus, uint32_t deviceHash, uint16_t
spn, units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds);
142 bool bWaitForUpdate, units::time::second_t timeoutSeconds,
144 double *hwtimestamp,
double *swtimestamp,
double *ecutimestamp, int32_t *
timestampType);
172 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds, std::initializer_list<BaseStatusSignal *> signals)
175 std::vector<BaseStatusSignal*>(signals.begin(), signals.end()));
200 static ctre::phoenix::StatusCode
WaitForAll(units::time::second_t timeoutSeconds,
const std::vector<BaseStatusSignal *> &signals)
203 const char kLocation[] =
"ctre::phoenix6::BaseStatusSignal::WaitForAll";
205 if (signals.size() < 1)
210 retval.GetDescription(),
217 for (
auto signal : signals)
220 if (network != signal->deviceIdentifier.network)
225 retval.GetDescription(),
232 ctre::phoenix::StatusCode retval =
Status_WaitForAll(signals, network.c_str(), timeoutSeconds);
235 if (
false == retval.IsOK())
238 retval.GetDescription(),
259 template <
typename U,
typename U_PER_SEC>
262 static_assert(units::traits::is_unit_t_v<U>,
"signal must be a unit signal");
263 static_assert(units::traits::is_unit_t_v<U_PER_SEC>,
"signalSlope must be a unit signal");
264 using lhs =
typename units::traits::unit_t_traits<U>::unit_type;
265 using rhs =
typename units::traits::unit_t_traits<U_PER_SEC>::unit_type;
266 static_assert(units::traits::is_convertible_unit_v<lhs, units::compound_unit<rhs, units::seconds>>,
267 "Compensation can only be performed on a signal with its derivative");
268 U nonCompensatedSignal = signal.
GetValue();
269 U_PER_SEC changeInSignal = signalSlope.
GetValue();
271 return nonCompensatedSignal + (changeInSignal * latency);
279 static ctre::phoenix::StatusCode
IsAllGood(std::initializer_list<BaseStatusSignal *> signals)
281 for (
auto signal : signals)
298 ctre::phoenix::StatusCode
SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds = 50_ms)
302 this->deviceIdentifier.deviceHash,
337 template <
typename L>
363 template <
typename T>
366 bool _containsUnderlyingTypes;
367 std::map<int, StatusSignal<T>> _basicTypeMap;
368 std::function<void()> _checkFirmVersFunction;
371 void RefreshSwitch(
bool block, units::time::second_t timeout)
374 if (!_containsUnderlyingTypes)
379 ctre::phoenix::StatusCode outputError =
Status_Get(
381 this->deviceIdentifier.deviceHash,
385 nullptr,
nullptr,
nullptr,
nullptr);
389 this->
error = outputError;
393 auto foundValue = _basicTypeMap.find(
static_cast<int>(switchValue));
394 if (foundValue != _basicTypeMap.end())
397 foundValue->second.RefreshValue(block, timeout,
false);
401 std::lock_guard<std::mutex> lock{_copyLck};
412 void RefreshNoSwitch(
bool block, units::time::second_t timeout)
415 if (_containsUnderlyingTypes)
419 double outHwTimestamp;
420 double outSwTimestamp;
421 double outEcuTimestamp;
422 int32_t outTimestampType;
424 ctre::phoenix::StatusCode outputError =
Status_Get(
426 this->deviceIdentifier.deviceHash,
430 &outHwTimestamp, &outSwTimestamp, &outEcuTimestamp, &outTimestampType);
433 if (outputError >= 0)
439 this->
error = outputError;
442 void RefreshValue(
bool block, units::time::second_t timeout,
bool ReportOnError)
444 _checkFirmVersFunction();
445 if (_containsUnderlyingTypes)
447 RefreshSwitch(block, timeout);
451 RefreshNoSwitch(block, timeout);
454 if (ReportOnError && !(this->
error.IsOK()))
456 std::stringstream location;
465 _containsUnderlyingTypes{false},
467 _checkFirmVersFunction{[] {}}
472 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
474 std::function<
void()> checkFirmVersFunction,
475 std::string signalName) : BaseStatusSignal{std::move(deviceIdentifier), spn, std::move(signalName)},
476 _containsUnderlyingTypes{false},
478 _checkFirmVersFunction{checkFirmVersFunction}
482 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
484 std::function<
void()> checkFirmVersFunction,
485 std::function<std::map<
int, StatusSignal<T>>()> map_filler,
486 std::string signalName) : BaseStatusSignal{std::move(deviceIdentifier), spn, std::move(signalName)},
487 _containsUnderlyingTypes{true},
488 _basicTypeMap{map_filler()},
489 _checkFirmVersFunction{checkFirmVersFunction}
494 StatusSignal(ctre::phoenix::StatusCode error) : BaseStatusSignal{error},
495 _containsUnderlyingTypes{false},
497 _checkFirmVersFunction{[] {}}
504 #if defined(_WIN32) || defined(_WIN64)
506 SetConsoleOutputCP(CP_UTF8);
508 if constexpr(units::traits::is_unit_t_v<T>)
520 std::stringstream ss;
535 if constexpr(units::traits::is_unit_t_v<T>)
537 return units::make_unit<T>(this->baseValue);
541 return static_cast<T
>(this->baseValue);
562 RefreshValue(
false, 0.300_s, ReportOnError);
579 RefreshValue(
true, timeoutSec, ReportOnError);
591 toRet.
value = GetValue();
592 toRet.
error = GetError();
593 toRet.
units = GetUnits();
594 toRet.
timestamp = GetTimestamp().GetTime();
606 {
return this->Refresh().GetValue(); };
617 template <
typename T>
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:1116
@ InvalidModeToGetSignal
The current mode of the device is invalid for getting this signal.
Definition: StatusCodes.h:1755
@ InvalidNetwork
InvalidNetwork.
Definition: StatusCodes.h:1703
@ InvalidParamValue
Incorrect argument passed into function/VI.
Definition: StatusCodes.h:1440
@ SigNotUpdated
No new response to update signal.
Definition: StatusCodes.h:1489
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
Class that provides operations to retrieve information about a status signal.
Definition: StatusSignal.hpp:44
std::string signalName
Definition: StatusSignal.hpp:55
void CopyFrom(const BaseStatusSignal &other)
Definition: StatusSignal.hpp:60
const AllTimestamps & GetAllTimestamps() const
Get the timestamps of this signals.
Definition: StatusSignal.hpp:319
AllTimestamps timestamps
Definition: StatusSignal.hpp:51
ctre::phoenix::StatusCode error
Definition: StatusSignal.hpp:54
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:200
uint16_t spn
Definition: StatusSignal.hpp:49
friend class StatusSignal
Definition: StatusSignal.hpp:58
static std::string Status_GetUnits(uint32_t signal)
Gets signal units.
static ctre::phoenix::StatusCode Status_Get(const char *network, int deviceHash, uint32_t signal, bool bWaitForUpdate, units::time::second_t timeoutSeconds, double *outValue, double *hwtimestamp, double *swtimestamp, double *ecutimestamp, int32_t *timestampType)
Get signal update.
int timestampType
Definition: StatusSignal.hpp:52
std::string units
Definition: StatusSignal.hpp:50
BaseStatusSignal(hardware::DeviceIdentifier deviceIdentifier, uint16_t spn, std::string signalName)
Definition: StatusSignal.hpp:70
static ctre::phoenix::StatusCode IsAllGood(std::initializer_list< BaseStatusSignal * > signals)
Checks if all signals have an OK error code.
Definition: StatusSignal.hpp:279
static ctre::phoenix::StatusCode Status_WaitForAll(std::initializer_list< BaseStatusSignal * > signals, const char *network, units::time::second_t timeoutSeconds)
Wait for multiple signals to arrive.
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:298
BaseStatusSignal(ctre::phoenix::StatusCode error)
Definition: StatusSignal.hpp:80
const std::string & GetUnits() const
Gets the units for this signal.
Definition: StatusSignal.hpp:313
static U GetLatencyCompensatedValue(StatusSignal< U > &signal, StatusSignal< U_PER_SEC > &signalSlope)
Definition: StatusSignal.hpp:260
double baseValue
Definition: StatusSignal.hpp:53
virtual ~BaseStatusSignal()=0
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< BaseStatusSignal * > signals)
Waits for new data on all provided signals up to timeout.
Definition: StatusSignal.hpp:172
hardware::DeviceIdentifier deviceIdentifier
Definition: StatusSignal.hpp:48
const Timestamp & GetTimestamp() const
Get the best timestamp available to this signal.
Definition: StatusSignal.hpp:325
static ctre::phoenix::StatusCode Status_WaitForAll(const std::vector< BaseStatusSignal * > &signals, const char *network, units::time::second_t timeoutSeconds)
Wait for multiple signals to arrive.
ctre::phoenix::StatusCode GetError() const
Get the error code from when we last received this signal.
Definition: StatusSignal.hpp:331
Represents a status signal with data of type T, and operations available to retrieve information abou...
Definition: StatusSignal.hpp:365
friend std::ostream & operator<<(std::ostream &os, const StatusSignal< T > &data)
Definition: StatusSignal.hpp:502
std::string ToString() const
Definition: StatusSignal.hpp:518
T GetValue() const
Gets the cached value from this status signal.
Definition: StatusSignal.hpp:533
StatusSignal< T > & Refresh(bool ReportOnError=true)
Refreshes the value of this status signal.
Definition: StatusSignal.hpp:560
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:588
std::function< T()> AsSupplier()
Returns a lambda that calls Refresh and GetValue on this object.
Definition: StatusSignal.hpp:603
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:577
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 ToString() const
Definition: DeviceIdentifier.hpp:34
std::string network
Definition: DeviceIdentifier.hpp:21
Parent class for all devices.
Definition: ParentDevice.hpp:30
Definition: string_util.hpp:14
Information from a single measurement of a status signal.
Definition: StatusSignal.hpp:339
std::string units
Units that correspond to this point.
Definition: StatusSignal.hpp:355
units::time::second_t timestamp
Timestamp of when the data point was taken.
Definition: StatusSignal.hpp:347
L value
The value of the signal, this may be an enum so it is stored as a string.
Definition: StatusSignal.hpp:343
ctre::phoenix::StatusCode error
Code response of getting the data.
Definition: StatusSignal.hpp:351