The Rust port lived two directories deep (rust-port/wifi-densepose-rs/) without any sibling under rust-port/ that warranted the extra level. Move the whole workspace up to v2/ to match v1/ (Python) at the same depth and shorten every cd / build command across the repo. git mv preserves history for all tracked files. 60 files updated for path references (CI workflows, ADRs, docs, scripts, READMEs, internal .claude-flow state). Two manual fixes for relative-cd paths in CLAUDE.md and ADR-043 that became wrong after the depth change (cd ../.. → cd ..). Validated: - cargo check --workspace --no-default-features → clean (after target/ nuke; the gitignored target/ was carried by the OS rename and had hard-coded old paths in build scripts) - cargo test --workspace --no-default-features → 1,539 passed, 0 failed, 8 ignored (same totals as pre-rename) - ESP32-S3 on COM7 → still streaming live CSI (cb #40300, RSSI -64 dBm) After-merge follow-up: contributors should `rm -rf v2/target` once and let cargo regenerate from the new path. |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
README.md
wifi-densepose-vitals
ESP32 CSI-grade vital sign extraction: heart rate and respiratory rate from WiFi Channel State Information (ADR-021).
Overview
wifi-densepose-vitals implements a four-stage pipeline that extracts respiratory rate and heart
rate from multi-subcarrier CSI amplitude and phase data. The crate has zero external dependencies
beyond tracing (and optional serde), uses #[forbid(unsafe_code)], and is designed for
resource-constrained edge deployments alongside ESP32 hardware.
Pipeline Stages
- Preprocessing (
CsiVitalPreprocessor) -- EMA-based static component suppression, producing per-subcarrier residuals that isolate body-induced signal variation. - Breathing extraction (
BreathingExtractor) -- Bandpass filtering at 0.1--0.5 Hz with zero-crossing analysis for respiratory rate estimation. - Heart rate extraction (
HeartRateExtractor) -- Bandpass filtering at 0.8--2.0 Hz with autocorrelation peak detection and inter-subcarrier phase coherence weighting. - Anomaly detection (
VitalAnomalyDetector) -- Z-score analysis using Welford running statistics for real-time clinical alerts (apnea, tachycardia, bradycardia).
Results are stored in a VitalSignStore with configurable retention for historical trend
analysis.
Feature flags
| Flag | Default | Description |
|---|---|---|
serde |
yes | Serialization for vital sign types |
Quick Start
use wifi_densepose_vitals::{
CsiVitalPreprocessor, BreathingExtractor, HeartRateExtractor,
VitalAnomalyDetector, VitalSignStore, CsiFrame,
VitalReading, VitalEstimate, VitalStatus,
};
let mut preprocessor = CsiVitalPreprocessor::new(56, 0.05);
let mut breathing = BreathingExtractor::new(56, 100.0, 30.0);
let mut heartrate = HeartRateExtractor::new(56, 100.0, 15.0);
let mut anomaly = VitalAnomalyDetector::default_config();
let mut store = VitalSignStore::new(3600);
// Process a CSI frame
let frame = CsiFrame {
amplitudes: vec![1.0; 56],
phases: vec![0.0; 56],
n_subcarriers: 56,
sample_index: 0,
sample_rate_hz: 100.0,
};
if let Some(residuals) = preprocessor.process(&frame) {
let weights = vec![1.0 / 56.0; 56];
let rr = breathing.extract(&residuals, &weights);
let hr = heartrate.extract(&residuals, &frame.phases);
let reading = VitalReading {
respiratory_rate: rr.unwrap_or_else(VitalEstimate::unavailable),
heart_rate: hr.unwrap_or_else(VitalEstimate::unavailable),
subcarrier_count: frame.n_subcarriers,
signal_quality: 0.9,
timestamp_secs: 0.0,
};
let alerts = anomaly.check(&reading);
store.push(reading);
}
Architecture
wifi-densepose-vitals/src/
lib.rs -- Re-exports, module declarations
types.rs -- CsiFrame, VitalReading, VitalEstimate, VitalStatus
preprocessor.rs -- CsiVitalPreprocessor (EMA static suppression)
breathing.rs -- BreathingExtractor (0.1-0.5 Hz bandpass)
heartrate.rs -- HeartRateExtractor (0.8-2.0 Hz autocorrelation)
anomaly.rs -- VitalAnomalyDetector (Z-score, Welford stats)
store.rs -- VitalSignStore, VitalStats (historical retention)
Related Crates
| Crate | Role |
|---|---|
wifi-densepose-hardware |
Provides raw CSI frames from ESP32 |
wifi-densepose-mat |
Uses vital signs for survivor triage |
wifi-densepose-signal |
Advanced signal processing algorithms |
License
MIT OR Apache-2.0