FMCW雷达测速测距系统(锯齿波 + CFAR检测)

一、系统原理与数学模型

1.1 FMCW锯齿波雷达原理

复制代码
发射信号:锯齿波调频连续波
接收信号:延迟+多普勒频移
混频输出:中频信号(IF)

关键公式:

  • 距离方程 :R=c⋅fIF2⋅SR = \frac{c \cdot f_{IF}}{2 \cdot S}R=2⋅Sc⋅fIF
  • 速度方程 :v=λ⋅fD2v = \frac{\lambda \cdot f_D}{2}v=2λ⋅fD
  • 调频斜率 :S=BTcS = \frac{B}{T_c}S=TcB

其中:

  • ccc:光速(3×10⁸ m/s)
  • fIFf_{IF}fIF:中频频率
  • SSS:调频斜率
  • BBB:带宽
  • TcT_cTc:锯齿波周期
  • λ\lambdaλ:波长
  • fDf_DfD:多普勒频率

1.2 信号模型

发射信号:

st(t)=Atcos⁡(2πfct+πBTct2)s_t(t) = A_t \cos\left(2\pi f_c t + \pi \frac{B}{T_c} t^2\right)st(t)=Atcos(2πfct+πTcBt2)

接收信号:

sr(t)=Arcos⁡(2πfc(t−τ)+πBTc(t−τ)2+2πfDt)s_r(t) = A_r \cos\left(2\pi f_c (t-\tau) + \pi \frac{B}{T_c} (t-\tau)^2 + 2\pi f_D t\right)sr(t)=Arcos(2πfc(t−τ)+πTcB(t−τ)2+2πfDt)

中频信号(混频后):

sIF(t)=AIFcos⁡(2πfIFt+2πfDt+ϕ0)s_{IF}(t) = A_{IF} \cos\left(2\pi f_{IF} t + 2\pi f_D t + \phi_0\right)sIF(t)=AIFcos(2πfIFt+2πfDt+ϕ0)


二、MATLAB实现代码

2.1 主程序:FMCW雷达系统

matlab 复制代码
%% FMCW雷达测速测距系统(锯齿波 + CFAR检测)
clear; clc; close all;

%% ========== 1. 雷达参数设置 ==========
fprintf('=== FMCW雷达测速测距系统 ===\n');

% 基本参数
c = 3e8;                  % 光速 (m/s)
fc = 77e9;                % 载频 77 GHz
B = 300e6;                % 带宽 300 MHz
Tc = 50e-6;               % 锯齿波周期 50 μs
fs = 10e6;                % 采样率 10 MHz
N_samples = 512;          % 每帧采样点数
N_chirps = 128;           % 帧数(慢时间维度)

% 目标参数
targets.R = [50, 120, 200];      % 目标距离 (m)
targets.v = [10, -5, 25];        % 目标速度 (m/s)
targets.rcs = [1.0, 0.5, 2.0];   % 雷达散射截面 (m²)

% 噪声参数
SNR_dB = 20;               % 信噪比 (dB)

fprintf('雷达参数:\n');
fprintf('  载频: %.1f GHz\n', fc/1e9);
fprintf('  带宽: %.1f MHz\n', B/1e6);
fprintf('  调频周期: %.1f μs\n', Tc*1e6);
fprintf('  距离分辨率: %.2f m\n', c/(2*B));
fprintf('  最大探测距离: %.1f m\n', c*fs/(2*B));
fprintf('  速度分辨率: %.2f m/s\n', c/(2*fc*N_chirps*Tc));

%% ========== 2. 生成FMCW信号 ==========
fprintf('生成FMCW信号...\n');

% 时间轴
t_fast = (0:N_samples-1)/fs;          % 快时间(单帧内)
t_slow = (0:N_chirps-1)*Tc;           % 慢时间(帧间)

% 调频斜率
S = B / Tc;                           % 调频斜率 (Hz/s)

% 生成发射信号(复数形式)
tx_signal = zeros(N_chirps, N_samples);
for chirp_idx = 1:N_chirps
    phase = 2*pi*fc*t_fast + pi*S*t_fast.^2;
    tx_signal(chirp_idx, :) = exp(1j*phase);
