先把话说在前头:这个项目名字是我自己起的,PLFM_RADAR,其中一个含义是“Platform for Low-cost Frequency Monitoring RADAR”,说白了就是一套基于低成本软件无线电(SDR)平台搭建的轻量级雷达探测系统。别看它名字起得挺唬人,实际解决的需求很朴素:在不开昂贵专用雷达设备的前提下,用几百块的SDR接收机加上开源信号处理链路,实现对周边运动目标的探测、测距和测速。这几年我在这个方向上反复折腾了不少版本,从最初的“能出一个频点图”到后面真正能画出距离-多普勒图谱,踩过的坑和值得说的细节都非常多。这篇内容就是基于我个人的实测经验,把整套系统的设计思路、硬件选型、参数计算、软件实现以及调试排错过程完整梳理一遍。如果你手头有SDR设备,或者正准备入门雷达信号处理,又不想一头扎进动辄几十页的理论公式里,那这篇文章应该能帮你少走很多弯路。
1. 整体设计思路与方案选型
1.1 为什么叫“PLFM_RADAR”,而不是直接叫“SDR雷达”
刚开始做这个项目的时候,我的目标其实很简单:用身边的SDR设备做一个能探测运动物体的东西。但真正去查资料时发现,“雷达”这个词的范围太大了。从脉冲多普勒雷达到调频连续波雷达,从气象雷达到车载毫米波雷达,每个方向都有自己的完整技术栈。
我之所以把项目叫做PLFM_RADAR,其实是给自己定了一个边界:做一个低成本、可复现、聚焦“探测与感知”的雷达实验平台。这里面的P代表Platform(平台),L代表Low-cost(低成本),F代表Frequency(频率),M代表Monitoring(监测)。平台强调系统是可扩展、可替换的,不是为了某一次实验而写的死代码;低成本意味着所有硬件加起来不超过主流手机的价格;频率监测点明了系统的工作基础——我们通过分析发射信号经目标反射后的频率变化,来反推目标的距离和速度信息。
说白了,PLFM_RADAR不是某一种具体体制的雷达,而是一个“壳子”:它承载了我对不同雷达体制的验证。今天想试FMCW就用FMCW的模式发射,明天想试连续波多普勒测速就切成单音模式。软件架构上,我把发射信号生成、接收信号采集、混频处理、FFT分析这些模块全部解耦,后续想往里加新的信号处理算法,只需要替换其中一个模块就行。
1.2 系统整体架构与工作流程
整套系统的工作流程可以用一句话概括:发射已知参数的射频信号,接收目标反射回来的回波,然后对回波进行混频和频谱分析,从频差和多普勒频移中解算出目标的距离和速度。
具体到物理链路,我采用的是零中频收发结构。发射链路和接收链路共用同一个本振源,发射信号通过天线辐射出去,遇到运动目标后产生反射,反射波被接收天线捕获。在接收机内部,回波信号与本振信号进行混频,得到包含目标信息的基带信号。这个基带信号经过ADC采样后送入计算机,剩下的全部工作在软件里完成。
这个架构的好处是省掉了传统雷达里昂贵的中频处理硬件。零中频结构下,混频直接落在基带,对ADC的采样率要求也能降下来。我用的是采样率不超过2MHz的配置,这个速率下普通声卡级别的ADC芯片就能胜任,数据量小时,连树莓派都能跑得动实时处理。当然代价也有,零中频结构对直流偏置和I/Q不平衡比较敏感,这部分问题我会在后面的问题排查章节详细说。
1.3 方案选型对比:为什么不用现成的雷达模块
做这个项目之前,我也认真考虑过直接用市面上现成的雷达模块,比如24GHz的毫米波雷达开发板,或者一些公司出的民用雷达套件。说实话,那些东西确实性能强,测距精度能到厘米级,测速也准,但它们的缺点是“黑盒”。模块内部到底怎么处理信号、怎么做目标检测、参数怎么调,你完全没有干预空间。
对想做信号处理学习的人来说,黑盒是最可怕的。你只能看着它输出一串距离和速度数据,但完全不知道这些数据是怎么来的。哪天测出来的数据不对,你连排查的方向都没有。而SDR方案虽然精度差点,但整个信号链路是透明的——发射信号的波形是你自己写的,接收数据是你自己采的,FFT的每一个点你都知道它代表什么物理含义。这种“全链路透明”的掌控感,是学习雷达原理时最宝贵的东西。
硬件成本方面,一套完整的PLFM_RADAR系统包括:一块RTL-SDR接收机(约80元)、一块ADALM-PLUTO发射板(约800元)或者自制的简易发射源(约100元)、一对2.4GHz频段的天线(约50元),再加上一些射频线缆和功分器。整套下来一千块出头,相比动辄上万甚至数万的商用雷达开发套件,成本优势非常明显。
| 方案 | 成本范围 | 链路透明度 | 可定制性 | 精度 | 适合人群 |
|---|---|---|---|---|---|
| 商用雷达模块 | 数千至数万 | 低,黑盒 | 差 | 高(厘米级) | 产品开发者 |
| 矢量网络分析仪方案 | 十万以上 | 中 | 中 | 极高 | 实验室研究 |
| PLFM_RADAR(SDR方案) | 千元左右 | 高,全透明 | 极强 | 中(分米到米级) | 学习者、电子爱好者 |
2. 核心原理:从电磁波反射到距离-多普勒图谱
2.1 雷达测距的基本逻辑:从回声到频差
雷达测距这件事,本质上和我们对着山谷喊话听回声没有区别。你喊一声,声音碰到山壁反射回来,你记录从发声到听到回声的时间差,再用声速乘以时间差除以2,就是山壁离你的距离。
电磁波雷达只是把这个过程搬到了射频段。电磁波以光速传播,我们发射一个信号,目标反射后回波被接收,通过测量发射信号与回波之间的时间差,就能算出目标的距离。但这里有一个问题:直接用脉冲测距,需要精确测量纳秒级的时间差。光速是3亿米每秒,目标距离每差1米,时间差只差大约6.7纳秒。普通设备根本测不了这么精细的时间。
所以FMCW体制换了个思路:不直接测时间,而是测频率。发射信号的频率随时间线性变化,就像一把频率“扫把”扫过一段频谱。信号从发射到接收,经历了往返传播的延迟。在这个延迟时间内,发射信号的频率已经继续变化了,于是回波信号的频率与当前发射信号的频率之间就出现了一个差值。这个频率差与往返时间成正比,而往返时间与距离成正比。由此,我们只需要在基带上测量这个频率差,就能换算出目标的距离。
2.2 从距离到速度:多普勒效应在雷达中的运用
测速用到的物理效应叫做多普勒效应,和火车鸣笛靠近你时音调变高、远离时音调变低是同一个原理。当目标相对雷达有径向运动时,反射回来的电磁波频率会发生偏移。目标靠近时,回波频率升高;目标远离时,回波频率降低。这个频率偏移量就是多普勒频移,它与目标的径向速度成正比。
在FMCW雷达中,多普勒频移和距离引起的频差是叠加在一起的。这带来一个问题:单从一次扫频的频谱上,我们无法把“远距离静止目标”和“近距离快速移动目标”区分开,因为它们在频谱上可能出现在同一个频率位置。
解决这个问题的办法是发射多个连续的扫频周期,然后对同一距离门上的多个周期做第二次FFT。第一次FFT把每个扫频周期内的信号按距离分辨,得到不同距离上的能量分布;第二次FFT针对某一个距离门上的时间序列,提取出多普勒频率轴。最终生成一个二维图谱:一维是距离,一维是速度,也就是雷达信号处理里常说的“距离-多普勒图”。
2.3 距离分辨率与速度分辨率的权衡
任何雷达系统都绕不开一组核心参数:距离分辨率、最大测量距离、速度分辨率和最大测量速度。这些参数相互制约,调了其中一个,其他几个会跟着变,颇有点“按下葫芦浮起瓢”的意思。
距离分辨率由扫频带宽决定,公式是分辨率等于光速除以两倍带宽。我用的SDR设备工作在2.4GHz频段,可用带宽大约20MHz。算下来理论距离分辨率是7.5米。这个数字不算好,但也足够区分走廊里走动的人和大楼墙面的反射了。
最大测量距离主要由扫频周期决定。扫频周期越长,可分辨的最大距离越远,但同时也会压低帧率,导致对快速目标的响应变慢。
速度分辨率与总观测时间成反比。想分辨两个速度很接近的目标,就需要更长的观测时间。而最大不模糊速度与扫频周期成反比,周期太长的话,高速目标的多普勒频移会“卷绕”到负速度区域,造成测速模糊。
| 参数 | 公式 | 我的配置 | 计算值 |
|---|---|---|---|
| 距离分辨率 | c / (2B) | B=20MHz | 7.5m |
| 最大测距 | c·T_c / (2·B) | T_c=1ms | 187.5m |
| 最大不模糊速度 | λ / (4·T_c) | 2.4GHz,T_c=1ms | 31.25m/s |
| 速度分辨率 | λ / (2·T_f) | T_f=128ms | 0.49m/s |
我在配置参数时就围绕这组公式做取值。2.4GHz频段波长约12.5厘米,扫频周期选1ms,一帧取128个扫频周期,总共128毫秒采集一帧。这样速度分辨率大约半米每秒,既能分辨慢走的人和停止的物体,又能测到最快每小时100公里出头的目标,覆盖校园和公路场景完全够用。
3. 软硬件环境准备与系统组成
3.1 硬件清单与选型逻辑
整套PLFM_RADAR的硬件清单非常克制,拢共五样东西:SDR接收机、发射源、收发天线、环形器或双天线方案、以及一台做处理的电脑。
接收机我用的是RTL-SDR,就是那种几十块钱的USB电视棒改造版。它本身是个宽带接收机,覆盖频率从几百兆到1.7GHz左右,通过调整本振还能往更高频段延伸。RTL-SDR的ADC位宽只有8位,动态范围有限,但对于接收强反射回波来说基本够用。它的采样率最高能到2.4MSPS,这些指标放在雷达场景里不算豪华,但胜在便宜、驱动成熟、社区资料多。
发射源我最初用的是ADALM-PLUTO,这是一块巴掌大的SDR收发板,频率覆盖325MHz到3.8GHz,发射功率大约10dBm。它支持全双工模式,能同时发射和接收,但我在做FMCW雷达时,发射和接收必须同时进行,而PLUTO的双通道设计正好可以支持。后来为了验证系统对硬件没有特殊依赖,我也试过用USRP B200做发射源,效果一样,只是成本高出不少。
天线的选择上,我踩过一个有意思的坑。一开始以为天线随便拿两根胶棒天线就能用,结果发现两根天线之间的距离和摆放角度对系统性能影响极大。后来换了带方向性的板载贴片天线,收发天线之间保持大约20厘米的间距,并把辐射主瓣对准测试区域,整个系统的信噪比立刻好了不少。
3.2 软件环境搭建:从驱动到信号处理库
软件部分,操作系统我用Ubuntu 22.04 LTS,也可以用Windows,但Linux下实时信号处理的延迟表现更好。整个软件栈自底向上分为三层。
第一层是设备驱动层。RTL-SDR使用的驱动是官方开源的librtlsdr,通过这个库我们能直接读到I/Q采样的原始数据流。PLUTO使用的驱动是libiio,这是一套跨平台的设备IO库,支持通过网络或USB访问设备。两个驱动都是开源社区维护的,出问题能查到大量现成解决方案。
第二层是信号处理层。我主要用GNU Radio配合Python的NumPy和SciPy库。GNU Radio提供了流式信号处理的图形化编程环境,但用Python手写信号链路的掌控感更强。我的做法是:用GNU Radio的osmocom源模块把SDR数据流接入,后续的混频、滤波、FFT全部用Python处理。
第三层是可视化层。实时显示距离-多普勒图谱用的是Matplotlib的交互模式,配合Scipy的signal模块做窗函数和滤波处理。整个系统的处理帧率大约在每秒7到8帧,勉强够实时观察目标运动趋势。
3.3 发射信号参数设计:一个1ms扫频周期的具体配置
参数设计是整套系统里最需要动脑子的环节。我确定下来的核心参数组是:中心频率2.4GHz、扫频带宽20MHz、扫频周期1ms、帧内扫频数128。
中心频率选2.4GHz主要是为了充分利用免许可频段和现成的Wi-Fi天线。这个频段电磁波波长在12.5厘米左右,天线尺寸小巧。扫频带宽20MHz对应7.5米的距离分辨率。这里需要说明的是,20MHz带宽在2.4GHz频段上已经几乎占满了Wi-Fi的整个信道空间,在实际测试时必须确认周围没有正在使用的Wi-Fi网络,否则会收到大量干扰。
扫频周期1ms时,最大不模糊速度是31.25米每秒。我测试的环境主要在校园道路上,正常行人速度每秒1到2米,骑自行车的人每秒5到8米,汽车每秒10到20米,这个上限覆盖这些目标绰绰有余。如果后续想测高速公路上的车,把扫频周期缩短到0.5ms就能把速度上限提升到62.5米每秒。
帧内扫频数128意味着每一帧数据包含128个扫频周期,总时长128毫秒。这个帧长对应的速度分辨率约0.49米每秒,足够区分两个速度差在0.5米每秒以上的目标。
生成发射信号的具体代码逻辑不复杂。每个扫频周期生成一个频率从2.39GHz线性增长到2.41GHz的线性调频信号,信号持续1毫秒,幅度恒定。在Python里生成基带信号就是用NumPy生成一个长度等于采样点数、频率随时间线性递增的复数数组,然后上变频到射频。
4. 核心算法实现与信号处理链路
4.1 数据处理流程总览
从SDR设备读回原始I/Q数据到最终画出距离-多普勒图谱,中间经过五个核心步骤。第一步是数据预处理,包括去除直流偏置、校正I/Q不平衡、滤除带外噪声。第二步是混频和下变频,将射频信号搬到基带。第三步是距离维FFT,把每个扫频周期的时域数据变换到频域,得到距离谱。第四步是运动目标检测,通过帧间差分或MTI滤波的方式抑制静止杂波。第五步是速度维FFT,对同一距离门上的多个周期做变换,得到速度维信息。
这五步里最容易被忽略的是第一步预处理。不少人做完混频直接上FFT,结果发现图谱上全是噪声和直流分量,目标根本看不清。我一开始也踩过这个坑,后来老老实实加了直流抑制和带通滤波,效果立竿见影。
4.2 距离维FFT的操作细节与窗函数选择
距离维FFT是整个信号链路的基石。每次扫频周期对应一组时域采样点,我的配置下1ms扫频周期、2MSPS采样率,每一组有2000个采样点。对这2000个点做FFT,输出1000个频点,每个频点对应一个距离门。
这里有个细节必须注意:直接对原始采样点做FFT,频谱会出现严重的频谱泄漏。因为信号在时间窗口的起始和结束时刻不是连续的,FFT默认把这2000个点当成周期信号处理,结果在频域上能量会从真实频点向两侧泄漏,形成宽大的裙边。解决办法是在FFT之前对数据加窗。
窗函数的选择我对比了几种。矩形窗旁瓣最高,但主瓣最窄,频率分辨率最好;汉宁窗旁瓣比矩形窗低很多,主瓣稍微变宽;布莱克曼窗旁瓣更低,但主瓣更宽。对雷达应用来说,旁瓣会掩盖附近距离门上的弱目标,所以优先选择旁瓣低的窗函数。我最终用的是汉宁窗,兼顾了旁瓣抑制和分辨率。加了窗之后,距离图谱上从目标位置延伸的干扰尾巴明显变短,弱目标的可见性好很多。
加窗的代价也显而易见:距离分辨率会变差大约一倍。矩形窗理论分辨率7.5米,加汉宁窗后实际能分辨的距离差大约是15米。这个精度对探测“有没有目标”和“目标大概在哪个方向”够用,但别指望它能区分相隔两三米的两辆车。
4.3 静止杂波抑制与运动目标检测的工程实现
雷达处理中有一个绕不开的现象:静止物体的反射强度远大于运动目标。墙壁、树木、路面的反射回波往往比一个走路的人强几十倍。如果直接把距离维FFT的结果显示出来,静止杂波会占据图谱上的大片区域,运动目标被淹没在强杂波里。
解决这个问题我试了两种方案,最终都在系统里保留了。第一种是帧间差分法。连续两帧数据相减,静止目标在两次测量中的表现完全相同,相减之后被抵消;运动目标在两个时刻的位置不同,相减之后就会留下明显的差分信号。这个方法实现最简单,缺点是信噪比会有损失,而且当目标速度很低、位移小于一个距离门时效果不佳。
第二种是MTI滤波器,原理是对沿慢时间维(同一距离门上的多个扫频周期)的信号做高通滤波,把多普勒频率为零的分量滤除,只保留有速度变化的目标回波。MTI滤波的效果比帧间差分稳定,代价是实现复杂度高一些,需要在距离维FFT之后再沿着慢时间维做一次滤波处理。
我在两套方案之间做的取舍是:对慢速行人场景用帧间差分法,对车辆等中高速目标场景用MTI滤波器。两者可以通过一个参数快速切换。
4.4 速度维FFT与距离-多普勒图谱生成
距离维FFT完成之后,数据被组织成一个二维数组:每一行是一个扫频周期的距离谱,行数等于帧内扫频数。对这个二维数组的每一列(即同一个距离门的128个多普勒采样)再分别做FFT,就得到了速度维信息。
第二次FFT的输出是一个128×1000的复数矩阵,横轴是距离门,纵轴是速度。对矩阵中的每个元素取幅度平方,得到的二维强度图就是距离-多普勒图谱。在显示时,我通常把幅度做对数压缩,这样强弱目标之间的对比度不至于过大,弱目标的细节才能肉眼可见。
图谱上横坐标从左到右表示距离从近到远,纵坐标从下到上表示速度从负到正。目标在图谱上呈现为一个高亮斑点,斑点的横坐标对应距离,纵坐标对应速度,斑点亮度对应回波强度。如果目标是靠近雷达移动,多普勒频移为正,斑点在纵轴正半轴;远离雷达则出现在负半轴。
4.5 目标检测与参数估计:CFAR算法和质心提取
图谱画出来只是第一步,真正要从图谱中得到“距离多少、速度多少”的数值,还需要做目标检测。这步不能用简单的幅度阈值法。因为环境中的噪声底有起伏,固定阈值在不同距离上表现完全不同:近距离处噪声高,远距离处噪声低,一个阈值很难兼顾。
我最终使用了CA-CFAR(单元平均恒虚警率)检测算法。原理不复杂:对每个待检测单元,取它左右两侧若干个单元作为参考窗口,计算参考窗口的平均功率,再乘以一个缩放因子作为自适应阈值。待检测单元的功率超过这个阈值,就判定为目标。这个方案的好处是阈值能跟着噪声底自动浮动,近处远处都能保持一致的虚警概率。
CFAR实现时要注意参考窗口长度的选择。窗口太短,阈值估计不稳定;窗口太长,会让两个距离上相近的目标互相干扰。我实测下来参考窗口取8个单元、保护单元取4个左右效果比较好。保护单元的作用是防止目标本身的大功率泄漏到参考窗口里,导致阈值虚高,把紧邻的弱目标淹没。
检测到目标之后,需要从周围几个超阈值单元中提取出精确的距离和速度值。直接取最大点的坐标虽然简单,但量化误差大。我用的是质心法:以峰值点为中心,取周围3×3的邻域,用幅度作为权重计算加权平均坐标。这样得到的目标距离和速度值能平滑一些,更接近真实值。
5. 实测过程与结果分析
5.1 实验场景设置与数据采集过程
为了验证系统性能,我设计了三个逐渐递进的实验场景。第一个场景是空旷广场上的单目标测距测速,目标是一个手持金属反射板匀速走动的人。第二个场景是校园小路上的多目标场景,同时有人走动、自行车经过和静止的建筑物。第三个场景是面向道路的车辆测速,验证系统在最接近真实应用环境下的表现。
采集数据时我遇到一个必须提前处理的干扰:2.4GHz频段是Wi-Fi和蓝牙的工作频段,周围环境中到处是跳频信号。在扫频带宽20MHz的设定下,Wi-Fi信号很可能直接落到我们的有效带宽内,形成宽带干扰。为了规避这个问题,我在2.4GHz频段里扫描了一圈,找到一段相对干净的子频段作为中心频率,把扫频带宽收窄到20MHz,避开了附近最活跃的Wi-Fi信道。
实验时天线架设在距离地面大约1.2米的高度,保持收发天线间距约20厘米,辐射方向朝向目标运动路线。每次采集持续30秒,SDR采样率2MSPS,原始数据以二进制文件记录,方便事后离线分析对比不同算法参数的效果。
5.2 单目标测距测速结果与误差分析
第一个场景里,测试人员手持金属反射板从距天线约10米处开始,以大约每秒1.2米的速度走向天线。系统实时生成的频谱图上,能清晰看到一个高亮斑点沿着距离轴匀速移动,纵坐标上有对应的正多普勒频移。
把离线保存的数据逐帧分析后,目标的距离轨迹与实测距离的吻合度相当不错。在距离30米以内,误差基本控制在2米以内。这个误差范围在距离分辨率7.5米的约束下算是合理表现,毕竟系统的最小可分辨距离单元就是7.5米,得到的距离估计值天然存在量化误差。
速度测量的表现比距离更好。因为速度信息来自慢时间维FFT,等效于对128个周期间的平均多普勒做估计,有天然的平滑效应。测试中目标以稳定速度步行时,系统测出的速度与用秒表标定的速度相差不超过0.3米每秒。这个结果让我挺意外,原本以为SDR这种档次的硬件能在速度上误差在一半量级就烧高香了。
| 指标 | 理论值 | 实测值 | 备注 |
|---|---|---|---|
| 距离分辨率 | 7.5m | 约10-15m | 加窗后展宽 |
| 距离精度 | — | ±2m | 30m内有效 |
| 速度精度 | 0.49m/s(分辨率) | ±0.3m/s | 多帧平均后更优 |
| 最大测距 | 187.5m | 约150m | 天线增益限制 |
| 最大测速 | 31.25m/s | 约28m/s | 接近边界时精度下降 |
5.3 多目标场景下的分辨率与识别能力
第二个场景比较热闹:一个人站在距离天线约20米处静止不动,一个人以大约1.5米每秒的速度横向走过天线前方,同时还有一辆自行车从较远处经过。这种情况下,频谱图上会出现多个目标斑点,要测试的关键点就是系统能不能把距离和速度双维度都隔得比较远的几个目标区分开。
实测结果给了我一个很直观的认知:距离维度上,由于7.5米分辨率的限制,两个距离靠近的目标几乎无法分开。但速度维度上,静止目标和运动目标在纵轴上的位置差异非常大,哪怕它们距离非常接近,也可以被轻松区分。这就是做距离-多普勒二维处理的价值所在——单看距离谱时以为只有一个目标,但二维图谱上一眼就能看出静止杂波里藏着一个运动目标。
多目标场景中最明显的失败案例是两辆并排行驶的自行车。两辆车的距离差在2米以内,速度几乎相同,在图谱上直接重叠成一个目标斑块。这种情况单靠2D-FFT解决不了,需要波束形成或MIMO阵列才行,超出了当前平台的能力范围。
5.4 车辆测速实验:算法参数对结果的影响
第三个场景把天线探头架在一条校园支路旁,目标是从约50米外驶来的汽车。这个场景测试下来让我对整套算法有了更深的理解,因为它暴露了参数选择的重要性。
按照默认参数配置,车辆从远到近的过程中,多普勒频移从正到负连续变化。系统能在目标进入检测范围内就锁定它,并且实时输出速度估计。问题是,当车速较高(超过20米每秒)时,目标的多普勒接近最大不模糊速度的边界,速度估计开始不稳定,每帧之间跳动明显。这正是因为实际速度接近模糊边界,造成部分帧内多普勒估计发生卷绕。
把扫频周期从1ms缩短到0.6ms后,最大不模糊速度提升到约52米每秒,高速目标不再触及边界,速度估计立刻稳定下来。但代价是最大测距从187米降到了约112米,对远距离目标的检测能力减弱。这个案例很好地展示了雷达参数设计中的“取舍”本质——没有完美的一组参数,只有适合当前场景的一组参数。
6. 常见问题与排查技巧实录
6.1 频谱图上一片模糊:直流偏置与I/Q不平衡
我遇到的第一个严重问题是频谱图全屏都是亮带,目标完全看不见。排查到最后发现是两个因素叠加导致的。
第一个因素是直流偏置。零中频接收机里,本振信号泄漏到接收链路后会形成直流分量,这个直流量在基带信号中表现为0Hz处的一个大尖峰。而0Hz在距离维FFT后对应的是0距离门,也就是雷达正前方的区域。这个尖峰如果不滤除,会让整个频谱图的动态范围被压缩,远处的小目标淹没在噪声中。
第二个因素是I/Q不平衡。零中频接收机的I路和Q路使用两组混频器、滤波器和ADC,任何一路的增益或相位偏差都会让镜像频率分量泄漏。在距离-多普勒图谱上,这个镜像表现为真实目标的对称“鬼影”,严重影响目标判读。
解决方法是分两步走。第一步在时域数据上减去直流偏置,直接计算整段数据的均值并从每个采样点中减去。第二步做I/Q校准,方法是发射一个已知的单音信号,测量接收到的I/Q数据,计算出增益误差和相位误差参数,然后在信号链路中对I/Q数据做补偿矩阵运算。校准一次之后,只要不更换设备,误差参数基本保持稳定。
6.2 目标时有时无:触发同步与时钟漂移
第二个让我头疼很久的问题是目标在频谱图上时隐时现,像闪烁一样。起初我以为是信号处理算法的问题,反复检查代码没发现异常,最后才定位到是硬件层面发射机和接收机的时钟不同步。
FMCW雷达对收发时钟同步的要求极为苛刻。理想情况下,发射信号的起始时刻必须和接收机采样时钟的起始时刻对齐,否则每个扫频周期内测到的距离会有一个随机偏差。我的发射源PLUTO和接收机RTL-SDR各自使用独立的晶振,两个晶振的频率误差虽然不大,但会导致采样时钟累积漂移,一段时间后发射和接收之间的相对相位关系就乱了。
解决这个问题的办法是构建一个外触发同步链路。我用PLUTO作为主设备,它输出一个同步脉冲信号到RTL-SDR的GPIO引脚,RTL-SDR收到脉冲后开始采样。同时,软件层面在每帧数据处理时增加了帧起始检测,通过搜索回波信号中已知的前导序列来确定有效数据的起始位置。
市面上更高端的SDR方案会直接用10MHz参考时钟线把所有设备锁定到同一个时钟源,精度更高。但考虑到成本,外触发加软件对齐的方案对这个平台来说已经足够。
6.3 近距离目标被淹没:近场杂波与天线隔离度
做近距离目标探测时,我发现一个反直觉的现象:距离天线3到5米范围内的目标反而很难被检测到,而十几米外的目标却清清楚楚。排查到根本原因是发射信号直接泄漏到了接收天线。
由于收发天线距离只有20厘米,发射天线辐射出的强信号会有一部分直接耦合进接收天线,而这个耦合信号在基带上表现为一个极大功率的直流分量加近零频分量。它在距离维FFT上对应到0到2米左右的几个距离门,功率远强于真实目标反射,相当于“光天化日之下拿强光手电照着眼睛看东西”。
这个问题有几个层面的解法。硬件层面,增加收发天线的间距是最直接的做法,间距从20厘米增加到50厘米后,泄漏功率下降明显。更高阶的做法是使用环形器,让收发共用一根天线,环形器内部隔离发射和接收通道,隔离度可以做到20dB以上。软件层面,对前几个距离门的数据做置零处理也能缓解近场杂波的影响,但代价是彻底放弃近距离探测能力。
我最终采用的是环形器加间距折中方案:用一根天线加环形器做收发,天线到环形器之间的线缆尽量短。实测下来近场盲区从5米压缩到了1米以内,系统的可用探测范围扩大了不少。
6.4 检测虚警率过高:环境干扰与参数联动
在校园里测试时,距离-多普勒图谱上偶尔会出现一些随机散布的高亮点,这些点在时间上不连续,位置也没有规律,但从功率上看又超过了CFAR的检测门限。这类虚警的来源五花八门:蓝牙设备的跳频信号、微波炉的辐射泄漏、甚至路过车辆的点火系统干扰。
为了降低虚警率,我做了三个改进。第一,在频域上加了带通滤波,只保留扫频带宽内的信号,带宽外的干扰被滤除。第二,把CFAR的虚警概率门限从默认的1e-2收紧到1e-4,虽然会漏掉一些弱目标,但噪声引起的误报明显减少。第三,加入多帧确认逻辑,一个目标必须连续在两帧以上的检测结果中出现,才被确认为有效目标。单次出现的孤立点一律丢弃。
多说一句关于参数联动的经验:CFAR门限和距离-多普勒图的动态范围是关联的。门限设得过严,虽然虚警少了,但系统能检测到的最远目标距离也会变短,因为远距离目标的回波功率本就不高,很容易被门限滤掉。我调了好几次才找到一个平衡点:虚警率大约每100帧1次,最大可检测距离约150米。
6.5 静物反射导致的“假目标”
还有一种比较隐蔽的假目标情况:某些静止物体在某些频点上表现出很强的散射特性,例如金属广告牌的边缘、路灯杆的接缝。这些物体的反射在距离谱上非常强烈,在帧间差分处理时,由于天线的微小位移或周边环境中电磁扰动,静止目标的回波幅度可能发生微小的随机起伏。这种起伏经过帧间差分后无法被完全抵消,就形成了类似运动目标的差分信号。
针对这个问题,我在MTI滤波之后额外增加了一步:对检测出的目标做速度合理性校验。人、自行车、汽车等地面目标的速度都有合理的物理范围,超过这个范围的目标大概率是虚警。我设定了一个速度有效窗口,对速度超出0到30米每秒范围的目标直接丢弃。这样操作之后,假目标的数量降到了几乎零。
7. 项目迭代方向与个人心得
7.1 还能往哪些方向扩展
PLFM_RADAR做到现在这个程度,已经是一个能稳定工作的实验平台。但说实话,它的潜力远不止这些。我目前已经规划了几个扩展方向,有的正在做,有的还在等配件到货。
最自然的扩展是增加发射通道数量,做成MIMO雷达。现在系统只有一发一收,测角需要借助天线扫描或机械转动。如果能做成一发两收或者两发两收的阵列,就能通过相位差解算目标的到达角,从二维探测升级到三维空间定位。
第二个方向是提高距离分辨率。目前受限于20MHz带宽,7.5米的分辨率确实有点粗糙。如果换用能工作在5GHz甚至更高频段的设备,扫频带宽能拉到100MHz以上,距离分辨率能提升到1.5米左右,和商用雷达的差距会缩小一大截。
第三个方向是接入机器学习的目标分类。目前系统只能告诉我们“那里有目标,目标距离多少、速度多少”,但不知道这个目标是人、自行车还是汽车。如果把高分辨距离像和速度特征输入到一个分类模型里,理论上能训练出一个目标识别器。网上已经有人用SDR雷达数据做过类似的实验,准确率相当可观。
第四个方向是实时可视化。当前的数据处理是离线为主的,实时帧率只有7到8帧每秒。如果使用GPU加速FFT,或者用C++重写核心处理链路,把帧率提升到30帧每秒以上,就能实现更流畅的实时监控体验。甚至可以叠加一个摄像头画面,把雷达探测到的目标位置在视频上框出来,这会是一个很有意思的演示项目。
7.2 做这个项目过程中最大的几个认知收获
回头看我做PLFM_RADAR这几个月的经历,有几个认知层面的收获值得记录。
第一个收获是“理论公式和工程实现之间的距离”。雷达原理教科书上的公式看起来干干净净、逻辑严密,但付诸实践时每一个环节都会出现教科书上不讲的脏问题:直流偏置、晶振漂移、天线耦合、干扰信号。这些问题的排查往往比算法本身更花时间。真正做出一个能稳定工作的系统,对原理的理解深度比读完三遍课本都有效。
第二个收获是“任何参数都有代价”。扫频周期、带宽、帧长、CFAR门限,没有一个参数是越大越好或越小越好,每个选择都在跟你收“过路费”。想测远的代价是看不清快的,想看清楚快的代价是测不远。优秀的雷达工程师本质上是在各种权衡中寻找适合应用场景的最优解。
第三个收获是老生常谈但在实践中被反复验证的:先跑通链路再优化性能。我一开始犯了大忌,第一版就接入了MTI滤波和CFAR检测一堆算法,结果每次出了问题都分不清是硬件的问题、采集的问题还是算法的锅。后来老老实实先做最原始的“时域波形显示”,再一步步加混频、加FFT、加检测。每加一层就在这一层上做充分验证,整个开发过程的焦虑感大幅下降。
7.3 最后分享几个调试小技巧
就用我实践中积累的几个小技巧来收尾吧。
第一个技巧:怀疑某个环节出错时,不要只盯着频谱图看,去直接看时域波形。FFT把信息压扁在频域里,看起来一团乱麻时很难定位问题。但时域波形能直接告诉你信号有没有进接收机、幅度是否正常、有没有剧烈的瞬态干扰。我排查过的几个最棘手的问题,最后都是靠时域波形定位的。
第二个技巧:SDR设备的设置检查顺序要固定。采样率、中心频率、增益、带宽,这四个参数任何一个设错了,后面全盘皆输。我的检查顺序是采样率先确认,然后中心频率,然后增益,最后带宽。每次实验前的两分钟快速检查能避免很长的调试折磨。
第三个技巧:数据记录和参数记录必须绑定。每次实验采集的数据都要同步记录一套完整的环境参数:中心频率、采样率、扫频周期、帧内扫频数、天线位置、目标路径。没有参数的数据是没有价值的,因为事后分析时你永远会忘了当时用了什么配置。我用了一个简单的Markdown文件记录每次实验的参数和时间戳,排查问题时对照起来非常方便。
第四个技巧:处理频谱时永远记得保存中间结果。我一开始只保存最终的图谱,后来为了排查一个异常,需要重新走一遍中间环节,但原始数据被覆盖,只能重做实验。从那以后我养成了习惯,每次处理都把多阶段的数据分别保存:去直流后的时域数据、距离维FFT后的数据、MTI滤波后的数据、最终的二维图谱。这些中间结果在调试时是无价之宝。