mirror of
https://github.com/ruvnet/RuView
synced 2026-08-05 19:41:44 +00:00
f49c722764
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.
81 lines
2.8 KiB
Rust
81 lines
2.8 KiB
Rust
//! ESP32 CSI-grade vital sign extraction (ADR-021).
|
|
//!
|
|
//! Extracts heart rate and respiratory rate from WiFi Channel
|
|
//! State Information using multi-subcarrier amplitude and phase
|
|
//! analysis.
|
|
//!
|
|
//! # Architecture
|
|
//!
|
|
//! The pipeline processes CSI frames through four stages:
|
|
//!
|
|
//! 1. **Preprocessing** ([`CsiVitalPreprocessor`]): EMA-based static
|
|
//! component suppression, producing per-subcarrier residuals.
|
|
//! 2. **Breathing extraction** ([`BreathingExtractor`]): Bandpass
|
|
//! filtering (0.1-0.5 Hz) with zero-crossing analysis for
|
|
//! respiratory rate.
|
|
//! 3. **Heart rate extraction** ([`HeartRateExtractor`]): Bandpass
|
|
//! filtering (0.8-2.0 Hz) with autocorrelation peak detection
|
|
//! and inter-subcarrier phase coherence weighting.
|
|
//! 4. **Anomaly detection** ([`VitalAnomalyDetector`]): Z-score
|
|
//! analysis with Welford running statistics for clinical alerts
|
|
//! (apnea, tachycardia, bradycardia).
|
|
//!
|
|
//! Results are stored in a [`VitalSignStore`] with configurable
|
|
//! retention for historical analysis.
|
|
//!
|
|
//! # Example
|
|
//!
|
|
//! ```
|
|
//! 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);
|
|
//! }
|
|
//! ```
|
|
|
|
pub mod anomaly;
|
|
pub mod breathing;
|
|
pub mod heartrate;
|
|
pub mod preprocessor;
|
|
pub mod store;
|
|
pub mod types;
|
|
|
|
pub use anomaly::{AnomalyAlert, VitalAnomalyDetector};
|
|
pub use breathing::BreathingExtractor;
|
|
pub use heartrate::HeartRateExtractor;
|
|
pub use preprocessor::CsiVitalPreprocessor;
|
|
pub use store::{VitalSignStore, VitalStats};
|
|
pub use types::{CsiFrame, VitalEstimate, VitalReading, VitalStatus};
|