基于 Python + NumPy 的雷达信号处理仿真平台设计与实现——从 LFM 波形到 CFAR 检测的完整信号链

基于 Python + NumPy 的雷达信号处理仿真平台设计与实现------从 LFM 波形到 CFAR 检测的完整信号链

本文环境:Python 3.9 + NumPy 1.24 + Matplotlib 3.7 + PyYAML 6.0

一、项目背景

雷达信号处理是雷达系统的核心环节,一条完整的处理链通常包含:波形生成 → 目标回波仿真 → 脉冲压缩 → MTD(多普勒 FFT)→ CFAR 检测

实际工程中,做雷达信号处理的研究者长期面临两个痛点:

  1. 真实数据获取难:雷达实测数据多涉密,公开数据集极少,标注成本高;
  2. 算法验证成本高:在真实硬件上测试新算法周期长、代价大。

本文介绍一个用纯 Python 实现的端到端雷达信号处理仿真平台 Radar-Sim,它同时具备两块能力:

  • 教学演示:19 张原理图解,覆盖天线、波形、信号链、关键概念;
  • 数据生产:带真值标签的仿真数据生成,可直接对接机器学习训练管道。

整个项目架构如下:

复制代码
radar-sim-main/
├── lib/                # 核心库(参数、信号、目标模型、场景编排)
│   ├── radar_params.py
│   ├── signal_utils.py
│   ├── target_model.py
│   └── scene_manager.py
├── simulator/          # 端到端仿真引擎
│   └── radar_simulator.py
├── demo/               # 7 大专题 Demo(相控阵/STAP/MIMO 等)
├── tutorials/          # 可视化教程脚本
└── output/             # 生成的 19 张教学图

二、雷达参数建模

所有仿真围绕统一的参数结构展开,使用 dataclass 封装物理量,保证单位一致(距离 m、功率 W、频率 Hz、时间 s)。

python 复制代码
@dataclass
class RadarParams:
    # 发射参数
    pt: float = 1e6                # 峰值功率 1 MW
    gain_db: float = 30.0          # 天线增益 30 dB
    freq_hz: float = 10e9          # X 波段 10 GHz
    bandwidth_hz: float = 50e6     # 带宽 50 MHz
    pulse_width_s: float = 10e-6   # 脉宽 10 μs
    prf_hz: float = 1000.0         # PRF 1 kHz

    # 接收参数
    noise_figure_db: float = 3.0   # 噪声系数 3 dB

    # 信号处理参数
    num_pulses: int = 64           # CPI 内脉冲数(2 的幂次,便于 FFT)

    @property
    def wavelength_m(self) -> float:
        """波长 λ = c / f"""
        return SPEED_OF_LIGHT / self.freq_hz

    @property
    def noise_power_w(self) -> float:
        """接收机噪声功率 P_n = k * T * F * B"""
        return BOLTZMANN * STANDARD_TEMP * self.noise_figure_linear * self.bandwidth_hz

    @property
    def time_bandwidth_product(self) -> float:
        """时宽带宽积 T*B = 500 → 脉压增益约 27 dB"""
        return self.pulse_width_s * self.bandwidth_hz

    @property
    def range_resolution_m(self) -> float:
        """距离分辨率 ΔR = c / (2B) = 3 m"""
        return SPEED_OF_LIGHT / (2 * self.bandwidth_hz)

几个值得注意的推导关系:

  • 时宽带宽积 T*B = 10μs × 50MHz = 500,即脉冲压缩可获得约 27 dB 的信噪比增益;
  • 距离分辨率 ΔR = c/(2B) = 3 m,只与带宽有关,与脉宽无关------这正是 LFM 能"又长又锐"的原因;
  • PRF = 1 kHz 时最大不模糊距离为 150 km,不模糊速度为 λ·PRF/4,这就是后面会遇到的测距测速模糊问题。

三、LFM 波形生成与脉冲压缩

3.1 线性调频信号生成

LFM 是应用最广的雷达波形:频率随时间线性变化,使信号同时拥有大时宽(高能量)和大带宽(高分辨率)。

python 复制代码
def generate_lfm(bandwidth_hz, pulse_width_s, sample_rate_hz,
                 up_chirp: bool = True) -> np.ndarray:
    """生成 LFM 复基带信号:s(t) = rect(t/T) * exp(jπKt²),K = ±B/T"""
    num_samples = int(round(pulse_width_s * sample_rate_hz))
    t = np.arange(num_samples) / sample_rate_hz   # 时间轴 [0, T)

    sign = 1.0 if up_chirp else -1.0              # 上调频 / 下调频
    chirp_rate = sign * bandwidth_hz / pulse_width_s

    phase = np.pi * chirp_rate * t**2             # 相位为时间的二次函数
    return np.exp(1j * phase)

3.2 频域匹配滤波