end

%% ========== 3. 生成接收信号 ==========
fprintf('生成接收信号...\n');

rx_signal = zeros(N_chirps, N_samples);

for target_idx = 1:length(targets.R)
    R = targets.R(target_idx);
    v = targets.v(target_idx);
    rcs = targets.rcs(target_idx);
    
    % 距离延迟
    tau = 2*R / c;
    
    % 多普勒频移
    fd = 2*v*fc / c;
    
    % 生成目标回波
    for chirp_idx = 1:N_chirps
        % 慢时间偏移(由于目标运动)
        t_offset = t_slow(chirp_idx);
        
        % 接收信号相位
        phase_rx = 2*pi*fc*(t_fast - tau + t_offset) + ...
                   pi*S*(t_fast - tau + t_offset).^2 + ...
                   2*pi*fd*(t_fast + t_offset);
        
        % 添加RCS衰减
        amplitude = sqrt(rcs) * exp(-2*R/1000);  % 距离衰减模型
        
        % 叠加到接收信号
        rx_signal(chirp_idx, :) = rx_signal(chirp_idx, :) + ...
                                 amplitude * exp(1j*phase_rx);
    end
end

% 添加高斯白噪声
rx_signal = awgn(rx_signal, SNR_dB, 'measured');

%% ========== 4. 混频与中频信号提取 ==========
fprintf('混频处理...\n');

% 混频(发射信号与接收信号相乘)
mixer_output = tx_signal .* conj(rx_signal);

% 低通滤波(去除高频分量)
[b, a] = butter(6, 0.1);  % 6阶巴特沃斯低通滤波器
if_signal = zeros(N_chirps, N_samples);
for chirp_idx = 1:N_chirps
    if_signal(chirp_idx, :) = filtfilt(b, a, real(mixer_output(chirp_idx, :)));
end

%% ========== 5. 距离FFT(快时间维度) ==========
fprintf('距离FFT处理...\n');

% 加窗(汉宁窗)
window = hann(N_samples)';
range_fft = zeros(N_chirps, N_samples);

for chirp_idx = 1:N_chirps
    % 加窗并FFT
    chirp_windowed = if_signal(chirp_idx, :) .* window;
    range_fft(chirp_idx, :) = fftshift(fft(chirp_windowed, N_samples));
end

% 距离轴
range_axis = (-N_samples/2:N_samples/2-1) * (c/(2*B)) / N_samples;

%% ========== 6. 速度FFT(慢时间维度) ==========
fprintf('速度FFT处理...\n');

% 多普勒FFT(对每个距离单元)
doppler_fft = zeros(N_samples, N_chirps);
for range_bin = 1:N_samples
    % 提取该距离单元的时间序列
    slow_time_series = range_fft(:, range_bin);
    
    % 加窗并FFT
    doppler_window = hann(N_chirps)';
    slow_time_windowed = slow_time_series .* doppler_window;
    doppler_fft(range_bin, :) = fftshift(fft(slow_time_windowed, N_chirps));
end

% 速度轴
velocity_axis = (-N_chirps/2:N_chirps/2-1) * (c/(2*fc*N_chirps*Tc));

%% ========== 7. CFAR检测 ==========
fprintf('CFAR检测...\n');

% 转换为幅度谱
rd_map = abs(doppler_fft);

% CA-CFAR检测
cfar_params.guard_cells = 2;      % 保护单元
cfar_params.training_cells = 8;   % 训练单元
cfar_params.pfa = 1e-6;           % 虚警概率
cfar_params.scale_factor = log(1/cfar_params.pfa);

% 执行CFAR检测
[detections, threshold_map] = ca_cfar_2d(rd_map, cfar_params);

% 提取目标信息
target_list = extract_targets(detections, range_axis, velocity_axis, rd_map);

%% ========== 8. 结果可视化 ==========
fprintf('结果可视化...\n');
visualize_results(range_axis, velocity_axis, rd_map, detections, target_list, targets);

%% ========== 9. 性能评估 ==========
fprintf('性能评估...\n');
evaluate_performance(target_list, targets);

2.2 CA-CFAR检测器实现

