📍 无忆研习社 › 开源解码 › WiFi也能"看见"人?RuView 开源项目深度解析:用无线信号实现穿墙人体姿态估计的完整技术指南

WiFi也能"看见"人?RuView 开源项目深度解析:用无线信号实现穿墙人体姿态估计的完整技术指南

摘要:RuView是一个基于WiFi信号的开源人体感知项目,通过分析信道状态信息(CSI),无需摄像头即可实现穿墙人体姿态估计、生命体征监测和存在检测。该项目源自卡耐基梅隆大学的研究,采用Rust语言重构,处理帧率高达54000帧/秒,延迟低于100微秒,可部署在ESP32-S3等边缘硬件上。系统支持多节点Mesh组网,通过智能算法将CSI信号转换为人体关键点坐标,在保护隐私的同时,为居家看护、智能家居等场景提供低成本、无感的感知方案。
字号 100%
行距 2.05
当前可见 60% 的内容
快速摘要
RuView 是一个基于 WiFi 信号的开源人体感知项目,它通过分析 WiFi 信道状态信息(CSI),在不使用任何摄像头的前提下,实现穿墙人体姿态估计、生命体征监测和存在检测。 该项目在 GitHub 上获得了超过 25000 星标的关注,其核心原理源自卡耐基梅隆大学(CMU)2022 年发表的论文《DensePose From WiFi》。整套系统使用 Rust 语言重构后,处理帧率可达 54000 帧/秒,单帧处理延迟低于 100 微秒,可部署在 ESP32-S3 等边缘硬件上。往下看,莫潇羽@无忆研习社 将为你从底层原理到实际部署,逐步拆解这项技术的全部细节。

一、为什么 WiFi 信号能"看见"人?

在大多数人的认知里,WiFi 的唯一用途就是上网。但事实上,WiFi 路由器每时每刻都在向四面八方发射无线电波——这些电磁波在房间里会经历反射、折射、散射和衰减,形成复杂的多径传播环境。当房间里没有人移动时,这些电磁波的传播路径是相对稳定的。可一旦有人走动,甚至只是站在原地呼吸,人体就会像一块投入池塘的石子,在无线信号的"水面"上激起涟漪。

这并不是什么科幻概念。早在 2014 年前后,学术界就已经开始系统性地研究利用 WiFi 信号感知环境变化的技术。清华大学、卡耐基梅隆大学、麻省理工学院等高校的研究团队先后发表了大量相关论文,涵盖室内定位、手势识别、跌倒检测、呼吸监测等方向。而 RuView 项目所聚焦的"WiFi 人体姿态估计",正是这一研究领域中最具挑战性、也最具应用前景的方向之一。

这项技术之所以能引起如此大的关注,核心原因在于三个字——无摄像头。传统的人体姿态估计依赖 RGB 摄像头、深度相机(如 Kinect)或者 LiDAR 激光雷达。这些方案在光线不足、存在遮挡的场景下表现欠佳,而且在卧室、浴室等私密空间部署摄像头,会带来严重的隐私争议。WiFi 感知技术完全绕开了视觉传感器,仅通过分析无线信号的波形变化来推断人体姿态,天然地规避了隐私问题。

莫潇羽@无忆研习社 在这里要特别说明一点:WiFi 感知技术并不会"拍照"或者"录像",它的输出是一组抽象的人体关键点坐标(比如 17 个 COCO 格式的身体关键点),而不是任何形式的图像。这意味着,即使有人获取了这些数据,也无法还原出你的长相、穿着或者房间的实际画面。


二、核心概念:什么是 CSI(信道状态信息)?

要理解 RuView 的工作原理,首先必须搞清楚一个关键概念——CSI(Channel State Information,信道状态信息)。

2.1 从 RSSI 到 CSI:精度的质变

你可能听说过 RSSI(Received Signal Strength Indicator,接收信号强度指示器),手机上显示的 WiFi 信号格数就是基于 RSSI 的。RSSI 是一个非常粗糙的指标,它只告诉你"信号有多强",但不会告诉你信号在传播过程中经历了什么。打个比方,RSSI 就像用温度计量体温——只能得到一个笼统的数字;而 CSI 则像一份完整的血液检测报告,能告诉你每一项指标的具体数值。