匹配滤波器是白噪声背景下检测已知波形的最优线性滤波器,频域实现即为 Y(f) = X(f)·H(f)

python 复制代码
def matched_filter(signal: np.ndarray, template: np.ndarray) -> np.ndarray:
    """频域匹配滤波,输出在目标位置形成尖峰"""
    n_fft = len(signal) + len(template) - 1
    n_fft = int(2 ** np.ceil(np.log2(n_fft)))     # 补到 2 的幂次加速 FFT

    S = np.fft.fft(signal, n_fft)
    H = np.fft.fft(template, n_fft)               # template 已是时域反转共轭
    result = np.fft.ifft(S * H)

    return result[:len(signal) + len(template) - 1]  # 线性卷积完整结果

核心结论:脉压后脉冲宽度 ≈ 1/B(3 m 分辨率),峰值幅度获得 T·B 倍增益;LFM 距离旁瓣约 -13.2 dB(sinc 包络第一旁瓣),工程上常用 Hamming 窗压低到 -43 dB 左右,代价是主瓣略有展宽。


四、目标模型:运动轨迹与 RCS 起伏

真实目标不是"静止的点",目标模型覆盖了两种关键特性。

4.1 运动模型

支持三类常用运动模型:

模型 英文 说明
匀速直线 CV 速度恒定,最简单的直线运动
匀加速直线 CA 恒定加速度,位置满足 x₀+v₀t+½at²
协调转弯 CT 水平面内恒定转弯速率,z 不变(飞机典型机动)

4.2 Swerling RCS 起伏模型

同一目标的 RCS 随视角、时刻剧烈变化,工程上用 Swerling 模型描述统计特性:

python 复制代码
def generate_rcs(config: RCSConfig, num_samples: int,
                 num_pulses_per_sample: int = 1, rng=None) -> np.ndarray:
    """按 Swerling 模型生成 RCS 序列"""
    rcs = np.zeros(num_samples * num_pulses_per_sample)

    if config.model == RCSModel.SWERLING_0:
        rcs[:] = config.mean_rcs_m2              # 非起伏

    elif config.model in (RCSModel.SWERLING_I, RCSModel.SWERLING_III):
        for i in range(num_samples):             # 慢起伏:扫描间变化
            rcs_val = _swerling_sample(config, rng)
            rcs[i * num_pulses_per_sample:(i + 1) * num_pulses_per_sample] = rcs_val

    elif config.model in (RCSModel.SWERLING_II, RCSModel.SWERLING_IV):
        for i in range(num_samples * num_pulses_per_sample):  # 快起伏:脉冲间变化
            rcs[i] = _swerling_sample(config, rng)

    return rcs

其中 Swerling I/II 服从指数分布(Rayleigh 幅度,等效 2 个独立散射点),Swerling III/IV 服从 4 自由度卡方分布(等效 4 个散射点)。这个细节对 ML 训练至关重要------训练数据必须包含 RCS 起伏多样性,模型才能学到鲁棒特征。


五、场景编排与回波仿真

5.1 场景生成

场景编排器负责把目标模型和雷达参数组合成完整仿真场景,支持随机多目标、批量生成、YAML 序列化:

python 复制代码
config = SceneConfig(
    num_targets=(1, 3),                 # 目标数量范围
    target_range_range_m=(10e3, 100e3), # 距离范围
    target_velocity_range_ms=(50, 500), # 速度范围
    target_rcs_range_m2=(1.0, 100.0),   # RCS 范围
    rcs_model=RCSModel.SWERLING_I,
    trajectory_model=MotionModel.CV,
)
generator = SceneGenerator(config, params, rng)
scenes = generator.generate_batch(3, seeds=[100, 200, 300])  # 批量生成

5.2 回波合成(雷达方程)

每个目标回波的幅度由完整雷达方程决定:

复制代码
Pr = (Pt · G² · λ² · σ) / ((4π)³ · R⁴)

核心实现(节选自 _generate_echo_data):

python 复制代码
# 目标延迟(距离→时延→采样点)
target_delay_s = 2.0 * target_range_m / SPEED_OF_LIGHT
target_delay_samples = int(round(target_delay_s * self.sample_rate_hz))

# 多普勒频移:fd = 2·vr/λ,叠加慢时间相位
fd_hz = 2.0 * radial_velocity_ms / self._wavelength_m
doppler_phase = np.exp(1j * 2.0 * np.pi * fd_hz * n * self._t_pri)

# 雷达方程计算接收功率,再归一化到噪声基底得到幅度
pr_w = (pt_w * gain_linear**2 * wavelength**2 * rcs_val) / \
       ((4 * np.pi)**3 * target_range_m**4)
amplitude = np.sqrt(pr_w / noise_power)

# 叠加回波 + 热噪声 → 匹配滤波 → 距离对齐
received[target_delay_samples:end_idx] += amplitude * doppler_phase * self._waveform[:echo_len]

