Source Code Learning Guide · 2026-09

RuView 源码原理与实现技术过程

面向工程实现的学习手册:从 WiFi CSI 物理基础,一路追踪到 ESP32 固件、Rust DSP、边缘 Vitals、Sensing Server、模型训练与 UI,再给出一个可以真正动手复现的 Mini-RuView 路线。

ESP32-S3 / C6WiFi CSIRust DSPAxumWebSocket PyO3RVF / WASM
先给结论:不要把 RuView 当成“一个 DensePose 模型仓库”。它本质上是一个完整的 RF 感知平台:采集硬件 + CSI 协议 + DSP + 边缘推断 + 服务端聚合 + 模型训练 + UI/自动化。真正适合学习的入口,是先复现 Presence/Vitals,再进入 Pose 与多节点融合。
01

项目判断:RuView 到底是什么

RuView 将 WiFi 无线信道从“通信链路”变成“空间传感器”。ESP32 读取每个 OFDM 子载波的 Channel State Information(CSI),人体移动、呼吸、姿态变化会改变多径传播路径,使复数信道响应 H(k,t) 的幅度与相位随时间产生可测扰动。

SensorESP32 捕获 I/Q 与 CSI
DSPPhase / Variance / Filter / FFT
InferencePresence / Vitals / Motion / Pose
能力当前实现方式工程判断
CSI 采集与 UDPESP32-S3/C6 + ESP-IDF CSI API + ADR-018 二进制帧核心可复现
Presence相位方差 + 自适应阈值,也可加载学习模型核心可复现
呼吸0.1–0.5 Hz 带通 + 零交叉 / Rust vitals pipeline实验性,需校准
心率0.8–2.0 Hz 带通 + 自相关/相干性加权实验性,非医疗测量
Fall / Motion相位加速度、运动能量等启发式可运行但依赖环境
17 点 PoseCandle / RVF / 训练流水线;仓库标注实时单节点模型仍 first-cut研究/开发中
多节点 / World Model多静态融合、图模型、OccWorld、RuField 等高级研究层
02

WiFi CSI 原理:为什么无线信号能“看到”人

2.1 CSI 是什么

OFDM WiFi 会把带宽拆成多个子载波。每个子载波都有一个复数信道响应:

H(k,t) = A(k,t) · exp(j · φ(k,t))

A = √(I² + Q²)            # 幅度
φ = atan2(Q, I)           # 相位

人体出现后,直达路径、反射路径和绕射路径一起变化。结果不是“看到图像”,而是观察到 一组高维、随时间变化的无线通道特征。

幅度变化

身体移动导致衰落、遮挡、多径叠加改变,适合检测运动强度、粗粒度 presence。

相位变化

对微小路径长度变化更敏感,适合呼吸、微动、速度/多普勒等分析,但需要 unwrap 与去噪。

关键认知:“穿墙检测”不是 X 光。系统测量的是 RF 传播场被人体扰动后的统计/时序变化,效果强烈依赖 AP/节点位置、墙体材料、信道、干扰、采样率与训练域。
03

总体架构:从 ESP32 到浏览器的完整链路

① WiFi AP / 空间
人体改变多径传播路径
↓
② ESP32 CSI Node
ESP-IDF CSI callback → I/Q → ADR-018 UDP;可在 Core 1 做 Edge DSP
↓
③ wifi-densepose-hardware
解析帧、节点状态、时间戳、幅相转换、硬件归一化
↓
④ wifi-densepose-signal / vitals
Phase sanitize → feature → motion / presence / breathing / HR
↓
⑤ sensing-server
Axum + Tokio:UDP 输入、状态机、模型、REST、WebSocket、MQTT/Matter
↓
⑥ UI / Home Assistant / Python / Agent
实时可视化、自动化、记录、训练、模型加载、语义事件
工程上要把 RuView 看成 两条并行数据平面:A)Raw CSI → 主机 DSP;B)ESP32 Tier 2 本地 DSP → 32-byte Vitals Packet。后者能显著降低带宽与延迟。
04

ESP32 固件:采集层是整个系统的地基

firmware/esp32-csi-node/
main/main.c — 启动、WiFi、CSI、任务
main/csi_collector.c — CSI callback / 序列化
main/stream_sender.c — UDP 发送 / ENOMEM backoff
main/nvs_config.c — SSID、目标 IP、edge tier 等
main/edge_processing.c — Core 1 DSP
Phase unwrap → Welford → Top-K
Biquad → BPM → Presence → Fall
main/wasm_runtime*.c — Tier 3 可编程感知

4.1 Raw CSI 帧(ADR-018)

0..3    u32  magic = 0xC5110001
4       u8   node_id
5       u8   n_antennas
6..7    u16  n_subcarriers
8..11   u32  channel/frequency metadata
12..15  u32  sequence
16      i8   RSSI
17      i8   noise floor
18..19       flags / reserved
20..N        I/Q pairs

