
搞雷达信号处理这些年脉冲多普勒PD处理一直是我心里最有分量的内容。很多人提到MATLAB仿真就想到调参数、跑图但PD处理如果不把原理吃透仿出来的结果也就只能看个热闹真正拿去做算法验证或者工程实现时往往会被各种细节卡住。这篇文章我就把从原理到代码的完整链路掰开揉碎讲一遍从回波模型开始逐步落到MATLAB仿真给出一个可以直接运行的脉冲多普勒处理流程顺便把我自己调仿真时踩过的几个典型坑一起说清楚。内容适合正在学雷达信号处理的学生、刚入行的FPGA/软件工程师以及所有想把PD处理从公式变成可运行代码的人。就算你只是对雷达感兴趣也能从这篇里知道一张距离-多普勒图到底是怎么变出来的为什么动目标能在强杂波里“现身”。1. 为什么PD处理是雷达信号处理的“主心骨”1.1 雷达要解决的核心矛盾从强杂波里抠出微弱动目标一部雷达接收到的信号里除了目标回波还有地面、海面、云雨、箔条等产生的杂波。这些杂波的功率往往比目标回波高出几十个dB。我刚做仿真的时候有个很天真的想法目标回波比噪声大画个幅度图不就能看到了现实很快打脸——杂波不是白噪声它和目标回波混在同一段距离门里而且频谱又低又宽单纯靠包络检测根本分不开。关键在于杂波和目标在速度上有差异。静止的地物杂波频谱集中在零多普勒附近而运动目标会因径向速度产生多普勒频移。如果雷达能测出回波的多普勒频率就等于拿到了一个区分目标和杂波的新维度。这个维度正是脉冲多普勒处理的核心价值。1.2 从连续波测速到脉冲测距一次关键的思维升级早先的多普勒雷达很多是连续波体制发射天线一直发接收天线一直收能测得准速度却测不了距离因为没有一个时间基准来对应回波延迟。脉冲雷达倒是能量出距离可单个脉冲只有一个窄包络多普勒信息非常弱很难直接把速度测出来。脉冲多普勒体制把两者结合起来发射一串相参脉冲脉冲载波的初相是严格同步的。这样每个脉冲回波里的包络延迟用来测距离而一串脉冲之间的相位变化则用来测速度。相参是最关键的字眼它意味着脉冲之间的相位关系没有丢失速度信息被完整保留在慢时间维度的相位旋转里。可以说PD处理是现代雷达能干“同时测距测速”这活的底层原因。1.3 PD处理在典型雷达信号处理链路中的位置一套完整的雷达信号处理链路通常包括接收机下变频、脉冲压缩、MTI或MTD、多普勒滤波、检波、CFAR检测、目标参数提取。PD处理不是一个孤立的点而是一条贯穿距离维和速度维的主干道。很多资料会把MTI和PD分开讲。MTI用一次或二次对消本质上是在慢时间做高通滤波能抑制静止杂波但得到的只是目标有无说不清速度具体是多少。PD则更进一步在慢时间做FFT相当于并行的一组窄带滤波器每个滤波器对应一个不同的多普勒频率于是目标速度被分到不同的通道里。理解了滤波器组这个视角后面再看FFT处理就会非常通透。2. 距离维处理回波模型与脉冲压缩是这样工作的2.1 从回波模型开始发射、延迟、混频后的中频信号要理解PD处理第一步得把回波模型写清楚。现代脉冲雷达普遍使用线性调频LFM信号也叫chirp信号。它的基带形式很简洁s_tx(t) rect(t/T) * exp(jπKt²)其中T是脉冲宽度K是调频斜率K B/TB是信号带宽。这个公式的意思是信号的瞬时频率从 -B/2 线性变化到 B/2所以脉冲内部带了一个“时间戳”。发射信号经过目标反射回波可以写成s_rx(t) A * rect((t - τ)/T) * exp(jπK(t - τ)²) * exp(-j2πf_c τ)τ 2R/c 是回波延迟R是目标距离c是光速f_c是载频。前面的rect和二次相位说明回波和发射信号结构相同只是时间平移了τ最后的 exp(-j2πf_c τ) 是载波相位项这个项在单脉冲里几乎恒定但在脉冲串里会随距离变化成为速度信息的载体。做仿真时我们通常工作在基带复信号域不需要把每个脉冲的载波都生成出来但要保留 τ 对应的相位变化。很多初学者在这里栽跟头把载频直接设成0结果多普勒信息全丢了。正确的做法是保留发射信号基带形式用延迟后的回波基带信号来模拟并在慢时间维度手动乘上多普勒相位。2.2 匹配滤波为什么能同时提高信噪比和距离分辨率脉冲压缩的核心操作是匹配滤波。匹配滤波器的冲激响应是发射信号的时间翻转共轭h(t) s_tx*(-t)在理论上白噪声背景下匹配滤波器是使输出信噪比最大的线性滤波器输出信噪比等于输入信号能量E除以噪声功率谱密度N0。这里有一个非常直观的解释LFM信号的能量被摊开在整个脉冲宽度T里峰值功率不高匹配滤波相当于对回波做相关运算把所有分散的能量在某一时刻“对齐”叠加产生一个能量集中的窄脉冲。这个窄脉冲的时间宽度约为1/B对应距离分辨率 ΔR c/(2B)。如果直接发射一个矩形窄脉冲要得到同样的距离分辨率需要脉宽已经很小平均发射功率就上不去。而LFM允许用宽脉冲发射、保证足够的能量再通过匹配滤波压缩成窄脉冲这就是“脉冲压缩”的意义。2.3 MATLAB实现LFM信号生成与匹配滤波下面这段MATLAB代码生成了一个基带LFM信号并用匹配滤波处理一个带延迟的回波。先定义基本参数% 参数设置 fs 20e6; % 采样率 20 MHz T 10e-6; % 脉冲宽度 10 us B 5e6; % LFM带宽 5 MHz K B / T; % 调频斜率 fc 5.4e9; % 载频 5.4 GHz仿真中用于多普勒相位 c 3e8; % 光速 % 基带LFM信号 t -T/2 : 1/fs : T/2 - 1/fs; s_tx exp(1j * pi * K * t.^2); % 目标距离 10 km回波基带 R 10e3; tau 2 * R / c; t_echo -T/2 tau : 1/fs : T/2 tau - 1/fs; s_rx exp(1j * pi * K * (t_echo - tau).^2); % 匹配滤波 h conj(s_tx(end:-1:1)); % 时间翻转共轭 y conv(s_rx, h); % 卷积 相关 压缩这段代码里最需要注意的是时间轴。回波信号不能只把发射信号做“延时”就完事还必须保证快时间采样窗覆盖住整个脉冲不然匹配滤波会截断回波输出波形会变得很难看。conv之后脉冲压缩峰值出现在回波延迟对应的位置从峰值位置可以反推目标距离。2.4 加窗的代价主瓣变宽但旁瓣降低匹配滤波输出的sinc函数形状主瓣附近有一串旁瓣第一旁瓣大约-13.2dB。强目标旁边的弱目标很可能被这个旁瓣淹没。工程上常用窗函数对匹配滤波器的参考信号做加窗比如汉明窗、海明窗、切比雪夫窗。代价也很直接加窗后主瓣宽度会变宽大约变成原来的1.3到1.5倍距离分辨率会下降一点。这是雷达处理里典型的“主瓣宽度-旁瓣电平”折中。我在仿真里一般先用不加窗跑通流程等确认目标都能检测到再考虑加窗压制旁瓣避免一上来加窗导致目标峰形糊成一团。3. 多普勒维处理相参积累和多普勒滤波器组3.1 一个运动目标如何体现为慢时间维度的相位旋转现在把单个脉冲升级成脉冲串。发射N个脉冲脉冲重复间隔为PRI对应脉冲重复频率PRF 1/PRI。假设第n个脉冲发射的时刻是n*PRI目标的径向速度是v那么第n个脉冲对应的目标距离近似为R_n R_0 v * n * PRI回波延迟 τ_n 2R_n/c。代入载波相位项 exp(-j2πf_c τ_n)就会发现一个关键结果在慢时间维度上每个脉冲回波的相位都会比上一个脉冲多一个固定的旋转量Δφ 4π v PRI / λ其中λ c/f_c是波长。也就是说慢时间序列在复数域是一个单频复正弦频率 f_d 2v/λ这就是多普勒频率。这个复正弦的频率直接对应目标速度而它的幅度对应目标的回波强度。静止杂波的速度v0多普勒频率为0集中出现在零频附近运动目标出现在非零频率位置于是我们就能用滤波器把它们分开。3.2 从FFT到多普勒滤波器组一次相参积累数字信号处理里对一个N点慢时间序列做FFT等价于用N个不同中心频率的窄带滤波器去“筛”这段信号。每一个FFT输出单元就是一个多普勒滤波器。目标回波落在哪个滤波器就意味着它的多普勒频率和该滤波器的中心频率最接近。这个过程同时是相参积累。相参积累是什么意思每个脉冲回波的噪声相位是随机的而目标回波的相位是有规律旋转的在FFT运算中N个脉冲的目标分量按相位对齐叠加幅度增长N倍噪声则因为相位随机幅度平均只增长√N倍。所以FFT之后信号的信噪比提高了约N倍也就是 10log10(N) dB。这是PD处理又一个核心增益所在。多普勒分辨率取决于总相参积累时间 T_coherent N * PRIΔf 1 / (N * PRI)速度分辨率Δv λ / (2 * N * PRI)举个例子如果λ0.055m约5.4GHz载频N64PRF1kHz那么速度分辨率约为0.43m/s。目标速度间隔大于这个值就能在距离-多普勒图上被分开。3.3 距离-多普勒二维谱怎么读把快时间维匹配滤波后的数据排列成矩阵行对应脉冲序号慢时间列对应距离采样点快时间然后对每一列做FFT慢时间维得到的就是距离-多普勒二维谱。二维谱的横轴是距离纵轴是多普勒频率或者速度幅度峰值的位置直接给出目标距离和速度。这里一定要清楚“快时间”和“慢时间”的区别。快时间在一个脉冲内部展开测量距离慢时间跨多个脉冲测量多普勒。很多刚开始做仿真的人会把FFT放错维度比如对快时间维做FFT那得到的是“距离像的频谱”不是目标速度。我自己的排查经验是先看数据矩阵的每一行是不是“同一个脉冲的距离维回波”如果是FFT就应该沿着列方向做。3.4 重频选择速度不模糊与距离不模糊的权衡PD处理绕不开一个经典矛盾PRF选高了多普勒不模糊测速范围大但距离不模糊范围变小PRF选低了距离不模糊范围大但目标速度很容易超出最大不模糊速度产生多普勒模糊。最大不模糊多普勒频率是±PRF/2对应最大不模糊速度v_max λ * PRF / 4最大不模糊距离R_max c / (2 * PRF)这两个公式放在一起看PRF一旦确定R_max和v_max就互相牵扯。没有任何一种单一重频能同时满足很远的距离和很高的速度所以真实雷达常常用多重频测距/测速来解模糊。做仿真时也要先把这两个公式写在程序注释里不然目标速度稍微一高跑出来的峰值位置就会让人困惑。4. 完整PD处理全流程的可运行MATLAB仿真4.1 仿真参数设计先用一个点目标验证流程理论说得再多不如直接跑通一个仿真。我建议第一次做PD仿真时不要一上来就放一堆目标和杂波先用一个点目标把整条链路跑通确认峰值位置和理论值一致再逐步增加复杂度。下面是我常用的一组参数参数数值说明载频 fc5.4 GHz对应波长约 0.0555 m带宽 B5 MHz距离分辨率约 30 m脉冲宽度 T10 us保证发射能量采样率 fs20 MHz满足奈奎斯特过采样PRF1 kHz不模糊距离 150 km速度范围约 13.9 m/s脉冲数 N64相参积累增益约 18 dB目标1距离/速度10 km / 30 m/s近目标目标2距离/速度10.1 km / 45 m/s第二个目标噪声高斯白噪声信噪比可调这里PRF取1kHz速度不模糊范围大约是±13.9m/s目标速度30m/s和45m/s其实都已经模糊了。我在仿真里故意保留了这个设置后面第5章再详细讲模糊问题。如果你想先把图像跑得“干净”可以把PRF抬高到5kHz但注意最大不模糊距离就缩短到30km。4.2 生成发射信号与目标回波代码生成N个脉冲的回波数据矩阵每一列是一个脉冲的基带回波采样。代码里快时间轴要覆盖最大不模糊距离对应的采样点至少需要round(fs * 2 * R_max / c)个点。% 核心参数 fs 20e6; T 10e-6; B 5e6; K B / T; fc 5.4e9; c 3e8; lambda c / fc; PRF 1e3; PRI 1 / PRF; N 64; R_max c / (2 * PRF); sample_num round(fs * 2 * R_max / c); % 快时间采样点数 % 目标配置 targets [10e3, 30; 10.1e3, 45]; % 距离(m), 速度(m/s) % 发射基带LFM一个脉冲 t_tx -T/2 : 1/fs : T/2 - 1/fs; s_tx exp(1j * pi * K * t_tx.^2); % 回波数据矩阵N行sample_num列 rx_data zeros(N, sample_num); for n 1:N slow_t (n - 1) * PRI; % 当前脉冲时间 one_pulse zeros(1, sample_num); for m 1:size(targets, 1) R0 targets(m, 1); v targets(m, 2); R_n R0 v * slow_t; % 距离随慢时间变化 tau 2 * R_n / c; delay_sample round(tau * fs) 1; if delay_sample length(s_tx) - 1 sample_num continue; % 超出不模糊距离忽略 end % 多普勒相位 phase exp(-1j * 2 * pi * fc * tau); one_pulse(delay_sample : delay_sample length(s_tx) - 1) ... one_pulse(delay_sample : delay_sample length(s_tx) - 1) ... s_tx * phase; end rx_data(n, :) one_pulse; end % 加噪声 snr_db 20; % 信号平均功率相对噪声的估值 noise_power mean(abs(rx_data(:)).^2) / (10^(snr_db/10)); rx_data rx_data sqrt(noise_power/2) * (randn(size(rx_data)) 1j*randn(size(rx_data)));这段代码用了两层循环目标少所以效率无所谓。循环里最关键的乘法是s_tx * phase它把慢时间的多普勒相位乘到每个脉冲的回波上。如果不乘phase目标就永远是零多普勒和静止杂波没区别。4.3 距离维和速度维处理代码接下来做快时间匹配滤波和慢时间FFT。% 快时间匹配滤波 h conj(s_tx(end:-1:1)); Nfft_fast 2^nextpow2(sample_num length(h) - 1); range_profiles zeros(N, sample_num); for n 1:N y ifft(fft(rx_data(n, :), Nfft_fast) .* fft(h, Nfft_fast)); range_profiles(n, :) y(1:sample_num); end % 慢时间维加窗和FFT对每一列 win_slow hamming(N).; rd_spectrum fftshift(fft(range_profiles .* win_slow, N, 1), 1); % 坐标轴 range_axis (0:sample_num-1) * c / (2 * fs); fd_axis (-N/2:N/2-1) * PRF / N; velocity_axis fd_axis * lambda / 2; % 画图 figure; imagesc(range_axis/1e3, velocity_axis, abs(rd_spectrum)); xlabel(距离 (km)); ylabel(速度 (m/s)); title(距离-多普勒谱); colorbar;匹配滤波我用的是频域快速卷积即FFT相乘再IFFT。这种方式比直接conv要快得多尤其当脉冲数量多、距离采样点多时。慢时间FFT前先乘了汉明窗用来降低多普勒维旁瓣。fftshift是为了让零多普勒显示在图像中央。4.4 结果可视化与性能评估跑完上面代码你会在距离-多普勒图的对应位置看到两个峰值。以目标1为例距离10km速度30m/s但因为我们设置的PRF1kHz最大不模糊速度只有约13.9m/s所以实际峰值会出现在速度大约30 - 227.8 -25.6m/s的折叠位置这里需要仔细计算一下。目标速度30m/s对应多普勒频率 fd 2v/λ ≈ 230/0.0555 ≈ 1081Hz而PRF1000Hz所以多普勒频率折叠后是1081 - 1000 81Hz对应速度 v_fold 81 * λ / 2 ≈ 2.25m/s。图像上的峰值其实不在30m/s而在2.25m/s附近。这就是多普勒模糊。如果第5章再讲这里可以先点一句看见峰值位置和理论设置对不上先别慌算一下是否发生了模糊。我还会在图上叠加一个理论的点用来验证处理正确性。比如计算目标的预期模糊速度用plot标记在图上若峰值坐标与标记一致说明整条链路没错。5. 实战经验PD处理仿真中常见的坑与调参建议5.1 距离分辨率与采样率为什么你的目标“胖”了一圈距离分辨率由带宽决定ΔR c/(2B)。B5MHz时ΔR30m。但如果你把采样率设得很低比如刚好等于2倍带宽那么一个点目标压缩后的sinc主瓣在数字域只有2到3个采样点峰值位置稍微偏移就看不准。我在仿真时通常会让采样率达到5到10倍带宽这样主瓣内能有足够的采样点目标峰形更平滑测距精度更高。需要留意的是采样率过高会让数据量暴涨。N64个脉冲每个脉冲采样20MHz一个PRT内采样点数可能多达20000点整个矩阵就是64×20000的复数。MATLAB直接跑没问题但如果你后面要加更多脉冲和更多接收通道就得分段处理、降采样或者用单精度变量来省内存。5.2 跨距离门走动长时间相参积累绕不开的问题当目标速度较大或相参积累时间较长时目标在慢时间维会从一个距离门逐渐“走”到另一个距离门。我在仿真里就遇到过一次目标速度300m/sN256PRF2kHz积累时间128ms距离走动量 300×0.128 38.4m超过了距离分辨单元30m。结果慢时间FFT的能量被分散到多个距离门峰值高度明显下降速度分辨率也变差。解决跨距离门走动的经典方法是Keystone变换它通过对快时间频率维做尺度变换把速度引起的线性走动校正掉。如果不想引入太复杂的变换工程上也可以用“子带分割”然后把多个距离门的数据做非相参积累虽然增益会损失一些但实现简单。这方面我的建议是仿真时先算一个“距离走动量”看看是否超过0.5个距离分辨单元如果超过就一定要考虑补偿否则后面的多普勒处理结果就别指望准。5.3 多普勒模糊与盲速两个容易被忽视的“隐形杀手”PD处理里最让我头疼的就是多普勒模糊。前面仿真里PRF1kHz目标30m/s对应多普勒频率1081Hz超出PRF一半范围峰值折叠到2.25m/s处。这不是代码写错了而是物理上的欠采样。盲速更隐蔽如果目标速度刚好使多普勒频率等于PRF的整数倍比如v n * λ * PRF / 2那么折叠后看起来是0Hz目标会和静止杂波重叠直接被MTI和PD滤波器抑制掉。实际雷达会通过选择合适PRF、多重频来规避盲速仿真时一定要把盲速公式算出来放在注释里免得怀疑人生。我调试模糊问题时的步骤一般是先用单目标扫速度从0到足够高观察峰值在速度轴上的跳跃规律再对比理论折叠后的速度最后通过两组不同PRF的测量结果反推真实速度。这一套方法虽然土但非常有效。5.4 如何判断仿真结果是“对”的指标验证思路很多新手跑出一张距离-多普勒图看到亮斑就算完成但实际并不知道结果是否正确。我自己习惯用三个维度来验证。第一个是峰值位置。目标理论距离和模糊速度算出来和图像峰值坐标对比误差不超过一个距离门/多普勒单元。第二个是信噪比改善量。测量目标峰值幅度与噪声底的平均幅度之比再和理论积累增益对比。比如N64相参积累理论上SNR提高18dB如果实测相差太多就要检查回波相位是否相参、窗函数是否吃掉了太多增益。第三个是分辨率。用两个距离/速度接近的目标看能否在二维谱里区分开。如果分辨不开多半是窗函数导致主瓣过宽或者是距离走动没有补偿。这些验证步骤听起来繁琐但能让你在加杂波、加干扰之前先把处理链路的底层逻辑确认清楚。我在实际项目中几乎每一次从仿真转到实测数据时都会重新走一遍这三个验证因为实测数据里的相位误差和幅相不一致很容易暴露出仿真掩盖的坑。5.5 运算量优化从直接卷积到FFT快速卷积最后说说速度。PD处理的运算量主要集中在两个地方快时间匹配滤波和慢时间FFT。匹配滤波用直接conv时每一个脉冲都要做一次长卷积N个脉冲就是N次。换成频域FFT快速卷积后每次迭代做三次FFT/IFFT但总复杂度从O(ML)降到O(NMlogM)M是距离采样点数。我最早跑200个脉冲、每脉冲10000个采样点直接用conv跑了十几秒换成FFT卷积后不到一秒。慢时间FFT可以用fft沿矩阵第一维做但要注意在FFT之前必须把窗函数乘好并且窗函数要放在慢时间域而不是快时间域。如果数据量特别大还可以用single类型存储回波数据或者把矩阵分块处理。MATLAB的向量化运算已经很快但多普勒维FFT的本质是一个对每列执行的批量操作直接用矩阵运算会比循环快很多。还有一个容易踩的坑FFT的点数不要盲目设成2的整数次幂。匹配滤波的FFT长度选nextpow2是为了用快速算法慢时间维的FFT点数等于脉冲数N即可多填零只会让频率轴插值不会提高物理分辨率。想要提高速度分辨率只能增加实际积累时间而不是靠补零。写到这里PD处理从原理到仿真链路已经完整走了一遍。老实说脉冲多普勒这套东西单独看每个环节都不难难的是把它们串起来的时候每一个参数变化都可能让结果变得面目全非。我建议你把上面的参考代码一行行自己敲一遍先跑通单目标再逐步加窗、加第二个目标、加杂波亲眼看一遍峰值怎么移动、怎么变模糊比背十遍公式都管用。之后再做实测数据处理你心里会有底很多。