首页
/ RuView ESP32 CSI 传感网格:从节点固件到汇聚端的分布式无摄像感知落地指南

RuView ESP32 CSI 传感网格:从节点固件到汇聚端的分布式无摄像感知落地指南

2026-09-07 13:25:04作者:蔡怀权

本文基于仓库架构决策记录 ADR-012,详解 RuView 如何用单价约 5–15 美元的 ESP32/ESP32-S3 构建可复现的多节点 CSI(信道状态信息)传感网格,打通"物理 WiFi 硬件 → CSI 字节流 → Rust/Python 处理管线"的完整数据通路。读完你将掌握 ESP-IDF CSI 采集三函数、节点固件与 UDP 汇聚端的分工、特征级融合规避跨节点时钟漂移的设计方法,以及从克隆固件、烧录、配置到实机验证的完整落地流程。

一、背景:硬件现实缺口与决策动机

ADR-012 是 RuView(WiFi-DensePose 演进体系)在硬件接入层面的关键架构决策。当时系统的 Rust 与 Python 管线已经实现了真实的信号处理(FFT、相位解缠、多普勒提取、相关特征),但缺少一条从物理 WiFi 硬件到 CSI 字节流再到管线输入的明确路径——csi_extractor.pyrouter_interface.py 仍是返回 np.random.rand() 的占位解析器(该问题在 ADR-011 中被称为"硬件现实缺口")。

要闭合这个缺口,需要选择一个具体、廉价、可复现的硬件平台来产生真实 CSI 数据,并把数据流入现有管线。

候选平台对比:为什么是 ESP32

ADR-012 将 ESP32/ESP32-S3 与两款经典科研网卡做了横向对比:

因素 ESP32/ESP32-S3 Intel 5300(iwl5300) Atheros AR9580
成本 约 5–15 美元/节点 约 50–100 美元(二手网卡) 约 30–60 美元(二手网卡)
可得性 大规模量产、现货充足 已停产,仅 eBay 有售 已停产,仅 eBay 有售
CSI 支持 官方 ESP-IDF API Linux CSI Tool(内核补丁) Atheros CSI Tool
形态 独立 MCU 需要 PCIe/Mini-PCIe 主机 需要 PCIe 主机
部署方式 电池/USB、无线 仅限台式机/笔记本 仅限台式机/笔记本
天线配置 1–2 TX、1–2 RX 3 TX、3 RX(MIMO) 3 TX、3 RX(MIMO)
子载波数 52–56(802.11n) 30(压缩) 56(完整)
保真度 较低(消费级 SoC) 较高(专用网卡) 较高(专用网卡)

结论很明确:ESP32 在"可部署性"上胜出。Intel 5300 与 Atheros 网卡需要特定主板、内核修改与老旧操作系统;而 ESP32 是唯一"陌生人可以从电商买几块板子、下午烧录固件、当晚就能跑起 CSI 网格"的选项。当然,文档也如实指出其保真度低于科研级网卡,这一代价由网格的空间分集来弥补。

二、ESP-IDF 官方 CSI 接口:三个函数打通采集链路

ESP32 的 CSI 采集能力由 Espressif 的 ESP-IDF 官方 API 提供,ADR-012 给出了最核心的三步配置:

// 1. 配置要采集的 CSI 数据
wifi_csi_config_t csi_config = {
    .lltf_en = true,         // Long Training Field(对 CSI 最有利)
    .htltf_en = true,        // HT-LTF
    .stbc_htltf2_en = true,  // STBC HT-LTF2
    .ltf_merge_en = true,    // 合并 LTFs
    .channel_filter_en = false,
    .manu_scale = false,
};
esp_wifi_set_csi_config(&csi_config);

// 2. 注册 CSI 数据接收回调
esp_wifi_set_csi_rx_cb(csi_data_callback, NULL);

// 3. 使能 CSI 采集
esp_wifi_set_csi(true);

// 回调收到的内容:
void csi_data_callback(void *ctx, wifi_csi_info_t *info) {
    // info->rx_ctrl: RSSI、noise_floor、channel、secondary_channel 等
    // info->buf: 原始 CSI 数据(每个子载波一组 I/Q 对)
    // info->len: CSI 数据缓冲区长度
    // 典型值:112 字节 = 56 个子载波 × 2 (I,Q) × 每项 1 字节
}