在现代 WiFi 标准中(802.11n/ac/ax),采用了 OFDM(正交频分复用)技术。以 20MHz 带宽为例,一个信道会被划分为 64 个子载波(subcarrier),其中 56 个用于数据传输和导频信号。CSI 记录的,就是每一个子载波上信号的幅度(amplitude)和相位(phase)信息。

这意味着什么呢?在同一时刻,RSSI 只给你 1 个数字,而 CSI 能给你 56 个复数值——每个复数值包含幅度和相位两个维度的信息。这种信息密度的差异,决定了 CSI 能够捕捉到环境中极其细微的变化,而 RSSI 则无能为力。

2.2 OFDM 与子载波:理解 CSI 的前置知识

在深入 CSI 的数学表达之前,有必要先理解 OFDM(Orthogonal Frequency Division Multiplexing,正交频分复用)的基本概念,因为 CSI 正是建立在 OFDM 技术之上的。

OFDM 的核心思想是将一个宽带信道划分为多个窄带子信道(即子载波),每个子载波独立传输数据。以 802.11n 标准的 20MHz 带宽为例,整个信道被划分为 64 个子载波,相邻子载波的间隔为 312.5kHz。其中 56 个子载波用于数据传输和导频,其余为保护间隔和直流子载波。

为什么要这样做?因为宽带信道中存在频率选择性衰落——不同频率的信号在多径环境中经历的衰减和延迟是不同的。通过将宽带信道拆分为多个窄带子载波,每个子载波内部的衰落可以近似为平坦衰落(即幅度和相位基本一致),这大大简化了接收端的均衡处理。

对于 WiFi 感知来说,OFDM 的这种多子载波结构恰好提供了一个"频率分集"的观测维度——同一时刻,56 个子载波各自"看到"的信道状态是不同的,因为它们对应的频率不同,对环境变化的响应也不同。这就好比用 56 双不同的"眼睛"同时观察房间,每双"眼睛"对环境的某些特征更敏感。这种多维度的观测能力,是 CSI 远超 RSSI 的根本原因。

在 MIMO(Multiple-Input Multiple-Output,多输入多输出)系统中,CSI 的维度进一步扩展。如果发射端有 (N_t) 根天线,接收端有 (N_r) 根天线,那么每个子载波上的 CSI 就是一个 (N_r \times N_t) 的复数矩阵。以常见的 3×3 MIMO 配置为例,每个子载波有 9 个独立的 CSI 值,56 个子载波总共提供 504 个复数测量值。这种高维度的数据为精细的人体姿态估计提供了充足的信息量。

2.3 CSI 的数学表达

用简化的数学语言来描述,CSI 可以表示为:

[

H(f, t) = \sum_{n=1}^{N} a_n(t) \cdot e^{-j2\pi f \tau_n(t)}

]

其中,(N) 是多径传播的路径数量,(a_n(t)) 是第 (n) 条路径在时刻 (t) 的信号衰减系数,(\tau_n(t)) 是该路径的传播延迟,(f) 是子载波频率。

简单来说,当一个人在房间里移动时,他的身体会改变部分路径的衰减系数和传播延迟。这些变化反映在 CSI 数据中,就表现为特定子载波的幅度和相位发生波动。通过持续采集和分析这些波动模式,就能推断出人体的位置、运动方向,乃至精细的肢体姿态。

2.4 为什么普通 WiFi 设备不能直接获取 CSI?

这里有一个很多初学者会踩的坑(莫潇羽@无忆研习社 曾经也在这个问题上花了不少时间弄清楚):普通的消费级 WiFi 设备(比如你的笔记本电脑、手机)是无法直接获取 CSI 数据的。 它们的驱动程序和固件只暴露 RSSI,而不会提供底层的子载波级别信息。

这背后的原因是:CSI 数据在 WiFi 芯片的物理层(PHY Layer)被提取和使用,主要用于信道均衡——让接收端知道信号在传播过程中发生了什么变化,从而正确地恢复原始数据。这些信息完成其使命后就被丢弃了,不会上传到操作系统的网络协议栈。芯片厂商没有动力把这些底层数据暴露给应用层,因为普通用户根本用不到。