注意 1/R⁴ 衰减------距离翻倍,回波功率降为 1/16,这是远距离目标检测难的根本原因。


六、信号处理链:MTD 与 CFAR 检测

6.1 MTD:慢时间 FFT 得到 RDM

对同一距离单元上的 64 个脉冲回波做 FFT,分离多普勒频率,得到距离-多普勒图(RDM):

python 复制代码
def _process_signal(self, iq_data: np.ndarray):
    """MTD:慢时间加窗 + FFT,生成距离-多普勒图"""
    n_pulses, n_range = iq_data.shape
    slow_time_window = np.hamming(n_pulses)     # 降低多普勒旁瓣

    rdm = np.zeros((n_pulses, n_range), dtype=np.complex128)
    for r in range(n_range):
        slow_data = iq_data[:, r] * slow_time_window
        rdm[:, r] = np.fft.fftshift(np.fft.fft(slow_data))

    rdm_power = np.abs(rdm) ** 2
    return rdm, rdm_power

6.2 CFAR 检测

固定门限在噪声变化时必然漏检或虚警,CFAR 用自适应门限解决:对被测单元(CUT)前后取训练单元估计噪声功率,紧邻单元作保护单元防止目标能量泄漏。

python 复制代码
def _detect_targets(self, rdm_power: np.ndarray):
    """简化 CFAR:中值估计噪声基底 + 峰值搜索"""
    noise_floor = np.median(rdm_power)          # 噪声基底估计

    indices = np.unravel_index(
        np.argsort(rdm_power.ravel())[::-1], rdm_power.shape)

    for d_idx, r_idx in zip(indices[0], indices[1]):
        # 与已选峰值的间距约束,避免同一目标重复检测
        if not is_far_enough:
            continue
        snr_db = 10 * np.log10(peak_power / noise_floor)
        if snr_db > 3.0:                        # 过门限才记录
            detections.append(DetectionResult(
                range_bin=r_idx,
                doppler_bin=d_idx,
                range_m=r_idx * self._sample_spacing_m,
                velocity_ms=self._doppler_bin_to_velocity(d_idx, n_pulses),
                snr_db=snr_db,
            ))

CFAR 的价值在于:环境噪声变大时门限自动抬高,变小时自动降低,虚警率恒定,这就是"恒虚警"的含义。


七、可视化教学模块

项目一键生成 19 张教学图,覆盖四个领域:

领域 示例图
天线 阵元方向图、栅瓣演示、阵列增益 vs 阵元数
波形 LFM 时域、频域、时频谱图
信号链 雷达工作流程、信号流详细图、RDM 形成过程
关键概念 脉冲压缩对比、多普勒模糊、距离模糊、CFAR 原理

典型如 v10_pulse_compression_comparison.png(不同 T·B 值脉压对比)和 v14_rdm_formation.png(RDM 形成流程),初学者一眼就能理解"长脉冲高能量 + 频率调制高分辨率"的思想。


八、验证体系

项目内置完整验证框架,81 项理论 vs 仿真验证全部通过,每项都带明确的误差容限。验证粒度覆盖:

  • 目标模型:轨迹运动学公式、RCS 均值与分布特性、径向速度计算;
  • 场景编排:目标数量范围、批量场景独立性、YAML 读写一致;
  • 仿真器:输出数据结构、检测命中率、批量仿真独立性、真值对比。

这意味着仿真的每个环节都有"理论值可对照",不是黑盒生成,适合作为算法验证的基准环境。


九、总结

从 LFM 波形生成、匹配滤波、雷达方程回波合成,到 MTD 和 CFAR 检测,Radar-Sim 用约 2000 行纯 Python 实现了雷达信号处理的完整链路,并额外覆盖了相控阵、STAP、MIMO 等进阶专题。它既能当教学工具,也能作为带真值标签的仿真数据工厂,为雷达检测 ML 模型提供训练数据。

工程代码与配套可视化脚本见:

原文链接EWFrontier

相关推荐
axinawang22 分钟前
Tesseract入门--把图片里印刷文字提取成文本
python
青 春 记 忆34 分钟前
LeetCode 283. 移动零|Python 解法详解
python·算法·leetcode
人工干智能43 分钟前
科普:Python中的生成器——带`yield`的函数
开发语言·python
whcyhhh44 分钟前
头歌实践教学平台:数据科学与大数据技术导论(十四)
大数据·开发语言·python
清水白石0081 小时前
Python dataclass 高级避坑指南:从 default_factory、frozen、slots 到哈希灾难
windows·python·哈希算法
在学了加油1 小时前
阿尔茨海默病诊断(优化特征选择版)
人工智能·python·dnn
淼澄研学1 小时前
GPT-4o及mini模型参数解析与Python API调用实操
开发语言·python
kyrie_sakura2 小时前
python学习笔记 7--- 文件(IO)操作
笔记·python·学习