日拱一卒之FMCW雷达基本原理5

FMCW雷达基本原理5

理论结合实际,才能读懂读通,当然实际雷达开发的过程中还会遇到别的问题,这里就简单的用matlab进行仿真,对FMCW雷达的应用有一个初步的认识就好。

verilog 复制代码
clc; clear; close all;

%% ================= 1. 雷达参数设置 =================
c = 3e8;                % 光速
fc = 77e9;              % 载波频率 77GHz
lambda = c/fc;          % 波长 (~3.9mm)

B = 150e6;              % 带宽 150MHz
Tc = 40e-6;             % Chirp 持续时间 (40us)
N_chirps = 64;          % 一帧里的 Chirp 数量
Fs = 10e6;              % 采样率
Ns = round(Tc * Fs);    % 每个 Chirp 的采样点数

% 标准 DSP 时间轴 (0 ~ N-1)
t = (0:Ns-1) / Fs;      
Slope = B/Tc;           % 调频斜率

%% ================= 2. 目标设置 =================
% 目标1: 20m, 0m/s (静止)
R1 = 20; v1 = 0;

% 目标2: 50m, 10m/s (远离,产生多普勒)
R2 = 50; v2 = 10;

%% ================= 3. 信号生成 =================
Mix_Data_Matrix = zeros(N_chirps, Ns);

fprintf('正在生成雷达回波信号...\n');
for m = 1:N_chirps
    t_slow = (m-1) * Tc; % 慢时间
    
    % 更新目标位置 (R = R0 + v*t)
    r1_curr = R1 + v1 * t_slow;
    r2_curr = R2 + v2 * t_slow;
    
    % 计算往返延迟
    tau1 = 2 * r1_curr / c;
    tau2 = 2 * r2_curr / c;
    
    % 生成中频信号 (IF Signal)
    Sig1 = exp(1j * 2*pi * (Slope * tau1 * t + fc * tau1));
    Sig2 = exp(1j * 2*pi * (Slope * tau2 * t + fc * tau2));
    
    % 叠加噪声 (SNR 调整)
    Noise = 0.5 * (randn(1, Ns) + 1j*randn(1, Ns));
    Mix_Data_Matrix(m, :) = Sig1 + Sig2 + Noise;
end

%% ================= 4. 信号处理 (FFT) =================

% --- 第一步: Range-FFT (对快时间做FFT) ---
Range_Map = fft(Mix_Data_Matrix, Ns, 2); 
Range_Map = Range_Map(:, 1:Ns/2); % 取正半轴

% 生成距离轴
f_bin_res = Fs / Ns;
f_axis = (0:Ns/2-1) * f_bin_res;
R_axis = c * f_axis / (2 * Slope); 

% --- 第二步: Doppler-FFT (对慢时间做FFT) ---
Doppler_Map = fft(Range_Map, N_chirps, 1);    
Doppler_Map = fftshift(Doppler_Map, 1);       % 零频移到中间

% 生成速度轴
v_res = lambda / (2 * N_chirps * Tc); % 速度分辨率
v_idx = -N_chirps/2 : N_chirps/2 - 1;
v_axis = v_idx * v_res;

%% ================= 5. 可视化绘图 =================
figure('Color', 'white', 'Position', [50, 50, 1200, 800]);

% --- 子图1: 混频器输出 (Mixer Output) ---
subplot(2,2,1);
plot(t*1e6, real(Mix_Data_Matrix(1,:)), 'LineWidth', 1);
title('1. 混频器输出 (单个Chirp时域)');
xlabel('时间 (us)'); ylabel('幅度');
grid on; axis tight;
subtitle('充满了噪声和杂波,看不出目标');

% --- 子图2: Range-FFT 结果堆叠 ---
subplot(2,2,2);
% 这里的维度是 [N_chirps x N_bins],所以 X轴是距离,Y轴是Chirp编号
imagesc(R_axis, 1:N_chirps, abs(Range_Map));
title('2. Range-FFT 结果 (垂直堆叠)');
xlabel('距离 (m)'); ylabel('Chirp 编号 (慢时间)');
colormap(jet);
xline(R1, 'w--', 'LineWidth', 1.5);
xline(R2, 'w--', 'LineWidth', 1.5);
xlim([0 80]);
subtitle('两条亮线位置不动,但颜色(相位)在变');