matlab 复制代码
function [detections, threshold_map] = ca_cfar_2d(rd_map, params)
    % 二维CA-CFAR检测器
    % rd_map: 距离-多普勒图 (range_bins × doppler_bins)
    % params: CFAR参数结构体
    
    [N_range, N_doppler] = size(rd_map);
    detections = zeros(N_range, N_doppler);
    threshold_map = zeros(N_range, N_doppler);
    
    % 遍历每个距离-多普勒单元
    for r = 1+params.guard_cells:N_range-params.guard_cells
        for d = 1+params.guard_cells:N_doppler-params.guard_cells
            
            % 提取训练单元
            training_cells = [];
            
            % 距离维度训练单元
            for dr = -params.training_cells:params.training_cells
                if abs(dr) > params.guard_cells
                    if r+dr >= 1 && r+dr <= N_range
                        training_cells = [training_cells; rd_map(r+dr, d)];
                    end
                end
            end
            
            % 多普勒维度训练单元
            for dd = -params.training_cells:params.training_cells
                if abs(dd) > params.guard_cells
                    if d+dd >= 1 && d+dd <= N_doppler
                        training_cells = [training_cells; rd_map(r, d+dd)];
                    end
                end
            end
            
            % 计算噪声功率估计(平均值)
            noise_power = mean(training_cells);
            
            % 计算检测阈值
            threshold = noise_power * params.scale_factor;
            threshold_map(r, d) = threshold;
            
            % 检测判断
            if rd_map(r, d) > threshold
                detections(r, d) = 1;
            end
        end
    end
    
    fprintf('CFAR检测完成,检测到 %d 个候选目标\n', sum(detections(:)));
end

2.3 目标信息提取

matlab 复制代码
function target_list = extract_targets(detections, range_axis, velocity_axis, rd_map)
    % 从检测结果中提取目标信息
    
    [N_range, N_doppler] = size(detections);
    target_list = [];
    
    % 连通域分析(聚类相邻检测点)
    labeled_detections = bwlabel(detections, 8);  % 8连通
    stats = regionprops(labeled_detections, 'Centroid', 'Area');
    
    for i = 1:length(stats)
        % 只保留足够大的目标
        if stats(i).Area >= 3
            centroid = stats(i).Centroid;
            
            % 距离索引
            range_idx = round(centroid(2));
            doppler_idx = round(centroid(1));
            
            % 确保索引有效
            range_idx = max(1, min(N_range, range_idx));
            doppler_idx = max(1, min(N_doppler, doppler_idx));
            
            % 提取目标参数
            range = range_axis(range_idx);
            velocity = velocity_axis(doppler_idx);
            power = 20*log10(rd_map(range_idx, doppler_idx));  % dB
            
            % 添加到目标列表
            target_list = [target_list; struct(...
                'range', range, ...
                'velocity', velocity, ...
                'power_dB', power, ...
                'range_bin', range_idx, ...
                'doppler_bin', doppler_idx)];
        end
    end
    
    fprintf('提取到 %d 个有效目标\n', size(target_list, 1));
end

2.4 结果可视化

