62static_assert(
sizeof(std::uint32_t) == 4,
"Expected 32-bit uint32_t");
63static_assert(
sizeof(float) == 4,
"Expected 32-bit float");
68inline void writeU32Be(std::uint8_t* dst, std::uint32_t v) {
72 dst[i] =
static_cast<std::uint8_t
>(v >> shift);
83 return (frequency_hz == 0) ?
static_cast<std::uint16_t
>(1000u)
84 :
static_cast<std::uint16_t
>((1000u + frequency_hz - 1u) / frequency_hz);
147 template <std::
size_t M>
150 std::uint16_t sendFrequency_hz)
197 template <std::
size_t N>
198 Telemetry(
const std::array<SendableSensorData*, N>& streams,
199 Stream& rfdSerialConnection,
201 : streams_(streams.data()),
203 rfdSerialConnection_(rfdSerialConnection),
204 commandLine_(commandLine),
205 nextEmptyPacketIndex_(0),
212 bool tick(std::uint32_t currentTime_ms);
242 void preparePacket(std::uint32_t timestamp_ms);
245 void setPacketToZero();
247 void checkForRadioCommandSequence(std::uint32_t currentTime_ms);
248 void enterCommandMode(std::uint32_t currentTime_ms);
249 void exitCommandMode();
250 bool shouldPauseTelemetryForCommandMode(std::uint32_t currentTime_ms);
252 void tryAppendStream(
SendableSensorData* stream, std::uint32_t currentTime_ms,
bool& payloadAdded);
253 bool finalizeAndSendPacket();
261 const std::size_t streamCount_;
264 Stream& rfdSerialConnection_;
268 std::uint32_t packetCounter_ = 0;
269 std::size_t nextEmptyPacketIndex_;
270 std::array<std::uint8_t, TelemetryFmt::kPacketCapacity_bytes> packet_;
273 bool inCommandMode_ =
false;
274 std::uint32_t commandModeEnteredTimestamp_ms_ = 0;
275 std::uint32_t commandModeLastInputTimestamp_ms_ = 0;
276 std::size_t commandEntryProgress_ = 0;
277 bool commandModeTimeoutLocked_ =
false;
278 std::uint32_t commandModeTimeoutLockDeadline_ms_ = 0;
Lightweight UART command-line interface with history and parsing.
Buffers sensor samples and forwards them to an IDataSaver at a controlled rate.
void forceExitCommandMode()
Immediately exit command mode if currently active.
void setCommandLine(CommandLine *newCommandLine)
Optional command line interface to drive while telemetry manages command mode.
void lockCommandModeTimeout(std::uint32_t lockDuration_ms)
Temporarily disable command-mode inactivity timeout.
void unlockCommandModeTimeout()
Re-enable command-mode inactivity timeout immediately.
bool isInCommandMode() const
True if telemetry is currently paused for radio command mode.
bool tick(std::uint32_t currentTime_ms)
Call every loop to send due telemetry streams.
Telemetry(const std::array< SendableSensorData *, N > &streams, Stream &rfdSerialConnection, CommandLine *commandLine=nullptr)
Construct from std::array (convenient and compile-time sized). The std::array must outlive the Teleme...
void writeU32Be(std::uint8_t *dst, std::uint32_t v)
Write a 32-bit value in big-endian order to dst[0..3].
constexpr std::size_t kPacketCapacity_bytes
constexpr std::size_t kStartByteIndex
std::uint16_t hzToPeriod_ms(std::uint16_t frequency_hz)
Convert frequency (Hz) to period (ms), using integer math.
constexpr char kCommandEntryChar
constexpr std::size_t kHeaderSize_bytes
constexpr std::size_t kBytesInU32_bytes
constexpr std::size_t kCommandEntrySequenceLength
constexpr std::uint8_t kStartByteValue
constexpr std::size_t kPacketCounterIndex
constexpr std::size_t kEndMarkerSize_bytes
constexpr std::uint32_t kCommandModeInactivityTimeout_ms
constexpr std::size_t kSyncZeroCount_bytes
constexpr std::uint8_t kEndByteValue
constexpr std::size_t kTimestampIndex
constexpr unsigned kBitsPerByte_bits
Declares one telemetry "stream" to include in packets.
const std::size_t multiSDHLength
bool isMulti() const
Convenience: true if configured as a multi SDH stream.
bool isSingle() const
Convenience: true if configured as a single SDH stream.
SendableSensorData(SensorDataHandler *sdh, std::uint16_t sendFrequency_hz)
Create a single SDH stream.
SendableSensorData(const std::array< SensorDataHandler *, M > &sdhList, std::uint8_t label, std::uint16_t sendFrequency_hz)
Create a multi SDH stream from a std::array.
void markWasSent(std::uint32_t now_ms)
Update internal state after sending.
std::uint8_t multiSDHDataLabel
std::uint32_t lastSentTimestamp_ms
bool shouldBeSent(std::uint32_t now_ms) const
Return true if enough time has elapsed such that this stream wants to be sent again.
SensorDataHandler *const * multiSDH
SensorDataHandler * singleSDH