add framed binary telemetry transport
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# TRK1 Binary Telemetry — Version 1
|
||||
|
||||
The binary stream is the shared transport and storage representation for USB,
|
||||
BLE, and any later nonvolatile buffer. All multibyte integers and IEEE-754
|
||||
float32 values are little-endian. Frames are self-identifying and may be split or
|
||||
combined by an underlying byte transport.
|
||||
|
||||
## Frame header (36 bytes)
|
||||
|
||||
| Offset | Size | Field |
|
||||
| ---: | ---: | --- |
|
||||
| 0 | 4 | ASCII magic `TRK1` |
|
||||
| 4 | 1 | Wire version (`1`) |
|
||||
| 5 | 1 | Packet type: metadata `1`, samples `2` |
|
||||
| 6 | 1 | Header size (`36`) |
|
||||
| 7 | 1 | Record size (`0` or `20`) |
|
||||
| 8 | 1 | Record count (`0` or 1–8) |
|
||||
| 9 | 1 | Packet flags |
|
||||
| 10 | 2 | Payload size |
|
||||
| 12 | 4 | Monotonic packet sequence |
|
||||
| 16 | 8 | Base ESP timer timestamp in microseconds |
|
||||
| 24 | 4 | Cumulative samples lost to read failure, queue overflow, or output failure |
|
||||
| 28 | 4 | Cumulative acquisition-loop overruns |
|
||||
| 32 | 4 | IEEE CRC-32 |
|
||||
|
||||
CRC uses polynomial `0xEDB88320`, initial value `0xFFFFFFFF`, and final XOR
|
||||
`0xFFFFFFFF`. It covers header bytes 4–31 followed by the complete payload. The
|
||||
magic and stored CRC field are excluded.
|
||||
|
||||
Packet flag bit 0 means at least one sample timestamp delta saturated.
|
||||
|
||||
## Sample record (20 bytes)
|
||||
|
||||
| Offset | Size | Field |
|
||||
| ---: | ---: | --- |
|
||||
| 0 | 4 | Sample sequence |
|
||||
| 4 | 2 | Timestamp delta from the preceding record, in 10 us units |
|
||||
| 6 | 2 | Enclosure accel X raw (`int16`) |
|
||||
| 8 | 2 | Enclosure accel Y raw (`int16`) |
|
||||
| 10 | 2 | Enclosure accel Z raw (`int16`) |
|
||||
| 12 | 2 | Enclosure gyro X raw (`int16`) |
|
||||
| 14 | 2 | Enclosure gyro Y raw (`int16`) |
|
||||
| 16 | 2 | Enclosure gyro Z raw (`int16`) |
|
||||
| 18 | 1 | Raw ADXL345 `INT_SOURCE` |
|
||||
| 19 | 1 | Raw L3G4200D `STATUS_REG` |
|
||||
|
||||
The first record has delta zero and uses the frame's base timestamp. Each later
|
||||
timestamp is reconstructed by cumulatively adding its delta. A delta that cannot
|
||||
fit is stored as `0xFFFF` and sets packet flag bit 0. Sample sequence gaps remain
|
||||
detectable independently.
|
||||
|
||||
Mapped raw counts are authoritative. The original sensor-native axes can be
|
||||
reconstructed because the mappings are lossless:
|
||||
|
||||
```text
|
||||
accel native = (-enclosure_y, enclosure_x, enclosure_z)
|
||||
gyro native = ( enclosure_x, enclosure_y, enclosure_z)
|
||||
```
|
||||
|
||||
## Metadata payload (48 bytes)
|
||||
|
||||
Metadata frames repeat approximately every five seconds so a receiver may attach
|
||||
midstream. The payload contains:
|
||||
|
||||
- Sample rate, accelerometer range, gyroscope range, and mapping/calibration flags
|
||||
- Three accel offset float32 values
|
||||
- Three accel counts/g float32 values
|
||||
- Three gyro bias float32 values
|
||||
- Nominal gyro mdps/LSB float32 value
|
||||
|
||||
A byte-stream receiver may begin inside an incomplete frame. It discards bytes
|
||||
until a magic/header/CRC combination validates. Host tools report any rejection
|
||||
before that first valid frame separately from CRC failures after synchronization.
|
||||
|
||||
## Buffering
|
||||
|
||||
Acquisition runs in a dedicated higher-priority task and writes complete samples
|
||||
to a 128-entry RAM queue. The lower-priority output task batches up to eight
|
||||
records per frame. At 100 Hz this queue represents about 1.28 seconds of
|
||||
decoupling from a blocked transport. Queue overflow never overwrites an older
|
||||
sample silently: sequence gaps and the cumulative lost-sample counter expose it.
|
||||
Reference in New Issue
Block a user