要获取 CSI 数据,你需要以下几类硬件之一:

  • ESP32-S3 系列微控制器:乐鑫(Espressif)官方在其 ESP-IDF 开发框架中提供了 CSI 采集的 API,这是目前唯一在标准固件中就原生支持 CSI 数据回调的消费级 WiFi 芯片。乐鑫提供了一个名为 esp-csi 的开源库,其中包含了接收端 CSI 采集示例(csi_recv)、发送端示例(csi_send)以及利用路由器作为信号源的示例(csi_recv_router)。单块开发板成本约 8 美元,是目前性价比最高的方案。
  • Intel 5300 网卡:这是学术研究中最经典的 CSI 采集方案,由华盛顿大学的研究团队开发了对应的 Linux 内核驱动补丁(Linux CSI Tool)。Intel 5300 可以在每个数据包中提供 30 个子载波的 CSI 信息。但 Intel 5300 已经停产多年,在二手市场的价格也在不断攀升。
  • Atheros CSI Tool:基于 Qualcomm Atheros 芯片组(如 AR9580)的 CSI 采集工具,可以提供 56 个子载波的 CSI 数据,但同样需要修改内核驱动。
  • 软件定义无线电(SDR)平台:如 USRP、WARP 等,可以在 2.4GHz、5GHz 甚至 60GHz 频段下提供完全自定义的 CSI 测量。灵活性最高,但成本也最高,通常在数千美元级别。
  • 部分企业级 WiFi 接入点:华为部分 Wi-Fi 7 AP 已经原生支持 CSI 感知功能,可以将 CSI 数据上报到华为的网络智能分析平台。但这些设备主要面向企业市场,个人开发者不太容易获取。

RuView 项目主要推荐使用 ESP32-S3,这也是目前开源社区中最活跃、文档最完善的方案。值得一提的是,乐鑫近期还推出了一款名为 esp-crab 的多天线共晶开发板,专门为 WiFi CSI 感知研究设计,集成了 ESP32-C3 和 ESP32-S3 两颗芯片以及三根板载定向天线,通过时钟缓冲器消除两颗芯片之间的频率偏移,可以直接利用 CSI 相位信息进行高精度感知。

2.5 CSI 与 RSSI 的能力边界

为了让读者更清晰地理解 CSI 和 RSSI 各自能做什么、不能做什么,莫潇羽@无忆研习社 在这里做一个直观的对比。

使用 RSSI 可以实现的感知任务包括:粗粒度的存在检测(房间里有没有人)、大幅度运动检测(有人走动还是没人走动)、基于指纹匹配的粗略室内定位(精度通常在 2—5 米级别)。这些任务不需要特殊硬件,任何支持 WiFi 的设备都可以做到。

使用 CSI 可以实现的感知任务则丰富得多:细粒度的手势识别(比如挥手、拍手、画圈等)、人体活动分类(走路、坐下、站起来、跌倒等)、呼吸和心跳频率估计、多人追踪与计数、人体姿态估计(关键点定位)、甚至键盘按键识别等。这些任务需要 CSI 采集硬件。

两者的能力差异根源在于信息量的巨大差距。RSSI 每次采样提供 1 个数值(标量),CSI 每次采样提供数百个复数值(矩阵)。打个比方:用 RSSI 做感知,就像蒙着眼睛听脚步声来判断房间里的情况;用 CSI 做感知,则像是戴上了一副能看到电磁波的特殊眼镜。


三、学术根基:CMU 的《DensePose From WiFi》论文

RuView 的核心算法并非凭空发明,而是建立在卡耐基梅隆大学(CMU)机器人研究所 Jiaqi Geng 等人发表的研究成果之上。这篇论文最早以硕士学位论文的形式于 2022 年 8 月发表(编号 CMU-RI-TR-22-59),随后以预印本的形式发布在 arXiv 上(论文编号 2301.00250)。

3.1 研究背景与动机

传统的人体姿态估计技术有几个明显的痛点。基于 RGB 摄像头的方案在遮挡和弱光环境下表现不佳;基于 LiDAR 和雷达的方案需要昂贵的专用硬件;在非公共区域部署任何视觉传感器都会引发隐私担忧。CMU 的研究团队提出了一个大胆的设想:能否仅使用 WiFi 信号,就实现与图像方法相当的人体姿态估计效果?

3.2 核心方法

CMU 团队的方法可以概括为以下几个步骤:

