Both capture scripts decoded a header layout the firmware does not send.
csi_collector.c and esp32_parser.rs use: magic u32 @0, node_id @4,
n_antennas @5, n_subcarriers u16 @6, freq_mhz u32 @8, sequence u32 @12,
rssi i8 @16, noise_floor i8 @17, ppdu_type @18, flags @19, then
n_antennas * n_subcarriers int8 I/Q pairs from @20.
- collect-training-data.py read a 16-byte header and int16 I/Q, so its
length check rejected every real single-antenna frame. It now reads the
20-byte header and int8 pairs, records freq/channel/seq/ppdu/flags, and
lets the recorder stamp receive time (the header has no timestamp).
- record-csi-udp.py read rssi from byte 6 and channel from byte 7 (the
n_subcarriers bytes) and treated bytes 8-19 as I/Q, so a 64-subcarrier
frame came out as 70 subcarriers with header bytes in the first six
amplitudes. It now checks the magic, reads the real fields, and writes
only the I/Q block to iq_hex.
- Add scripts/tests/test_capture_adr018.py, which builds frames with the
esp32_parser.rs test layout and checks the decoded fields.
Co-Authored-By: claude-flow <ruv@ruv.net>
1. record-csi-udp.py stamped LOCAL time with a 'Z' (UTC) suffix → camera/CSI disagreed
by the UTC offset → 0 aligned pairs. Now writes true UTC via datetime.now(timezone.utc).
2. align-ground-truth.js kept empty-keypoint (non-detection) records at confidence 0,
collapsing window avgConf below threshold → all windows rejected. Now skipped at load.
3. extractCsiMatrix silently zero-padded/truncated mixed-subcarrier frames. Now frames
are filtered to the session's modal subcarrier count before windowing — never padded.
4. CSI/feature matrices are filled frame-major but were labeled shape [nSc, nFrames] —
transposed. Labels corrected to [nFrames, nSc] / [nFrames, dim].
Co-Authored-By: claude-flow <ruv@ruv.net>
- Add activation clamping [-10, 10] in TCN forward pass to prevent NaN
from real CSI amplitude ranges after normalization
- Add safe sigmoid with input clamping [-20, 20]
- Add scripts/record-csi-udp.py: lightweight ESP32 CSI UDP recorder
Validated on real paired data (345 samples):
ESP32 CSI: 7,000 frames at 23fps from COM8
Mac camera: 6,470 frames at 22fps via MediaPipe
PCK@20: 92.8% | Eval loss: 0.083 | Bone loss: 0.008
Co-Authored-By: claude-flow <ruv@ruv.net>