在仓库的实际固件中,这套逻辑位于 csi_collector.c

  • 代码以编译期断言强制要求 CONFIG_ESP_WIFI_CSI_ENABLED 打开(见 ADR-057 思路),否则直接 #error 阻止编译,避免"编过了但运行时报 CSI not enabled in menuconfig!"这类令人困惑的失败;
  • 回调以 100–500 Hz 频率触发,为防 lwIP pbuf 耗尽,代码实现了 50 Hz 速率限制(距上次成功 sendto() 不足 20 ms 的帧被静默丢弃)与 ENOMEM 退避sendto() 返回 errno 12 时暂停发送 100 ms)两道保护;
  • 回调内还做了防御性拷贝:把 NVS 配置字段与 MAC 过滤配置复制为模块级静态量,规避 wifi_init_sta()g_nvs_config 的破坏导致 LoadProhibited 崩溃(源码注释记录了 80:b5:4e:c1:be:b8 设备上的实测案例)。

三、总体架构:从 3–6 个节点到可视化

ADR-012 确立的架构决策是:以 ESP32 CSI 传感网格作为主要硬件接入路径,建立从固件到汇聚端、再到 Rust 管线与可视化的全栈体系

┌─────────────────────────────────────────────────────────────────────┐
│                   ESP32 CSI Sensor Mesh                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐                          │
│  │ ESP32    │  │ ESP32    │  │ ESP32    │  ... (3-6 nodes)         │
│  │ Node 1  │  │ Node 2  │  │ Node 3  │                          │
│  │          │  │          │  │          │                          │
│  │ CSI Rx   │  │ CSI Rx   │  │ CSI Rx   │  ← WiFi frames from     │
│  │ FFT      │  │ FFT      │  │ FFT      │     consumer router     │
│  │ Features │  │ Features │  │ Features │                          │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘                          │
│       │              │              │                                │
│       │    UDP/TCP stream (WiFi or secondary channel)               │
│       │              │              │                                │
│       ▼              ▼              ▼                                │
│  ┌─────────────────────────────────────────┐                        │
│  │           Aggregator                     │                        │
│  │  (Laptop / Raspberry Pi / Seed device)  │                        │
│  │  1. Receive CSI streams from all nodes  │                        │
│  │  2. Timestamp alignment (per-node)       │                        │
│  │  3. Feature-level fusion                │                        │
│  │  4. Feed into Rust/Python pipeline      │                        │
│  │  5. Serve WebSocket to visualization    │                        │
│  └──────────────────┬──────────────────────┘                        │
│                      │                                               │
│                      ▼                                               │
│  ┌─────────────────────────────────────────┐                        │
│  │        WiFi-DensePose Pipeline           │                        │
│  │  CsiProcessor → FeatureExtractor →      │                        │
│  │  MotionDetector → PoseEstimator →       │                        │
│  │  Three.js Visualization                 │                        │
│  └─────────────────────────────────────────┘                        │
└─────────────────────────────────────────────────────────────────────┘

三条软件路径的当前落地状态

ADR-012 声明状态为"Accepted — Partially Implemented",其后续执行由 ADR-018 细化。对照当前仓库,各层均已落地到具体源码:

  1. 固件层 firmware/esp32-csi-node/:完整的 ESP-IDF 工程(当前 README 标注 ESP-IDF v5.4、支持 ESP32-S3 生产目标与 ESP32-C6 研究目标),main/ 下由 main.c(入口、NVS 初始化、WiFi 初始化)、csi_collector.c(采集 + ADR-018 二进制序列化 + 信道跳频)、nvs_config.c(Kconfig 默认值 + NVS 运行时覆盖)、stream_sender.c(UDP 发送)等模块组成,并有 edge_processing.cwasm_runtime.cmock_csi.c 等后续演进模块;
  2. 解析器与汇聚端 wifi-densepose-hardware cratesrc/esp32_parser.rs 实现 ADR-018 二进制帧解析(含 magic 校验、n_subcarriers≤512 边界检查、parse_stream() 的流重同步),src/aggregator/mod.rs 实现 UDP 汇聚二进制,src/csi_frame.rs 定义 CsiFrame/CsiMetadata/SubcarrierData 并实现 to_amplitude_phase()src/bridge.rs 完成 CsiFrame → CsiData 到信号管线的桥接;
  3. Python 侧真实数据入口:ADR-018 中规划以 UDP socket 实现替换 Python 硬件层 NotImplementedError 桩(原始 v1 归档位于 archive/v1/src/hardware/csi_extractor.py)。