最小实现最重要的不是“复杂算法”,而是让 帧格式、字节序、序列号、采样节奏稳定,否则后面所有信号算法都会被脏数据拖垮。

4.2 为什么固件要双核

CSI callback 位于 WiFi 路径,不能做重计算。RuView 将采集和 DSP 解耦:Core 0 只采集/入环形缓冲区,Core 1 处理 phase、variance、filter。这种结构避免 WiFi 任务因为 DSP 阻塞而丢包。

Core 0: WiFi CSI callback
    ↓  enqueue
SPSC Ring Buffer
    ↓
Core 1: phase → stats → filters → events
实机里最常见的问题不是算法,而是 sendto() 太频繁导致 lwIP pbuf 耗尽。仓库使用速率限制 + ENOMEM backoff。学习实现时务必先做吞吐/丢包监控。
05

Rust 信号处理:CSI 如何变成可用特征

5.1 数据模型

wifi-densepose-signal::CsiData 将原始数据统一成 amplitude[antenna, subcarrier] 与 phase[antenna, subcarrier],然后所有算法围绕同一数据结构运行。

Raw I/Q
i8 / complex samples
↓
Amplitude + Phase
sqrt(I²+Q²), atan2(Q,I)
↓
PhaseSanitizer
unwrap → outlier remove → smoothing
↓
FeatureExtractor
Amplitude / Phase / Correlation / Doppler / PSD
↓
Detector / Model
motion / presence / activity / pose
特征源码意义
Amplitude mean / variance / RMSfeatures.rs整体衰落、活动能量
Phase difference / gradientfeatures.rs空间/频域变化
Phase coherencefeatures.rs不同天线/子载波的一致性
PSDfeatures.rs周期性运动、呼吸频段
Dopplerfeatures.rs / ruvsense运动速度方向线索
Fresnel / CIR / BVPfresnel.rs / cir / bvp.rs更高级空间与时序建模

5.2 相位为什么必须 sanitize

atan2 输出被限制在 [-π, π],真实连续相位跨过边界时会突然跳 2π。如果不 unwrap,速度、呼吸频率、相位加速度都会出现伪峰值。

raw:       2.9, 3.0, 3.1, -3.1, -3.0
unwrap:    2.9, 3.0, 3.1,  3.18, 3.28
06

Presence / 呼吸 / 心率:最值得先复现的算法

6.1 Presence

最简单可靠的学习版本可以只做“空房校准 + 相位方差”。RuView 的 Edge Pipeline 使用 Welford 在线统计维护均值/方差,并采用约 1200 帧、3σ 的自适应阈值。

# 空房标定
μ0, σ0 = running_stats(phase_variance)

# 在线
score = current_variance
presence = score > μ0 + 3 * σ0

这不是“识别人”,而是“检测 RF 场相对空房基线是否出现明显扰动”。风扇、门、微波炉、AP 发射功率变化都可能产生误报。

6.2 呼吸

静止人体胸腔周期运动会在 CSI 中形成低频扰动。

residual
  ↓
bandpass 0.1–0.5 Hz
  ↓
zero crossing / period
  ↓
BPM = cycles/min

6.3 心率

频率更高、幅度更弱,因此比呼吸难得多。

residual
  ↓
bandpass 0.8–2.0 Hz
  ↓
autocorrelation
+ phase coherence weight
  ↓
HR estimate

6.4 Rust vitals crate 四阶段

  1. CsiVitalPreprocessor:EMA 去除静态分量;
  2. BreathingExtractor:0.1–0.5 Hz 带通 + 零交叉;
  3. HeartRateExtractor:0.8–2.0 Hz 带通 + 自相关 + 子载波相干性加权;
  4. VitalAnomalyDetector:Welford Z-score 做趋势/异常检测。
注意:这些 Vitals 输出应作为实验性 RF sensing 指标使用,不应直接等价为医疗级生命体征。真正验证必须使用同步参考设备、标注时间线与误差统计。
07

Sensing Server:系统真正的“中枢”

v2/crates/wifi-densepose-sensing-server/src/main.rs 是单二进制部署面。它用 Axum + Tokio 把底层 CSI、模型、训练、状态和 UI 统一起来。

UDP :5005HTTPWS :8765MQTTMatterRVF
模块职责
csi输入 CSI 数据源与解析
vital_signs生命体征检测
pose / pose_physics姿态模型与物理约束
adaptive_classifier环境自适应分类
training_api / trainer记录、训练、进度与模型生成
rvf_container / rvf_pipeline模型/模块容器与渐进加载
multistatic_bridge多节点融合
field_bridge统一 RF field / provenance surface
学习源码时,不建议从 main.rs 第一行顺读到最后。更有效的方式是沿数据流追踪:UDP receive → frame parse → AppState → detector/model → broadcast → WebSocket JSON。
08