% --- 子图3: 相位旋转演示 (Phasor Rotation) ---
% 提取目标2 (50m) 的相位数据
[~, idx_target2] = min(abs(R_axis - R2)); 
phase_history = angle(Range_Map(:, idx_target2)); 

subplot(2,2,3);
% 画单位圆背景
theta = linspace(0, 2*pi, 100);
plot(cos(theta), sin(theta), 'k:', 'LineWidth', 1); hold on;
% 画前12个Chirp的相位矢量
for k = 1:12
    phasor = exp(1j * phase_history(k));
    col = [1 0 0] * (1 - (k-1)/15); % 颜色渐变
    % 画箭头
    quiver(0, 0, real(phasor), imag(phasor), 'Color', col, ...
        'LineWidth', 2, 'MaxHeadSize', 0.5, 'AutoScale', 'off');
end
axis equal; grid on; xlim([-1.2 1.2]); ylim([-1.2 1.2]);
title('3. 目标2(50m, 10m/s) 的相位旋转');
xlabel('实部 I'); ylabel('虚部 Q');
text(-0.9, -1.1, '箭头随Chirp逆时针旋转 \rightarrow', 'Color', 'r', 'FontSize', 10);

% --- 子图4: 2D-FFT 最终结果 (已修正) ---
subplot(2,2,4);