四、节点固件规范:结构与关键设计决策

ADR-012 规划了固件工程的文件结构(当前仓库已按此落地并大幅演进):

firmware/esp32-csi-node/
├── CMakeLists.txt
├── sdkconfig.defaults      # Menuconfig 默认值(CSI 使能)
├── main/
│   ├── main.c              # 入口、NVS 配置、WiFi 初始化、CSI 回调
│   ├── csi_collector.c     # CSI 采集、混杂模式、ADR-018 序列化
│   ├── nvs_config.c        # 来自 NVS 的运行时配置(WiFi 凭据、目标 IP)
│   ├── stream_sender.c     # 向汇聚端发送 UDP 流
│   └── Kconfig.projbuild   # Menuconfig 选项
└── README.md               # 烧录说明(已验证可用)

当前固件 README 将处理管线组织为四层可配置分级(tier),这是对 ADR-012 的重要演进:

Tier 名称 状态 内容
Tier 0 原始 CSI 透传 Stable(默认) 将驱动回调中的 CSI 帧按 ADR-018 格式 UDP 上报,约 20 pps/信道,20 字节头 + 每子载波每天线 2 字节 I/Q
Tier 1 基础 DSP Stable 相位解缠、Welford 滑动统计、Top-K 高方差子载波选择、XOR+RLE 差分压缩(约省 70% 带宽)
Tier 2 完整边缘管线 Stable 呼吸/心率带通、存在性检测、跌倒检测、多目标槽计数、1 Hz 32 字节 vitals 包
Tier 3 WASM 可编程感知 Alpha 通过 HTTP 上传签名 RVF 容器中的 WASM 模块,热切换算法无需重新烧录

关于"机载特征提取"的设计反转

ADR-012 原文规划了一个约 470 字节/帧的机载特征帧结构(csi_feature_frame_t,含 amplitude[56]、phase[56]、doppler_energy、breathing_band 等),并据此估算带宽:100 Hz × 470 B ≈ 47 KB/s/节点,6 节点约 280 KB/s。

ADR-018 明确推翻了这一可选路径(文档自注"contradicting ADR-012's optional feature extraction path"):机载 FFT 不做,固件只负责把原始 I/Q 按 ADR-018 二进制格式流式上传,特征提取交给 Rust 汇聚端复用成熟的 wifi-densepose-signal 管线。理由有两个:

  1. 原始 I/Q 在 ESP32 采样率下足够便宜(约 100 Hz × 56 子载波 ≈ 35 KB/s/节点,ADR-018 进一步指出 3 天线 56 子载波全速下约 210 KB/s,LAN 内完全可行);
  2. 让固件保持精简(ADR-012 规划把固件 C 代码压在 200 行以内),把质量敏感的特征工程全部集中在宿主侧。

这套"瘦固件 + 胖汇聚端"的分层在源码中得到印证:固件侧的 csi_collector.c 只负责把 wifi_csi_info_t 转成定长二进制帧并交给 stream_sender,而 DSP 全部位于 Rust crate 与 Tier 1/2 的边缘处理代码中。

固件关键设计决策(ADR-012 原述)

  1. 机载特征提取:原始 CSI I/Q → 幅值 + 相位 + 频谱带,把每帧带宽从原始约 11 KB 压到约 470 字节(该方案当前已被 ADR-018 的原始 I/Q 透传取代,见上);
  2. 单调时钟时间戳:每节点用自己的单调时钟,不做跨节点 NTP 同步——时钟漂移交由汇聚端以特征融合而非原始相位融合来消化(见下节);
  3. UDP 流式传输:低延迟、容忍丢包,缺失帧可接受,顺序靠序列号维持;
  4. 可配置采样率:10–100 Hz(menuconfig),100 Hz 用于运动检测,10 Hz 对占用检测已足够。