第一步:数据采集。 研究者使用 3 个 WiFi 发射器和 3 个对齐的接收器,同时采集 CSI 数据和同步的摄像头图像。3 对收发天线产生一个 3×3 的 CSI 矩阵,每个矩阵元素包含多个子载波的幅度和相位信息。

第二步:信号预处理。 原始 CSI 数据包含大量噪声,需要进行幅度和相位的清洗(sanitization)。相位数据尤其需要处理,因为硬件时钟不同步会引入采样时间偏移(STO)和采样频率偏移(SFO),导致相位数据出现漂移。

第三步:模态转换网络(Modality Translation Network)。 这是整个方法中最巧妙的部分。研究者设计了一个双分支编码器-解码器网络,将一维的 CSI 信号"翻译"成二维的类图像特征图(feature map),尺寸为 3×720×1280。这一步本质上是在做跨模态的域转换——从射频信号域到图像空间域。

第四步:WiFi-DensePose RCNN。 将第三步输出的特征图送入一个改进版的 DensePose-RCNN 架构。这个网络包含两个分支:关键点检测头(Keypoint Head)负责定位 17 个 COCO 格式的身体关键点;DensePose 头负责估计人体表面的 UV 坐标(将人体表面映射到 24 个身体区域)。关键点分支的存在可以辅助 DensePose 分支的学习,特别是在肢体等细节部位的估计上效果显著。

第五步:知识蒸馏训练。 训练过程采用了教师-学生(Teacher-Student)框架。教师网络是一个标准的基于图像的 DensePose 模型,学生网络就是上述的 WiFi-DensePose 模型。通过让学生网络的特征向教师网络对齐,避免了对 WiFi 数据进行人工标注的需求——标注信息直接由摄像头图像经教师网络生成。训练完成后,推理阶段完全不需要摄像头。

3.3 实验结果

CMU 团队在 15 个不同的空间布局下进行了训练,并在 1 个未见过的布局下进行测试。实验结果表明,WiFi-DensePose 的视觉效果与图像方法具有可比性,能够同时估计多个人的密集姿态。不过,论文也诚实地指出,在跨布局泛化(从训练环境迁移到新环境)时,精度会有明显下降。


四、RuView 项目:从论文到工程实现

了解了学术背景之后,我们来看 RuView 项目具体做了什么。RuView 并不只是简单地复现了 CMU 的论文,而是在工程层面做了大量的优化和扩展,使其从一个实验室原型变成了一个可以实际部署的系统。

项目的 GitHub 地址为:https://github.com/ruvnet/RuView

4.1 五层架构设计

RuView 采用了分层解耦的架构设计,从底层到顶层依次为五个层级,各层职责清晰且可独立扩展。

硬件采集层 是整个系统的基础。这一层负责获取原始的 CSI/RSSI 数据,并适配不同的硬件方案。核心组件包括 ESP32-S3 Mesh 节点固件(支持轻量化 CSI 流式采集)和通用网卡适配模块(兼容 Intel 5300 等专业网卡)。数据传输基于 QUIC/TLS 1.3 协议保障安全性。ESP32 节点通过 UDP 协议将采集到的 CSI 二进制帧发送到上层的 Rust 聚合器。

信号预处理层 负责对原始 CSI/RSSI 数据进行降噪和特征增强。具体的处理流水线如下:

原始 CSI → 共轭乘法(相位清洗)→ Hampel 滤波器(离群值去除)
→ 子载波选择(Top-K)→ CSI 频谱图(时频分析)
→ Fresnel 模型(呼吸检测)+ BVP(活动识别)

这里面几个关键技术点值得展开说说。共轭乘法是相位清洗的核心手段——通过将相邻天线或子载波的 CSI 值进行共轭相乘,可以消除由硬件时钟偏移引入的公共相位误差。Hampel 滤波器用于去除突发性的离群值(outlier),比如 WiFi 信号受到微波炉等设备的瞬时干扰。SpotFi 算法则用于多径分离,它能从混叠的 CSI 信号中分离出不同传播路径的分量,这对于穿墙感知至关重要。

智能建模层 是整个系统的核心。训练流水线使用纯 Rust 实现,总计约 7832 行代码,不依赖任何外部机器学习框架。它训练一个图变换器(Graph Transformer)模型,使用交叉注意力机制将 CSI 特征矩阵映射到 17 个 COCO 身体关键点和 DensePose UV 坐标。RuVector 组件库提供了底层的构建模块:ruvector-attention 实现交叉注意力层,ruvector-mincut 实现多人匹配,ruvector-temporal-tensor 实现 CSI 缓冲区压缩。

