跳转至

项目实现方式

这个项目不是把雷达仿真做成黑盒,而是拆成一条可以逐步检查的处理流水线。每个模块负责一个阶段,上一个阶段的输出就是下一个阶段的输入。

总体设计

主数据链路是:

mesh 文件
-> TriangleMesh
-> 每个 chirp 下变换后的三角面
-> 可见三角面
-> ScatterSet
-> 原始雷达数据立方体
-> FFT 输出
-> 可视化图片

这个项目的重要设计选择是:不直接从 mesh 跳到热力图,而是显式保留中间概念:

  • mesh 加载
  • 几何可见性
  • 散射近似
  • 通道级信号合成
  • 距离/速度/角度 FFT

这样更容易调试,也更适合讲清楚雷达模拟器原理。

1. Mesh 加载

mesh_loader.py 读取 OBJSTLGLB 文件,并统一转换成 TriangleMesh

TriangleMesh 只保存:

  • vertices:顶点坐标
  • faces:三角面顶点索引

纹理、材质、动画等渲染信息会被忽略,因为当前雷达模拟器只需要几何形状。

2. 每个 Chirp 下的目标变换

对每个 chirp,目标会作为刚体变换一次。

目标位置是:

position(t) = initial_position + velocity * slow_time

然后再应用固定欧拉角旋转。这个模型足够支撑早期距离和多普勒实验。

3. 可见性筛选

visibility.py 会去掉不应该贡献回波的三角面。

它做两个判断:

  1. 朝向判断:只保留法向大致朝向雷达的三角面。
  2. 遮挡判断:从雷达相位中心向三角面中心发射射线,如果中途被其他三角面挡住,就丢弃该面。

这套方法故意保持直接和可读。当前还没有用 BVH 或空间索引加速。

4. 散射模型

scatter_model.py 把每个可见三角面转换成一个散射点。

散射点放在三角面中心,强度由这些因素决定:

  • 三角面面积
  • 入射角
  • 目标整体反射率

这不是完整电磁模型,而是教学导向的近似模型。它能让“几何形状如何影响雷达信号”这件事变得可观察。

5. 信号合成

signal_synth.py 生成原始雷达数据立方体。

对每个 chirp、每个虚拟通道、每个散射点,它会计算:

  • Tx 到散射点的距离
  • 散射点到 Rx 的距离
  • 往返延迟
  • 距离衰减
  • beat frequency
  • fast time 上的复数相位

所有散射点回波会叠加成一个通道的复数信号。

输出形状是:

num_adc_samples x num_chirps x (num_tx * num_rx)

6. FFT 流水线

fft_pipeline.py 执行三次 FFT:

  1. 沿 ADC 采样点做 Range FFT。
  2. 沿 chirp 序列做 Doppler FFT。
  3. 沿 MIMO 虚拟通道做 Angle FFT。

输出既包含完整数据立方体,也包含方便画图的投影 map。

为什么这样拆分

这个实现刻意保持模块边界清晰:

  • 几何代码不理解雷达参数
  • 雷达配置不生成信号
  • 可见性模块不做 FFT
  • 多进程只拆任务,不改变物理模型

这种拆分让后续扩展更容易。例如之后可以把可见性阶段换成 BVH 加速,或者把散射模型换成更细的材料模型,而不需要重写整个项目。

初学者阅读路径

如果你刚开始看这个项目,建议从外到内读:

  1. 先看 main.py。它展示完整命令行流程:解析参数、创建配置对象、加载 mesh、运行仿真、运行 FFT、保存输出。
  2. 再看 radar_model.py。它解释雷达需要哪些参数:载频、带宽、chirp 时长、ADC 采样点、chirp 数、天线数。
  3. mesh_loader.pygeometry.py。这两个文件解释 3D 模型如何变成三角面,以及三角面如何计算中心、法向和面积。
  4. visibility.py。这里决定雷达到底能看到哪些表面。
  5. scatter_model.py。这里把可见表面转换成点状散射体。
  6. signal_synth.py。这是核心文件,距离在这里变成延迟,延迟变成 beat frequency,散射体变成复数雷达采样。
  7. fft_pipeline.py。这里把原始数据立方体解释成距离、速度和角度图。

这个顺序比按文件名读更容易,因为它跟实际运行路径一致。

每个阶段的输入和输出

理解这个项目最好的方式,是把每个阶段看成一次数据转换:

阶段 输入 输出
Mesh 加载 OBJ / STL / GLB 文件 TriangleMesh
几何变换 mesh + 目标运动 每个 chirp 下的三角面位置
可见性判断 变换后的三角面 + 雷达位置 可见三角面
散射模型 可见三角面 散射点位置和强度
信号合成 散射点 + 雷达配置 原始复数 RDC
FFT 流水线 原始复数 RDC 距离/速度/角度输出
绘图 FFT map PNG 热力图

这张表也可以当调试指南。如果结果不对,就从最早出现异常的中间阶段开始查。

为什么模型要保持简单

当前模拟器故意省略了很多高级雷达效应。这不是缺陷,而是设计选择。第一目标是把主信号链路讲清楚。

真实工程雷达可能包括天线方向图、接收机噪声、标定误差、泄漏、多径、杂波抑制、CFAR 检测和目标跟踪。如果一次性全加进去,代码会很难学习。

本项目先保留一条更小的链路:

表面几何 -> 简化散射 -> 复数采样 -> FFT 图

先理解这条路径,再逐个加入高级效果,项目才不会变成黑盒。

代码和雷达概念如何对应

代码命名尽量对应雷达概念:

  • RadarConfig 是雷达硬件和波形描述。
  • TargetMotion 是运动目标描述。
  • TriangleMesh 是目标几何。
  • VisibilityResult 是雷达能直接看到的表面集合。
  • ScatterSet 是简化后的散射模型。
  • rdc 是 FFT 解释前的原始雷达数据立方体。

最重要的变量是 rdc。它是仿真和雷达信号处理之间的桥。rdc 之前的代码负责生成信号,rdc 之后的代码负责解释信号。

后续扩展应该先改哪里

不同研究方向对应不同模块:

目标 优先修改模块
更好的 mesh 加载 mesh_loader.py
更快的可见性判断 visibility.py
更真实的散射模型 scatter_model.py
噪声或硬件效应 signal_synth.py
不同雷达坐标轴 fft_pipeline.py
更多命令行参数 main.py

这就是项目拆成小文件的意义:后续实验尽量局部修改,而不是全局重写。