matlab 复制代码
function visualize_results(range_axis, velocity_axis, rd_map, detections, target_list, true_targets)
    % 可视化结果
    
    figure('Position', [100, 100, 1400, 900]);
    
    % 1. 距离-多普勒图(热图)
    subplot(2,3,1);
    imagesc(velocity_axis, range_axis, 20*log10(rd_map));
    xlabel('速度 (m/s)');
    ylabel('距离 (m)');
    title('距离-多普勒图 (dB)');
    colorbar;
    axis xy;
    grid on;
    
    % 标记真实目标位置
    hold on;
    for i = 1:length(true_targets.R)
        plot(true_targets.v(i), true_targets.R(i), 'ro', ...
             'MarkerSize', 10, 'LineWidth', 2, 'MarkerFaceColor', 'r');
    end
    legend('检测目标', '真实目标');
    
    % 2. CFAR检测结果
    subplot(2,3,2);
    imagesc(velocity_axis, range_axis, detections);
    xlabel('速度 (m/s)');
    ylabel('距离 (m)');
    title('CFAR检测结果');
    axis xy;
    grid on;
    
    % 标记检测到的目标
    hold on;
    for i = 1:size(target_list, 1)
        plot(target_list(i).velocity, target_list(i).range, 'go', ...
             'MarkerSize', 8, 'LineWidth', 2, 'MarkerFaceColor', 'g');
    end
    
    % 3. 距离剖面(第一个chirp)
    subplot(2,3,3);
    range_profile = 20*log10(abs(rd_map(:, end)));  % 使用最后一个多普勒bin
    plot(range_axis, range_profile);
    xlabel('距离 (m)');
    ylabel('幅度 (dB)');
    title('距离剖面');
    grid on;
    
    % 标记目标距离
    hold on;
    for i = 1:length(true_targets.R)
        yline(true_targets.R(i), 'r--', 'LineWidth', 1.5);
    end
    
    % 4. 速度剖面(最近目标距离)
    subplot(2,3,4);
    [~, nearest_idx] = min(abs(range_axis - 50));  % 50m处的速度剖面
    velocity_profile = 20*log10(abs(rd_map(nearest_idx, :)));
    plot(velocity_axis, velocity_profile);
    xlabel('速度 (m/s)');
    ylabel('幅度 (dB)');
    title('速度剖面 (50m处)');
    grid on;
    
    % 5. 目标参数表格
    subplot(2,3,5);
    if ~isempty(target_list)
        table_data = cell(size(target_list, 1), 4);
        for i = 1:size(target_list, 1)
            table_data{i,1} = sprintf('%.1f m', target_list(i).range);
            table_data{i,2} = sprintf('%.1f m/s', target_list(i).velocity);
            table_data{i,3} = sprintf('%.1f dB', target_list(i).power_dB);
            table_data{i,4} = sprintf('(%d,%d)', target_list(i).range_bin, target_list(i).doppler_bin);
        end
        
        column_names = {'距离', '速度', '功率', '坐标'};
        uitable('Data', table_data, 'ColumnName', column_names, ...
                'Position', [50 50 400 150], 'RowName', []);
    end
    
    % 6. 误差分析
    subplot(2,3,6);
    if ~isempty(target_list)
        detected_ranges = [target_list.range];
        detected_velocities = [target_list.velocity];
        
        % 计算与真实目标的匹配
        range_errors = zeros(length(true_targets.R), 1);
        velocity_errors = zeros(length(true_targets.v), 1);
        
        for i = 1:length(true_targets.R)
            [~, closest_idx] = min(abs(detected_ranges - true_targets.R(i)));
            range_errors(i) = detected_ranges(closest_idx) - true_targets.R(i);
            velocity_errors(i) = detected_velocities(closest_idx) - true_targets.v(i);
        end
        
        % 绘制误差条形图
        bar(1:length(true_targets.R), [range_errors, velocity_errors]);
        set(gca, 'XTick', 1:length(true_targets.R), ...
                 'XTickLabel', {'目标1', '目标2', '目标3'});
        ylabel('误差');
        title('测距测速误差');
        legend('距离误差(m)', '速度误差(m/s)');
        grid on;
    end
    
    sgtitle('FMCW雷达测速测距系统结果');
end

2.5 性能评估

