仿真流程¶
仿真器采用一条尽量透明的雷达处理链路。它不是直接把一个 3D 模型变成最终图片,而是把每个中间步骤都保留下来:先处理几何,再处理散射,再合成雷达原始数据,最后用 FFT 解释成距离、速度和角度。
如果你是初学者,可以先把整个项目理解成一个“翻译器”:
三维几何语言 -> 雷达回波语言 -> 频谱图语言
三维几何语言描述的是物体表面在哪里;雷达回波语言描述的是这些表面会产生什么复数采样;频谱图语言则把采样解释成我们熟悉的距离、速度和角度。
总览¶
- 读取
OBJ、STL或GLBmesh。 - 将 mesh 转换为三角面片。
- 对每个 chirp 应用目标平移和固定欧拉角旋转。
- 保留法向朝向雷达相位中心的三角面。
- 去掉被其他三角面遮挡的面。
- 将可见面转换为简化散射单元。
- 为每个 TX/RX 通道合成原始雷达数据立方体。
- 执行 Range FFT、Doppler FFT 和 Angle FFT。
1. 读取 Mesh¶
输入的目标是一个 3D 模型文件,例如:
examples/meshes/box.objexamples/meshes/Thanh.glb
这些文件本来是给三维渲染或建模软件用的。雷达仿真不需要颜色、纹理、骨骼动画,只需要表面几何。所以第一步是把模型统一转换成三角面片。
对应代码在 mesh_loader.py:
load_mesh()负责根据扩展名选择加载方式。_load_obj()处理简单 OBJ 文件。_load_stl()处理 STL 文件。_load_glb()使用trimesh处理 GLB 文件。
最终输出统一是 TriangleMesh。
2. 三角面片几何处理¶
三角面片是后续所有计算的基本单位。每个三角面都可以计算:
- 中心点:用作散射点位置。
- 法向量:判断它是否朝向雷达。
- 面积:影响回波强度。
对应代码在 geometry.py:
triangle_centers()计算中心。triangle_normals()计算法向。triangle_areas()计算面积。ray_triangle_intersection()判断射线是否打到三角面。
这一步不涉及雷达公式,只是纯几何。
3. 每个 Chirp 下更新目标位置¶
FMCW 雷达会发出一串 chirp。目标可能在这些 chirp 之间移动,所以每个 chirp 都要计算一次目标位置。
目标位置使用简单恒速模型:
当前位置 = 初始位置 + 速度 * slow_time
然后再应用固定欧拉角旋转。这样可以模拟一个整体移动的刚体目标。
对应代码在 signal_synth.py 的 _simulate_block() 中。它会在每个 chirp 内调用 transform_vertices(),把原始 mesh 顶点变换到当前时刻的位置。
4. 筛选雷达可见面¶
不是所有表面都应该产生雷达回波。比如一个人体模型背后的面,或者被前面身体挡住的面,不应该直接被雷达看到。
可见性筛选分两步:
- 朝向判断:法向背向雷达的面先丢弃。
- 遮挡判断:从雷达到面中心发射一条射线,如果中途撞到其他三角面,说明这个面被挡住。
对应代码在 visibility.py。这一步很直观,但计算量也大,因为它可能需要把很多射线和很多三角面做相交测试。
5. 把可见面变成散射点¶
雷达信号合成不直接处理完整三角面,而是把每个可见三角面近似成一个点状散射体。
每个散射点包含:
- 位置:三角面中心
- 强度:由面积、入射角和整体反射率决定
简单理解:
大面片 + 正对雷达 = 强回波
小面片 + 斜着对雷达 = 弱回波
背向雷达 = 不产生回波
对应代码在 scatter_model.py。
6. 合成原始雷达数据立方体¶
这是整个仿真的核心。
对每个散射点、每个 chirp、每个 TX/RX 通道,模拟器都会计算:
- 发射天线到散射点的距离
- 散射点到接收天线的距离
- 往返延迟
- beat frequency
- 复数相位
- 幅度衰减
然后把所有散射点贡献的复数信号叠加起来。
最终得到的原始数据形状是:
num_adc_samples x num_chirps x (num_tx * num_rx)
这就是 rdc,也是后续 FFT 的输入。
7. 三次 FFT¶
原始 rdc 还不是人容易看的结果,需要通过三次 FFT 解释:
| FFT | 处理维度 | 得到什么 |
|---|---|---|
| Range FFT | ADC 采样点 | 距离 |
| Doppler FFT | chirp 序列 | 速度 |
| Angle FFT | MIMO 虚拟通道 | 角度 |
对应代码在 fft_pipeline.py。
8. 绘图¶
FFT 输出仍然是数组。为了看结果,examples/plot/plot_thanh_run.py 会把它们画成热力图:
- 距离-速度图
- 距离-角度图
- 速度-角度图
- 距离-Chirp 图
- 四图总览
这些图不是额外算法,而是把 FFT 输出可视化,帮助检查仿真是否合理。
当前建模范围¶
第一版有意保持信号模型简单:
- 不加噪声
- 不做滤波
- 不做 CFAR
- 不做 MUSIC
- 不做额外微多普勒专用后处理
这样可以让代码更容易检查,同时保留 MIMO FMCW 雷达主链路。
为什么流程要这样拆¶
这个项目的目标不是“一步得到漂亮图”,而是让每一步都能解释:
- 如果 mesh 加载错了,可以先查
TriangleMesh。 - 如果目标完全没回波,可以查可见性筛选。
- 如果距离不对,可以查 beat frequency 和 Range FFT。
- 如果速度不对,可以查 slow-time 和 Doppler FFT。
- 如果角度不对,可以查虚拟通道和 Angle FFT。
这种拆法更适合学习和调试,也方便以后逐步加入更真实的雷达效应。