模型与姿态:为什么不能一上来就做 DensePose

Pose 的目标是学习映射:

CSI time window
    ↓
Encoder / embedding
    ↓
spatial-temporal representation
    ↓
17 keypoints / pose state

但真正难点是 监督数据:需要 WiFi CSI 与摄像头/动作捕捉标签严格时间对齐。单房间、单 AP、单人的训练数据通常会产生很强的域过拟合。

层级建议
阶段 A先复现 Presence / Motion,确认采集链路可靠。
阶段 B学习 128-d embedding / contrastive pretraining,先做环境与动作分类。
阶段 C采集同步 Camera + CSI 数据,训练 17-keypoint head。
阶段 D跨房间、跨设备、跨人物 domain adaptation。
仓库 README 已主动区分:公开 MM-Fi benchmark 的高分,和当前 live 单 ESP32 on-device pose 模型不是同一个能力。技术学习时要把“benchmark 模型”“运行时实现”“实机验证”三件事分开。
09

源码地图:按学习价值排序

RuView/
firmware/esp32-csi-node/
main/csi_collector.c ← 第一优先
main/edge_processing.c ← 第一优先
v2/crates/wifi-densepose-hardware/
src/csi_frame.rs / esp32 parser ← 第二优先
v2/crates/wifi-densepose-signal/
csi_processor.rs / phase_sanitizer.rs
features.rs / motion.rs / ruvsense/*
v2/crates/wifi-densepose-vitals/ ← 第三优先
v2/crates/wifi-densepose-sensing-server/ ← 第四优先
python/ ← PyO3 / client 使用
ui/ ← 可视化
docs/adr/ ← 理解决策与演进

推荐阅读顺序

README → user-guide → ADR-018 → firmware README → csi_collector → csi_frame → phase_sanitizer → features → vitals → sensing-server。

不要先读 100+ Cogs、World Model、Matter、Agent、HomeKit 等外围模块。那会稀释对核心 RF sensing pipeline 的理解。

10

先跑通项目:无硬件与有硬件两条路径

10.1 无硬件:Docker / 模拟数据

docker pull ruvnet/wifi-densepose:latest
docker run -p 3000:3000 -p 5005:5005/udp \
  -e CSI_SOURCE=simulated \
  ruvnet/wifi-densepose:latest

目标不是验证“WiFi 能看人”,而是先理解 UI、API、WebSocket 消息、状态结构和完整软件链。

10.2 Rust 源码运行

git clone https://github.com/ruvnet/RuView.git
cd RuView/v2

cargo build --release
cargo test --workspace --no-default-features

cargo run -p wifi-densepose-sensing-server -- \
  --http-port 3000 \
  --source simulate

10.3 ESP32-S3 实机

# 1. ESP-IDF 构建
cd firmware/esp32-csi-node
idf.py set-target esp32s3
idf.py build

# 2. flash
idf.py -p /dev/ttyUSB0 flash

# 3. 写入 WiFi 与 server IP
python provision.py \
  --port /dev/ttyUSB0 \
  --ssid "YOUR_WIFI" \
  --password "YOUR_PASS" \
  --target-ip 192.168.1.20

# 4. server
cd ../../v2
cargo run -p wifi-densepose-sensing-server -- \
  --source esp32 \
  --udp-bind 0.0.0.0 \
  --udp-allow 192.168.1.0/24
11

从零实现一个 Mini-RuView:建议的工程过程

PHASE 1 · 数据协议
先用 Python 生成假的 CSI UDP 帧

定义 20-byte header + I/Q payload,写 sender/receiver,验证 sequence、丢包和 endian。不要碰算法。

PHASE 2 · CSI 数学
实现 I/Q → amplitude / phase

写单元测试:I=3,Q=4 → amplitude=5;phase 使用 atan2。然后加入 unwrap。

PHASE 3 · Presence MVP
做空房 baseline + variance threshold

保存 30–60 秒空房统计,计算 μ + kσ。先实现二分类 presence,而不是 pose。

PHASE 4 · ESP32 真 CSI
替换 synthetic source

ESP-IDF CSI callback 将 I/Q 以 UDP 发送。对比 synthetic 与 real 的 parser 行为是否一致。

PHASE 5 · Vitals
加入 EMA + Biquad + 呼吸频段

先呼吸,后心率。每次只加入一个滤波器,并用离线录制数据验证频谱。

PHASE 6 · Server / UI
Rust Axum + WebSocket

将 detector 输出统一为 JSON event,UI 只订阅状态,不直接理解底层 CSI。

11.1 Mini-RuView 最小目录

mini-ruview/
├── firmware/
│   └── esp32/
│       ├── main.c
│       ├── csi.c
│       └── udp.c
├── server/
│   ├── protocol.rs
│   ├── csi.rs
│   ├── phase.rs
│   ├── presence.rs
│   ├── vitals.rs
│   └── main.rs
├── simulator/
│   └── synth_csi.py
├── ui/
│   └── index.html
└── tests/
    ├── protocol/
    └── signals/

11.2 MVP 的核心 Rust 逻辑

// 伪代码
loop {
    let packet = udp.recv().await?;
    let frame = parse_adr018(packet)?;

    let amp = iq_to_amplitude(&frame.iq);
    let phase = iq_to_phase(&frame.iq);
    let clean = unwrap_and_smooth(phase);

    baseline.update_if_calibrating(&clean);
    let score = phase_variance(&clean);

    let presence = score > baseline.mean + 3.0 * baseline.std;

    ws.broadcast(json!({
        "type": "sensing_update",
        "node": frame.node_id,
        "presence": presence,
        "score": score
    }));
}
12

学习路线:按 4 周掌握核心技术

周重点产出
Week 1OFDM / CSI / I-Q / amplitude / phase / FFT / 滤波Python notebook:合成 CSI + 频谱 + unwrap
Week 2Rust 数据结构、UDP、ADR-018、signal crate自己的 Rust CSI parser + presence detector
Week 3ESP-IDF CSI、SPSC、UDP、NVS、采样稳定性ESP32 → PC 实时 CSI 流
Week 4Vitals、Axum、WebSocket、校准和实机评估Mini-RuView Dashboard
如果目标是“真正理解 RuView”,最重要的 5 个关键词是:CSI、Phase Sanitization、Adaptive Baseline、Temporal Filtering、Domain Shift。
13

调试与验证:RF 项目最容易踩坑的地方

现象优先排查
完全没有 CSIESP-IDF CSI enable、promiscuous/management traffic、板型 overlay、WiFi channel
UDP 收不到目标 IP、同子网、路由器 WiFi↔LAN 隔离、防火墙、bind 地址
Presence 常亮空房 baseline 不干净、风扇/门/路由器变化、阈值过低
呼吸 BPM 飘采样率假设错误、窗口太短、subject motion、带通参数
心率随机SNR 不足、位置不佳、没有相干性权重、运动伪影
模型训练很好、换房间失效典型 domain shift:环境多径被模型记住

必须记录的工程指标

CSI callbacks/s UDP sent/s drop rate RSSI / noise floor subcarrier count effective sample rate baseline variance presence score filter latency
14

二次开发方案:从“会跑”升级到“有产品价值”

A. 家庭 Presence

单节点/双节点,重点做校准、抗干扰、状态机、Home Assistant。技术难度最低,最适合产品 MVP。

B. 睡眠呼吸

固定床位 + 位置约束,持续采样,做呼吸趋势与异常,而非追求瞬时心率。

C. 多房间跟踪

每房间多个节点,使用时间同步、节点图与 transition state,难点是标定和跨房间关联。

D. Pose Research

CSI+摄像头同步数据集、对比学习预训练、关键点 head、跨环境 adaptation。投入最大。

推荐的产品化优先级

Presence → Motion → Room Activity → Breathing Trend → Fall Risk → Multi-room → Pose。

这是按“可验证性 / 数据需求 / 泛化难度”排序,而不是按视觉炫酷程度排序。

15

能力边界与隐私设计

  • RF sensing 不是稳定成像。房型、家具、AP、节点朝向都会改变多径场。
  • 训练集 benchmark ≠ 现场准确率。必须给出数据集、split、环境与硬件条件。
  • 多人的可分离性明显更难。单天线/少节点情况下尤其受限。
  • 生命体征需要参考设备验证。不要把实验性 BPM 输出当医疗结论。
  • 隐私风险是真实的。无需摄像头不等于无需授权;部署应明确告知、限制采集范围、最小化原始 CSI 保存,并优先本地处理。
16

关键源码与文档入口

GitHub · ruvnet/RuView

docs/user-guide.md — 安装、运行、数据源与训练入口

firmware/esp32-csi-node — ESP32 CSI 采集与 Edge DSP

ADR-018 — CSI 二进制协议与实现顺序

ADR-039 — ESP32 Edge Intelligence

wifi-densepose-signal — CSI / phase / features

wifi-densepose-vitals — 呼吸与心率

wifi-densepose-sensing-server — 运行时中枢

源码快照:本文分析基于仓库 main 分支在 2026-09-16 的最新可见提交 dd02efe... 附近代码。RuView 迭代非常快,实际运行前建议再次核对 README、firmware release 与相关 ADR。
← 返回内容索引