项目实现方式¶
这个项目不是把雷达仿真做成黑盒,而是拆成一条可以逐步检查的处理流水线。每个模块负责一个阶段,上一个阶段的输出就是下一个阶段的输入。
总体设计¶
主数据链路是:
mesh 文件
-> TriangleMesh
-> 每个 chirp 下变换后的三角面
-> 可见三角面
-> ScatterSet
-> 原始雷达数据立方体
-> FFT 输出
-> 可视化图片
这个项目的重要设计选择是:不直接从 mesh 跳到热力图,而是显式保留中间概念:
- mesh 加载
- 几何可见性
- 散射近似
- 通道级信号合成
- 距离/速度/角度 FFT
这样更容易调试,也更适合讲清楚雷达模拟器原理。
1. Mesh 加载¶
mesh_loader.py 读取 OBJ、STL 和 GLB 文件,并统一转换成 TriangleMesh。
TriangleMesh 只保存:
vertices:顶点坐标faces:三角面顶点索引
纹理、材质、动画等渲染信息会被忽略,因为当前雷达模拟器只需要几何形状。
2. 每个 Chirp 下的目标变换¶
对每个 chirp,目标会作为刚体变换一次。
目标位置是:
position(t) = initial_position + velocity * slow_time
然后再应用固定欧拉角旋转。这个模型足够支撑早期距离和多普勒实验。
3. 可见性筛选¶
visibility.py 会去掉不应该贡献回波的三角面。
它做两个判断:
- 朝向判断:只保留法向大致朝向雷达的三角面。
- 遮挡判断:从雷达相位中心向三角面中心发射射线,如果中途被其他三角面挡住,就丢弃该面。
这套方法故意保持直接和可读。当前还没有用 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:
- 沿 ADC 采样点做 Range FFT。
- 沿 chirp 序列做 Doppler FFT。
- 沿 MIMO 虚拟通道做 Angle FFT。
输出既包含完整数据立方体,也包含方便画图的投影 map。
为什么这样拆分¶
这个实现刻意保持模块边界清晰:
- 几何代码不理解雷达参数
- 雷达配置不生成信号
- 可见性模块不做 FFT
- 多进程只拆任务,不改变物理模型
这种拆分让后续扩展更容易。例如之后可以把可见性阶段换成 BVH 加速,或者把散射模型换成更细的材料模型,而不需要重写整个项目。
初学者阅读路径¶
如果你刚开始看这个项目,建议从外到内读:
- 先看
main.py。它展示完整命令行流程:解析参数、创建配置对象、加载 mesh、运行仿真、运行 FFT、保存输出。 - 再看
radar_model.py。它解释雷达需要哪些参数:载频、带宽、chirp 时长、ADC 采样点、chirp 数、天线数。 - 看
mesh_loader.py和geometry.py。这两个文件解释 3D 模型如何变成三角面,以及三角面如何计算中心、法向和面积。 - 看
visibility.py。这里决定雷达到底能看到哪些表面。 - 看
scatter_model.py。这里把可见表面转换成点状散射体。 - 看
signal_synth.py。这是核心文件,距离在这里变成延迟,延迟变成 beat frequency,散射体变成复数雷达采样。 - 看
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 |
这就是项目拆成小文件的意义:后续实验尽量局部修改,而不是全局重写。