
做雷达信号处理的工程师看到 PLFM_RADAR 这个项目名第一反应基本指向两件事波形设计和雷达系统仿真。PLFM 常见理解是相位编码线性调频Phased Linear Frequency Modulation把 LFM 的连续线性调频和离散相位编码组合成一种混合波形后缀 RADAR 则说明这更像一条完整的雷达信号处理链路而不是画完波形图就收工。这类项目通常要解决的是单一 LFM 在复杂电磁环境下旁瓣偏高、容易被干扰的问题同时还要在不上硬件、不烧仪器的前提下把波形的模糊函数、距离分辨率和多普勒容忍度全部摸清楚。适合雷达感知方向的学生、做波形设计的工程师以及想从理论公式跳到工程实现的算法研究者参考。这篇文章我按自己的完整实操路径来写尽量把每一步为什么这么做讲透。1. 项目核心思路与波形选型逻辑PLFM到底解决什么问题1.1 PLFM_RADAR定位拆解混合波形的完整仿真链路先说说 PLFM_RADAR 这个项目名的拆法。PLFM 这个缩写在不同团队中指的东西不完全一致有人把它理解成 Phase-coded LFM也就是在 LFM 信号基础上叠加离散相位编码也有人理解成 Piecewise LFM即分段线性调频把整个带宽切分成若干子段每段用不同斜率。这两条路线在工程里都存在。PLFM_RADAR 这个名字没有带更多上下文我按工程上最常见的理解展开基于相位编码序列P4码、Frank码、Costas阵列等对 LFM 信号进行相位调制形成“连续调频 离散编码”的混合波形然后基于该波形搭建完整的雷达收发链路仿真。会提到这一点是因为不同定义下的波形数学形式和性能差异很大。如果直接搜代码或者参考别人论文先确认对方用的哪种 PLFM 很重要否则参数对不上后面全是坑。我自己的习惯是拿到这种项目名第一件事就是把命名定义写进 README明确“本项目采用相位编码线性调频作为默认波形”避免中途改弦更张。PLFM_RADAR 这类项目的完整链路一般包含四个模块发射波形生成、目标回波模拟、匹配滤波脉压、恒虚警检测。前两个解决“信号怎么构造”后两个解决“目标怎么发现”。在数字域里把这四步跑通就相当于拥有了一台可以随便改参数的软件雷达。波形改了、带宽改了、码型换了重跑一次脚本就能对比性能这才是这个项目的核心价值。1.2 波形对比PLFM相对LFM和纯相位编码的取舍要看 PLFM 怎么取舍先看它的两个“前身”。LFM 线性调频是雷达领域最经典的波形。它的优势是匹配滤波后的主瓣非常窄距离分辨率高而且多普勒容限好目标有速度时峰值衰减不大。但有个老问题脉压输出旁瓣偏高矩形窗下第一旁瓣只比主瓣低约 13.2dB。13dB 是什么概念一个强反射目标的旁瓣能轻易淹没旁边弱目标的真实峰值这在多目标场景里非常致命。纯相位编码波形比如二相码、多相码不一样。它把脉冲分成 N 个子码每个子码用不同相位调制自相关旁瓣可以设计得很低抗干扰能力也强。缺点是它对多普勒非常敏感目标速度一旦变大匹配滤波主峰迅速衰减相当于“目标一跑快就找不到了”。PLFM 就是把两者叠起来。用 LFM 提供距离分辨率和多普勒宽容度用相位编码压低旁瓣、增强波形的多样性。用一个不太严谨但好理解的类比LFM 像大嗓门但含混不清纯相位编码像口齿伶俐但怕跑调PLFM 等于让合唱团按谱子唱既有稳定音准又有清晰吐字。波形类型距离分辨率多普勒容限旁瓣水平抗干扰/抗截获能力工程复杂度LFM高好较高约-13dB一般低纯相位编码高差可设计得很低较好中PLFM高介于两者之间可低可高取决于码型和窗较好中高实际项目中选 PLFM多半不是因为它十全十美而是它在几个矛盾指标之间给出了一个工程可接受的折中。代价也很明显系统复杂度上来了需要设计码型、需要对子码边界做处理、需要仔细分析多普勒性能这也是为什么这类项目值得用完整的仿真正式做一遍。1.3 为什么先用数字仿真验证方案雷达波形设计的迭代成本很高。如果每一步都上硬件需要信号源、任意波形发生器、收发组件、采集卡一套设备的时间和资金成本都不是个人项目能随便承受的更别说调一次参数要重新烧一遍波形、重新测一遍数据。所以 PLFM_RADAR 这类项目天然适合先在数字域完整跑一遍。我个人的工具选型是 Python NumPy SciPy Matplotlib。原因很简单Matlab 的雷达工具箱确实全但授权成本摆在那里而且很多信号处理细节被封装得过于“傻瓜”不利于理解原理。Python 生态里所有操作都是显式的从波形生成到匹配滤波每一行代码都对应一个物理过程遇到问题可以一层层扒开看。对于只想快速验证波形的场景纯 Python 足够了不需要 GPU不需要 TensorFlow 那套。真正到了要跑大规模相控阵仿真再考虑 PyTorch 做并行加速也不迟。PLFM_RADAR 的核心在“波形设计与脉压处理逻辑”不在算力。2. PLFM雷达波形与信号处理核心细节2.1 PLFM波形的数学结构、参数设计与计算示例先把 LFM 的数学形式写出来。发射信号s_tx(t) A · exp(j · 2π · (f0 · t 0.5 · K · t²))0 ≤ t ≤ T其中 K B / T 是调频斜率B 是带宽T 是脉冲宽度。匹配滤波后的距离分辨率 δR c / (2B)时宽带宽积 D B · T 直接决定脉压增益。这个乘积越大雷达能积累的能量越多分辨率也越好。在 LFM 基础上叠加相位编码就把脉冲分成 N 个子码每个子码宽度 Tc T / N在第 n 个子码上额外加一个相位项s_plfm(t) A · exp(j · (2π · (f0 · t 0.5 · K · t²) φ_n))(n-1) · Tc ≤ t n · Tcφ_n 就是码序列决定的相位。以 P4 码为例相位序列是φ_n (π / N) · (n-1)² - π · (n-1)n 1, 2, ..., N我项目里给过一组可直接套用的基础参数载频 f0 3GHzS波段适合交通感知和气象类场景带宽 B 20MHz脉宽 T 100μs子码数 N 100采样率 fs 50MHz。距离分辨率 δR 3×10⁸ / (2 × 20×10⁶) 7.5 米时宽带宽积 D 20×10⁶ × 100×10⁻⁶ 2000理论上脉压增益就是 2000约 33dB子码宽度 Tc 1μs每个子码内部是一个带宽为 0.2MHz、时宽为 1μs 的小 LFM子码时宽带宽积极小近似单载频调制这正好是编码起作用的区域采样率取了 2.5 倍带宽比奈奎斯特最低标准的 40MHz 略高给相位跳变带来的频谱扩展留出裕量注意时宽带宽积 D 不是越大越好。D 大了脉压增益确实高但波形对多普勒的敏感度也会变化相位编码部分的相干积累时间变长后速度失配损失会更明显。做参数设计时要把目标速度范围一起考虑进来不能只看分辨率一个指标。提示采样率是这类项目最容易出错的地方。相位编码信号在码元切换处有相位跳变频谱会比理想 LFM 展宽不少。如果采样率只卡在 2 倍带宽高频分量会折叠回带内表现为匹配滤波后的杂散抬高基线不再平滑。工程上我给的是 2.5 到 4 倍宁高勿低。2.2 脉冲体制参数PRF与模糊问题的权衡PLFM_RADAR 走的是脉冲体制那就绕不开脉冲重复频率 PRF 的选择。PRF 决定两件事最大不模糊距离和最大不模糊多普勒频率。最大不模糊距离R_un c / (2 · PRF)最大不模糊多普勒fd_max PRF / 2对应最大不模糊速度 v_un λ · PRF / 4两个约束是矛盾的。PRF 高不模糊距离小但速度测量范围大PRF 低不模糊距离大但速度容易模糊。以我上面的参数为例载频 3GHz波长 λ 0.1m如果 PRF 1kHz那么最大不模糊距离是 150km这个距离对绝大多数近程感知都足够但最大不模糊速度只有v_un 0.1 × 1000 / 4 25 m/s这个速度范围太小了。场景里如果目标是高速运动的必须提高 PRF又会牺牲距离探测范围。工程上常用多重 PRF 交替发射来解距离/速度模糊即用两个不同 PRF 的测量结果联立求解真实距离和速度。PLFM_RADAR 里我建议先把单 PRF 的仿真跑通再在数据后处理里加多 PRF 解模糊模块这样逻辑更清晰。这个取舍没有标准答案完全取决于应用场景。车载近程雷达目标距离近、速度高PRF 就选高一些远程监视雷达要求看得远PRF 就压低。做波形仿真时一定要把场景先定义清楚否则后面做的所有分析都没有落点。2.3 匹配滤波与加窗处理的取舍匹配滤波是雷达信号处理的“看家本领”。接收回波和发射波形的共轭时间反转做卷积输出信号在目标时延处形成尖峰同时把噪声压低。在数字实现里等价于对回波做傅里叶变换、乘上发射信号的共轭频谱、再逆变换回来或者直接用 scipy.signal.fftconvolve 做快速卷积。脉压后 SNR 增益等于时宽带宽积 D这一点在上一节已经算过。但匹配滤波给的是理论最佳性能前提是回波和目标环境没有任何失配。实际使用里几乎总要加窗因为默认的矩形窗旁瓣太高PLFM 的相位编码部分又可能引入额外旁瓣。加窗有两个结论性的经验汉明窗旁瓣可以压到约 -43dB但主瓣宽度大约展宽 2 倍SNR 损失约 1.3dB切比雪夫窗可以指定任意旁瓣电平比如 -40dB主瓣宽度按参数调整更灵活但需要自己算等效噪声带宽窗外加在哪个环节很多初学者容易搞错。有人直接把窗乘在回波上这是不对的。加窗要加在匹配滤波器的参考信号上或者在频域匹配滤波时乘到频域信号上否则会破坏匹配滤波的“匹配”关系导致失配损失。我自己的做法是先生成发射波形的共轭反转序列乘以窗函数再用它当滤波器系数做卷积。这样既压了旁瓣又保持了脉压的正确性。窗类型第一旁瓣典型值主瓣展宽倍数SNR损失典型值适用场景矩形窗-13.2dB1x0dB理论基线对比汉明窗-43dB2x1.3dB常规多目标检测切比雪夫窗-40dB-40dB约1.4x约1.2dB需要控制旁瓣电平的场合加窗的直接代价是主瓣变宽也就是距离分辨率变差。原来 7.5 米的分辨率加汉明窗后实际可分辨距离大约变成 15 米。所以不能一味靠窗压旁瓣波形本身的设计要先把旁瓣压低窗只是最后一道兜底。3. 实操过程从波形生成到目标检测全流程3.1 仿真环境与目标场景搭建整个仿真代码量不大我建议按模块拆分参数配置、波形生成、回波模拟、脉压、检测、画图。环境依赖就三个库numpy、scipy、matplotlib安装不超过五分钟。场景我设置了三个目标让旁瓣性能和多普勒性能都能暴露出来目标编号距离 (km)速度 (m/s)相对幅度说明目标110.001.0静止强目标目标210.1300.3相距100m的弱目标考验距离分辨率目标312.5-800.5高速目标考验多普勒容限三个目标里目标 2 距离目标 1 只有 100 米在 7.5 米分辨率下理论上是完全能分开的但如果目标 1 的旁瓣太高弱目标很容易被淹没。目标 3 用高速来做多普勒敏感性的试金石。噪声加的是高斯白噪声把接收端信噪比控制在约 15dB保证不是被噪声“难倒”的。3.2 PLFM波形生成与回波模拟波形生成代码我直接给出核心部分。P4 码相位序列和 PLFM 波形生成可以这样写import numpy as np def p4_phase(N): n np.arange(1, N 1) return (np.pi / N) * (n - 1) ** 2 - np.pi * (n - 1) def gen_plfm(T, B, fs, f0, N): t np.arange(0, T, 1 / fs) K B / T # 基础LFM相位 phase_lfm 2 * np.pi * (f0 * t 0.5 * K * t ** 2) # P4码相位按时间映射到子码 code_idx np.floor(t / (T / N)).astype(int) code_idx np.clip(code_idx, 0, N - 1) phase_code p4_phase(N)[code_idx] return np.exp(1j * (phase_lfm phase_code)), t这里np.floor(t / (T / N))的作用是把连续时间轴切成 N 段每一段对应一个子码序号再取该子码对应的 P4 相位。相位序列一旦选定波形就固定了。回波模拟的关键是给每个目标叠加时延、幅度和多普勒频移def simulate_targets(s_tx, t, fs, targets, f03e9, c3e8): rx np.zeros_like(s_tx, dtypecomplex) for distance, velocity, amp in targets: tau 2 * distance / c fd 2 * velocity * f0 / c delay_samples int(round(tau * fs)) if delay_samples len(s_tx): continue # 回波 延迟后的发射波形 * 多普勒相位 rx[delay_samples:] amp * s_tx[:len(s_tx) - delay_samples] * \ np.exp(1j * 2 * np.pi * fd * t[:len(s_tx) - delay_samples]) return rx这里有两个容易踩的坑。第一个是回波延迟如果不是采样周期的整数倍直接按四舍五入取整会带来距离量化误差。我这个场景里目标距离 10km 时时延是 66.67μs在 50MHz 采样率对应 3333.33 个采样点四舍五入后是 3333误差 0.33 个采样点相当于 1 米左右的距离偏移。对 7.5 米分辨率可以接受但如果要做更高精度的分析需要用插值或频域相位法精确实现小数时延。第二个坑是多个目标回波叠加时幅度容易溢出。目标多、幅度大、再加上噪声数字域峰值可能超过 1e6直接画图会爆坐标轴。回波生成时可以把幅度归一化或者画图时用 dB 显示我习惯上先把回波整体除以最大幅度再进入后续处理。3.3 匹配滤波脉压与CFAR检测脉压实现我用的频域快速卷积等效于时域卷积但计算更快。关键是要在参考信号上先加窗from scipy.signal import fftconvolve def matched_filter(rx, s_tx, windowNone): # 匹配滤波器系数 发射波形的共轭时间反转 h s_tx[::-1].conj() if window is not None: h h * window y fftconvolve(rx, h, modefull) return y接收端信噪比 15dB 时脉压输出里目标 1 和 目标 2 应该能清晰分离。目标 2 距离目标 1 只有 100 米按 7.5 米分辨率两个峰值相距约 13 个采样单元完全可以在脉压曲线上直接用峰值位置估算距离。脉压只能给出“距离维”的信息真正稳健的目标检测要靠恒虚警检测。PLFM_RADAR 里我用了最经典的单元平均 CFARCA-CFARdef ca_cfar(abs_y, guard_bins4, ref_bins16, pfa1e-4): n len(abs_y) threshold np.zeros_like(abs_y) for i in range(n): left ref_bins guard_bins right ref_bins guard_bins if i - left 0 or i right n: threshold[i] np.inf continue ref_win np.concatenate([ abs_y[i - left : i - guard_bins], abs_y[i guard_bins 1 : i right 1] ]) noise_est np.mean(ref_win) alpha ref_bins * 2 * (pfa ** (-1 / (ref_bins * 2)) - 1) threshold[i] alpha * noise_est return abs_y thresholdCA-CFAR 的数学原理是用目标单元周围的参考单元估计噪声功率再乘一个门限因子得到自适应门限。门限因子 α 的设计保证了虚警概率恒定——噪声越大门限跟着升高目标越多周围单元平均功率可能被抬高所以要在目标两侧留出保护单元。保护单元的数量要大于目标脉压主瓣的宽度否则目标自己的旁瓣会进入参考窗把门限拉高导致弱目标被漏检。我实测下来保护单元设 4 个、参考单元单侧 16 个对 100μs 脉宽、50MHz 采样率的波形比较稳妥。CIFAR 的关键不是门限公式而是窗口设计。窗口设计不合理强目标会把弱目标“顶”出检测门限。3.4 模糊函数与性能指标评估脉压和检测跑通只是完成了“能用”这一步。PLFM_RADAR 真正要回答的问题是为什么这个波形好、好在哪里、坏在哪里。这就必须看模糊函数。模糊函数是发射波形对时延和多普勒的二维匹配滤波响应公式形式每个教科书都有我直接说怎么看把波形复制一份加上不同的时延 τ 和多普勒频移 fd分别做匹配滤波取模平方画出二维等高线图。横轴时延反映距离分辨率纵轴多普勒反映速度容忍度主瓣形状反映距离-多普勒耦合程度。对 PLFM 波形你会在模糊函数图上看到两个典型特征距离轴主瓣很窄说明分辨率好但沿着多普勒轴存在若干“脊线”或旁瓣区域说明编码部分在某些速度上会产生额外的杂散响应。这些都是纯 LFM 看不到的需要靠仿真在波形设计阶段就暴露出来。性能指标我一般看四个主瓣 3dB 宽度、峰值旁瓣电平 PSLR、积分旁瓣电平 ISLR、多普勒 3dB 宽度。PLFM 设计目标通常要求 PSLR 低于 -25dB 到 -30dBISLR 尽可能低。如果脉压后旁瓣压不下来就回到码型选择和窗函数上去调这才是波形设计的核心闭环。4. 常见问题与排查技巧实录4.1 脉压后旁瓣抬高小目标被淹没怎么办这是 PLFM 项目里最常碰到的问题。具体表现是脉压后主峰旁边一堆隆起的“包子”弱目标峰值被埋在包子底下CFAR 检测不出来。排查顺序我是这么定的先用矩形窗跑一遍基线看是窗的问题还是波形本身的问题。如果矩形窗下旁瓣就有问题说明波形设计有问题比如相位编码在子码边界产生了严重频谱扩展如果矩形窗还行、加窗后旁瓣仍然高才考虑是窗函数和主瓣匹配的问题。另外一个容易忽略的原因是 P4 码相位在子码切换瞬间发生跳变这个跳变相当于对波形做了一个相位调制冲击频谱会向外扩展。解决方向有两个一是提高采样率给频谱扩展留出空间二是在子码边界做相位连续化处理比如在切换点附近用一个很小的过渡带平滑相位。第二个方法效果更直接但会让码的约束变弱需要反复试。我实测下来把采样率从 2 倍带宽提到 2.5 倍PSLR 改善就很明显。4.2 多普勒敏感导致的检测损失PLFM 相对纯 LFM 更敏感于多普勒。场景里那个 80m/s 的目标在 S 波段 3GHz 载频下多普勒频率约 1600Hz脉压峰值会比静止目标明显下降如果速度更大甚至会直接漏检。原因是相位编码波形好比一串精心编排的口令目标一有速度回波每个码元之间会叠加上一个额外相位增量相当于“口令跑调了”匹配滤波器的匹配关系被破坏。PLFM 因为有 LFM 成分容忍度比纯编码好但依然有限。工程上解决多普勒敏感性的主流做法是多普勒滤波器组对同一距离门做多个不同多普勒假设的匹配滤波每个假设覆盖一段速度范围用一组滤波器把目标“捞”出来。具体实现就是在匹配滤波前给参考信号乘上不同 fd 的旋转因子逐次扫描。代价自然是计算量成倍上涨。波形设计阶段可以先用模糊函数看多普勒 3dB 宽度如果目标速度范围明显超出就必须考虑补偿或滤波器组不要等实机跑完再补救。4.3 相位量化与采样率不足的坑如果波形最终要交给 DDS 或任意波形发生器生成相位量化位数就要在仿真里先考虑。相位量化常见 8bit256 级或 12bit量化误差近似 2π / 2^M。量化位数太低等效于在波形上叠加一个相位噪声脉压输出会抬高底噪基线看起来像“雾”一样。我做过一组对比6bit 量化和 12bit 量化前者的检测底噪能抬升好几个 dBCFAR 门限被迫拉高弱目标检测能力明显下降。采样率不足的坑更隐蔽。PLFM 的相位跳变产生频谱扩展这部分扩展分量如果超过了奈奎斯特带宽会混叠回带内表现为匹配滤波后主瓣附近出现对称的小杂散。判断方法很简单保持波形不变把采样率从 2 倍带宽提到 4 倍带宽如果旁瓣和杂散明显变化说明原来采样率不足。正常设计至少留 20% 到 30% 的带宽余量。4.4 距离-速度耦合与解耦思路LFM 信号有一个固有特性叫距离-多普勒耦合匹配滤波峰值的时延位置不仅和真实距离有关还和目标速度有关。理论推导可以看出峰值时延偏移约等于 -fd / K换算成距离偏移是ΔR ≈ -v · f0 · T / B代入我上面的 S 波段参数目标速度 100m/s 时ΔR ≈ 100 × 3×10⁹ × 100×10⁻⁶ / 20×10⁶ 1.5 米。速度 300m/s 时ΔR 约 4.5 米已经超过 7.5 米分辨率的一半。如果不补偿测距误差会随着目标速度线性放大。PLFM 的编码部分在一定程度上打破了这种线性耦合但整体行为仍然由 LFM 主导不能忽略。解耦思路最常用的是发射正负调频斜率交替的脉冲利用正斜率脉冲和负斜率脉冲对同一目标产生的距离偏移方向相反联立两个方程就能解出真实距离和速度。PLFM_RADAR 里可以先不做这套解模糊但要清楚如果最终系统要求测距精度优于 2 米速度补偿就是必须的模块波形设计前期就要把接口留出来。4.5 常见问题速查表现象可能原因排查方法建议解法脉压旁瓣高相位跳变频谱扩展提高采样率对比加窗、相位连续化底噪基线抬高相位量化位数不足对比不同量化位数提升到 8bit 以上弱目标漏检LFM 旁瓣淹没 / CFAR 参考窗含目标先看脉压曲线加窗压低旁瓣、增加保护单元高速目标幅度下降多普勒失配检查模糊函数多普勒轴多普勒滤波器组、多脉冲补偿距离估计偏大距离-多普勒耦合计算 ΔR 随速度变化正负调频联合解算匹配滤波输出位置偏移回波时延非整数采样检查延迟取整逻辑小数时延插值4.6 实操心得与扩展建议拿 PLFM_RADAR 这套仿真做下来我最大的体会是千万不要上来就写 PLFM先把纯 LFM 链路完整跑通确认脉压、检测、参数都没问题再叠加相位编码。叠加编码后再出现问题就能用“去掉编码是否复现”这个二分法快速定位是编码引入的问题还是链路本身的问题。这个排查习惯帮我省了很多时间。另外一个小技巧波形仿真过程一定要把每个阶段的关键中间量存下来波形、回波、脉压结果、门限曲线全部导出成数组继续分析时直接载入。否则每次改参数重跑一遍回头想对比几组波形时只能重新跑既慢又容易搞混。我自己会在工程目录下建一个 results 文件夹每个参数组合一个子目录命名带时间和关键参数比如 plfm_20M_100us_p4_50MHz这个是个人项目里最容易忽略但收益最大的习惯。PLFM_RADAR 跑顺之后扩展方向很明确换码型Frank码、Costas阵列、加目标跟踪模块、做多 PRF 解模糊甚至把接收段换成阵列信号处理模型。但所有扩展的地基都是波形本身把这个地基用仿真夯实后面做什么都稳。