% [重要修正] 转置 Doppler_Map 以匹配 (x=速度, y=距离)
% Doppler_Map.' 的维度变成 [200 x 64]
imagesc(v_axis, R_axis, abs(Doppler_Map).'); 

title('4. 最终结果: 距离-速度热力图');
xlabel('速度 (m/s)'); ylabel('距离 (m)');
axis xy; % 翻转Y轴方向,让0在下面
colormap(jet); 
colorbar;

% 限制显示范围,聚焦目标
ylim([0 80]); 
xlim([-15 15]); 

% 加上辅助线验证 (理论位置)
hold on;
xline(v1, 'w--', 'LineWidth', 1.5); 
yline(R1, 'w--', 'LineWidth', 1.5);
plot(v1, R1, 'wo', 'MarkerSize', 8, 'LineWidth', 2); % 画个圈

xline(v2, 'w--', 'LineWidth', 1.5); 
yline(R2, 'w--', 'LineWidth', 1.5);
plot(v2, R2, 'wo', 'MarkerSize', 8, 'LineWidth', 2); % 画个圈

legend('理论位置', 'Location', 'best');
subtitle('红点精准落在白虚线交叉处');

fprintf('绘图完成!请查看弹出的窗口。\n');

这是一段MATLAB仿真的代码,分析一下:

第一部分:搭建雷达系统 (System Parameters)

这部分定义了雷达的物理属性,决定了它"能看多远"和"能看多细"。

matlab 复制代码
c = 3e8;                % 光速
fc = 77e9;              % 载波频率 77GHz
lambda = c/fc;          % 波长
B = 150e6;              % 带宽 150MHz
Tc = 40e-6;             % Chirp 持续时间
Slope = B/Tc;           % [关键] 调频斜率 S

  1. 波长 λ \lambda λ

    λ = c f c ≈ 3.9 mm \lambda = \frac{c}{f_c} \approx 3.9 \text{mm} λ=fcc≈3.9mm

    决定了雷达对微小位移(相位变化)的敏感度。测速全靠它。

  2. 调频斜率 S S S (Slope)

    S = B T c S = \frac{B}{T_c} S=TcB

    这是 FMCW 的"刻度尺"。它定义了频率随时间增加得有多快。后续计算距离时,需要用它把"频率差"换算回"时间延迟"。

  3. Tc = 40e-6; % Chirp 持续时间 (40us)

    Fs = 10e6; % 采样率

    Ns = round(Tc * Fs); % 每个 Chirp 的采样点数

    这里采样点数是通过计算得出的,可以想想为什么这么计算。


第二部分:信号生成核心 (Signal Generation)

这是整个仿真中最"硬核"的部分,模拟了物理世界中的回波混频。

matlab 复制代码
for m = 1:N_chirps
    t_slow = (m-1) * Tc;       % 慢时间
    r1_curr = R1 + v1 * t_slow;% 实时距离
    tau1 = 2 * r1_curr / c;    % 往返延迟
    
    % [核心公式] 生成中频信号
    Sig1 = exp(1j * 2*pi * (Slope * tau1 * t + fc * tau1));
    ...
end
对应的物理原理与公式推导

这行代码 exp(...)​ 实际上是 FMCW 混频输出公式 的直接实现。

  1. 发射信号 (Tx) :频率随时间 t t t 线性增加。

    相位 ϕ T x ( t ) = 2 π ( f c t + 1 2 S t 2 ) \phi_{Tx}(t) = 2\pi (f_c t + \frac{1}{2} S t^2) ϕTx(t)=2π(fct+21St2)

  2. 接收信号 (Rx) :比发射晚了 τ \tau τ 秒。

    相位 ϕ R x ( t ) = 2 π ( f c ( t − τ ) + 1 2 S ( t − τ ) 2 ) \phi_{Rx}(t) = 2\pi (f_c (t-\tau) + \frac{1}{2} S (t-\tau)^2) ϕRx(t)=2π(fc(t−τ)+21S(t−τ)2)

  3. 混频 (Mixer) :执行减法 Δ ϕ = ϕ T x − ϕ R x \Delta \phi = \phi_{Tx} - \phi_{Rx} Δϕ=ϕTx−ϕRx。

    忽略掉高次项( S τ 2 S\tau^2 Sτ2 极小),剩下的相位差为:

    Δ ϕ ( t ) ≈ 2 π ( S τ t ⏟ 频率项 + f c τ ⏟ 相位项 ) \Delta \phi(t) \approx 2\pi \left( \underbrace{S \tau t}{\text{频率项}} + \underbrace{f_c \tau}{\text{相位项}} \right) Δϕ(t)≈2π 频率项 Sτt+相位项 fcτ

解读代码中的两项:
  • 第1项:Slope * tau1 * t(距离频率项)

    这一项包含快时间 t t t。

    对 t t t 求导得到频率: f = S τ f = S \tau f=Sτ。这就是拍频 (Beat Frequency)

  • 作用: 给 Range-FFT 提供频率信息,用来算距离。

  • 第2项:fc * tau1(多普勒相位项)

    这一项不包含 t t t,对于单个 Chirp 来说是个常数(初相)。

    但在不同的 Chirp 之间( m m m 变化),由于物体运动, r c u r r r_{curr} rcurr 变了 → \rightarrow → τ \tau τ 变了。

    相位变化量: Δ ϕ = 2 π f c Δ τ \Delta \phi = 2\pi f_c \Delta \tau Δϕ=2πfcΔτ。

  • 作用: 给 Doppler-FFT 提供相位旋转信息,用来算速度。


第三部分:距离测量 (Range-FFT)

matlab 复制代码
Range_Map = fft(Mix_Data_Matrix, Ns, 2); % 沿维度2(快时间)做FFT

% 坐标轴转换公式
f_bin_res = Fs / Ns;             
f_axis = (0:Ns/2-1) * f_bin_res; % 得到拍频 fb
R_axis = c * f_axis / (2 * Slope); % 将 fb 转换为 距离 R
对应的物理原理

这里利用的是 拍频与距离的线性关系

  1. 拍频公式

    由混频原理可知,拍频 f b f_b fb 等于斜率乘以延迟:

    f b = S ⋅ τ f_b = S \cdot \tau fb=S⋅τ

  2. 代入延迟公式 τ = 2 R c \tau = \frac{2R}{c} τ=c2R:

    f b = S ⋅ 2 R c f_b = S \cdot \frac{2R}{c} fb=S⋅c2R

  3. 反解距离 R R R(即代码中的最后一行):

    R = c ⋅ f b 2 S R = \frac{c \cdot f_b}{2S} R=2Sc⋅fb

FFT 找到了信号里包含哪个频率 f b f_b fb,代码用上面的公式把这个频率直接翻译成了距离 R R R。

!NOTE

坐标中的转换公式,可以好好想想


第四部分:速度测量 (Doppler-FFT)

这是最神奇的一步,利用相位旋转测速。

matlab 复制代码
Doppler_Map = fft(Range_Map, N_chirps, 1); % 沿维度1(慢时间)做FFT

% 坐标轴转换公式
v_res = lambda / (2 * N_chirps * Tc); 
v_idx = -N_chirps/2 : N_chirps/2 - 1;
v_axis = v_idx * v_res;
对应的物理原理

这里利用的是 多普勒效应引起的相位变化

  1. 位移与相位

    相邻两个 Chirp 间隔时间 T c T_c Tc。物体移动了 Δ d = v ⋅ T c \Delta d = v \cdot T_c Δd=v⋅Tc。

    这导致的相位变化 Δ ϕ \Delta \phi Δϕ 为:

    Δ ϕ = 4 π Δ d λ = 4 π v T c λ \Delta \phi = \frac{4\pi \Delta d}{\lambda} = \frac{4\pi v T_c}{\lambda} Δϕ=λ4πΔd=λ4πvTc

  2. 角频率与 FFT

    如果在慢时间轴上做 FFT,得到的"频率"索引 k k k (代码中的 v_idx) 代表了相位的旋转速度。

    其关系满足:

    2 π k N c h i r p s = Δ ϕ = 4 π v T c λ 2\pi \frac{k}{N_{chirps}} = \Delta \phi = \frac{4\pi v T_c}{\lambda} 2πNchirpsk=Δϕ=λ4πvTc

  3. 反解速度 v v v

    v = λ 2 T c ⋅ k N c h i r p s v = \frac{\lambda}{2 T_c} \cdot \frac{k}{N_{chirps}} v=2Tcλ⋅Nchirpsk

    观察代码:v_res = lambda / (2 * N_chirps * Tc)​ 其实就是上面公式里的系数部分。

    所以 v = v_idx * v_res 就是把 FFT 的索引变成了速度值。

!NOTE

同样,坐标轴的转换还是值得去想想为什么需要这么做。

结果

总结全流程

  1. S τ t S \tau t Sτt (快时间项) → Range-FFT \xrightarrow{\text{Range-FFT}} Range-FFT 提取出 f b f_b fb → R = c f b 2 S \xrightarrow{R=\frac{c f_b}{2S}} R=2Scfb 算出距离
  2. f c τ f_c \tau fcτ (慢时间项) → Doppler-FFT \xrightarrow{\text{Doppler-FFT}} Doppler-FFT 提取出 Δ ϕ \Delta \phi Δϕ → v = λ Δ ϕ 4 π T c \xrightarrow{v=\frac{\lambda \Delta \phi}{4\pi T_c}} v=4πTcλΔϕ 算出速度

坐标轴转换

FFT(快速傅里叶变换)本质上是一个数学工具,它只懂 "数字" (索引 Index 0, 1, 2...),不懂 "物理" (米、米/秒)。

之所以能把 FFT 的结果坐标轴画成"距离"和"速度",是因为在雷达设计之初,就建立了一套严密的物理映射关系

一、 距离轴转换 (Range Axis)

代码源头:

matlab 复制代码
f_bin_res = Fs / Ns;              % 1. FFT的一个格子代表多少Hz
f_axis = (0:Ns/2-1) * f_bin_res;  % 2. 生成频率轴 (Hz)
R_axis = c * f_axis / (2 * Slope);% 3. 把 Hz 换算成 米
1. 第一步:从"格子(Bin)"到"频率(Hz)"

FFT 的输出是一个数组。数组的第 k k k 个元素(Bin k k k)代表什么频率?

这取决于你的采样参数:

  • 总带宽: 也就是采样率 F s F_s Fs(Sampling Rate)。
  • 切成几份: 也就是采样点数 N s N_s Ns。

所以,每一个格子代表的频率宽度(分辨率)是:

Δ f = F s N s \Delta f = \frac{F_s}{N_s} Δf=NsFs

第 k k k 个格子的频率就是: f = k ⋅ Δ f f = k \cdot \Delta f f=k⋅Δf。

2. 第二步:从"频率(Hz)"到"时间(s)"

这是 FMCW 的核心特性。

  • 发射的 Chirp 是线性调频波,斜率是 S S S (Slope)。
  • 意思是:每过 1秒,频率增加 S S S Hz。
  • 反过来:如果你看到了 f b f_b fb 的频率差,说明信号延迟了 τ \tau τ 秒。

τ = f b S \tau = \frac{f_b}{S} τ=Sfb

3. 第三步:从"时间(s)"到"距离(m)"
  • 信号是电磁波,以光速 c c c 飞行。
  • 信号走了往返(去+回),所以路程是 2 R 2R 2R。

τ = 2 R c \tau = \frac{2R}{c} τ=c2R

4. 终极合并:从"频率"到"距离"

联立上面两步:

f b S = 2 R c \frac{f_b}{S} = \frac{2R}{c} Sfb=c2R

把 R R R 挪到左边:

R = c ⋅ f b 2 S R = \frac{c \cdot f_b}{2S} R=2Sc⋅fb

这就是代码中 R_axis = c * f_axis / (2 * Slope) 的物理来源。

  • 直观理解: 频率越高 → \rightarrow → 延迟越大 → \rightarrow → 距离越远。

二、 速度轴转换 (Velocity Axis)

代码源头:

matlab 复制代码
v_res = lambda / (2 * N_chirps * Tc); % 1. 一个格子代表多少速度
v_idx = -N_chirps/2 : N_chirps/2 - 1; % 2. 生成索引 (-32 ~ +31)
v_axis = v_idx * v_res;               % 3. 生成速度轴

这个转换稍微绕一点,因为它涉及到了相位

1. 物理源头:相位差与速度

正如之前分析的,相邻两个 Chirp(间隔 T c T_c Tc)之间,物体移动距离 Δ d = v ⋅ T c \Delta d = v \cdot T_c Δd=v⋅Tc。

这导致的相位变化 Δ ϕ \Delta \phi Δϕ 是:

Δ ϕ = 4 π ⋅ ( v ⋅ T c ) λ \Delta \phi = \frac{4\pi \cdot (v \cdot T_c)}{\lambda} Δϕ=λ4π⋅(v⋅Tc)

2. FFT 的视角:角频率

我们在慢时间维度(Chirp 序列)上做 FFT。FFT 看到的"频率"(这里指数字角频率 ω \omega ω)其实就是相位变化率

FFT 的第 k k k 个格子,代表的相位变化是:

Δ ϕ = 2 π ⋅ k N c h i r p s \Delta \phi = \frac{2\pi \cdot k}{N_{chirps}} Δϕ=Nchirps2π⋅k

(注:这里假设 k k k 覆盖一个完整周期)

3. 建立映射:从"格子"到"速度"

让上面两个 Δ ϕ \Delta \phi Δϕ 相等:

4 π v T c λ = 2 π k N c h i r p s \frac{4\pi v T_c}{\lambda} = \frac{2\pi k}{N_{chirps}} λ4πvTc=Nchirps2πk

4. 求解速度 v v v

我们把 v v v 解出来:

v = ( λ 2 ⋅ T c ⋅ N c h i r p s ) ⏟ 代码中的 v_res ⋅ k v = \underbrace{\left( \frac{\lambda}{2 \cdot T_c \cdot N_{chirps}} \right)}_{\text{代码中的 v\_res}} \cdot k v=代码中的 v_res (2⋅Tc⋅Nchirpsλ)⋅k

  • λ \lambda λ:波长。波长越短,同样的移动产生的相位变化越大,测量越灵敏。
  • T c ⋅ N c h i r p s T_c \cdot N_{chirps} Tc⋅Nchirps:这就是一帧的总时间 T f r a m e T_{frame} Tframe。观测时间越长,速度分辨率越高(分母越大,分辨率数值越小)。

这就是代码中 v_res 公式的由来。

总结表

维度 FFT 输出 (数学) 中间物理量 (桥梁) 最终物理量 (人话) 核心转换因子
距离轴 频率 Bin ( k k k) 拍频 f b f_b fb (Hz) 距离 R R R (m) c 2 S \frac{c}{2S} 2Sc (光速除以2倍斜率)
速度轴 频率 Bin ( k k k) 相位差 Δ ϕ \Delta \phi Δϕ (rad) 速度 v v v (m/s) λ 2 T f r a m e \frac{\lambda}{2 T_{frame}} 2Tframeλ (波长除以2倍总时长)
  • 距离转换 依赖于 Slope (调频斜率)
  • 速度转换 依赖于 Wavelength (波长)Time (观测时长)
相关推荐
Wishell20158 天前
日拱一卒之FMCW雷达基本原理2
雷达
Wishell20159 天前
日拱一卒之FMCW雷达基本原理1
雷达
Wishell201510 天前
日拱一卒之零中频接收机简述
雷达
Wishell201511 天前
日拱一卒之超外差接收机简述
雷达
Wishell201513 天前
日拱一卒之雷达散射截面与dBZ
雷达
Wishell201514 天前
日拱一卒之射频系统中的噪声
雷达
Wishell201516 天前
日拱一卒之雷达接收机的性能指标
雷达
飞睿科技1 个月前
探讨雷达在智能家居与消费电子领域的应用
人工智能·嵌入式硬件·智能家居·雷达·毫米波雷达
Hi202402171 个月前
相机与激光雷达联合标定:如何选择高辨识度的参照物
数码相机·自动驾驶·雷达·相机标定·机器视觉