docs/adr/ADR-077-novel-rf-sensing-applications.md
Status: Accepted
Date: 2026-04-02
Authors: ruv
Depends on: ADR-018 (CSI binary protocol), ADR-073 (multifrequency mesh scan), ADR-075 (MinCut person separation), ADR-076 (CSI spectrogram embeddings)
The existing ESP32 CSI + Cognitum Seed infrastructure collects rich multi-modal data:
No new hardware is required. All 6 applications below derive novel insights from data already being collected via the ADR-018 binary protocol over UDP port 5006.
Implement 6 novel RF sensing applications as standalone Node.js scripts that process live UDP or replayed .csi.jsonl recordings.
Breathing rate (BR) and heart rate (HR) time series from vitals packets (0xC5110002), sampled at ~1 Hz per node over 6-8 hours.
Sliding window analysis (5-minute windows, 1-minute stride) classifying sleep stages:
| Stage | BR (BPM) | BR Variance | HR Pattern | Motion |
|---|---|---|---|---|
| Deep (N3) | 6-12 | Very low (<2.0) | Slow, regular | None |
| Light (N1/N2) | 12-18 | Moderate (2.0-8.0) | Normal | Minimal |
| REM | 15-25 | High (>8.0), irregular | Elevated | Eyes only (low CSI motion) |
| Awake | >18 or <6 | Any | Variable | Moderate-high |
Each 5-minute window is scored by:
motion_energy field)Overnight recording (overnight-1775217646.csi.jsonl, 113k frames, ~40 min) should show:
Consumer-grade sleep tracking without wearables. RF-based sensing avoids compliance issues (forgotten wristbands, dead batteries). Not diagnostic; informational only.
Breathing rate time series from vitals packets at ~1 Hz.
Detect respiratory events in the BR time series:
| Event | Definition | Duration |
|---|---|---|
| Apnea | BR drops below 3 BPM (effective cessation) | >= 10 seconds |
| Hypopnea | BR drops > 50% from 5-min rolling baseline | >= 10 seconds |
Scoring:
| AHI | Severity |
|---|---|
| < 5 | Normal |
| 5-15 | Mild |
| 15-30 | Moderate |
| > 30 | Severe |
Pre-screening tool for obstructive sleep apnea (OSA). Provides motivation for clinical polysomnography referral. Not a diagnostic device; informational pre-screen only.
Heart rate time series from vitals packets at ~1 Hz.
Heart Rate Variability (HRV) analysis:
RMSSD (Root Mean Square of Successive Differences):
LF/HF Ratio (via FFT on 5-minute HR windows):
Stress Score (0-100):
score = 50 * (1 - RMSSD_norm) + 50 * LF_HF_normRMSSD_norm = RMSSD / max_expected_RMSSD (capped at 1.0)LF_HF_norm = min(LF_HF / 4.0, 1.0)Cadence Extraction: FFT on motion_energy within 5-second sliding windows
Stride Regularity: Autocorrelation of motion_energy
Asymmetry Detection: Compare motion energy oscillation between two ESP32 nodes
Tremor Detection: High-frequency phase variance analysis
Overnight data should show clear stationary periods with no cadence detected. Any walking segments should show cadence in the 0.8-2.0 Hz range.
Per-subcarrier amplitude from raw CSI frames (0xC5110001).
Baseline Establishment (first 10 minutes or configurable):
Change Detection (sliding 30-second windows):
Material Classification heuristic:
Overnight data has 19% null baseline. Changes in null pattern over the recording period indicate environment changes (doors opening/closing, person entering/leaving).
Online Clustering using running k-means (k=5, updateable centroids):
State Labeling (heuristic from vitals correlation):
Transition Tracking:
Daily Profile:
Overnight recording should show 2-3 stable clusters corresponding to activity periods at different times. Transitions should be infrequent and correspond to real behavioral changes.
All scripts share common infrastructure:
--replay <file> for offline, --port <N> for live, --json for programmatic output| Script | Primary Packets | Key Algorithm |
|---|---|---|
sleep-monitor.js | vitals (0xC5110002) | BR/HR window classification |
apnea-detector.js | vitals (0xC5110002) | BR pause detection, AHI scoring |
stress-monitor.js | vitals (0xC5110002) | HRV RMSSD + FFT LF/HF |
gait-analyzer.js | vitals + raw CSI | FFT cadence + phase tremor |
material-detector.js | raw CSI (0xC5110001) | Null pattern baseline + delta |
room-fingerprint.js | feature (0xC5110003) + vitals | Online k-means clustering |