Updated with native ui (imgui + qt)

This commit is contained in:
Martino Ferrari
2026-05-27 15:46:50 +02:00
parent 3dd0d863fa
commit cf174edde8
205 changed files with 157039 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <stdexcept>
// ─── Protocol constants (matching UDPStreamer wire format) ──────────
constexpr uint32_t UDPS_MAGIC = 0x53504455u; // 'UDPS' LE
constexpr uint8_t UDPS_TYPE_DATA = 0u;
constexpr uint8_t UDPS_TYPE_CONFIG = 1u;
constexpr uint8_t UDPS_TYPE_ACK = 2u;
constexpr uint8_t UDPS_TYPE_CONNECT = 3u;
constexpr uint8_t UDPS_TYPE_DISCONNECT = 4u;
constexpr size_t UDPS_HEADER_SIZE = 17;
constexpr size_t UDPS_SIGDESC_SIZE = 136;
// Type codes (matching Go protocol.go)
constexpr uint8_t TC_UINT8 = 0u;
constexpr uint8_t TC_INT8 = 1u;
constexpr uint8_t TC_UINT16 = 2u;
constexpr uint8_t TC_INT16 = 3u;
constexpr uint8_t TC_UINT32 = 4u;
constexpr uint8_t TC_INT32 = 5u;
constexpr uint8_t TC_UINT64 = 6u;
constexpr uint8_t TC_INT64 = 7u;
constexpr uint8_t TC_FLOAT32 = 8u;
constexpr uint8_t TC_FLOAT64 = 9u;
// Quantisation types
constexpr uint8_t QUANT_NONE = 0u;
constexpr uint8_t QUANT_UINT8 = 1u;
constexpr uint8_t QUANT_INT8 = 2u;
constexpr uint8_t QUANT_UINT16 = 3u;
constexpr uint8_t QUANT_INT16 = 4u;
// Time modes
constexpr uint8_t TM_PACKET = 0u;
constexpr uint8_t TM_FULL_ARRAY = 1u;
constexpr uint8_t TM_FIRST_SAMPLE = 2u;
constexpr uint8_t TM_LAST_SAMPLE = 3u;
constexpr uint32_t NO_TIME_SIGNAL = 0xFFFFFFFFu;
#pragma pack(push, 1)
struct UDPSPacketHeader {
uint32_t magic;
uint8_t type;
uint32_t counter;
uint16_t fragment_idx;
uint16_t total_fragments;
uint32_t payload_bytes;
};
struct UDPSSignalInfo {
char name[64];
uint8_t type_code;
uint8_t quant_type;
uint8_t num_dimensions;
uint32_t num_rows;
uint32_t num_cols;
double range_min;
double range_max;
uint8_t time_mode;
double sampling_rate;
uint32_t time_signal_idx;
char unit[32];
};
#pragma pack(pop)
static_assert(sizeof(UDPSPacketHeader) == 17, "Header must be 17 bytes");
static_assert(sizeof(UDPSSignalInfo) == 136, "Signal desc must be 136 bytes");
// ─── Parsed signal metadata ─────────────────────────────────────────
struct SignalDef {
std::string name;
uint8_t type_code = 0;
uint8_t quant_type = 0;
uint32_t num_elements = 0; // rows * cols
uint32_t num_rows = 1;
uint32_t num_cols = 1;
double range_min = 0.0;
double range_max = 0.0;
uint8_t time_mode = TM_PACKET;
double sampling_rate = 0.0;
uint32_t time_signal_idx = NO_TIME_SIGNAL;
std::string unit;
int element_byte_size() const;
};
// ─── One DATA packet worth of samples ───────────────────────────────
struct DataPacket {
uint64_t hrt_timestamp = 0;
// Per-signal float values (always float64 after dequantisation)
std::vector<std::vector<double>> values;
};
// ─── Parser functions ───────────────────────────────────────────────
/** Validate a UDP datagram header. Returns false if magic or size is wrong. */
bool parse_header(const uint8_t* buf, size_t len, UDPSPacketHeader& hdr);
/** Parse a reassembled CONFIG payload into a signal list. */
std::vector<SignalDef> parse_config(const uint8_t* payload, size_t len);
/** Parse a reassembled DATA payload into float64 values per signal. */
DataPacket parse_data(const uint8_t* payload, size_t len,
const std::vector<SignalDef>& sig_defs);
/** Build a 17-byte CONNECT packet. */
std::vector<uint8_t> build_connect();
/** Build a 17-byte DISCONNECT packet. */
std::vector<uint8_t> build_disconnect();