五、汇聚端设计:多节点 UDP 聚合与状态跟踪

ADR-012 为汇聚端定义了核心 Rust 类型(规划于 wifi-densepose-hardware/src/esp32/,当前实际实现在 v2/crates/wifi-densepose-hardware/src/aggregator/mod.rs):

pub struct Esp32Aggregator {
    /// UDP 套接字,监听节点数据流
    socket: UdpSocket,

    /// 每节点状态(最后时间戳、特征缓冲、漂移估计)
    nodes: HashMap<u8, NodeState>,

    /// 融合特征帧的环形缓冲
    fused_buffer: VecDeque<FusedFrame>,

    /// 到管线的通道
    pipeline_tx: mpsc::Sender<CsiData>,
}

/// 一个时间窗内所有节点的融合帧
pub struct FusedFrame {
    /// 时间戳(汇聚端本地单调时钟)
    timestamp: Instant,

    /// 每节点特征(节点掉线时允许空缺)
    node_features: Vec<Option<CsiFeatureFrame>>,

    /// 跨节点相关(由汇聚端计算)
    cross_node_correlation: Array2<f64>,

    /// 融合运动能量(各节点取最大)
    fused_motion_energy: f64,

    /// 融合呼吸带(相位对齐处做相干求和)
    fused_breathing_band: f64,
}

在 ADR-018 的实现版本中,汇聚端主循环更加聚焦:recv_from() 收到 UDP 包后交给 Esp32CsiParser::parse_frame() 解析,以帧头 node_id 维护每节点状态,通过序列号间隙累计 drop_count,随后经 tx.try_send(frame) 转发(管线满则丢帧);解析失败只打日志绝不崩溃。关键特性是:汇聚端纯解析字节缓冲区、无任何 C FFI 或硬件依赖wifi-densepose-hardware crate README 明确"Parsers either parse real bytes or return explicit ParseError values. There are no synthetic fallbacks"——同一帧字节在任何平台解析结果确定,因此在无硬件时也可用回环 UDP + build_test_frame() 合成帧做完整测试。

时钟漂移处理:特征级融合而非信号级融合

这是 ADR-012 全篇最重要的工程判断。ESP32 晶振漂移约 20–50 ppm,一小时后两个节点可能偏差 72–180 ms,跨节点原始相位对齐在物理上不可行:

信号级融合(对 ESP32 是错的):
  对齐各节点的原始 I/Q 采样 → 需要 <1µs 级同步 → 不切实际

特征级融合(对 ESP32 是对的):
  每节点:原始 CSI → 幅值 + 相位 + 频谱特征(本地完成)
  汇聚端:收集特征 → 相关分析 → 融合决策
  无需跨节点相位对齐

具体融合策略:

  • 运动能量:各节点取最大(任意节点看到运动即算运动);
  • 呼吸带:以 SNR 最高节点为主、其余节点佐证;
  • 位置估计:用跨节点幅值比估计位置(无需相位)。

六、按部署规模评估的感知能力(诚实清单)

ADR-012 用一张矩阵明确告知读者:能力上限随节点数上升,但 ESP32 有其物理天花板

能力 1 节点 3 节点 6 节点 依据
存在性检测 良好 极佳 极佳 单节点 RSSI 方差
粗略运动 良好 极佳 极佳 多普勒能量
房间级定位 良好 极佳 幅值比
呼吸 勉强 良好 良好 0.1–0.5 Hz 频带,依赖摆放
心跳 差–勉强 勉强 需理想摆放与低噪声
多人计数 勉强 良好 空间分集
姿态估计 勉强 需模型 + 足够分集