这一层还包含了一个名为 MERIDIAN 的域泛化系统。前面提到,WiFi 感知模型在从训练环境迁移到新环境时,精度通常会下降 40%—70%。MERIDIAN 通过 10 秒钟的自动校准解决了这个问题:系统会在新环境中快速采集少量 CSI 数据,然后使用对比测试时训练(Contrastive Test-Time Training)自动生成环境特定的 LoRA 权重,将跨环境精度损失控制在 15% 以内。

高性能计算层 是 RuView 相对于原始 Python 实现最大的差异化优势。整个核心流水线使用 Rust 语言重写后,实现了 810 倍的端到端加速。运动检测模块的性能提升更是达到了 5400 倍。生命体征检测器在单线程基准测试中可以处理 11665 帧/秒。单帧处理延迟低于 100 微秒,完全满足实时性要求。Docker 镜像仅 132MB,可以直接部署在边缘设备上。

应用层 提供统一的 REST API 和 WebSocket 实时数据流接口,以及基于 Web 的可视化界面。部署后通过浏览器访问即可查看实时姿态估计结果。

4.2 RuVector:AI 智能骨干

RuVector 是 RuView 的 AI 智能层,它的存在解决了一个核心问题:原始 WiFi 信号是嘈杂的、冗余的、且高度依赖环境的。如果不经过智能处理,直接将原始 CSI 数据送入神经网络,不仅效果差,而且计算开销巨大。

RuVector 使用注意力机制来学习"应该信任哪些信号"——不同子载波对人体不同部位的运动敏感度不同,注意力机制可以自动发现这种关联,而无需人工设定阈值。图算法(Graph Algorithm)模块则自动发现哪些 WiFi 信道对人体运动最敏感,这在多节点 Mesh 组网的场景下尤为重要。压缩表示(Compressed Representation)模块将高维的 CSI 特征压缩成紧凑的向量,使得整个模型可以在仅 55KB 内存的 ESP32 芯片上运行。

4.3 自学习系统

RuView 还内建了一套自学习系统,这是它能够实现"即插即用"的关键。传统的 WiFi 感知系统需要在每个新环境中重新采集标注数据并训练模型。RuView 的自学习系统可以直接从原始 WiFi 数据中进行无监督学习——它将每一个 WiFi 信号转化为一个 128 维的"环境指纹"向量,通过对比学习来理解"相似"和"不同"的含义。

这个自学习过程不需要摄像头、不需要标注、不需要人工监督。你只需要将传感器插入电源,等待约 10 分钟,系统就会自动学习当前环境的特征。学习完成后,它可以进行房间识别、入侵检测、人员识别和活动分类——仅使用 WiFi 信号。


五、硬件方案详解:ESP32-S3 Mesh 组网

对于想要动手实践的读者,莫潇羽@无忆研习社 在这里详细介绍 RuView 推荐的硬件方案。

5.1 为什么选择 ESP32-S3?

乐鑫(Espressif)是全球知名的 WiFi/蓝牙芯片厂商,总部位于上海。其 ESP32 系列芯片在 IoT 领域有着广泛的应用。在 CSI 感知能力方面,乐鑫官方给出的芯片排名为:

ESP32-C5 > ESP32-C6 > ESP32-C3 ≈ ESP32-S3 > ESP32

ESP32-S3 之所以被 RuView 选作主要硬件方案,原因在于它的综合表现最为均衡:双核 240MHz CPU 支持 AI 指令集,能够运行轻量级的机器学习推理;支持 STA + Promiscuous(混杂)模式,可以在连接 WiFi 的同时监听 CSI 数据;价格低廉,单块开发板约 8 美元;乐鑫官方提供了完善的 esp-csi 开源库和文档支持。

5.2 推荐组网方案

RuView 推荐使用 3—6 个 ESP32-S3 节点组成 Mesh 网络。这些节点分布在房间的不同位置,每个节点既是 WiFi 信号的发射器也是接收器。