matlab 复制代码
function evaluate_performance(target_list, true_targets)
    % 评估系统性能
    
    fprintf('\n========== 性能评估 ==========\n');
    
    % 检测概率
    detection_probability = size(target_list, 1) / length(true_targets.R);
    fprintf('检测概率: %.2f%%\n', detection_probability * 100);
    
    % 虚警率(假设检测到的目标多于真实目标)
    false_alarms = max(0, size(target_list, 1) - length(true_targets.R));
    false_alarm_rate = false_alarms / (size(target_list, 1) + eps);
    fprintf('虚警率: %.2f%%\n', false_alarm_rate * 100);
    
    % 测距精度
    if ~isempty(target_list)
        range_errors = zeros(length(true_targets.R), 1);
        velocity_errors = zeros(length(true_targets.v), 1);
        
        for i = 1:length(true_targets.R)
            % 找到最近的检测目标
            distances = sqrt(([target_list.range] - true_targets.R(i)).^2 + ...
                           ([target_list.velocity] - true_targets.v(i)).^2);
            [min_dist, closest_idx] = min(distances);
            
            if min_dist < 10  % 10m内的目标认为是同一个
                range_errors(i) = target_list(closest_idx).range - true_targets.R(i);
                velocity_errors(i) = target_list(closest_idx).velocity - true_targets.v(i);
            end
        end
        
        fprintf('\n测距精度:\n');
        fprintf('  平均误差: %.2f m\n', mean(abs(range_errors)));
        fprintf('  最大误差: %.2f m\n', max(abs(range_errors)));
        fprintf('  均方根误差: %.2f m\n', sqrt(mean(range_errors.^2)));
        
        fprintf('\n测速精度:\n');
        fprintf('  平均误差: %.2f m/s\n', mean(abs(velocity_errors)));
        fprintf('  最大误差: %.2f m/s\n', max(abs(velocity_errors)));
        fprintf('  均方根误差: %.2f m/s\n', sqrt(mean(velocity_errors.^2)));
    end
    
    % 分辨率分析
    range_resolution = c / (2*B);
    velocity_resolution = c / (2*fc*N_chirps*Tc);
    
    fprintf('\n分辨率分析:\n');
    fprintf('  距离分辨率: %.2f m\n', range_resolution);
    fprintf('  速度分辨率: %.2f m/s\n', velocity_resolution);
    
    % 检查是否可分辨两个目标
    if length(true_targets.R) >= 2
        min_range_sep = min(diff(sort(true_targets.R)));
        min_velocity_sep = min(diff(sort(true_targets.v)));
        
        fprintf('  最小距离间隔: %.2f m (%s)\n', min_range_sep, ...
                ternary(min_range_sep > range_resolution, '可分辨', '不可分辨'));
        fprintf('  最小速度间隔: %.2f m/s (%s)\n', min_velocity_sep, ...
                ternary(min_velocity_sep > velocity_resolution, '可分辨', '不可分辨'));
    end
end

function result = ternary(condition, true_str, false_str)
    if condition
        result = true_str;
    else
        result = false_str;
    end
end

2.6 高级CFAR算法(可选)

matlab 复制代码
function [detections, threshold_map] = advanced_cfar(rd_map, method, params)
    % 高级CFAR检测器
    % method: 'CA', 'GO', 'SO', 'OS'
    
    [N_range, N_doppler] = size(rd_map);
    detections = zeros(N_range, N_doppler);
    threshold_map = zeros(N_range, N_doppler);
    
    for r = 1+params.guard_cells:N_range-params.guard_cells
        for d = 1+params.guard_cells:N_doppler-params.guard_cells
            
            % 提取训练单元
            training_cells = extract_training_cells(rd_map, r, d, params);
            
            switch method
                case 'CA'  % 单元平均CFAR
                    noise_power = mean(training_cells);
                    
                case 'GO'  % 最大选择CFAR
                    noise_power = max([mean(training_cells(1:params.training_cells)), ...
                                       mean(training_cells(params.training_cells+1:end))]);
                    
                case 'SO'  % 最小选择CFAR
                    noise_power = min([mean(training_cells(1:params.training_cells)), ...
                                       mean(training_cells(params.training_cells+1:end))]);
                    
                case 'OS'  % 有序统计CFAR
                    sorted_cells = sort(training_cells);
                    k = round(0.75 * length(sorted_cells));  % 75%分位数
                    noise_power = sorted_cells(k);
            end
            
            % 计算阈值
            threshold = noise_power * params.scale_factor;
            threshold_map(r, d) = threshold;
            
            % 检测
            if rd_map(r, d) > threshold
                detections(r, d) = 1;
            end
        end
    end
end

function training_cells = extract_training_cells(rd_map, r, d, params)
    % 提取训练单元(环形结构)
    training_cells = [];
    
    for dr = -params.training_cells:params.training_cells
        for dd = -params.training_cells:params.training_cells
            if abs(dr) > params.guard_cells || abs(dd) > params.guard_cells
                if r+dr >= 1 && r+dr <= size(rd_map,1) && ...
                   d+dd >= 1 && d+dd <= size(rd_map,2)
                    training_cells = [training_cells; rd_map(r+dr, d+dd)];
                end
            end
        end
    end