诚实评估原文:"ESP32 CSI 保真度低于 Intel 5300 或 Atheros。心跳检测依赖摆放且不可靠;呼吸在摆放得当的前提下可用;运动与存在检测是可靠的。"这种能力边界在后续固件文档中被反复强调——例如 v0.8.8 发行说明(docs/releases/v0.8.8-esp32.md)专门列了一节"What this release does not prove",声明该版本不证明医疗级生命体征、准确的多人计数、身份识别、稠密姿态或穿墙视频等能力。

故障模式与缓解措施

故障模式 严重度 缓解
杂乱房间中多径占主导 网格分集:3+ 节点多角度布置
人体遮挡节点到路由器的路径 网格中其他节点仍有清晰路径
时钟漂移破坏跨节点融合 仅特征级融合,不做跨节点相位对齐
高流量下 UDP 丢包 序列号 + 对 <100 ms 缺口插值
ESP32 WiFi 驱动 CSI bug 锁定 ESP-IDF 版本,在已知良好板卡上测试
节点断电 汇聚端优雅处理缺失节点

七、硬件清单与克隆-烧录-运行的最小构建

Starter Kit 物料清单(约 54 美元)

物品 数量 单价 小计
ESP32-S3-DevKitC-1 3 10 美元 30 美元
USB-A 转 USB-C 线 3 3 美元 9 美元
多口 USB 电源适配器 1 15 美元 15 美元
消费级 WiFi 路由器 1 0(复用现有) 0
汇聚端(笔记本或树莓派 4) 1 0(复用现有) 0
合计 54 美元

硬件选型上当前仓库 README 有补充约束:推荐 ESP32-S3-DevKitC-1 与 XIAO ESP32-S3 这类全尺寸开发板,并明确警告硬币大小的克隆板(ESP32-S3-Zero、SuperMini 等)在固件持续满负荷运行 WiFi 下可能发热到损坏稳压器——部署时需留气流、避免堆叠密闭、首几分钟要手触测温。另注意大多数 DevKitC 开发板只有单板载天线,多天线数据需要带 U.FL 接口与外部天线的板卡。

Option A:使用预编译二进制(无需工具链)

# 从发布页下载对应芯片/Flash 的预编译包后(当前版本含 bootloader/分区表/OTA 元数据/app 与校验和),
# 用 esptool 烧录(pip install esptool)
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash_mode dio --flash_size 8MB \
  0x0     bootloader.bin \
  0x8000  partition-table.bin \
  0xf000  ota_data_initial.bin \
  0x20000 esp32-csi-node.bin

# 配置 WiFi 凭据(无需重编译)
python firmware/esp32-csi-node/provision.py --port COM7 \
  --ssid "YourWiFi" --password "secret" --target-ip 192.168.1.20

# 运行汇聚端
cargo run -p wifi-densepose-hardware --bin aggregator -- --bind 0.0.0.0:5005 --verbose

注意:当前发行包的偏移量为四段(bootloader=0x0partition-table=0x8000otadata=0xf000app(ota_0)=0x20000),其中分区表偏移相较 ADR-012 早期版本的 0x8000 方案已经演进,须以所用固件自带的 partitions_display.csv/partitions_4mb.csv 为准。完整安装包不含 NVS 镜像,因此四偏移安装会保留已有 WiFi 与节点配置。

Option B:Docker 从源码构建(免装 ESP-IDF)

# Step 1: 编辑 WiFi 凭据
vim firmware/esp32-csi-node/sdkconfig.defaults

# Step 2: 用 Docker 构建(仓库根目录执行)
MSYS_NO_PATHCONV=1 docker run --rm \
  -v "$(pwd)/firmware/esp32-csi-node:/project" -w /project \
  espressif/idf:v5.4 bash -c \
  "rm -rf build sdkconfig && idf.py set-target esp32s3 && idf.py build"

# Step 3: 烧录(build/ 下产物)
python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  write_flash --flash_mode dio --flash_size 8MB \
  0x0     firmware/esp32-csi-node/build/bootloader/bootloader.bin \
  0x8000  firmware/esp32-csi-node/build/partition_table/partition-table.bin \
  0xf000  firmware/esp32-csi-node/build/ota_data_initial.bin \
  0x20000 firmware/esp32-csi-node/build/esp32-csi-node.bin