单个接入点的感知能力有明显的局限性:人体背后的肢体是"看不见"的,深度信息是模糊的,两个处于同一距离的人会在信号中混叠在一起。这些都是物理层面的限制,软件无法解决。多节点 Mesh 组网正是为了突破这个物理瓶颈。以 4 个节点为例,它们之间可以形成 4×(4-1)=12 条 TX-RX 测量链路,覆盖 360 度的观测角度。

每个节点在 WiFi 信道 1、6、11 上跳频工作,通过 TDM(时分复用)协议协调,避免节点之间的信号冲突。3 个信道 × 56 个子载波 = 168 个虚拟子载波,有效带宽从 20MHz 扩展到了 60MHz。注意力加权的融合层会自动学习每个观测角度对每个身体部位的重要性——比如,侧面视角对手臂姿态的贡献大于正面视角。

以下是一个 4 节点的组网示意:

    [节点 0]
       |
       |  ← 12条测量链路
       |
[节点 3] ---- 被感知区域 ---- [节点 1]
       |                        |
       |                        |
    [节点 2]

5.3 硬件成本估算

一套基础的 3 节点 ESP32-S3 Mesh 系统的硬件成本大约在 54 美元左右(约合人民币 390 元),具体包括:

  • 3 块 ESP32-S3 开发板(约 8 美元/块)
  • USB 数据线和供电适配器
  • 可选:外接 2.4GHz 天线(IPEX 接口的天线效果优于 PCB 天线)

如果需要更高的感知精度和覆盖范围,可以扩展到 6 个节点。整套系统不需要任何特殊硬件,所有组件都可以从主流电商平台购买到。


六、完整部署指南:从零开始搭建 WiFi 感知系统

以下是莫潇羽@无忆研习社 整理的完整部署流程。整个过程分为三个阶段:软件环境搭建、硬件固件烧录、系统启动与调试。

6.1 第一阶段:软件环境搭建

方案一:Docker 部署(推荐新手使用)

这是最快速的入门方式,30 秒内即可启动一个带有模拟数据的演示环境:

# 拉取 Docker 镜像
docker pull ruvnet/wifi-densepose:latest

# 启动服务
docker run -p 3000:3000 ruvnet/wifi-densepose:latest

# 在浏览器中访问 http://localhost:3000 查看可视化界面

Docker 模式下,系统会使用合成数据运行完整的处理流水线。虽然没有真实的 CSI 输入,但你可以借此熟悉整个系统的 API 接口、数据格式和可视化界面。

方案二:从源码编译(适合开发者)

如果你需要修改代码或连接真实硬件,需要从源码编译 Rust 版本:

# 克隆仓库
git clone https://github.com/ruvnet/RuView.git
cd RuView

# 使用安装脚本(自动安装 Rust 工具链)
./install.sh --profile rust --yes

# 编译并运行
cargo run -p wifi-densepose-sensing-server -- \
  --http-port 3000 --ws-port 3001 --tick-ms 500

不同操作系统的启动命令有所差异:

# Linux(需要 root 权限进行主动扫描)
sudo ./target/release/sensing-server \
  --source linux --http-port 3000 --ws-port 3001 --tick-ms 500

# macOS(需要先编译 Swift 辅助工具)
swiftc -O v1/src/sensing/mac_wifi.swift -o mac_wifi
./target/release/sensing-server \
  --source macos --http-port 3000 --ws-port 3001 --tick-ms 500

# Windows
./target/release/sensing-server \
  --source windows --http-port 3000 --ws-port 3001 --tick-ms 500

6.2 第二阶段:ESP32-S3 固件烧录

如果你购买了 ESP32-S3 硬件,需要将 CSI 采集固件烧录到芯片上。RuView 项目提供了预编译的固件二进制文件,无需自行编译 ESP-IDF。

步骤一:安装烧录工具

pip install esptool --break-system-packages

步骤二:烧录固件

python -m esptool --chip esp32s3 --port COM7 --baud 460800 \
  --before default_reset --after hard_reset \
  write_flash --flash_mode dio --flash_freq 80m --flash_size 4MB \
  0x0 bootloader.bin \
  0x8000 partition-table.bin \
  0x10000 esp32-csi-node.bin

注意将 COM7 替换为你的实际串口号。在 Linux 上通常是 /dev/ttyUSB0,在 macOS 上通常是 /dev/cu.usbserial-*。

步骤三:配置 WiFi 凭据

