feat: 算法升级、整车配准集成与性能分析文档

算法更新: delivery v1.2.1、平整度v1.5、测距v2.2、整车配准v1.3
适配器: vehicle-registration 新增、各算法 manifest 和 adapter 更新
后端: taskCadFiles/source 字段迁移、derivedPointClouds 注册、取消任务联动
前端: ElapsedTime 时长显示、两步算法流程、canRun 逻辑修复
文档: 新增5份算法性能分析报告
This commit is contained in:
2026-06-25 08:22:20 +00:00
parent cec0766e67
commit 29f1d45d66
266 changed files with 1311475 additions and 2846 deletions

View File

@@ -0,0 +1,160 @@
# 整车配准算法性能分析报告
> 分析时间:2026-06-25
> 算法版本:`整车配准v1.3`
> 入口函数:`translate_align_by_front_tail`(`translate_align_pointcloud_to_cad.py`)
> 测试环境:INTEL SSDSC2KB01(SATA SSD,~394 MB/s);A100 40 GB;CPU 128 核
> **实测数据**:12 GB / 10 亿点 binary PLY 输入,总耗时 **10 min 24 s**
---
## 执行流程总览
```
translate_align_by_front_tail()
├─ 1. CAD STEP → mesh → 30k 点云采样 ← 实测 6 min 30 s(无 cache 时)
│ └─ [cache 命中] 直接加载 .ply ← 实测 ~5 s
├─ 2. 加载原始点云(Open3D binary PLY) ← 实测 1 min 17 s
├─ 3. 车头 / 车尾裁剪 × 4 ← 实测 2 min 17 s
├─ 4. 车头 / 车尾局部采样(1000 pts × 4)← 实测 7.6 ms
├─ 5. 平移估计(点集质心差) ← 实测 1.3 ms
├─ 6. ICP 精配准(采样 20 万点) ← 实测 1.9 s
├─ 7. 应用变换 + 写入配准结果 PLY ← 实测 12.8 s
└─ 8. 对齐误差统计(采样 10 万点 KNN) ← 实测 977 ms
```
---
## 各步骤详细说明与时间估算
### 第一阶段:CAD 准备(STEP → 采样点云)
| # | 步骤 | 代码位置 | 说明 | 无 cache | 有 cache |
|---|---|---|---|---|---|
| 1a | `read_step_file`(OCC 加载) | `translate_align...py:73` | OCC `STEPControl_Reader` 读 STEP | ~10 s | 跳过 |
| 1b | `BRepMesh_IncrementalMesh`(tessellate) | `translate_align...py:147` | OCC 三角剖分,147,275 个面 | **~6 min** | 跳过 |
| 1c | 提取顶点/三角形数组 | `translate_align...py:100` | Python for loop 遍历所有面 | ~15 s | 跳过 |
| 1d | `o3d.PointCloud` + 均匀采样 30k 点 | `translate_align...py:155` | 从 mesh 均匀采样 `cad_sample_points=30000` | ~3 s | 跳过 |
| 1e | **加载 cache PLY**(`useCadCache=true`) | `translate_align...py:510` | 直接读 1.4 MB PLY,30k 点 | — | **~1 s** |
> **CAD cache 机制**:首次运行时 STEP tessellate 需约 6 分钟,生成 `cad_cache/<hash>.ply`(1.4 MB)。后续所有运行直接加载 cache,耗时降至 1 秒以内。**务必开启 `useCadCache=true`(已默认开启)**,且不要删除 `cad_cache/` 目录。
---
### 第二阶段:加载原始点云
| # | 步骤 | 代码位置 | 说明 | 实测时间 |
|---|---|---|---|---|
| 2 | `o3d.io.read_point_cloud`(binary PLY) | `translate_align...py:547` | Open3D C++ 读 12 GB binary PLY,直接构造 PointCloud | **~1 min 17 s** |
Open3D 读取速度约 158 MB/s(受限于磁盘顺序读速 ~394 MB/s + float 转换)。12 GB 需要约 75 秒,无法进一步优化除非换更快的磁盘。
---
### 第三阶段:车头 / 车尾裁剪(主要瓶颈)
| # | 步骤 | 代码位置 | 说明 | 实测时间 |
|---|---|---|---|---|
| 3 | `crop_end_region_by_ratio` × 4 | `translate_align...py:180` | 对 10 亿点 Open3D PointCloud 做 4 次 `pcd.crop(AABB)`(CAD 前/后 + 扫描前/后) | **~2 min 17 s** |
虽然 `o3d.crop` 是 C++ 实现,但对 10 亿点的 PointCloud 内部仍需遍历全量点做 AABB 测试(O(N) × 4 次),实测每次约 34 秒,4 次共计 137 秒。
裁剪后车头/尾各只有 ~几千到几万点(ratio=0.01,即取前 1% 长度),所以裁剪结果本身非常小,耗时全部来自对全量 10 亿点的遍历。
---
### 第四阶段:局部采样 + 粗配准
| # | 步骤 | 代码位置 | 说明 | 实测时间 |
|---|---|---|---|---|
| 4 | `sample_farthest_points_simple` × 4 | `translate_align...py:235` | 随机采样 1000 点;裁剪后点数已很少,O(M) | **7.6 ms** |
| 5 | 平移估计 | `translate_align...py:638` | 车头质心差 + 车尾质心差均值估计初始平移 | **1.3 ms** |
---
### 第五阶段:ICP 精配准
| # | 步骤 | 代码位置 | 说明 | 实测时间 |
|---|---|---|---|---|
| 6 | `sample_farthest_points_simple`(20 万点采样) | `translate_align...py:355` | 从 10 亿点随机采样 `icp_sample_points=200000` | **< 1 s** |
| 7 | `o3d.registration.registration_icp` | `translate_align...py:375` | Point-to-point ICP,source 20 万点 → target CAD 30k 点,最多 50 次迭代;Open3D C++ | **1.9 s** |
ICP 本身非常快,因为:
- source 只用 20 万点(采样)
- target CAD 只有 30k 点
- Open3D ICP 是 C++ SIMD 实现
---
### 第六阶段:应用变换 + 写入结果
| # | 步骤 | 代码位置 | 说明 | 实测时间 |
|---|---|---|---|---|
| 8 | `aligned_pcd.transform(T_final)` | `translate_align...py:704` | 对 10 亿点做 4×4 矩阵变换(Open3D C++,SIMD) | **~2 s** |
| 9 | `write_point_cloud_float32_xyz` | `translate_align...py:314` | 分块写 binary PLY,float32,12 GB → 分 1000 个 chunk 写 | **~10 s** |
| 10 | 误差统计(`compute_error_stats`) | `translate_align...py:740` | 采样 10 万点,KNN 建树 + 查询,scipy C++ | **977 ms** |
---
## 实测时间汇总
| 阶段 | 实测时间 | 占比 |
|---|---|---|
| CAD 采样(无 cache) | **6 min 30 s** | 63% |
| CAD 采样(有 cache) | **~1 s** | <1% |
| **加载原始点云(Open3D)** | **1 min 17 s** | 12% |
| **车头/尾裁剪 × 4(Open3D C++ crop)** | **2 min 17 s** | 22% |
| 局部采样 + 平移估计 | **<0.01 s** | <1% |
| ICP 精配准(20 万点) | **1.9 s** | <1% |
| 写 12 GB 结果 PLY | **12.8 s** | 2% |
| 误差统计 | **977 ms** | <1% |
| **总计(有 cache)** | **~10 min 24 s** | — |
| **总计(无 cache,首次)** | **~17 min** | — |
---
## 主要瓶颈分析
### 瓶颈 1:车头/尾裁剪 2 min 17 s(无法简单绕过)
`pcd.crop(AABB)` 是 Open3D C++ 全量遍历,10 亿点 × 4 次不可避免。
```
缓解方案:将 crop_ratio 从 0.01 增大到 0.02–0.05,
提取更多点用于粗配准,同时不影响裁剪本身速度(依然 O(N))。
根本方案:将 Open3D PointCloud 替换为 numpy 数组,
4 次 crop 变为 4 次 numpy 布尔索引,
并行化(4 个 crop 独立,可多线程),
估计可从 2 min 17 s 降至 ~30 s。
```
### 瓶颈 2:加载原始点云 1 min 17 s(I/O 受限)
Open3D 读 12 GB 文件,受限于 SATA SSD 394 MB/s 顺序读速,理论下限约 30 s(NVMe),实测 77 s 说明还有额外开销(float 类型转换)。升级到 NVMe 可降至 ~35 s。
### 瓶颈 3:CAD tessellate 6 min(首次,已有 cache 机制解决)
OCC 对 147,275 个面的 CAD 做三角剖分只需要跑一次,结果缓存为 1.4 MB PLY。**只要 `useCadCache=true` 且 CAD 文件未更换,后续每次配准这一步只需 1 秒**。
---
## 优化目标
| 场景 | 当前 | 优化后目标 |
|---|---|---|
| 有 cache,12 GB 输入 | 10 min 24 s | ~4 min(crop 多线程 + numpy 化) |
| 首次运行(无 cache) | ~17 min | ~4 min + 6 min(CAD build 无法优化) |
---
## GPU 使用情况
| 模块 | GPU 使用 |
|---|---|
| STEP 解析 / tessellate(OCC) | ❌ CPU |
| 点云读取(Open3D) | ❌ CPU(I/O 受限) |
| crop / transform(Open3D) | ❌ CPU(C++ SIMD) |
| **ICP 精配准(Open3D)** | ❌ CPU(Open3D ICP 不使用 CUDA) |
| 误差统计(scipy KNN) | ❌ CPU |
**整车配准全程不使用 GPU**,A100 完全闲置。ICP 最有潜力用 GPU 加速(Open3D 有 `registration_colored_icp` + CUDA),但当前输入只有 20 万点,ICP 本身已是 1.9 s,瓶颈在 I/O 和 crop,GPU 化 ICP 收益有限。