# Step 4: 运行汇聚端
cargo run -p wifi-densepose-hardware --bin aggregator -- --bind 0.0.0.0:5005 --verbose

固件 README 专门解释了"为什么必须用 Docker":ESP-IDF 在 Windows 的 Git Bash/MSYS2 下不可用(idf.py 检测到 MSYSTEM 环境变量会跳过 main(),即便移除该变量,cmd.exe 子进程注入的 doskey 别名也会破坏 ninja 链接器),因此 Docker 是唯一可靠跨平台构建方式。MSYS_NO_PATHCONV=1 前缀用于防止 Git Bash 把 /project 篡改成 C:/Program Files/Git/project

对于无显示屏的 DevKitC 板卡,构建时应叠加 sdkconfig.defaults.devkitc overlay(默认构建会编入显示支持,运行时的面板探测在无面板板卡上误报从而禁用 CSI 升级并把吞吐拉到 0)。

以 NVS 运行时配置替代重编译

这是"克隆-烧录-运行"体验的关键。通过 provision.py 把配置写进 ESP32 的 NVS 分区,NVS 值覆盖 Kconfig 默认值,无需为每个新 WiFi 环境重新编译。核心网络配置项:

NVS Key 类型 默认值 说明
ssid string wifi-densepose WiFi SSID
password string (空) WiFi 密码
target_ip string 192.168.1.100 汇聚端 IP
target_port u16 5005 汇聚端 UDP 端口
node_id u8 1 节点唯一标识(0–255)

此外固件已演进出信道跳频/TDM(hop_countchan_listdwell_mstdm_slottdm_nodes,见 ADR-029/ADR-073 思路)、边缘智能(edge_tier 0/1/2、pres_threshfall_threshvital_winvital_intsubk_count)、信道覆盖与 MAC 过滤(csi_channelfilter_mac,见 ADR-060)等一整组 NVS 键。provision.py 的 CLI 参数与 CSV 生成逻辑(build_nvs_csv)与 CONFIG_VALUE_CHECKS 一一对应,且采用"默认增量合并"策略:脚本把每个串口先前写入的状态保存在本机用户配置目录,每次调用把新 CLI 值叠加到旧状态上,避免整库擦除造成客户流失配置。

八、二进制帧格式(ADR-018):固件与解析器的契约

由于固件选择透传原始 I/Q,帧格式就成了两端必须严格对齐的线协议契约。ADR-018 与固件 README 同时给出如下布局:

偏移  大小  字段
0     4     Magic: 0xC5110001
4     1     节点 ID
5     1     天线数
6     2     子载波数(LE u16)
8     4     频率 MHz(LE u32)
12    4     序列号(LE u32)
16    1     RSSI(i8)
17    1     噪声底(i8)
18    2     保留
20    N*2   I/Q 对(n_antennas * n_subcarriers * 2 字节)

帧总大小 = 20 + 天线数 × 子载波数 × 2 字节。以 3 天线 56 子载波为例,每帧 356 字节。当前固件在此基础上还扩展了按 magic 区分的包族:0xC5110001(CSI 帧,约 20 Hz)、0xC5110002(vitals 包,1 Hz,32 字节,携带 presence/fall/motion 标志、呼吸率 BPM×100 定点数、心率、RSSI、人数与运动能量)、0xC5110004(WASM 事件输出)。

固件侧序列化见 csi_collector.c(小端写 magic、节点 ID、天线数 = rx_ctrl.antn_sub = info->len / 2、频率、自增序列号、RSSI/噪声底,再把 info->buf 原样拼到 20 字节头之后);Rust 侧解析见 wifi-densepose-hardware/src/esp32_parser.rs,验证 magic、对 n_subcarriers≤512 做边界检查、并在 parse_stream() 中按 magic 搜索重同步流。

九、无硬件可测:分层可测试性与真机证据

ADR-018 的四层实现全部设计为"买板之前即可测试":

测试方法
固件二进制格式 在 Rust 中实现 build_test_frame() 辅助函数,输出与手工计算的参考帧逐字节比对
汇聚端 回环 UDP:测试向 127.0.0.1:5005 发送合成帧,汇聚端接收并沿通道转发
桥接层 assert_eq!(csi_data.amplitude[0], sqrt(i² + q²)) 到 f64 精度
Python UDP 读取器 pytest 中后台线程起 mock UDP server