烧录完成后,使用 provision.py 脚本配置 WiFi 连接信息。这些信息写入芯片的 NVS(非易失性存储),不会嵌入固件二进制文件中,确保安全性。

python provision.py --port COM7 \
  --ssid "你的WiFi名称" --password "你的WiFi密码" \
  --target-ip 192.168.1.20 --target-port 5005

步骤四:多节点 TDM 配置

如果使用多个 ESP32-S3 节点,需要为每个节点配置 TDM 时隙以避免信号冲突:

# 节点 0
python provision.py --port COM7 --ssid "WiFi" --password "pass" \
  --target-ip 192.168.1.20 --tdm-slot 0 --tdm-total 3

# 节点 1
python provision.py --port COM8 --tdm-slot 1 --tdm-total 3

# 节点 2
python provision.py --port COM9 --tdm-slot 2 --tdm-total 3

步骤五:启动 CSI 聚合器

在服务器端(可以是你的电脑或树莓派)启动 Rust 聚合器,接收来自所有 ESP32 节点的 CSI 数据:

# 从源码运行
cargo run -p wifi-densepose-hardware --bin aggregator -- \
  --bind 0.0.0.0:5005 --verbose

# 或使用 Docker
docker run -p 3000:3000 -p 5005:5005/udp \
  ruvnet/wifi-densepose:latest --source esp32

如果你使用 Windows 系统,还需要配置防火墙规则允许 UDP 5005 端口:

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

6.3 第三阶段:系统启动与 API 调用

系统启动后,可以通过以下方式与之交互。

REST API 调用示例:

# 健康检查
curl http://localhost:3000/health

# 获取最新感知帧
curl http://localhost:3000/api/v1/sensing/latest

# 获取生命体征数据
curl http://localhost:3000/api/v1/vital-signs

# 获取当前姿态估计
curl http://localhost:3000/api/v1/pose/current

# 获取服务器信息
curl http://localhost:3000/api/v1/info

Python SDK 调用示例:

from wifi_densepose import WiFiDensePose

# 初始化系统
system = WiFiDensePose()
system.start()

# 获取最新姿态数据
poses = system.get_latest_poses()
print(f"检测到 {len(poses)} 个人")

# 停止系统
system.stop()

WebSocket 实时数据流:

import asyncio
import websockets
import json

async def stream():
    async with websockets.connect("ws://localhost:3001/ws/sensing") as ws:
        async for msg in ws:
            data = json.loads(msg)
            persons = data.get('persons', [])
            print(f"当前检测人数: {len(persons)}")
            for i, person in enumerate(persons):
                keypoints = person.get('keypoints', [])
                print(f"  人员 {i+1}: {len(keypoints)} 个关键点")

asyncio.run(stream())

七、信号处理流水线深度拆解

对于想要深入理解技术细节的读者,莫潇羽@无忆研习社 在这里对信号处理流水线的每一步进行详细拆解。

7.1 CSI 数据帧格式

ESP32-S3 节点通过 UDP 协议发送的每一帧 CSI 数据,遵循如下二进制格式:

偏移量  大小    字段说明
0       4      魔术数: 0xC5110001
4       1      节点 ID
5       1      天线数量
6       2      子载波数量 (小端序 u16)
8       4      频率 MHz (小端序 u32)
12      4      序列号 (小端序 u32)
16      1      RSSI (有符号 i8)
17      1      噪声底板 (有符号 i8)
18      2      保留字段
20      N*2    I/Q 数据对 (int8 对, 天线数 × 子载波数 × 2)

每一帧包含所有天线在所有子载波上的原始 I/Q(同相/正交)值。I/Q 值以有符号 8 位整数的形式编码,每对 I/Q 值可以计算出对应子载波的幅度和相位。

7.2 相位清洗:共轭乘法

原始的 CSI 相位数据是不可靠的,因为发射端和接收端的时钟没有同步。具体表现为:采样时间偏移(STO)会在整个频域引入线性相位斜率;采样频率偏移(SFO)会引入缓慢漂移;载波频率偏移(CFO)会叠加一个随时间变化的全局相位。

共轭乘法是一种优雅的解决方案。假设两根接收天线在同一子载波上的 CSI 值分别为 (H_1) 和 (H_2),它们的共轭乘积 (H_1 \cdot H_2^*) 可以消除上述所有公共相位误差,只保留与空间路径差异相关的有用信息。

