Full implementation of Project AETHER — Contrastive CSI Embedding Model. ## Phases Delivered 1. ProjectionHead (64→128→128) + L2 normalization 2. CsiAugmenter (5 physically-motivated augmentations) 3. InfoNCE contrastive loss + SimCLR pretraining 4. FingerprintIndex (4 index types: env, activity, temporal, person) 5. RVF SEG_EMBED (0x0C) + CLI integration 6. Cross-modal alignment (PoseEncoder + InfoNCE) 7. Deep RuVector: MicroLoRA, EWC++, drift detection, hard-negative mining, SEG_LORA ## Stats - 276 tests passing (191 lib + 51 bin + 16 rvf + 18 vitals) - 3,342 additions across 8 files - Zero unsafe/unwrap/panic/todo stubs - ~55KB INT8 model for ESP32 edge deployment Also fixes deprecated GitHub Actions (v3→v4) and adds feat/* branch CI triggers. Closes #50
103 lines
3.9 KiB
Markdown
103 lines
3.9 KiB
Markdown
# wifi-densepose-vitals
|
|
|
|
[](https://crates.io/crates/wifi-densepose-vitals)
|
|
[](https://docs.rs/wifi-densepose-vitals)
|
|
[](LICENSE)
|
|
|
|
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
|
|
|
|
1. **Preprocessing** (`CsiVitalPreprocessor`) -- EMA-based static component suppression,
|
|
producing per-subcarrier residuals that isolate body-induced signal variation.
|
|
2. **Breathing extraction** (`BreathingExtractor`) -- Bandpass filtering at 0.1--0.5 Hz with
|
|
zero-crossing analysis for respiratory rate estimation.
|
|
3. **Heart rate extraction** (`HeartRateExtractor`) -- Bandpass filtering at 0.8--2.0 Hz with
|
|
autocorrelation peak detection and inter-subcarrier phase coherence weighting.
|
|
4. **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
|
|
|
|
```rust
|
|
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
|
|
|
|
```text
|
|
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`](../wifi-densepose-hardware) | Provides raw CSI frames from ESP32 |
|
|
| [`wifi-densepose-mat`](../wifi-densepose-mat) | Uses vital signs for survivor triage |
|
|
| [`wifi-densepose-signal`](../wifi-densepose-signal) | Advanced signal processing algorithms |
|
|
|
|
## License
|
|
|
|
MIT OR Apache-2.0
|