end

三、工程应用优化

3.1 参数优化建议

参数 推荐值 调整建议
带宽B 300-500 MHz 分辨率要求高时增大
扫频周期Tc 20-100 μs 速度分辨率要求高时增大
CFAR保护单元 2-4 目标扩展大时增加
CFAR训练单元 8-16 噪声波动大时增加
虚警概率Pfa 10⁻⁶-10⁻⁴ 根据应用场景调整

3.2 实时处理优化

matlab 复制代码
function realtime_processing()
    % 实时处理优化版本
    
    % 1. 使用FFT加速
    fft_plan = dsp.FFT('FFTLength', N_samples);
    
    % 2. 流水线处理(边接收边处理)
    persistent buffer
    if isempty(buffer)
        buffer = zeros(N_chirps, N_samples);
    end
    
    % 3. 增量更新距离-多普勒图
    for chirp_idx = 1:N_chirps
        % 获取新的一帧数据
        new_frame = get_new_frame();
        
        % 更新缓冲区
        buffer(chirp_idx, :) = new_frame;
        
        % 每N帧更新一次距离-多普勒图
        if mod(chirp_idx, update_interval) == 0
            rd_map = compute_rd_map(buffer);
            detections = cfar_detect(rd_map);
            update_display(detections);
        end
    end
end

3.3 抗干扰技术

matlab 复制代码
function anti_interference()
    % 抗干扰技术
    
    % 1. 杂波图抑制
    clutter_map = zeros(N_range, N_doppler);
    alpha = 0.1;  % 遗忘因子
    
    for frame = 1:num_frames
        rd_map_current = compute_rd_map(frame);
        clutter_map = (1-alpha)*clutter_map + alpha*rd_map_current;
        rd_map_clean = rd_map_current - clutter_map;
    end
    
    % 2. 多普勒滤波(零速通道抑制)
    zero_velocity_bin = find(abs(velocity_axis) < 0.5);
    rd_map(zero_velocity_bin, :) = 0;
    
    % 3. 恒虚警率自适应
    adaptive_threshold = estimate_noise_floor(rd_map);
end

参考代码 锯齿调频波仿真 www.youwenfan.com/contentcsv/79206.html

四、总结

本系统实现了完整的FMCW雷达测速测距功能:

  1. 锯齿波调频连续波:生成线性调频信号
  2. 距离-多普勒处理:2D-FFT获取目标信息
  3. CFAR检测:自适应阈值检测目标
  4. 性能评估:量化测距测速精度

系统特点:

  • 完整的信号处理链
  • 可配置的CFAR算法
  • 实时可视化界面
  • 工程级参数优化
  • 抗干扰设计

应用场景:

  • 汽车自动驾驶雷达
  • 无人机避障雷达
  • 工业测距测速
  • 安防监控雷达
相关推荐
qq_297574672 小时前
设计模式系列文章(基础篇第 11 篇):模板方法模式——定义算法骨架,实现代码复用与流程统一
算法·设计模式·模板方法模式
lqqjuly2 小时前
知识蒸馏:理论、算法与可运行实现
人工智能·深度学习·算法
水上冰石2 小时前
comfui的sd1.5模型,有多少采样算法,详解每一个采样算法
人工智能·算法
黎阳之光2 小时前
视频孪生+空天地水工融合,黎阳之光构建智慧水利监测新范式
大数据·人工智能·物联网·算法·安全
cheems95272 小时前
[算法手记] 贪心 爬楼梯问题
算法·贪心算法
KaMeidebaby2 小时前
卡梅德生物技术快报|酵母双杂交 cDNA 文库构建与蛋白互作筛选流程
服务器·前端·数据库·人工智能·算法
sheeta19983 小时前
LeetCode 每日一题笔记 日期:2026.05.27 题目:3121. 统计特殊字母的数量 II
笔记·算法·leetcode
ST——Jess3 小时前
年度行业趋势研究报告:泛心理数字化赛道“流日推演”的算法困境与高保真交互范式重构
人工智能·算法·架构
Tisfy3 小时前
LeetCode 3300.替换为数位和以后的最小元素:一次遍历
数学·算法·leetcode·模拟