RuView 实战指南:从 ESP32-S3 CSI 硬件采集到浏览器实时姿态可视化的端到端流水线(ADR-059 全解读)
2026/9/8 23:22:27 网站建设 项目流程

RuView 实战指南:从 ESP32-S3 CSI 硬件采集到浏览器实时姿态可视化的端到端流水线(ADR-059 全解读)

【免费下载链接】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

导读

本指南基于 RuView 架构决策记录 ADR-059,完整讲解一条“真实硬件 → 浏览器”的 CSI(信道状态信息)实时感知流水线:ESP32-S3 固件采集原始 WiFi I/Q 数据,通过 UDP 送入 Rust/Axum 的 sensing server,再经 WebSocket 推送至浏览器 Demo 完成实时可视化。读完本文,你将掌握该流水线各环节的启动参数、二进制帧契约、Windows 原生构建方法、网络排障要点,以及「真机数据与仿真回退共存」的设计取舍,可直接用于复现或二次开发。

一、决策背景:为什么需要打通真机链路

ADR-059 是在 ADR-058 的基础上提出的。ADR-058 建立了一个「摄像头视频 + WiFi CSI」双模态浏览器姿态 Demo,但当时使用的是仿真 CSI 数据(GitHub Pages 等静态环境下没有后端可连)。要证明真实能力,就必须打通一条从物理 ESP32 硬件一直延伸到浏览器可视化的完整链路。

在 ADR-059 之前,两个关键环节已经各自就绪,唯独缺少连接件:

环节已有能力缺口
ESP32-S3 固件(firmware/esp32-csi-node/)支持 CSI 采集与 UDP 流式发送(ADR-018 帧格式)未与上层服务衔接
sensing server(v2/crates/wifi-densepose-sensing-server/)已支持 UDP 接入与 WebSocket 桥接未接入真实 ESP32 数据源
浏览器 Demo已能消费 WebSocket / 仿真数据未实现「自动连接 + 自动回退」

因此 ADR-059 的决策是:把上述三段串成一条完整的实时流水线。

二、流水线总体架构与核心数据契约

ADR-059 给出了端到端流水线的标准形态:

ESP32-S3 (CSI capture) → UDP:5005 → sensing-server (Rust/Axum) → WS:8765 → browser demo

2.1 数据流与速率

ADR-059 对链路各级的协议、格式与速率约定如下:

阶段协议格式速率
ESP32 → ServerUDPADR-018 二进制帧(magic0xC5110001,I/Q 对)~100 Hz(采集侧)
Server → BrowserWebSocketADR-018 二进制帧(转发)~10 Hz(tick-ms=100
Browser decodeJavaScriptFloat32 幅度/相位数组每帧一次

这里值得注意一个工程权衡:ESP32 采集侧可以到 100 Hz 量级,但服务端只按约 10 Hz(100 ms tick)向下游广播——因为姿态动画的可视化帧率无需与射频采样率一致,中间由 sensing server 做窗口聚合,能显著降低浏览器端处理与网络开销。

2.2 ADR-018 二进制帧格式(链路共用的数据契约)

整条链路上 UDP 段与 WebSocket 段传输的都是 ADR-018 定义的二进制帧,格式细节定义在 ADR-018。帧由 20 字节定长头 + 变长 I/Q 载荷组成:

偏移大小字段
04Magic:0xC5110001(小端)
41Node ID(0–255)
51天线数
62子载波数(小端 u16)
84频率字段(小端 u32,数值形如 2412 表示 2.4 GHz 信道 1)
124序号(小端 u32)
161RSSI(i8, dBm)
171噪声底(i8, dBm)
182保留(置零)
20N×2I/Q 对:每个子载波 (i8, i8),按天线重复

总帧长 = 20 + (天线数 × 子载波数 × 2) 字节。例如 3 天线 × 56 子载波时为 20 + 336 = 356 字节/帧。ADR-018 同时约束了解析器对n_subcarriers的上限校验(≤ 512)以及按 magic 重同步的流式解析策略。

2.3 固件侧的序列化实现

帧序列化逻辑可以在当前固件源码 main/csi_collector.c 的csi_serialize_frame()中直接找到:从wifi_csi_info_t中读取信道并换算中心频率、填充 magic / node id / 子载波数 / 序号 / RSSI / 噪声底,再原样拷贝info->buf的 I/Q 载荷。该文件还在编译期通过#ifndef CONFIG_ESP_WIFI_CSI_ENABLED做守卫(对应 ADR-057),避免“能编译但运行时报 CSI not enabled”的困惑。而发送侧由 main/stream_sender.c 的stream_sender_init()依据 Kconfig 宏CONFIG_CSI_TARGET_IP/CONFIG_CSI_TARGET_PORT打开 UDP 套接字并sendto(),从源码层面印证了「目标 IP 编译进固件」这一 ADR-059 提到的负面约束。

三、组件一:ESP32 固件侧(Windows 本机原生构建)

ADR-059 对应的开发阶段采用Windows 原生 ESP-IDF v5.4.0 工具链(不使用 Docker),这与当前固件 README 中“CI/Docker 是唯一可靠跨平台构建方式”的结论并不冲突——后者针对通用开发者,而 ADR-059 描述的是在已经装好 Windows 版 ESP-IDF 的开发机上用脚本自动完成构建的本地工作流。

3.1 配套辅助脚本

ADR-059 为固件新增了两个 PowerShell 辅助脚本,仓库中均已落地:

脚本作用
firmware/esp32-csi-node/build_firmware.ps1设置 IDF 环境、清理、编译并烧录,一次完成
firmware/esp32-csi-node/read_serial.ps1串口监视器,支持 DTR/RTS 复位

其中build_firmware.ps1之所以能“自动处理一切”,是因为它负责了 Windows 下 ESP-IDF 的四项环境要点(详见本文第七节),避免手工配置出错。

3.2 网络目标配置

固件在编译前需把目标网络与 PC 的 IP 写进sdkconfig。以仓库固件 README 中给出的sdkconfig.defaults片段为例,与 ADR-059 链路直接相关的关键是:

CONFIG_ESP_WIFI_CSI_ENABLED=y CONFIG_CSI_NODE_ID=1 CONFIG_CSI_WIFI_SSID="wifi-densepose" CONFIG_CSI_TARGET_IP="192.168.1.100" CONFIG_CSI_TARGET_PORT=5005

即 ESP32 以 STA 身份连上 WiFi 后,把 CSI 帧发往192.168.1.100:5005——也就是本机运行 sensing server 的地址与 UDP 端口。

运行时免重刷的替代方案:目标 IP / 端口也可通过 NVS 覆盖(对应 ADR-059 负面清单里的 “NVS override”)。仓库的provision.py即为此设计:

python firmware/esp32-csi-node/provision.py --port COM7 \ --ssid "MyWiFi" --password "MyPassword" --target-ip 192.168.1.20

NVS 键ssid/password/target_ip/target_port/node_id会覆盖 Kconfig 默认值,从而避免为换一次 IP 就重新编译固件。

四、组件二:Sensing Server 的启动方式与参数解读

ADR-059 规定 sensing server(Rust/Axum)以如下方式启动:

cargo run -p wifi-densepose-sensing-server -- \ --source esp32 \ --bind-addr 0.0.0.0 \ --ui-path <path>
  • --source esp32:期望接收真实 ESP32 UDP 帧(区别于默认的auto与仿真数据源);
  • --bind-addr 0.0.0.0:接受来自任意网卡的连接(供局域网内的 ESP32 投递 UDP);
  • --ui-path <path>:通过 HTTP 托管演示 UI 静态文件。

上述参数与默认值都可以在 cli.rs 的 clap 定义中验证:udp_port默认5005ws_port默认8765http_port默认8080tick_ms默认100(即约 10 fps)、bind_addr默认127.0.0.1(注释明确“设为0.0.0.0以开放网络访问”)、source取值支持auto/wifi/esp32/simulate

服务端当前实现还在此基础上做了健壮性增强(见 main.rs 中的plan_source()effective_source()):一旦首帧真实 ESP32 数据到达,数据源会自动提升到esp32;若超过 5 秒(ESP32_OFFLINE_TIMEOUT)没有新帧,则返回esp32:offline,让 UI 能区分「活跃真机」与「连接已中断」。

4.1 端口全景

整条链路涉及三个端口,排障时可对照检查:

端口方向用途
UDP 5005ESP32 → ServerCSI 二进制帧接入
WS 8765Server → Browser/ws/sensing传感数据流
HTTP 8080Server → BrowserUI 静态文件 + REST API

五、组件三:浏览器 Demo 的自动连接与优雅回退

链路最后一段是浏览器 Demo。ADR-059 的关键决策是:Demo 的main.js在页面加载时自动连接ws://localhost:8765/ws/sensing;当 WebSocket 不可用时(例如部署在静态托管的 GitHub Pages 上),则自动回退到仿真 CSI

这一设计带来两个直接好处:

  1. 同一个 Demo 两种形态:本地打开即为“真机实时”模式,静态部署即为“仿真演示”模式,无需维护两套前端;
  2. 渐进式体验:即使没有硬件,Demo 依旧可展示;一旦接上 server 与 ESP32,页面无需改动即切换为真实数据流。

浏览器端收到 ADR-018 帧后,由 JavaScript 解码为 Float32 幅度/相位数组(to_amplitude_phase的解码逻辑可追溯 ADR-018 中CsiFrame的类型设计),供姿态估计与渲染使用。

六、网络配置与典型排障

6.1 IP 别名:避免重刷固件的临时方案

ADR-059 指出:ESP32 会向编译进固件的目标 IP 发包。如果 PC 当前 IP 与固件编译目标不一致,可以给网卡追加一个辅助 IP 别名来快速对齐(Windows PowerShell 需管理员权限):

New-NetIPAddress -IPAddress 192.168.1.100 -PrefixLength 24 -InterfaceAlias "Wi-Fi"

这相当于在不重新编译固件的前提下,让 PC 额外“认领”固件期望的那个地址。

6.2 Windows 防火墙放行 UDP 5005

ADR-059 明确警告 Windows 防火墙可能拦截入站 UDP:5005。对应的放行规则(固件 README 与 ADR 两侧一致)为:

netsh advfirewall firewall add rule name="ESP32 CSI" dir=in action=allow protocol=UDP localport=5005

6.3 混合内容(Mixed Content)限制

由于 HTTPS 页面不允许连接不加密的ws://由 HTTPS 托管的页面无法直连本地ws://localhost:8765。这正是 Demo 必须保留“仿真回退”的深层原因:真实数据链路只能在本地 HTTP 环境(或做了相应处理的内网页面)下使用。

七、Windows 构建环境四要点

ADR-059 明确列出了 ESP-IDF v5.4.0 在 Windows 上可用的前置条件:

环境项要求
IDF_PATH指向 ESP-IDF 框架目录
IDF_TOOLS_PATH指向工具链二进制目录
MSYS/MinGW 环境变量必须移除——ESP-IDF 会拒绝它们
Python 虚拟环境使用 ESP-IDF 自带的 venv 来执行idf.py

值得注意的是:ESP-IDF 对 MSYS/MinGW 的排斥正是仓库固件 README 反复强调“Git Bash/MSYS2 下无法工作”的根因(idf.py检测到MSYSTEM后会跳过main())。build_firmware.ps1的价值在于把以上所有设置封装成一条命令,开发者不需要手工拼接环境。

八、后果评估:收益与限制

ADR-059 对这项决策做了坦诚的双向评估,理解这些边界对实际复现很重要。

正面收益

  • 首次打通「真实 WiFi CSI → 浏览器姿态估计」的端到端演示——仿真数据终于被真实射频数据取代;
  • Windows 下固件构建不依赖 Docker,本地迭代更快;
  • Demo优雅降级:无 server 时自动回到仿真 CSI,演示永不白屏;
  • 同一套 Demo 在静态托管(仿真)与本地(真机)两种模式下均可运行。

负面限制

  • ESP32 目标 IP 编译进固件:更改 IP 需重新编译,或通过 NVS 覆盖(见 3.2);
  • Windows 防火墙可能拦截 UDP:5005,需用户手动放行;
  • 混合内容限制:HTTPS 页面无法连接ws://,真机模式仅限本地 HTTP 环境;
  • 补充一条来自固件源码的工程背景:CSI 回调在混杂模式下可高达 100–500+ 次/秒,csi_collector.c 与 stream_sender.c 分别用「最小发送间隔限速」和「ENOMEM 指数退避」来防止 lwIP pbuf 耗尽导致设备崩溃——因此实际到达 server 的速率是经过限速与背压保护的稳定值,ADR-059 表格中的 ~100 Hz 应理解为采集侧量级而非保证值。

九、进阶:无硬件先行验证

如果你还没有 ESP32 板卡,也并非无法验证链路。ADR-018 设计时就坚持了四层均可无硬件测试

  • 固件二进制格式:用build_test_frame()与手工推算的参考帧逐字节比对;
  • 聚合/服务端接入:往127.0.0.1:5005回环 UDP 发送合成帧;
  • 帧→信号桥接:amplitude[0] == sqrt(I₀² + Q₀²)精度断言;
  • 上层数据源:simulate数据源与 QEMU + mock CSI(固件sdkconfig.qemu)可在无硬件情况下走通整条逻辑。

待真机到位后,即可按 ADR-018 的三阶段顺序接入:先固件 + UDP 抓包验证(Wireshark 确认帧到达),再做流水线集成,最后进入真实硬件端到端联调。

十、关联文档与源码地图

围绕 ADR-059 这条实时流水线,仓库中值得继续深入阅读的资料如下:

  • ADR-059:Live ESP32 CSI Pipeline Integration——本文主体(跟踪 Issue #245);
  • ADR-018:ESP32 Development Implementation Path——二进制帧格式、四层开发序列与无硬件测试方法;
  • ADR-058:RuVector/WASM 双模态浏览器姿态 Demo——本流水线所服务的浏览器端载体;
  • ADR-039:ESP32 边缘智能框架——固件侧边缘处理分层设计;
  • firmware/esp32-csi-node/README.md——固件构建、烧录、NVS 键位与 ADR-018 帧契约完整参考;
  • firmware/esp32-csi-node/main/csi_collector.c——帧序列化与 CSI 回调源码;
  • firmware/esp32-csi-node/main/stream_sender.c——UDP 发送与 ENOMEM 背压源码;
  • v2/crates/wifi-densepose-sensing-server/README.md——sensing server 架构与启动示例;
  • v2/crates/wifi-densepose-sensing-server/src/cli.rs——--source/--bind-addr/--tick-ms/ 端口等全部参数定义与默认值。

以上各文档结合阅读,即可从「为什么」(ADR-059/018 的决策逻辑)、「怎么做」(固件与服务端源码)、「怎么跑」(启动参数与排障命令)三个层面完整掌握这条 ESP32 实时 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

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询