chore: add workspace metadata and crate READMEs for publishing
Add license, authors, repository, documentation, keywords, categories, and readme fields to all crate Cargo.toml files. Add crate-level README files for documentation. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -4,6 +4,12 @@ version.workspace = true
|
||||
edition.workspace = true
|
||||
description = "ESP32 CSI-grade vital sign extraction (ADR-021): heart rate and respiratory rate from WiFi Channel State Information"
|
||||
license.workspace = true
|
||||
authors = ["rUv <ruv@ruv.net>", "WiFi-DensePose Contributors"]
|
||||
repository.workspace = true
|
||||
documentation = "https://docs.rs/wifi-densepose-vitals"
|
||||
keywords = ["wifi", "vital-signs", "breathing", "heart-rate", "csi"]
|
||||
categories = ["science", "computer-vision"]
|
||||
readme = "README.md"
|
||||
|
||||
[dependencies]
|
||||
tracing.workspace = true
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user