
简介面向电子工程、物理研究人员、大学生及工程技术人员的MATLAB雷达仿真学习包系统讲解雷达测速与测距中的多普勒效应核心原理。内容覆盖发射信号建模、回波接收、多普勒频移提取、目标距离与速度解算及数据处理等完整流程并通过仿真实验直观呈现测量结果。压缩包共593个文件总大小约7.75MB以480个m源码文件为主体辅以mat数据文件、fig图像与png结果图、c/cpp扩展及dll动态库等便于在MATLAB中直接运行、修改与验证算法。已有178人学习下载。可运行的MATLAB实现帮助读者快速重现多普勒测速测距实验理清频移计算与距离速度联合解算思路同时融入交通管理、军事侦察、气象监测等应用前景讨论并引用多份参考资料为后续深入研究提供延伸方向。1. 雷达测速测距的仿真从哪里下手多普勒频移与差频信号不能分开看做雷达测速测距的算法验证最难的不是套公式而是不知道数据里哪一部分该做 FFT、做完 FFT 又该看哪个轴。只用连续波测速时多普勒频移只给出速度距离信息完全缺失只用 FMCW 测距时差频频率可以映射距离但目标一旦运动差频里又会混进多普勒频移直接算距离会偏。要同时解开两个量惯用的做法是把一帧里的多个 chirp 排成矩阵沿快时间维做距离 FFT、沿慢时间维做速度 FFT最后从距离-多普勒图里同时读取距离和速度。MATLAB 在整套流程里顺手得多波形生成、窗函数、二维 FFT 和图像显示都是现成函数几十行代码就能把原理落成可见结果。这篇文章会从信号模型、最小可运行代码、结果分析一直讲到参数边界和验证方式适合课程设计、雷达算法预研以及刚接触毫米波雷达数据的读者。2. 多普勒测速与 FMCW 测距的原理在 MATLAB 里先要建立哪两个模型2.1 距离信息在快时间维速度信息在慢时间维两者由同一个差频信号携带FMCW 雷达发射信号的频率随时间线性上升。设调频带宽为 Bchirp 持续时间为 Tc则调频斜率 SB/Tc。发射信号用复数形式写为s_tx(t)exp(j2π(f_c t 1/2 S t^2))目标回波相对于发射信号有一个时间延迟 τ2R/c。接收机把回波信号与发射信号的共轭相乘得到差频拍频信号。忽略幅度和多径后差频信号的相位近似为s_if(t)exp(j2π(f_c τ Sτ t))其中第一项是固定相位第二项是一个随时间线性变化的相位项其瞬时频率是 Sτ。对快时间 t 做 FFT会在频率 Sτ 处形成一个谱峰因为 τ2R/c所以谱峰位置正比于距离。这就是 FMCW 测距的基本关系。当目标以径向速度 v 运动时每个 chirp 对应的 τ 都在变化。设慢时间为 t_slow则距离 R(t_slow)R0v·t_slowτ(t_slow)2R(t_slow)/c。把它代回 s_if(t) 的固定相位项 f_c τ 中会看到该相位随 chirp 序号线性变化。相邻 chirp 之间的相位差是 4πvTc/λ也就是慢时间维上的多普勒频移 f_d2v/λ。快时间维和慢时间维在同一个差频信号矩阵里但分属不同维度这正是二维 FFT 可以同时得到雷达测距和雷达测速结果的原因。2.2 先定好 6 个雷达参数再看距离分辨率和速度分辨率的边界在 MATLAB 里做仿真要先定一组参数。我一般用下面这组它接近常见的毫米波雷达前级参数参数符号取值作用由它决定的边界fc77 GHz载波频率λc/fc≈3.9 mm速度换算系数B200 MHz调频带宽距离分辨率 ΔRc/(2B)0.75 mTc50 µs单个 chirp 时长最大不模糊速度 v_maxλ/(4Tc)≈19.5 m/sfs4 MHz快时间采样率最大不模糊距离 R_maxc·fs/(4S)≈75 mNchirp128一帧内 chirp 数量速度分辨率 Δvλ/(2Nchirp·Tc)≈0.305 m/sS4×10^12 Hz/s调频斜率由 B/Tc 计算不要手工写死把这组参数代进去距离分辨率 0.75 m速度分辨率 0.305 m/s。一个 50 m 处、以 10 m/s 靠近的目标差频约 1.33 MHz在 N_range256 时谱峰大约落在第 86 个 bin多普勒维大约落在第 33 个 bin。第一次跑仿真时目标参数一定要放在这两个边界以内如果直接设速度 25 m/s慢时间采样率 1/Tc20 kHz而 f_d2×25/0.0039≈12.8 kHz超过了 10 kHz 的奈奎斯特频率速度谱会混叠成一个错误的负速度峰。同理目标放在 80 m 时差频 f_IFS·2R/c≈2.13 MHz也会超过 fs/22 MHz被折叠到一个虚假的近距峰。看到这种“测出来的值突然变小”的结果先检查有没有越过边界而不是急着调 FFT 参数。2.3 为什么差频信号在 MATLAB 里用 exp(1j*...) 而不写成 cos仿真代码里几乎不会出现 cos(2πft) 这种写法。原因有两个。第一差频信号是单边频谱用复数指数建模后快时间 FFT 的峰值只在正频率一侧出现负频率部分不会生成镜像目标检测的峰值干净得多。第二慢时间维度需要保留速度方向也就是正负多普勒频移。cos 信号在频谱上对称地分成 ±f 两个峰幅度和相位信息被拆散处理起来很别扭。相位式 exp(1j2πf_cdelay 1j2πSdelay*t_fast) 既包含当前 chirp 对应的距离延迟又能通过跨 chirp 的固定相位变化还原出速度方向。因此后续所有代码都按复数基带形式组织。3. 用 MATLAB 串起差频信号、二维 FFT 与峰值读取的最小链路3.1 生成差频信号矩阵的完整 MATLAB 代码先给最小可运行代码。下面这段脚本会生成一个 Ns×Nchirp 的复数差频矩阵 IF_sig行对应快时间采样列对应一帧里的不同 chirp。% 雷达与波形参数 fc 77e9; % 载频 77 GHz c 3e8; % 光速 B 200e6; % 调频带宽 200 MHz Tc 50e-6; % 单个 chirp 时长 50 us fs 4e6; % 差频信号采样率 4 MHz S B / Tc; % 调频斜率 4e12 Hz/s % 目标与帧参数 R0 50; % 目标初始距离 50 m v 10; % 目标径向速度 10 m/s正值表示靠近雷达 Nchirp 128; % 一帧内 chirp 数量 % 时间轴 Ns round(Tc * fs); % 每个 chirp 的采样点数 t_fast (0:Ns-1) / fs; % 快时间轴 t_slow (0:Nchirp-1) * Tc; % 慢时间轴 lambda c / fc; % 波长 % 差频信号矩阵 IF_sig zeros(Ns, Nchirp); for k 1:Nchirp % 当前 chirp 发送时刻目标的真实距离 R_k R0 v * t_slow(k); delay 2 * R_k / c; % 回波延迟 % 差频信号快时间项 S*delay*t_fast 对应距离 % 恒定相位项 fc*delay 跨 chirp 变化对应多普勒 IF_sig(:, k) exp(1j * 2 * pi * (fc * delay S * delay * t_fast)); end这段代码直接写出了差频后的相位等价于先构造 s_tx、s_rx 再做s_tx.*conj(s_rx)没有缺步骤。最核心的地方在于 delay 的计算。如果用 delay2*R0/c 并固定不变测速信息就完全丢失后面多普勒 FFT 不会出现峰值v_est 会变成 0。这里的 R_k 随 t_slow 变化正是多普勒频移的来源。Tc*fs200是整数所以Ns直接取 round 也不会有问题如果换参数后不是整数必须用 round 并检查Ns*fs是否准确对应一个 chirp 时长否则多普勒轴会整体偏移。t_slow从 0 开始相邻 chirp 的间隔就是 Tc它决定了慢时间的采样周期。3.2 沿快时间做距离 FFT沿慢时间做多普勒 FFT下一步是二维 FFT。先用 nextpow2 把两个维度的 FFT 长度都取成 2 的幂再用 hamming 窗压低旁瓣。% FFT 长度取 2 的幂方便频点计算 N_range 2^nextpow2(Ns); N_doppler 2^nextpow2(Nchirp); % 窗函数减少距离维和多普勒维的频谱泄漏 range_win hamming(Ns); doppler_win hamming(Nchirp); % 第一步快时间 FFT得到距离维频谱 RD_map fft(IF_sig .* range_win, N_range, 1); % 第二步慢时间 FFT得到多普勒维频谱 % doppler_win 是列向量用转置变为行向量后与矩阵按维相乘 RD_map fft(RD_map .* doppler_win, N_doppler, 2); % 将多普勒零频移动到中间方便按照正负频率查看 RD_map fftshift(RD_map, 2);逻辑说明第一次 fft 沿着第 1 维做等价于对每个 chirp 做一次距离维变换输出是“距离门 × chirp 序号”的二维复数矩阵。第二次 fft 沿着第 2 维做输入是同一个距离门在一帧内各 chirp 的相位序列输出就是多普勒频谱。两个维度合在一起才得到距离-多普勒矩阵 RD_map也就是常说的距离-多普勒图。这里fftshift只作用于第 2 维距离维轴仍然从零频开始不需要 shift。IF_sig .* range_win中 range_win 是 Ns×1 列向量与 Ns×Nchirp 矩阵相乘时由 MATLAB 的隐式扩展完成doppler_win需要转置成 1×Nchirp 才能沿着列方向扩展。如果版本较老显式写repmat会更保险。下面是这一步的维度关系FFT 步骤作用维度输入矩阵输出矩阵语义fft(IF_sig .* range_win, N_range, 1)快时间维Ns×NchirpN_range×Nchirp每一列是单个 chirp 的距离谱fft(..., N_doppler, 2)慢时间维N_range×NchirpN_range×N_doppler距离与多普勒的二维联合谱fftshift(..., 2)多普勒维同上多普勒零频移到中间按正负速度查看3.3 从峰值位置把距离和速度换算出来峰值检索和换算也可以直接写成代码% 找距离-多普勒图上幅度最大的点 [~, idx] max(abs(RD_map(:))); [r_idx, d_idx] ind2sub(size(RD_map), idx); % 距离维由 FFT bin 换算到差频频率再换算到距离 f_if_est (r_idx - 1) / N_range * fs; R_est f_if_est * c / (2 * S); % 多普勒维由 fftshift 后的 bin 换算到多普勒频率再换算到速度 f_d_axis (-N_doppler/2 : N_doppler/2 - 1) / N_doppler / Tc; f_d_est f_d_axis(d_idx); v_est f_d_est * lambda / 2; fprintf(估计距离: %.2f m\n, R_est); fprintf(估计速度: %.2f m/s\n, v_est);这段代码把频率轴定义和 bin 索引换算讲清楚了。MATLAB 的fft结果从下标 1 开始所以真实频率要写成(r_idx-1)/N_range*fs和索引从 0 开始的 C 语言 FFT 不同。多普勒维因为做了fftshift频率轴是负半轴在前、正半轴在后直接和f_d_axis(d_idx)对应。运行后 R_est 应该在 50 m 附近v_est 在 10 m/s 附近但不会精确等于设定值因为 FFT 频率分辨率的限制让峰值落在 bin 中心之外这是正常的栅栏效应下一节会讲怎么进一步压缩这个误差。4. 距离-多普勒图的结果研究峰值换算、参数对照与三个常见误设4.1 把谱峰读数换成距离和速度的两级换算上一章的换算里隐藏了一个细节R_est是先把 FFT 的 bin 索引换算成差频频率再把差频频率换算成距离。距离维频率分辨率是fs/N_range。以 N_range256 为例距离维 bin 间隔约为 1.17 m但物理距离分辨率由带宽 B 决定是 c/(2B)0.75 m。补零到 2048 只是把 bin 间隔变小让谱峰看起来更平滑不会把两个相距 0.5 m 的目标分开。多普勒维的情况类似。多普勒频率分辨率是1/(Nchirp*Tc)速度分辨单元是λ/(2*Nchirp*Tc)。想提高速度分辨率直接增加 Nchirp 最有效。不过 Hamming 窗会把主瓣展宽约 1.44 倍加窗后的实际分辨能力比理论值略差这一点在多目标邻近时尤其明显。4.2 雷达测速测距参数调整对照表调参是结果研究里最重要的部分。很多初学的人觉得距离分辨率不够就调大带宽结果差频超过采样率反而测不出正确距离。下面这张表是调参时最常用的依据优化目标推荐改法副作用与代价提高距离分辨率增大带宽 B差频频率随 B 上升fs 不够时最大测距下降提高最远测距提高 fs 或增大 Tc增大 Tc 会降低多普勒不模糊速度可能出现测速混叠提高速度分辨率增大一帧内 chirp 数 Nchirp帧时间变长实时性下降更新率降低提高最大不模糊速度减小 Tc单个 chirp 变短快时间采样点变少距离分辨率受限压低旁瓣换凯塞窗等主瓣展宽峰值定位误差变大例如要把距离分辨率从 0.75 m 提高到 0.375 mB 从 200 MHz 涨到 400 MHz在 Tc 不变时 S 翻倍同样的 50 m 目标差频从 1.33 MHz 变成 2.67 MHz已经超过 fs/2距离谱会混叠。此时要么把 fs 同步提到 8 MHz要么接受最大测距减半。反过来把 Tc 从 50 µs 加大到 100 µs最大不模糊速度从 19.5 m/s 降到 9.75 m/s10 m/s 的目标会立刻变成“折叠”后的假速度。调参时距离边界和速度边界必须一起看。注意当目标距离超过 R_maxc·fs/(4S) 时差频峰值会发生频谱折叠。如果你发现 R_est 突然变得很小且和设置值对不上先算这个边界而不是改 FFT 长度。4.3 三种最常导致“跑不出峰”的 MATLAB 误设第一取实部丢了速度方向。把IF_sig用real(IF_sig)处理后再做 FFT会得到对称的双峰峰值定位严重受影响。差频信号应该保持复数形式。第二两个 FFT 的维度写反。快时间和慢时间都做 FFT 后应当得到一个二维复数矩阵如果fft(...,2)被误写成fft(...,1)速度维根本没有展开RD_map 上不会出现孤立峰而会出现一整条沿距离维的亮线。第三忘记 fftshift 或 shift 了错误维度。多普勒轴如果不 shift零速度峰被放在频谱两端负速度目标会显示在右边缘初看容易误判。检查方法很简单先画出mesh(abs(RD_map))距离维看峰的位置能否对应 R0多普勒维看峰是否落在零频附近且只有一侧有清晰旁瓣不符合预期就回去检查 FFT 的维度。5. 用峰值插值和二维 CFAR 把雷达测速测距结果推得更稳5.1 三点抛物线插值压低栅栏误差FFT 峰值落在整数 bin 之间时max得到的 bin 索引会带来最多半个分辨单元的误差。对单目标场景一个三点抛物线插值就能明显改善取峰值前后的 bin 幅度拟合抛物线顶点就是更精确的峰位置。if r_idx 1 r_idx N_range y abs(RD_map(r_idx-1:r_idx1, d_idx)); delta_r 0.5 * (y(3) - y(1)) / (y(1) - 2*y(2) y(3) eps); f_if_est ((r_idx - 1 delta_r) / N_range) * fs; R_est f_if_est * c / (2 * S); end这个公式就是二次函数在三个等距采样点上的顶点坐标。eps是为了避免分母为零。多普勒维用同样的方式插值速度估计会更接近真实值。5.2 多目标场景把单峰 max 换成二维 CFAR 检测max搜索在多目标场景下会被强目标盖住弱目标。更接近工程化的做法是使用 Phased Array System Toolbox 提供的二维恒虚警检测器phased.CFARDetector2D对每个距离-多普勒单元用周围训练单元估计噪声底超过门限才认为是目标。cfar phased.CFARDetector2D( ... TrainingBandSize, [4 4], ... GuardBandSize, [2 2], ... FalseAlarmRate, 1e-4); det cfar(abs(RD_map), (1:numel(RD_map))); mask reshape(det, size(RD_map));FalseAlarmRate是虚警概率门限取 1e-4 是比较稳的起点TrainingBandSize和GuardBandSize控制参考窗和保护窗的尺寸。训练单元太小门限会被邻近目标抬高保护单元太小目标能量会泄漏进参考窗。这里的 [4 4] 和 [2 2] 要按距离-多普勒图中目标的实际尺寸调整不是固定值。5.3 仿真结果的验证方法跑完上面任意一种检测把 R_est、v_est 与仿真里设置的 R0、v 直接相减误差落在半个分辨单元的量级内就说明差频、FFT、换算这条链路是自洽的。还想进一步确认速度方向时把 v 改成 -10 重跑一次观察 RD_map 上的峰是否移动到多普勒轴的负半轴这是最直观的方向验证。本文还有配套的精品资源点击获取