Proof of Reality(ADR-012 记录的真机实测):用 ESP32-S3-DevKitC-1(CP2102,MAC 3C:0F:02:EC:C2:28)实测 18 秒捕获 693 帧(约 21.6 fps),序列号连续、零帧丢失,存在性检测确认(运动评分 10/10,基于每秒幅值方差),实测帧型覆盖 64 子载波(148 B)、128 子载波(276 B)、192 子载波(404 B),伴随 20 个 Rust 测试 + 6 个 Python 测试通过。

后续固件演进(0.8.8,发行说明)还提供了更新的硬件测量矩阵:2026-08-31 实测 ESP32-C6 节点 4(300.64 秒,原始 CSI 均值 34.92 pps,DSP 时钟 8.00 Hz,稳态传输错误 0)、ESP32-C6 节点 7(36.32 pps,覆盖率 97.40%)、ESP32-S3 节点 1(28.03 pps,覆盖率 100.00%)。这些数据证明的是时序与传输稳定性,而非更好的心率、姿态或计数精度——这是理解该网格当前能力边界的重要标尺。

此外,固件工程还提供 QEMU 模拟测试路径(见 firmware/esp32-csi-nodesdkconfig.qemu overlay 与 mock_csi.c):编译期用定时器驱动的合成帧注入器替代真实 WiFi CSI 回调,可覆盖双人呼吸、跌倒、信道扫描、MAC 过滤、环形缓冲溢出、边界 RSSI、零长帧等 10 种场景,并在 CI 中以 14 种 NVS 配置矩阵跑完整 UART 校验——意味着即便没有物理硬件,边缘处理全管线依然可回归。

十、后果与后续 ADR 的衔接

正向后果

  • 54 美元入门套件:接触真实 CSI 数据的最低门槛;
  • 硬件全球现货:ESP32 板卡全球充足;
  • 真实数据通路:以真实硬件输入替换掉每一个 np.random.rand() 占位符;
  • 证据工件:捕获的 CSI + 期望哈希可证明管线处理的是真实数据(延续 ADR-011 的 Proof of Reality 要求);
  • 网格可扩展:加节点加覆盖,无需改软件;
  • 特征级融合:绕开了跨节点相位同步这一不可能问题。

负向后果

  • 保真度低于科研级网卡(比 Intel 5300 噪声更大);
  • 心跳检测不可靠(微多普勒分辨率不足以稳定测心跳);
  • ESP-IDF 有学习曲线(固件开发需要嵌入式 C 知识);
  • WiFi 干扰:节点与数据流量共享信道会引入噪声;
  • 摆放敏感:呼吸检测需要细心规划节点位置。

与其他 ADR 的关系:ADR-011 由 ESP32 提供真实 CSI 证据包;ADR-008 的网格节点可用简化版 Raft 做配置分发;ADR-003 思路下汇聚端以 RVF 格式存 CSI 特征;ADR-004 思路下 ESP32 网格产生的环境指纹喂给 HNSW 索引。后续实现细节承接自 ADR-018,而固件侧的能力扩展(C6 研究目标、边缘智能分级、WASM 可编程感知、QEMU 测试、信道跳频 TDM、MAC 过滤)则进一步体现在 firmware/esp32-csi-node/README.md 及 ADR-029/039/040/057/060/061 等一系列后续决策中。

结语

ADR-012 的核心价值在于它给出了一条从"想用 WiFi 感知"到"真实节点在跑"的完整决策链:对比平台选型 → 用官方三函数建立采集 → 用瘦固件 + 二进制线协议喂给汇聚端 → 用特征级融合绕开时钟漂移 → 用分层测试做到无硬件可开发。当你需要为 RuView 部署一房间的分布式无摄像感知时,这套"3–6 个 S3 开发板 + 一个汇聚端"的组合,既是仓库中证据最充分的硬件路径,也是验证信号处理算法真实性的最小闭环起点。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388