RuView WiFi-Mat 领域模型实战解读:以 DDD 规范 CSI 灾难搜救中的幸存者检测、定位与检伤分类
【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView
本文以 docs/ddd/wifi-mat-domain-model.md 这份领域驱动设计(DDD)规格文档为主体,结合仓库中
wifi-densepose-matcrate(v2/crates/wifi-densepose-mat)的实际实现与 ADR-001 的架构决策,从通用语言、限界上下文、实体与值对象、领域事件、领域服务到防腐层与仓储接口逐层拆解,帮助你快速读懂一套可落地的搜救感知领域模型,并能据此在 RuView 中定位、调用与扩展这套「WiFi 穿墙搜救」能力。
一、WiFi-Mat 与领域模型的定位
WiFi-Mat(Mass Casualty Assessment Tool,大规模伤亡评估工具)是 RuView 项目中面向灾害搜救场景的子系统:利用 WiFi Channel State Information(CSI)穿透混凝土、木质与干墙等非金属废墟,检测被困人员极其微弱的呼吸、心跳与肢体动作,并对多伤员进行 START 协议检伤分类与优先级告警。这一场景最早由 docs/adr/ADR-001-wifi-mat-disaster-detection.md 记录,完整的操作级使用说明见 docs/wifi-mat-user-guide.md,而本文聚焦的核心是 docs/ddd/wifi-mat-domain-model.md——一套描述该子系统"业务真相"的 DDD 规格。
为什么要为搜救系统单独建立领域模型?仓库的 docs/ddd/README.md 给出了明确动机:DDD 将代码库围绕"要解决的问题"组织,而非围绕技术分层;每个限界上下文(bounded context)拥有自己的数据、规则与语言,上下文之间通过领域事件通信,而不是共享可变状态——这让系统更容易被推理、测试和扩展,"无论使用方是人还是 AI Agent"。WiFi-Mat 领域模型即是在此方法论下的产物,划分出Detection(检测)、Localization(定位)、Alerting(告警)三个上下文。
在代码层面,该规格已在 RuView 工作区中落地为wifi-densepose-matcrate(Cargo.toml,version 0.3.2),其src/目录结构与领域模型的边界高度对应:
- src/domain:核心领域实体与值对象(survivor、disaster_event、scan_zone、triage、vital_signs、coordinates、events 等)
- src/detection:呼吸 / 心跳 / 动作检测与集成分类(breathing、heartbeat、movement、ensemble、pipeline)
- src/localization:三角定位、深度估计与融合(triangulation、depth、fusion、range_constraint)
- src/alerting:检伤优先级计算、告警生成与分发
- src/integration:防腐层适配器(signal_adapter、neural_adapter、hardware_adapter 等)
- 另扩展有 src/tracking、src/ml 与可选 REST/WebSocket 的 src/api
下文将以领域模型规格为骨架逐一展开。
二、通用语言(Ubiquitous Language):先统一 8 个术语
DDD 的第一块基石,是让领域专家与工程师使用同一套精确词汇。该文档给出了一张术语表,它们是后续所有代码与告警内容的基础:
| 术语 | 精确定义 |
|---|---|
| Survivor | 在扫描区域内被检测到的人类,可能被困 |
| Vital Signs | 可探测的生命指示:呼吸、心跳、动作 |
| Scan Zone | 正被主动监控的一块定义地理区域 |
| Detection Event | 一次"检测到生命迹象"的发生 |
| Triage Status | 医学优先级分类(Immediate/Delayed/Minor/Deceased,即红/黄/绿/黑四级) |
| Confidence Score | 检测的统计置信度(0.0–1.0) |
| Penetration Depth | 到幸存者的瓦砾穿透距离估计 |
| Debris Field | 位于传感器与幸存者之间的障碍材料集合 |
注意这里有一个贯穿全文的领域约束:Confidence Score >= 0.3才被认为是有效检测(见后文 Survivor 不变式)。这套词汇也原样反映到了 crate 的公共 API 中,例如 src/lib.rs 直接 re-export 了Survivor、SurvivorId、TriageStatus、ConfidenceScore对应的VitalSignsReading等类型。
三、限界上下文(Bounded Contexts):三大职责边界
规格将系统切分为三个互不越界的上下文,每个上下文拥有独立的聚合根与值对象集合。
3.1 Detection Context(检测上下文)
职责:分析 CSI 数据以检测并分类人类生命迹象。
┌─────────────────────────────────────────────────────────┐ │ Detection Context │ ├─────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Breathing │ │ Heartbeat │ │ │ │ Detector │ │ Detector │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ └─────────┬─────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Movement │ │ │ │ Classifier │ │ │ └────────┬────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Ensemble │──▶ VitalSignsReading │ │ │ Classifier │ │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘该上下文的输出是聚合根VitalSignsReading,其值对象包括BreathingPattern、HeartbeatSignature、MovementProfile、ConfidenceScore。这种"呼吸 + 心跳 → 动作分类 → 集成分类"的流水线在 crate 中对应 src/detection/pipeline.rs(DetectionPipeline)与 src/detection/ensemble.rs(EnsembleClassifier),后者在 lib.rs 中被 re-export 为公共类型。
3.2 Localization Context(定位上下文)
职责:估计幸存者在废墟场中的位置。
┌─────────────────────────────────────────────────────────┐ │ Localization Context │ ├─────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ │ │ │Triangulation │ │Fingerprinting│ │ │ │ Engine │ │ Matcher │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ └─────────┬─────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Depth │ │ │ │ Estimator │ │ │ └────────┬────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Position │──▶ SurvivorLocation │ │ │ Fuser │ │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘聚合根为SurvivorLocation,值对象为Coordinates3D、DepthEstimate、LocationUncertainty、DebrisProfile。实现上对应 src/localization/triangulation.rs(三角定位)、src/localization/depth.rs(深度估计)与 src/localization/fusion.rs(PositionFuser/LocalizationService融合)。
3.3 Alerting Context(告警上下文)
职责:基于检测结果生成并分发告警。
┌─────────────────────────────────────────────────────────┐ │ Alerting Context │ ├─────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Triage │ │ Alert │ │ │ │ Calculator │ │ Generator │ │ │ └──────┬───────┘ └──────┬───────┘ │ │ │ │ │ │ └─────────┬─────────┘ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Dispatcher │──▶ Alert │ │ └─────────────────┘ │ └─────────────────────────────────────────────────────────┘聚合根Alert,值对象TriageStatus、Priority、AlertPayload。实现对应 src/alerting/triage_service.rs、src/alerting/generator.rs 与 src/alerting/dispatcher.rs。
四、核心领域实体与聚合根
规格在实体(Entity,具有身份与生命周期)与值对象(Value Object,不可变且有业务含义)之间做了严格区分。
4.1 Survivor(Entity)
幸存者是整个模型中最核心的实体,携带其从"首次被检测"到"获救/丢失"的完整状态:
pub struct Survivor { id: SurvivorId, detection_time: DateTime<Utc>, location: Option<SurvivorLocation>, vital_signs: VitalSignsHistory, triage_status: TriageStatus, confidence: ConfidenceScore, metadata: SurvivorMetadata, }规格为其明确了三条不变式(Invariants),它们是领域规则必须始终为真的底线:
- 必须至少有一次生命迹象检测才能存在(不存在"空存活者");
- 每次生命迹象更新后都必须重新计算检伤状态(Triage 不可滞后于健康状态变化);
- Confidence 必须 >= 0.3 才视为有效检测(低于此阈值的信号一律视为可疑而非幸存者)。
这些不变式在实现中有迹可循:crate 的 src/domain/survivor.rs 定义了Survivor、SurvivorId、SurvivorMetadata、SurvivorStatus,而 lib.rs 中survivor::{Survivor, SurvivorId, SurvivorMetadata, SurvivorStatus}为公共导出;lib.rs 的survivor.should_alert()表明何时需要生成告警也由幸存者实体自身的状态机决定。
4.2 DisasterEvent(Aggregate Root)
灾情事件是整场搜救行动的聚合根,一个事件可以包含多个扫描区与多个幸存者:
pub struct DisasterEvent { id: DisasterEventId, event_type: DisasterType, start_time: DateTime<Utc>, location: GeoLocation, scan_zones: Vec<ScanZone>, survivors: Vec<Survivor>, status: EventStatus, }其不变式刻画了灾情建模的边界:
- 必须至少包含一个扫描区(不允许"无区域的事件");
- 所有幸存者必须位于某个扫描区内(区域是归属的硬约束);
- 事件关闭后不能再添加幸存者(事后补登违反审计语义)。
实现位于 src/domain/disaster_event.rs,导出的DisasterEvent、DisasterEventId、DisasterType、EventStatus出现在 lib.rs。另外从源码看,lib.rs 的initialize_event负责创建事件,add_zone则把扫描区挂到当前事件下——这两步在聚合根的生存期内是有先后约束的。
4.3 ScanZone(Entity)
pub struct ScanZone { id: ScanZoneId, bounds: ZoneBounds, sensor_positions: Vec<SensorPosition>, scan_parameters: ScanParameters, status: ZoneStatus, last_scan: DateTime<Utc>, }扫描区把"在哪里搜"这一地理概念沉淀为带身份的实体,聚合了传感器位置与扫描参数。实现上 src/domain/scan_zone.rs 提供ScanParameters、ZoneBounds、ZoneStatus等类型。值得注意的是,在实际 crate 中扫描区不止是被动数据容器——lib.rs 的扫描主循环会跳过非ZoneStatus::Active的区域,这对应规格中对区域状态管理的隐含需求。
五、值对象(Value Objects)
值对象承载"有业务含义的不可变数据",规格逐一给出其结构:
5.1 VitalSignsReading
pub struct VitalSignsReading { breathing: Option<BreathingPattern>, heartbeat: Option<HeartbeatSignature>, movement: MovementProfile, timestamp: DateTime<Utc>, confidence: ConfidenceScore, }值得注意breathing与heartbeat是Option——废墟环境下并非总能同时探测到两者,这正是后续 TriageService 需要按"先呼吸后心跳"顺序推理的原因。
5.2 TriageStatus(Enumeration)
pub enum TriageStatus { Immediate, // Red tag Delayed, // Yellow tag Minor, // Green tag Deceased, // Black tag Unknown, // 数据不足,无法分类 }四条带颜色标签的检伤档位(红/黄/绿/黑)与灾难医学中的 START 协议一致:Immediate为危及生命需立即干预,Delayed为严重但可等待,Minor为可自主行动的轻伤员,Deceased为超过阈值周期未探测到生命迹象。额外保留的Unknown处理"数据不足"这一真实野外情况,避免模型把不确定性强行塞进四档。
5.3 BreathingPattern
pub struct BreathingPattern { rate_bpm: f32, // 每分钟呼吸次数(正常:12-20) amplitude: f32, // 信号强度 regularity: f32, // 0.0-1.0,节律一致性 pattern_type: BreathingType, } pub enum BreathingType { Normal, Shallow, Labored, Irregular, Agonal, }BreathingType::Agonal(濒死喘息式呼吸)是搜救领域特有的关键信号——它往往意味着伤者已极度危险,需立即升级处理。
5.4 HeartbeatSignature
pub struct HeartbeatSignature { rate_bpm: f32, // 每分钟心跳(正常:60-100) variability: f32, // 心率变异性 strength: SignalStrength, }5.5 Coordinates3D 与 LocationUncertainty
pub struct Coordinates3D { x: f64, // 相对参考点的东西向偏移(米) y: f64, // 相对参考点的南北向偏移(米) z: f64, // 地表以下深度(米,负值 = 地下) uncertainty: LocationUncertainty, } pub struct LocationUncertainty { horizontal_error: f64, // 米(95% 置信度) vertical_error: f64, // 米(95% 置信度) }规格刻意把"估计值"与"不确定性"打包进同一值对象,坐标上还显式给出 95% 置信区间,而非单个点值——这提示调用方把定位结果当概率分布看待。实现上 src/domain/coordinates.rs 提供Coordinates3D、DepthEstimate、LocationUncertainty,并出现在 lib.rs 的公共导出中。
六、领域事件(Domain Events):系统解耦的"信使"
三个上下文不直接调用彼此的内部方法,而是通过领域事件异步通信。规格定义了两组事件:
6.1 Detection Events(幸存者生命周期事件)
pub enum DetectionEvent { SurvivorDetected { survivor_id, zone_id, vital_signs, location, timestamp }, VitalsUpdated { survivor_id, previous, current, timestamp }, TriageStatusChanged { survivor_id, previous, current, reason, timestamp }, LocationRefined { survivor_id, previous, current, timestamp }, SurvivorLost { survivor_id, last_detection, reason }, } pub enum LostReason { Rescued, FalsePositive, SignalLost, ZoneDeactivated }这组事件完整覆盖了幸存者从"发现 → 体征更新 → 检伤变化 → 定位修正 → 丢失"的全生命周期。LostReason的设计特别务实:区分Rescued(已获救)、FalsePositive(误报)、SignalLost(信号丢失)与ZoneDeactivated(区域关闭),保证了事件审计的可追溯性。
6.2 Alert Events(告警生命周期事件)
pub enum AlertEvent { AlertGenerated { alert_id, survivor_id, priority, payload }, AlertAcknowledged { alert_id, acknowledged_by: TeamId, timestamp }, AlertResolved { alert_id, resolution: AlertResolution, timestamp }, }告警被建模为一段有生命周期的状态流转(生成 → 由救援队acknowledged_by签收 → 按AlertResolution解决),而非一次性通知。
在实现中,src/domain/events.rs 定义了DetectionEvent、AlertEvent,以及更上层的DomainEvent、EventStoretrait 与InMemoryEventStore(见 lib.rs)。事件确实是实际运行时的重要环节:DisasterResponse::new默认挂载一个InMemoryEventStore(lib.rs),扫描循环中每次新发现幸存者都会追加SurvivorDetected事件并视情况追加AlertGenerated事件(lib.rs)。这正是 ADR-001 中"事件驱动架构支持审计追踪、重放与多搜救队分布式部署"决策的具体形态。
七、领域服务(Domain Services):当规则不属于任何实体
有些规则横跨多个实体/值对象,不适合塞进某个对象内部,于是建模为领域服务。
7.1 TriageService:START 协议的数字化
pub trait TriageService { fn calculate_triage(&self, vitals: &VitalSignsReading) -> TriageStatus; fn should_upgrade_priority(&self, history: &VitalSignsHistory) -> bool; }其中calculate_triage依据灾难医学START(Simple Triage and Rapid Treatment)协议实现了 7 条判定规则:
- 未探测到呼吸 → 检查是否有动作;
- 有动作但无呼吸 →Immediate(气道问题);
- 呼吸 > 30 次/分 →Immediate;
- 呼吸 < 10 次/分 →Immediate;
- 无桡动脉搏动等价物(心跳微弱)→Immediate;
- 无法遵令活动(无响应性动作)→Immediate;
- 否则依据严重程度归入Delayed 或 Minor。
可以直观看出:规则的判据全部来自领域模型定义的生命迹象值对象(VitalSignsReading中的呼吸频率、心跳、动作),而优先级又与上一节的TriageStatus/Priority值对象联动。should_upgrade_priority则对应"恶化升级"的告警语义。实现对应 src/alerting/triage_service.rs,其TriageCalculator/TriageStatus也经由 lib.rs 公开。
7.2 LocalizationService:多种定位技术的融合入口
pub trait LocalizationService { fn estimate_position( &self, csi_data: &[CsiReading], sensor_positions: &[SensorPosition], ) -> Result<Coordinates3D, LocalizationError>; fn estimate_depth( &self, signal_attenuation: f64, debris_profile: &DebrisProfile, ) -> Result<DepthEstimate, LocalizationError>; }estimate_position在内部融合多 AP 三角定位与 CSI 指纹匹配,estimate_depth则依据信号衰减与瓦砾材料剖面(DebrisProfile)推算埋深。两者都返回带不确定性的领域值对象,且以领域错误类型LocalizationError表达失败,而非裸异常。
八、上下文映射与防腐层:如何与上游共存
8.1 上下文映射(Context Map)
规格给出了整系统一张图:
┌────────────────────────────────────────────────────────────────┐ │ WiFi-Mat System │ ├────────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ │ │ │ Detection │◄───────►│ Localization│ │ │ │ Context │ Partner │ Context │ │ │ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ Publishes │ Publishes │ │ ▼ ▼ │ │ ┌─────────────────────────────────────┐ │ │ │ Event Bus (Domain Events) │ │ │ └─────────────────┬───────────────────┘ │ │ │ │ │ │ Subscribes │ │ ▼ │ │ ┌─────────────┐ │ │ │ Alerting │ │ │ │ Context │ │ │ └─────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ UPSTREAM (Conformist) │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ │wifi-densepose │ │wifi-densepose │ │wifi-densepose │ │ │ │ -signal │ │ -nn │ │ -hardware │ │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ └────────────────────────────────────────────────────────────────┘规格同时用 DDD 语境明确了三种关系类型的语义差异:
- Detection ↔ Localization:Partnership(伙伴关系)——两者紧密协作,检测结果为定位提供目标,定位结果反过来辅助分类;
- Detection → Alerting:Customer/Supplier(客户/供应商)——检测发布事件,告警订阅消费,是单向的;
- WiFi-Mat → 上游 crates:Conformist(遵从者)——适配层需要顺从上游(signal/nn/hardware)已定的数据模型,而非反过来改造上游。
8.2 防腐层(Anti-Corruption Layer)
为隔离上游模型变化对本领域的影响,规格定义了两类适配器(这也是 ADR-001 中的integration/目录规划):
/// 将 wifi-densepose-signal 的类型适配到 Detection 上下文 pub struct SignalAdapter { processor: CsiProcessor, feature_extractor: FeatureExtractor, } impl SignalAdapter { pub fn extract_vital_features( &self, raw_csi: &[Complex<f64>], ) -> Result<VitalFeatures, AdapterError>; } /// 将 wifi-densepose-nn 适配为专用检测模型 pub struct NeuralAdapter { breathing_model: OnnxModel, heartbeat_model: OnnxModel, } impl NeuralAdapter { pub fn classify_breathing( &self, features: &VitalFeatures, ) -> Result<BreathingPattern, AdapterError>; }SignalAdapter负责把上游的原始复数 CSI(&[Complex<f64>])翻译成本上下文的VitalFeatures;NeuralAdapter则包装 ONNX 模型完成呼吸分类。两者统一以AdapterError作为出错边界。实际 crate 中 src/integration/signal_adapter.rs、src/integration/neural_adapter.rs 均存在,且 src/integration 下还扩展了hardware_adapter、csi_receiver(CSI 接收)、feitcsi(宽频 802.11ax CSI 记录解析)等模块。所有适配器错误经 lib.rs 的MatError::Integration(#[from] AdapterError)统一汇入 crate 级错误类型。
九、仓储接口:持久化的领域端口
规格用 async trait 定义了三个仓储端口,将持久化实现与领域逻辑隔离:
#[async_trait] pub trait SurvivorRepository { async fn save(&self, survivor: &Survivor) -> Result<(), RepositoryError>; async fn find_by_id(&self, id: &SurvivorId) -> Result<Option<Survivor>, RepositoryError>; async fn find_by_zone(&self, zone_id: &ScanZoneId) -> Result<Vec<Survivor>, RepositoryError>; async fn find_active(&self) -> Result<Vec<Survivor>, RepositoryError>; } #[async_trait] pub trait DisasterEventRepository { async fn save(&self, event: &DisasterEvent) -> Result<(), RepositoryError>; async fn find_active(&self) -> Result<Vec<DisasterEvent>, RepositoryError>; async fn find_by_location(&self, location: &GeoLocation, radius_km: f64) -> Result<Vec<DisasterEvent>, RepositoryError>; } #[async_trait] pub trait AlertRepository { async fn save(&self, alert: &Alert) -> Result<(), RepositoryError>; async fn find_pending(&self) -> Result<Vec<Alert>, RepositoryError>; async fn find_by_survivor(&self, survivor_id: &SurvivorId) -> Result<Vec<Alert>, RepositoryError>; }值得注意的三个查询方法分别对应搜救现场的高频需求:find_active(当前还有哪些幸存者/事件)、find_by_location(radius_km)(按地理位置圈定附近灾情,便于多团队协作)、find_pending(未处理告警队列)。在实现层面,crate 的 src/domain/events.rs 提供了EventStoretrait 与内存实现InMemoryEventStore,并且 lib.rs 的DisasterResponse::with_event_store允许调用方注入自定义持久化实现(如数据库或测试用实现),体现了"面向端口编程"的一致思想。
十、从规格到运行时:一次扫描周期的事件流
将上面的规格拼装起来,就能在 crate 的真实实现中看到模型是如何运转的。DisasterResponse(src/lib.rs)是面向调用方的主协调器,聚合了DetectionPipeline、LocalizationService、AlertDispatcher、EventStore、EnsembleClassifier与SurvivorTracker。其scan_cycle(lib.rs)恰好走完一遍"领域事件流水线":
- 遍历事件下所有
Active扫描区; - 对每个区域调用
DetectionPipeline::process_zone得到潜在VitalSignsReading; EnsembleClassifier集成呼吸/心跳/动作得到集成置信度;- 只有当
ensemble_result.confidence >= confidence_threshold时才触发LocalizationService::estimate_position定位; - 对达标检测调用
event.record_detection(...)更新聚合根,并写入SurvivorDetected领域事件; - 若
survivor.should_alert(),则AlertDispatcher生成并分发告警,同时写入AlertGenerated领域事件。
数据入口在 lib.rs 的push_csi_data:它要求振幅与相位数组等长且非空,否则返回领域错误。启动与停止则通过 start_scanning(依据continuous_monitoring与scan_interval_ms决定是否循环)与stop_scanning控制。
最小的使用示例可见 crate 文档注释与 docs/wifi-mat-user-guide.md:
use wifi_densepose_mat::{ DisasterResponse, DisasterConfig, DisasterType, ScanZone, ZoneBounds, }; #[tokio::main] async fn main() -> anyhow::Result<()> { let config = DisasterConfig::builder() .disaster_type(DisasterType::Earthquake) .sensitivity(0.85) .confidence_threshold(0.5) .max_depth(5.0) .continuous_monitoring(true) .build(); let mut response = DisasterResponse::new(config); response.initialize_event( geo::Point::new(-122.4194, 37.7749), "Building collapse - Market Street", )?; let zone = ScanZone::new( "North Wing - Ground Floor", ZoneBounds::rectangle(0.0, 0.0, 30.0, 20.0), ); response.add_zone(zone)?; response.start_scanning().await?; let survivors = response.survivors(); println!("Detected {} potential survivors", survivors.len()); let immediate = response.survivors_by_triage(TriageStatus::Immediate); println!("{} survivors require immediate rescue", immediate.len()); Ok(()) }其中DisasterConfig的完整字段与默认值在 lib.rs:sensitivity默认 0.8、confidence_threshold默认 0.5、max_depth默认 5.0 米、scan_interval_ms默认 500ms、continuous_monitoring默认开启;Builder 对sensitivity/confidence_threshold做了 0.0–1.0 的 clamp(lib.rs),对scan_interval_ms限制不小于 100ms。
十一、能力边界与阅读路线
理解这套领域模型时也应记住它的边界。ADR-001 中给出的检测时延 <500ms、误报率 <5%、漏报率 <1%、穿透深度 3–5m 等属于架构设计目标而非已测结果;docs/wifi-mat-user-guide.md 的 Safety Considerations 也明确提醒:WiFi-Mat 是辅助搜救的工具,阴性结果不能证明无幸存者,必须配合声学探测、搜救犬、热成像与人工排查等手段交叉验证,并在清除瓦砾后复扫。
希望继续深入时,推荐按此路线阅读:
- 领域模型规格:docs/ddd/wifi-mat-domain-model.md
- DDD 方法总览与其他子系统模型:docs/ddd/README.md
- 架构决策(背景、性能目标、风险与缓解):docs/adr/ADR-001-wifi-mat-disaster-detection.md
- 操作级用户指南(配置、部署、API 参考、疑难排查):docs/wifi-mat-user-guide.md
- 完整 crate 源码:v2/crates/wifi-densepose-mat(入口见 src/lib.rs)
小结
WiFi-Mat 的领域模型示范了如何把「CSI 穿墙感知 + 灾难搜救」这一高复杂、高不确定性的现实问题,翻译成一套边界清晰、语言统一、可独立测试的软件模型:三个限界上下文各司其职,聚合根与值对象承载领域不变量,领域事件驱动上下文间协作,防腐层将上游信号/神经网络/硬件 crate 的模型变化隔离在外。规格中的每一处设计——从Confidence >= 0.3才有效、Unknown检伤档位,到LostReason::FalsePositive、Deceased须经阈值周期确认——都在回答同一个问题:在"宁可错报、不可漏报"的搜救伦理与物理信号的不确定性之间,软件应如何诚实地建模。
【免费下载链接】RuViewπ RuView turns commodity WiFi signals into real-time spatial intelligence, vital sign monitoring, and presence detection — all without a single pixel of video.项目地址: https://gitcode.com/GitHub_Trending/wi/RuView
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考