7.3 Hampel 滤波器

Hampel 滤波器是一种基于中位数的鲁棒滤波器,特别适合去除突发性离群值。它的工作原理是:在一个滑动窗口内,计算所有数据点的中位数和中位绝对偏差(MAD)。如果某个数据点偏离中位数的程度超过 MAD 的若干倍(通常设为 3 倍),就将其替换为中位数。

相比简单的均值滤波或低通滤波,Hampel 滤波器的优势在于它对突发干扰(如微波炉启动、蓝牙设备跳频)的处理能力更强,同时不会过度平滑正常的信号变化。

7.4 子载波选择

并非所有的 56 个子载波都对人体运动同样敏感。有些子载波可能处于信号的深度衰落点(deep fade),即便有人移动也几乎没有反应;有些子载波则对特定方向或距离的运动高度敏感。

RuView 使用 Top-K 选择策略,通过分析一段时间内各子载波的信号方差(或者更精细的指标如 Normalized Bandwidth Variance Index, NBVI),自动选出对当前环境最具信息量的 K 个子载波参与后续处理。这不仅提高了感知精度,还减少了计算量。

7.5 CSI 频谱图

选定的子载波时域信号通过短时傅里叶变换(STFT)或连续小波变换(CWT)转化为二维的时频频谱图。频谱图的横轴是时间,纵轴是频率,颜色/亮度代表能量大小。

人体不同类型的运动在频谱图上呈现出截然不同的模式。比如走路产生的多普勒频移通常在 5—20Hz 范围内,而呼吸引起的体表微动则集中在 0.1—0.5Hz 的极低频段。频谱图将这些信息以直观的二维形式呈现出来,非常适合作为神经网络的输入。

7.6 Fresnel 呼吸检测与心率估计

RuView 使用菲涅尔模型(Fresnel Zone Model)来检测呼吸。这个概念来源于光学中的菲涅尔衍射理论,被巧妙地应用到了 WiFi 信号感知领域。

WiFi 发射器和接收器之间的空间可以被划分为一系列同心椭球面,称为菲涅尔区(Fresnel Zone)。第一菲涅尔区是最重要的——WiFi 信号的大部分能量集中在这个区域内。当人体位于第一菲涅尔区的边界附近时,胸廓随呼吸产生的厘米级起伏,会导致人体在相邻菲涅尔区之间交替移动,引起接收信号的周期性增强和衰减。

具体来说,呼吸检测的信号处理流程如下:首先,从预处理后的 CSI 数据中选取对呼吸最敏感的子载波(不同子载波对不同身体部位的微动敏感度不同,有些子载波对胸廓起伏高度敏感,有些则几乎没有反应);然后,对选定子载波的时域信号应用带通滤波器,保留 0.1—0.5Hz 的频段(对应正常成人 6—30 次/分钟的呼吸频率范围);最后,使用自相关函数或快速傅里叶变换(FFT)提取信号的主周期,得到呼吸频率。

心率检测的原理类似,但难度更高。心跳引起的体表振动

🔒
该内容仅对更高等级社区用户开放
请谨慎解锁时效性强且发布日期较早的文章
单篇解锁后若未显示全文请刷新页面
您当前:游客 · 可见 60% 内容 · 升级至 注册用户 可见 70%
👀
游客
可见 60%
✓ 当前
注册用户
注册用户
可见 70%
社区精英
社区精英
可见 100%
社区守护
社区守护
可见 100%
仅解锁本文,永久有效。如需PDF珍藏版,请联系站长获取。 当前单篇价格 ¥9.9
✏️ 发表评论

请先登录后发表评论

前往登录
📊 站点统计
今日发布0 篇
文章总数1107 篇
昨日发布1 篇
本月发布31 篇
建站时间456 天
🔍 搜索
站长微语

联系站长

QQ:2805463528
AIGC 技术社区
致力于解码 AI前沿技术 与经验分享
纯粹的技术应用社区

💡 欢迎您的建议与反馈,让社区变得更好

快速通道
联系站长
站长QQ二维码
AI交流群
AI交流群
仍在路上

那些寒夜里追赶过的方向

那些冷眼下没放弃的理想

一篇一篇写到现在

仍在路上

"不羁放纵爱自由"

—— 致敬 Beyond
持续创作中 莫潇羽 · 无忆研习社
▲