单链路WiFi被动人体追踪:从CSI多普勒到BVP位置解算
发布时间:2026/10/22 12:06:47 锦皓数字建站

做无线感知的人十有八九都听过这句话WiFi 不仅能传数据还能当雷达用。但真正去复现相关论文时你会发现绝大多数方案要么依赖多链路设备要么需要密集的指纹标定能做到“单条WiFi链路 无设备携带 连续坐标输出”的屈指可数。Widar2.0 这篇论文的标题本身就把这三个关键词摆到了台面上Passive Human Tracking with a Single Wi-Fi Link。我读完第一遍时的感受是思路不复杂但每个环节都踩在信号处理的关键点上。这篇读 Paper 笔记我想把它讲透。单链路为什么难CSI 里到底藏着什么信息BVP 这个速度-位置联合估计是怎么把多普勒频移变成坐标的以及复现过程中最容易翻车的几个工程细节。适合刚接触无线感知方向的研究生也适合打算把手势识别、跌倒检测、人员看护这类能力往智能家居里塞的开发者。我的建议是不管你是准备跑实验还是想落地产品先把这篇论文的物理模型吃透再看代码顺序反了很容易被一堆参数绕晕。1. 这篇论文到底在解决什么问题1.1 什么是单链路被动人体追踪被动人体追踪用大白话说就是人身上不挂任何设备系统只靠环境里的无线信号变化判断这个人现在站在哪、往哪走。这和手机定位、手环定位有本质区别——被动追踪不需要目标主动配合也不需要目标携带信标。典型场景是老人夜间起床跌倒检测、室内入侵感知、智能照明跟随这些场景里人是“零负担”的体验上比任何可穿戴设备都自然。那“单链路”又是什么链路指的是一个发射机和一个接收机之间的无线信道。所谓单链路就是整个系统里只有一台发射设备比如一个普通无线路由器和一台接收设备比如一台带无线网卡的笔记本数据也只在这一个收发对之间采集。没有多个 AP 协同没有天线阵列硬件上几乎零改动。这在实际部署里吸引力极大成本低、安装简单、不需要对房间做专门改造。但问题也随之而来。单链路意味着空间采样维度极少传统的到达角、到达时间、双曲线定位等方法都需要多个收发端或者较大天线阵列才能提供足够约束。所以 Widar2.0 最核心的贡献不是提出一个新的滤波公式而是证明了即使只有一个链路只要把多普勒信息用到位人体跟踪依然是可解的。1.2 为什么此前没人做出来在 Widar2.0 之前学术界在 WiFi 人体感知上的主流路线其实已经不少了。手势识别用 CSI 幅度波动步态识别用多普勒特征室内定位用 RSSI 指纹或者 CSI 指纹。但这些方向大多在回答“这个人做了什么动作”或者“这个人大概在哪个区域”要连续输出“他现在具体在哪个坐标”精度通常不够。原因是多方面叠加的。第一WiFi 信号带宽有限距离分辨率很低不可能像 FMCW 雷达那样直接测目标距离。第二室内多径严重直接拿 CSI 幅度做特征很容易被环境中的静态反射淹没。第三单链路条件下目标相对发射机和接收机的运动信息只有一维的投影从一维观测恢复二维坐标数学上是个典型的欠定问题。Widar2.0 的破局点在于换了一个观测对象——不再盯着 CSI 的幅度变化而是用高灵敏度的多普勒频移并且在反演阶段没有试图单帧求解而是把多帧观测通过速度-位置联合估计框架BVP融合起来。多径在这里不再是干扰反而成了额外约束的信息源。这个思路在当年属于比较超前的现在看依然是单链路人体追踪绕不开的参考方案。1.3 技术定位与贡献总览从论文整体来看Widar2.0 的完整流程可以概括为采集 CSI → 相位校准 → 短时傅里叶变换生成多普勒谱 → 提取多普勒谱峰 → 构建速度-位置联合估计问题 → 求解目标位置 → 平滑输出轨迹。这个流程里有几个关键决策值得注意。用 CSI 而不是 RSSI保证了多普勒提取的灵敏度。用多普勒频移而不是直接测距规避了 WiFi 带宽对距离分辨率的限制。用离线轻量标定而不是密集指纹提升了环境迁移能力。用 BVP 联合估计而不是单帧定位解决了单链路欠定问题。方案类型设备要求目标是否携带设备空间标定成本输出精度主动雷达专用毫米波雷达否低厘米级多链路 WiFi 指纹定位多个 AP 采集端否高需逐点采集米级Widar2.0 单链路多普勒一个 Tx 一个 Rx否低只需少量位置标定亚米级到米级表格里最后一行就是 Widar2.0 的定位。它没有去和专用雷达比精度而是在“普通 WiFi 设备 无佩戴 低成本标定”这个约束组合下把精度做到了可用的程度。这个取舍非常务实也是我觉得这篇论文最值得学习的地方。2. 底层物理量CSI 才是 WiFi 感知的灵魂2.1 RSSI 为什么做不了这件事很多第一次接触 WiFi 感知的人会问直接用网卡上报的 RSSI 不行吗答案是不行而且不是精度问题是信息量问题。RSSI 是接收端把整个信道里所有路径的能量叠加之后再取平均值得到的一个功率值。它只回答“信号强不强”完全不含“信号是怎么复合出来的”这些细节。打个比方RSSI 像是全班考试的平均分平均分高了你只知道整体不错但不知道谁擅长数学谁擅长语文更不知道哪个学生今天缺考。而 CSI 是每个学生的各科详细成绩单每个子载波都有独立的幅度和相位能看出多径干涉的“频谱花纹”。人体移动时反射径长度发生变化会在不同子载波上引起不同程度的相位旋转和幅度涨落这些微观变化只有 CSI 才捕捉得到。所以 Widar2.0 的一开始就是从 CSI 下手。实验里如果你手上只有 RSSI 数据就算后端算法再强也无法提取出多普勒频移的微量波动——这个方向直接就被 RSSI 的信息瓶颈卡死了。2.2 CSI 里到底装了什么信息WiFi 的 OFDM 系统把一个信道划分成若干子载波每个子载波都可以看作一个独立的窄带信道。CSI 就是对这些子载波信道的复增益估计通常表示为幅度和相位两部分。以常见的 20 MHz 带宽为例有几十个子载波40 MHz 带宽则上百个。每个子载波上的复增益实际上是发射端、接收端、目标、环境共同作用的结果。由于人体运动速度很慢由人体反射引起的 CSI 变化频率也很低通常在 0.1 Hz 到 30 Hz 这个范围。而无线网卡的帧采样率可以做到几百到一千赫兹完全覆盖这个动态范围。这意味着 CSI 中其实包含了远低于通信系统“有效载荷”频率的低频运动信息只是平时这些信息作为干扰被通信系统滤掉了。Widar2.0 做的事情本质上就是把这些平时被当成噪声的低频成分提取出来再用物理模型解释它们。这一步很关键不是拿到 CSI 就直接上深度学习而是先明确“信号里有什么物理量”再设计对应的提取算法。论文把重点放在多普勒频移而不是 CSI 幅度上就是因为多普勒与人体运动速度之间有一个非常干净的物理对应关系幅度特征在这种量级下反而容易非线性失真。2.3 多普勒频移是怎么从 CSI 里冒出来的多普勒频移这个现象大家都熟悉火车靠近时汽笛声变尖远离时变低沉。无线信号也一样。当人体移动导致反射路径长度持续变化时接收信号的相位会持续旋转等效频率发生偏移。对一条反射路径来说瞬时频率偏移量与路径长度变化率成正比公式写出来就是f_d -(1/λ)(v · u_T v · u_R)其中 λ 是 WiFi 信号波长v 是人体运动速度矢量u_T 是从目标指向发射机的单位向量u_R 是从目标指向接收机的单位向量。λ在 2.4 GHz 频段大约 0.125 米人体以每秒 1 米的速度行走时多普勒频移大约 8 Hz听起来很低频但完全在 CSI 的时间分辨率之内。从信号处理角度看多普勒频移是相位的微分量。所以采集到的 CSI 必须保留准确的相位信息而且相位必须足够稳定否则微小的频移会被噪声淹没。这也是后面所有工程细节里最麻烦的一点WiFi 收发两端时钟不同步相位本身存在恒定漂移如果不对 CSI 相位做校准多普勒谱直接是糊的。3. 核心算法拆解BVP 速度-位置联合估计3.1 信号处理前端从 CSI 到干净的多普勒谱先说前端因为后面所有位置解算都建立在多普勒谱的质量上。我的经验是至少一半的复现问题出在这一步而不是算法本身。标准前端流程一般分四步。第一步采集原始 CSI。需要拿到每个子载波在每个包时刻的复数值通常用支持 CSI 导出的开源工具完成。第二步做相位校准。由于发射机和接收机的本地振荡器不同步CSI 相位里会混入一个线性递增的漂移项。常用的做法是对一段时间内的相位做线性拟合再把残差当作有效相位。第三步按子载波把 CSI 序列重排为时间序列对每个子载波做短时傅里叶变换STFT得到“多普勒频移-时间”的二维图谱。第四步在多普勒谱上做峰值提取。人体反射对应的多普勒峰通常是最强且连续的一段用峰值追踪算法可以把它从背景杂波中分离出来。STFT 的窗长选择是个取舍。窗长越长频率分辨率越高但时间分辨率越低。在 2.4 GHz 频段0.5 秒的窗大约对应 2 Hz 的频率分辨率折算成人步行速度大概能分辨每秒 0.25 米的变化基本满足连续追踪的需求。如果再强调实时性可以用 0.3 秒左右然后配合后端的平滑滤波。3.2 多普勒观测与空间几何的约束关系现在问题进入核心有了多普勒频移怎么变成位置把前面那个公式翻过来看。给定一个候选位置 P 和一个候选速度向量 v我们可以根据房间几何算出 u_T 和 u_R再算出预测的多普勒频移。实际观测到的多普勒频移是从信号里提取出来的。于是定位问题变成一个逆问题找一条位置-速度轨迹使得每个时刻的预测多普勒都尽可能等于观测多普勒。难点在于单个时刻的多普勒观测只是一个标量而未知量是二维位置加二维速度对应四个自由度。一个标量方程显然没法唯一确定四个未知量解空间是一个有冗余的超曲面。这就是为什么单帧定位做不了。但把时间维度引入后情况完全不一样。目标的运动不是独立的相邻时刻的位置变化由速度决定速度本身又有运动学约束。多帧观测串联起来等于是用连续时间上的多个标量观测去约束一条位置-速度轨迹。多普勒方程在这个过程里就像锁链一样一环扣一环把欠定问题逐步收紧成一个可解的优化问题。这就是 Widar2.0 里 BVPBody-Velocity-Profile的核心思想不是把目标当作瞬时点而是当作一条在速度-位置空间里连续演化的轨迹来估计。3.3 位置解算里的工程技巧数学上BVP 的求解可以写成最小化预测多普勒与观测量之间残差的优化问题同时加入两个先验位置变化必须与速度向量自洽速度大小必须落在人体运动合理区间内比如 0 到 3 米每秒。实际求解时直接做全局搜索代价很高论文采用的做法是先做一个解析初始化再用迭代优化精修。解析初始化相当于先找出一个大概的候选区域缩小优化范围迭代阶段再用牛顿法或梯度法在初始值附近收敛。这种“先粗后细”的思想在工程上很常见但它特别依赖前端多普勒谱的干净程度。我在实际复现中发现单纯看多普勒谱峰值还不行。因为人体各个部位反射强度不同躯干反射最强手臂摆动也会产生额外的多普勒分量。峰值追踪如果不加约束经常会跳到手臂或者腿对应的旁瓣上。后来我加了一个速度连续性的逻辑当前帧追踪到的峰值位置必须离上一帧峰值位置足够近否则认为是错误峰。这个技巧很朴素但对定位稳定性的提升非常明显。3.4 为什么不用指纹也能定位传统指纹定位的做法是把房间划分成网格在每个网格位置采集大量 WiFi 特征构建特征-位置映射数据库在线阶段用当前特征查数据库。问题在于采集工作量极大而且环境一变家具移动、人员桌位变化数据库就失效需要重新采集。Widar2.0 之所以能避开指纹是因为它内部有一个参数化的物理模型。模型参数只有房间几何、收发端位置、反射面关系这些有限项离线阶段只需要在房间里走几条路径、站几个已知位置把模型中的少量偏差项校准出来即可。这比逐点采集省了一个数量级的功夫而且模型的可解释性更强换环境后的迁移成本也低。这里我想多说一句指纹方案并不是完全没用在某些强多径、非视距严重的场景下指纹反而比物理模型更鲁棒。但指纹方案天生不适合从一个房间搬到另一个房间而 Widar2.0 的模型迁移只需要重新做一轮轻量标定。对于要做产品的人来说这个差别往往决定了成本上限。4. 离线标定与在线解算工程系统怎么搭4.1 离线阶段要标定什么Widar2.0 的离线标定不需要你在房间网格上站几百个点。实测下来标定流程大概是这样确定发射机和接收机的固定位置记录它们的坐标在房间里选几个有代表性的路径让人按已知轨迹走动同时采集 CSI提取多普勒谱把已知轨迹真值代入用于拟合模型中的偏差参数。这些标定动作本质上是在解决两个问题一是消除系统性的相位和非理想因素二是校准信号传播模型中的反射系数和路径损耗。由于模型参数数量有限几段标定轨迹通常就够用了整个过程大概十几分钟。对比之下我在其他多链路方案上做过逐点指纹采集一个 20 平方米的房间要采几百个点每点还要停留若干秒一搞就是大半天。只要环境变一次就是一次灾难。所以 Widar2.0 这种“轻量标定 物理模型”的路线工程友好度是明显占优的。4.2 在线阶段的数据流在线阶段的处理流程比离线更简洁。持续从无线网卡读取 CSI。对相位做同样的校准避免长期漂移。滑动窗口计算多普勒谱。峰值追踪得到目标的多普勒频率序列。将频率序列送入 BVP 求解器得到位置坐标。用卡尔曼滤波器平滑轨迹输出最终坐标。这里有个参数值得重点提CSI 的包采样率。理论上越高越好因为人体动作在快走时多普勒频率可能到 15 Hz 往上为了不混叠需要至少 30 Hz 的采样率。但实际采集时我通常设到 100 Hz 以上一方面是为了留足余量另一方面是后续 STFT 需要多个子载波联合平均数据多一点能显著提高谱质量。缺点是数据量变大实时处理时要注意队列积压。实测中 100 Hz 的 CSI 数据跑一个简单的多普勒谱估计加 BVP 迭代普通 CPU 上仍然能实时运行性能压力并不大。4.3 环境泛化到底能做到什么程度很多人关心换一间房间要不要重新训练Widar2.0 的做法决定了它比指纹方案泛化能力强但也不是完全不用管。因为 BVP 模型里仍然需要知道发射机、接收机的坐标以及环境中主要反射面的位置。换一个房间只要重新量一下设备位置和几个反射面坐标然后走一小段标定轨迹就能继续使用。所以准确说Widar2.0 的泛化逻辑是“参数重置”不是“零配置”。这在实际部署中已经非常理想了毕竟没有任何感知方案可以完全不考虑环境变化。论文里展示的实验大多是在空旷室内和普通办公室环境下做的我在类似环境复现时精度基本能达到“知道人在房间哪个区域、往哪边移动”的粒度在杂物很多、金属家具密集的环境下精度会下降得明显一些这时需要增加离线标定的轨迹数量来补偿。5. 复现中踩过的坑与排查实录5.1 相位漂移多普勒谱最大的敌人复现 Widar2.0 最痛苦的部分不是算法而是相位漂移。WiFi 收发两端的时钟频率不可能完全一致导致 CSI 相位里混入了一个随时间线性增长的漂移项。如果不处理直接对 CSI 相位做 STFT你会发现谱图上出现一条稳定斜向上的亮线根本分不清真实多普勒。解决办法分两层一是对每个子载波的相位序列做线性拟合把整体漂移减去二是在 STFT 之前做子载波间的相位校正因为不同子载波的漂移可能不同。我踩过的坑是只做了整体线性拟合没针对子载波逐一遍历结果低频段还好、高频子载波上残留漂移依然明显。后来把“逐子载波去漂移”加进预处理流程多普勒谱一下子就干净了。这条经验在几乎所有基于 CSI 相位的工作里都通用。5.2 多普勒模糊与人和物分辨多普勒模糊是个原理性问题同一时刻房间不同位置的两个人如果相对发射机接收机的径向速度相同会产生几乎一样的多普勒频率。单纯依赖多普勒是无法分辨这种模糊的。Widar2.0 能缓解这个问题的原因是它追踪的不是单帧孤立的速度而是连续轨迹不同位置的轨迹在速度空间里的演化方式不同配合位置连续性大部分模糊都能被排除。但在实际场景里如果房间里有一个移动的吊扇、宠物或者另一个静止的人多普勒谱会出现额外的峰。峰值追踪一旦追踪错对象定位就会跳到完全不相关的区域。我的做法是在追踪阶段维护多个候选峰让 BVP 求解器对每个候选都解一次再根据轨迹连续性选择最合理的一个。计算量稍微变大但鲁棒性提升明显。另外人的躯干反射能量比四肢强得多所以多普勒谱里通常有一个主峰对应躯干速度几个较弱峰对应四肢。实验时尽量让人正常行走而不是原地挥手否则追踪极易被四肢峰值带偏。5.3 追踪跳变、静止检测和边缘失效跳变是定位系统常见病。现象是轨迹上一帧还在房间左侧下一秒跳到右侧再下一秒又跳回来。原因往往是多普勒谱出现误峰或者 BVP 优化落入了错误的局部极小值。缓解手段除了前面说的多候选追踪还可以在优化目标里加大位置平滑项的权重让轨迹不能突变。卡尔曼滤波器虽然不能解决数据层面的错误但能把突变成滤波后的缓变看起来更自然也不会造成执行器误动作。静止检测则是另一个容易被忽视的问题。目标完全静止时多普勒频移为零谱峰落在零频附近和静态多径混在一起。所以系统里需要单独设计一个判断如果连续若干帧的多普勒能量都集中在零频就认为目标静止保持上一帧位置输出。这个逻辑看着简单但没有它目标一旦停下定位结果会随机漂。边缘失效发生在目标接近房间边界或者被大型遮挡物挡住的时候。此时反射路径消失多普勒峰可能突然断裂。我的应对是给峰值追踪算法加一个“保持窗口”如果峰丢失不超过几百毫秒用上一帧速度外推位置超过这个时间才宣布丢失。这样短暂失效不会把轨迹切成几段。5.4 一个小而高效的处理流程代码骨架这里给一个从 CSI 相位序列估计多普勒谱的伪代码骨架实际工程里在这个基础上加滤波和峰值追踪就能形成完整前端。# 伪代码从 CSI 相位序列估算多普勒谱 # csi_data: shape (子载波数, 时间帧数) all_spectra [] for sub in range(csi_data.shape[0]): # 1. 提取相位并解卷绕 phase unwrap(angle(csi_data[sub, :])) # 2. 线性拟合去除收发时钟造成的相位漂移 coeffs polyfit(t_axis, phase, deg1) phase_corrected phase - polyval(coeffs, t_axis) # 3. 短时傅里叶变换得到多普勒谱 freq_axis, time_axis, spectrum stft( phase_corrected, window_length0.5, # 秒 overlap0.5, # 50% 重叠 sampling_rate100 # CSI 帧率 Hz ) all_spectra.append(abs(spectrum) ** 2) # 4. 对所有子载波的谱平均增强信噪比 doppler_map mean(all_spectra, axis0)代码里最关键的是第二步。很多人刚开始会把 unwrap 误写成直接取 angle结果相位在 -π 和 π 之间跳变STFT 后全是伪峰。另一个常见问题是对整段长时间数据只做一次线性拟合但 WiFi 时钟漂移并不是稳定常数它会随温度缓慢变化。工程上更稳妥的做法是把数据切成长度适中的块比如 10 秒一段逐段做线性拟合效果会好很多。6. 常见问题速查与排查经验现象可能原因处理方法多普勒谱糊成一片看不到清晰峰相位漂移未完全校正逐子载波线性去漂移分块拟合谱峰存在但不连续跳动明显峰值追踪误跟到旁瓣或四肢峰加速度连续性约束多候选追踪目标静止时坐标随机漂零频特征与静态多径混叠加静止检测静止时保持上一帧输出目标走到房间角落时轨迹断裂反射路径被遮挡峰丢失加保持窗口用上一帧速度外推运动方向经常判断反多普勒符号受相位解卷绕错误影响检查 unwrap 是否正确确认采样速率换房间后误差明显增大模型参数未更新重新标定设备坐标和反射面参数实时处理时数据越积越多STFT 窗长过大或采样率过高降低窗长到 0.3 秒适当降采样率排查时我的习惯是先把前端多普勒谱可视化确认谱图干净再往后走。如果谱图质量不行后端算法再努力也白搭。这算是整个复现里性价比最高的一步。根据我个人经验有几个细节想再强调一下。第一个是不要一上来就追求高精度厘米级Widar2.0 的定位粒度更适合描述为“房间内区域级连续追踪”能知道人在哪个区域、什么时候开始移动、往哪个方向移动这已经能支撑很多智能场景。第二个是实验环境的干扰比想象中多隔壁办公室的 WiFi 信号、微波炉、手机蓝牙都会在频谱上留下痕迹采集时尽量选 WiFi 信道拥堵程度低、时段安静的场景。第三个是算法参数别照搬论文论文里的参数是在他们的实验环境下调出来的到了你的房间至少要把目标速度范围、STFT 窗长、平滑权重重新过一遍。最后再分享一个小技巧调试 BVP 时把预测多普勒和观测多普勒画在同一张图上如果两条曲线形状整体吻合只是有固定偏移那是模型标定误差如果形态对不上那是峰值追踪或者相位处理的问题。这个区分能帮你快速定位到底是哪个环节出了问题省下大量盲目调参的时间。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。