Loading [MathJax]/extensions/tex2jax.js
CTRE Phoenix 6 C++ 23.2.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
15#include <functional>
16#include <initializer_list>
17#include <map>
18#include <ostream>
19#include <sstream>
20#include <string>
21#include <units/base.h>
22#include <units/frequency.h>
23#include <units/time.h>
24
25#if defined(_WIN32) || defined(_WIN64)
26#include <Windows.h> // For UTF-8 support
27#endif
28
29namespace ctre {
30namespace phoenix6 {
31
32 namespace hardware {
33 class ParentDevice;
34 }
35
36 template <typename T>
37 class StatusSignal;
38
39 /**
40 * \brief Class that provides operations to
41 * retrieve information about a status signal.
42 */
44 {
45 friend hardware::ParentDevice; // Allow ParentDevice to set error
46
47 protected:
49 uint16_t spn;
50 std::string units;
53 double baseValue = 0;
55 std::string signalName;
56
57 template <typename T>
58 friend class StatusSignal;
59
60 void CopyFrom(const BaseStatusSignal &other)
61 {
62 this->units = other.units;
63 this->timestamps = other.timestamps;
64 this->timestampType = other.timestampType;
65 this->baseValue = other.baseValue;
66 this->error = other.error;
67 // We don't care about copying the signal name, because the user will expect the original name
68 }
69
71 uint16_t spn,
72 std::string signalName) : deviceIdentifier{std::move(deviceIdentifier)},
73 spn{spn},
75 signalName{std::move(signalName)}
76 {
77 }
78
79 /* Constructor for an invalid BaseStatusSignal */
80 BaseStatusSignal(ctre::phoenix::StatusCode error) : deviceIdentifier{hardware::DeviceIdentifier{}},
81 spn{0},
82 error{error},
83 signalName{"Invalid"}
84 {
85 }
86
87 /**
88 * \brief Wait for multiple signals to arrive
89 *
90 * \param signals Signals to wait for
91 * \param network Network to wait for the signals on
92 * \param timeoutSeconds Maximum time to wait for all these signals
93 * \returns Status of the wait
94 */
95 static ctre::phoenix::StatusCode Status_WaitForAll(
96 std::initializer_list<BaseStatusSignal *> signals,
97 const char *network,
98 units::time::second_t timeoutSeconds);
99
100 /**
101 * \brief Wait for multiple signals to arrive
102 *
103 * \param signals Signals to wait for
104 * \param network Network to wait for the signals on
105 * \param timeoutSeconds Maximum time to wait for all these signals
106 * \returns Status of the wait
107 */
108 static ctre::phoenix::StatusCode Status_WaitForAll(
109 const std::vector<BaseStatusSignal *> &signals,
110 const char *network,
111 units::time::second_t timeoutSeconds);
112
113 ctre::phoenix::StatusCode SetUpdateFrequency(const char *canbus, uint32_t deviceHash, uint16_t spn, units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds);
114
115 /**
116 * Gets signal units.
117 *
118 * \param signal Signal to get
119 * \returns Units of the signal
120 */
121 static std::string Status_GetUnits(uint32_t signal);
122
123 /**
124 * Get signal update. Caller either get last received, or wait for an update.
125 *
126 * \param network Name of bus (can, canfd, canivore-name, future protocols)
127 * \param deviceHash Hash id of the device (based on device id and model)
128 * \param signal Signal to get
129 * \param bWaitForUpdate If true, API will wait up to timeoutSeconds for an update. If false, routine will poll last received and use timeoutSeconds to return error code if too old.
130 * \param timeoutSeconds How long to wait or how old the signal can be before error'ing
131 * \param outValue Value of the signal
132 * \param hwtimestamp Timestamp of the signal
133 * \param swtimestamp Timestamp of the signal
134 * \param ecutimestamp Timestamp of the signal
135 * \param timestampType Which type of timestamp was gotten
136 * \returns Status of the get
137 */
138 static ctre::phoenix::StatusCode Status_Get(
139 const char *network,
140 int deviceHash,
141 uint32_t signal,
142 bool bWaitForUpdate, units::time::second_t timeoutSeconds,
143 double *outValue,
144 double *hwtimestamp, double *swtimestamp, double *ecutimestamp, int32_t *timestampType);
145
146 public:
147 virtual ~BaseStatusSignal() = 0; // Declare virtual destructor to make this class abstract
148
149 /**
150 * \brief Waits for new data on all provided signals up to timeout.
151 * This API is typically used with CANivore Bus signals as they will be synced using the
152 * CANivore Timesync feature and arrive simultaneously. Signals on a roboRIO bus cannot
153 * be synced and may require a significantly longer blocking call to receive all signals.
154 *
155 * Note that CANivore Timesync requires Phoenix Pro.
156 *
157 * This can also be used with a timeout of zero to refresh many signals at once, which
158 * is faster than calling Refresh() on every signal.
159 *
160 * \param timeoutSeconds Maximum time to wait for all the signals to arrive.
161 * Pass zero to refresh all signals without blocking.
162 * \param signals Signals to wait on, passed as initializer list of signal addresses.
163 * \return An InvalidParamValue if signals array is empty,
164 * InvalidNetwork if signals are on different CAN bus networks,
165 * RxTimeout if it took longer than timeoutSeconds to receive all the signals,
166 * MultiSignalNotSupported if using the roboRIO bus with more than one signal and a non-zero timeout.
167 * An OK status code means that all signals arrived within timeoutSeconds and they are all OK.
168 *
169 * Any other value represents the StatusCode of the first failed signal.
170 * Call GetError() on each signal to determine which ones failed.
171 */
172 static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, std::initializer_list<BaseStatusSignal *> signals)
173 {
174 return WaitForAll(timeoutSeconds,
175 std::vector<BaseStatusSignal*>(signals.begin(), signals.end()));
176 }
177 /**
178 * \brief Waits for new data on all provided signals up to timeout.
179 * This API is typically used with CANivore Bus signals as they will be synced using the
180 * CANivore Timesync feature and arrive simultaneously. Signals on a roboRIO bus cannot
181 * be synced and may require a significantly longer blocking call to receive all signals.
182 *
183 * Note that CANivore Timesync requires Phoenix Pro.
184 *
185 * This can also be used with a timeout of zero to refresh many signals at once, which
186 * is faster than calling Refresh() on every signal.
187 *
188 * \param timeoutSeconds Maximum time to wait for all the signals to arrive.
189 * Pass zero to refresh all signals without blocking.
190 * \param signals Signals to wait on, passed as vector of signal addresses.
191 * \return An InvalidParamValue if signals array is empty,
192 * InvalidNetwork if signals are on different CAN bus networks,
193 * RxTimeout if it took longer than timeoutSeconds to receive all the signals,
194 * MultiSignalNotSupported if using the roboRIO bus with more than one signal and a non-zero timeout.
195 * An OK status code means that all signals arrived within timeoutSeconds and they are all OK.
196 *
197 * Any other value represents the StatusCode of the first failed signal.
198 * Call GetError() on each signal to determine which ones failed.
199 */
200 static ctre::phoenix::StatusCode WaitForAll(units::time::second_t timeoutSeconds, const std::vector<BaseStatusSignal *> &signals)
201 {
202 /* static string for location */
203 const char kLocation[] = "ctre::phoenix6::BaseStatusSignal::WaitForAll";
204
205 if (signals.size() < 1)
206 {
207 /* We don't have any signals to wait for, so return early */
208 ctre::phoenix::StatusCode retval = ctre::phoenix::StatusCode::InvalidParamValue;
209 c_ctre_phoenix_report_error(true, retval, 0,
210 retval.GetDescription(),
211 kLocation,
213 return retval;
214 }
215 const std::string &network = (*signals.begin())->deviceIdentifier.network;
216
217 for (auto signal : signals)
218 {
219 /* Check that they all have the same network */
220 if (network != signal->deviceIdentifier.network)
221 {
222 ctre::phoenix::StatusCode retval = ctre::phoenix::StatusCode::InvalidNetwork; // Networks don't match, return early
223
224 c_ctre_phoenix_report_error(true, retval, 0,
225 retval.GetDescription(),
226 kLocation,
228 return retval;
229 }
230 }
231 /* Now wait for all the signals */
232 ctre::phoenix::StatusCode retval = Status_WaitForAll(signals, network.c_str(), timeoutSeconds);
233
234 /*error reporting */
235 if (false == retval.IsOK())
236 {
237 c_ctre_phoenix_report_error(retval.IsError(), retval, 0,
238 retval.GetDescription(),
239 kLocation,
241 }
242 return retval;
243 }
244 /**
245 * \brief Performs latency compensation on signal using the signalSlope and signal's latency to determine
246 * the magnitude of compensation. The caller must refresh these StatusSignals beforehand;
247 * this function only does the math required for latency compensation.
248 *
249 * \example units::turn_t compensatedTurns = GetLatencyCompensatedValue(fx.GetPosition(), fx.GetVelocity());
250 *
251 * \tparam U Type of signal's underlying type. This is the type that the function will return.
252 * \tparam U_PER_SEC Type of signalSlope's underlying type. This must be the derivative of U.
253 * \param signal Signal to be latency compensated. Caller must make sure this signal is up to date
254 * either by calling \c Refresh() or \c WaitForUpdate().
255 * \param signalSlope Derivative of signal that informs compensation magnitude. Caller must make sure this
256 * signal is up to date either by calling \c Refresh() or \c WaitForUpdate().
257 * \returns Latency compensated value from the signal StatusSignal.
258 */
259 template <typename U, typename U_PER_SEC>
261 {
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();
270 units::second_t latency = signal.GetTimestamp().GetLatency();
271 return nonCompensatedSignal + (changeInSignal * latency);
272 }
273 /**
274 * \brief Checks if all signals have an OK error code.
275 *
276 * \param signals Signals to check error code of.
277 * \returns True if all signals are OK, false otherwise
278 */
279 static ctre::phoenix::StatusCode IsAllGood(std::initializer_list<BaseStatusSignal *> signals)
280 {
281 for (auto signal : signals)
282 {
283 if (signal->GetError() != ctre::phoenix::StatusCode::OK)
284 return false;
285 }
286 return true;
287 }
288
289 /**
290 * \brief Sets the rate at which the device will publish this signal.
291 *
292 * The minimum supported signal frequency is 4 Hz, and the maximum is 1000 Hz.
293 *
294 * \param frequencyHz Rate to publish the signal in Hz.
295 * \param timeoutSeconds Maximum amount of time to wait when performing the action
296 * \returns Status code of setting the update frequency
297 */
298 ctre::phoenix::StatusCode SetUpdateFrequency(units::frequency::hertz_t frequencyHz, units::time::second_t timeoutSeconds = 50_ms)
299 {
300 /* attempt to change the frequency */
301 return SetUpdateFrequency(this->deviceIdentifier.network.c_str(),
302 this->deviceIdentifier.deviceHash,
303 this->spn,
304 frequencyHz,
305 timeoutSeconds);
306 }
307
308 /**
309 * \brief Gets the units for this signal
310 *
311 * \returns String representation of units for this signal
312 */
313 const std::string &GetUnits() const { return units; }
314 /**
315 * \brief Get the timestamps of this signals
316 *
317 * \returns All timestamps for this signal
318 */
319 const AllTimestamps &GetAllTimestamps() const { return timestamps; }
320 /**
321 * \brief Get the best timestamp available to this signal
322 *
323 * \returns Best available timestamp for this signal
324 */
326 /**
327 * \brief Get the error code from when we last received this signal
328 *
329 * \returns Last cached Error Code
330 */
331 ctre::phoenix::StatusCode GetError() const { return error; }
332 };
333
334 /**
335 * Information from a single measurement of a status signal.
336 */
337 template <typename L>
339 {
340 /**
341 * \brief The value of the signal, this may be an enum so it is stored as a string
342 */
344 /**
345 * \brief Timestamp of when the data point was taken
346 */
347 units::time::second_t timestamp;
348 /**
349 * \brief Code response of getting the data
350 */
351 ctre::phoenix::StatusCode error;
352 /**
353 * \brief Units that correspond to this point
354 */
355 std::string units;
356 };
357
358 /**
359 * \brief Represents a status signal with data of type T,
360 * and operations available to retrieve information about
361 * the signal.
362 */
363 template <typename T>
365 {
366 bool _containsUnderlyingTypes;
367 std::map<int, StatusSignal<T>> _basicTypeMap;
368 std::function<void()> _checkFirmVersFunction;
370
371 void RefreshSwitch(bool block, units::time::second_t timeout)
372 {
373 /* Just make sure we don't do anything if we're not a switching statement */
374 if (!_containsUnderlyingTypes)
375 return;
376
377 double switchValue;
378 /* We only care about the switch value, so get that quickly */
379 ctre::phoenix::StatusCode outputError = Status_Get(
380 this->deviceIdentifier.network.c_str(),
381 this->deviceIdentifier.deviceHash,
382 this->spn,
383 block, timeout,
384 &switchValue,
385 nullptr, nullptr, nullptr, nullptr);
386
387 if (outputError != ctre::phoenix::StatusCode::OK)
388 {
389 this->error = outputError;
390 return;
391 }
392
393 auto foundValue = _basicTypeMap.find(static_cast<int>(switchValue));
394 if (foundValue != _basicTypeMap.end())
395 {
396 /* Found it, so refresh it and set our values to it */
397 foundValue->second.RefreshValue(block, timeout, false); // Top-level refresh will handle the error
398
399 /* save to members, use locks because string copies are not atomic */
400 {
401 std::lock_guard<std::mutex> lock{_copyLck};
402 CopyFrom(foundValue->second);
403 }
404 }
405 else
406 {
407 /* Didn't find it, so set our error */
409 }
410 }
411
412 void RefreshNoSwitch(bool block, units::time::second_t timeout)
413 {
414 /* Just make sure we don't do anything if we are a switching statement */
415 if (_containsUnderlyingTypes)
416 return;
417
418 /* fetch values */
419 double outHwTimestamp;
420 double outSwTimestamp;
421 double outEcuTimestamp;
422 int32_t outTimestampType;
423
424 ctre::phoenix::StatusCode outputError = Status_Get(
425 this->deviceIdentifier.network.c_str(),
426 this->deviceIdentifier.deviceHash,
427 this->spn,
428 block, timeout,
429 &this->baseValue,
430 &outHwTimestamp, &outSwTimestamp, &outEcuTimestamp, &outTimestampType);
431
432 /* save to members, use locks if need be (remember though Java locks are not reliable) */
433 if (outputError >= 0)
434 {
435 this->timestamps.Update(Timestamp{units::time::second_t{outSwTimestamp}, Timestamp::TimestampSource::System},
436 Timestamp{units::time::second_t{outHwTimestamp}, Timestamp::TimestampSource::CANivore},
437 Timestamp{});
438 }
439 this->error = outputError;
440 }
441
442 void RefreshValue(bool block, units::time::second_t timeout, bool ReportOnError)
443 {
444 _checkFirmVersFunction();
445 if (_containsUnderlyingTypes)
446 {
447 RefreshSwitch(block, timeout);
448 }
449 else
450 {
451 RefreshNoSwitch(block, timeout);
452 }
453
454 if (ReportOnError && !(this->error.IsOK()))
455 {
456 std::stringstream location;
457 location << this->deviceIdentifier.ToString() << " Status Signal " << this->signalName;
458 c_ctre_phoenix_report_error(this->error.IsError(), this->error, 0, this->error.GetDescription(), location.str().c_str(), ctre::phoenix::platform::GetStackTrace(1).c_str());
459 }
460 }
461
463
465 _containsUnderlyingTypes{false},
466 _basicTypeMap{},
467 _checkFirmVersFunction{[] {}}
468 {
469 CopyFrom(other);
470 }
471
472 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
473 uint16_t spn,
474 std::function<void()> checkFirmVersFunction,
475 std::string signalName) : BaseStatusSignal{std::move(deviceIdentifier), spn, std::move(signalName)},
476 _containsUnderlyingTypes{false},
477 _basicTypeMap{},
478 _checkFirmVersFunction{checkFirmVersFunction}
479 {
480 }
481
482 StatusSignal(hardware::DeviceIdentifier deviceIdentifier,
483 uint16_t spn,
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}
490 {
491 }
492
493 /* Constructor for an invalid StatusSignal */
494 StatusSignal(ctre::phoenix::StatusCode error) : BaseStatusSignal{error},
495 _containsUnderlyingTypes{false},
496 _basicTypeMap{},
497 _checkFirmVersFunction{[] {}}
498 {
499 }
500
501 public:
502 friend std::ostream &operator<<(std::ostream &os, const StatusSignal<T> &data)
503 {
504 #if defined(_WIN32) || defined(_WIN64)
505 // Set console code page to UTF-8 so console known how to interpret string data
506 SetConsoleOutputCP(CP_UTF8);
507 #endif
508 if constexpr(units::traits::is_unit_t_v<T>)
509 {
510 os << data.GetValue().value() << " " << data.GetUnits();
511 }
512 else
513 {
514 os << data.GetValue() << " " << data.GetUnits();
515 }
516 return os;
517 }
518 std::string ToString() const
519 {
520 std::stringstream ss;
521 ss << *this;
522 return ss.str();
523 }
524
525 /**
526 * \brief Gets the cached value from this status signal.
527 *
528 * \details Gets the cached value. To make sure the value is up-to-date
529 * call \c Refresh() or \c WaitForUpdate()
530 *
531 * \returns Cached value
532 */
533 T GetValue() const
534 {
535 if constexpr(units::traits::is_unit_t_v<T>)
536 {
537 return units::make_unit<T>(this->baseValue);
538 }
539 else
540 {
541 return static_cast<T>(this->baseValue);
542 }
543 }
544
545 /**
546 * \brief Refreshes the value of this status signal.
547 *
548 * If the user application caches this StatusSignal object
549 * instead of periodically fetching it from the hardware device,
550 * this function must be called to fetch fresh data.
551 *
552 * \details This performs a non-blocking refresh operation. If
553 * you want to wait until you receive the signal, call
554 * \c WaitForUpdate() instead.
555 *
556 * \param ReportOnError Whether to report any errors to the Driver Station/stderr.
557 *
558 * \returns Reference to itself
559 */
560 StatusSignal<T> &Refresh(bool ReportOnError = true)
561 {
562 RefreshValue(false, 0.300_s, ReportOnError); // Don't block and error if signal is older than 0.300 seconds
563 return *this;
564 }
565 /**
566 * \brief Waits up to timeoutSec to get the up-to-date status signal value.
567 *
568 * \details This performs a blocking refresh operation. If
569 * you want to non-blocking refresh the signal, call
570 * \c Refresh() instead.
571 *
572 * \param timeoutSec Maximum time to wait for the signal to update
573 * \param ReportOnError Whether to report any errors to the Driver Station/stderr.
574 *
575 * \returns Reference to itself
576 */
577 StatusSignal<T> &WaitForUpdate(units::time::second_t timeoutSec, bool ReportOnError = true)
578 {
579 RefreshValue(true, timeoutSec, ReportOnError);
580 return *this;
581 }
582
583 /**
584 * \brief Get a basic data-only container with this information, to be used for things such as data logging.
585 *
586 * \returns Basic structure with all relevant information
587 */
589 {
591 toRet.value = GetValue();
592 toRet.error = GetError();
593 toRet.units = GetUnits();
594 toRet.timestamp = GetTimestamp().GetTime();
595 return toRet;
596 }
597
598 /**
599 * \brief Returns a lambda that calls Refresh and GetValue on this object. This is useful for command-based programming.
600 *
601 * \returns std::function<T()> that calls Refresh() and returns this value.
602 */
603 std::function<T()> AsSupplier()
604 {
605 return [this]()
606 { return this->Refresh().GetValue(); };
607 }
608 };
609
610 /**
611 * \deprecated BaseStatusSignalValue will be removed in 2024. Users should use \c BaseStatusSignal instead.
612 */
613 using BaseStatusSignalValue [[deprecated("BaseStatusSignalValue will be removed in 2024. Users should use BaseStatusSignal instead.")]] = BaseStatusSignal;
614 /**
615 * \deprecated StatusSignalValue will be removed in 2024. Users should use \c StatusSignal instead.
616 */
617 template <typename T>
618 using StatusSignalValue [[deprecated("StatusSignalValue will be removed in 2024. Users should use StatusSignal instead.")]] = StatusSignal<T>;
619
620}
621}
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
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
CTREXPORT std::string GetStackTrace(int offset)
Get a stack trace, ignoring the first "offset" symbols.
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