自动化计算两个场景之间的坐标偏移,并应用到地图和场景文件。
本工具链用于处理 Apollo 自动驾驶场景数据的坐标对齐问题。
- 偏移计算: 使用匈牙利算法自动匹配障碍物并计算坐标偏移
- 可视化验证: 生成多种图表验证匹配质量
- 地图变换: 将偏移应用到 Apollo HD Map
- 场景生成: 创建新的 OpenSCENARIO 场景文件
- 地图辅助: 自动生成 sim_map 和 routing_map
匈牙利算法(Hungarian Algorithm)
- 用于解决二分图最优匹配问题
- 成本函数 = 坐标距离 + 尺寸差异惩罚
- 自动找到全局最优的障碍物配对
# Python 3.7+
python3 --version
# 安装依赖
pip install -r requirements.txt-
必需文件:
input/scenarios.json- OpenSCENARIO 格式的场景文件(包含地图路径)
-
数据源(二选一):
input/raw.json- 加密的原始数据(推荐)input/data.json- 已解密的障碍物数据
python3 run_pipeline.pyPipeline 会自动执行所有步骤:
- Step 0: 检测并解密
raw.json(如果存在) - Step 1: 计算偏移量
- Step 2: 生成可视化图表
- Step 3: 应用偏移到地图和场景(并行处理)
- Step 4: 生成 sim_map、routing_map 并组织为 ready-to-use 格式
apollo-map-offsets/
├── README.md # 本文档
├── requirements.txt # Python 依赖
├── run_pipeline.py # 主运行脚本
│
├── src/ # 核心脚本
│ ├── step0_decrypt_raw_data.py # 解密原始数据
│ ├── step1_calculate_offset.py # 计算偏移量
│ ├── step2_apply_offset_to_map.py # 应用偏移到地图
│ ├── step3_create_scenario.py # 创建新场景
│ ├── step4_organize_outputs.py # 组织输出
│ ├── visualize.py # 统一可视化模块
│ ├── map_generator.py # 地图辅助文件生成
│ └── font_helper.py # 字体辅助
│
├── utils/ # 工具文件
│ ├── simhei.ttf # 中文字体
│ └── test_font.py # 字体测试
│
├── docs/ # 文档
│ ├── CHANGELOG_v2.md # 更新日志
│ ├── INSTALL.md # 安装说明
│ ├── PIPELINE_FLOW.md # 详细流程说明
│ ├── QUICK_REFERENCE.md # 快速参考
│ └── README_FONT.md # 字体配置说明
│
├── input/ # 输入文件
│ ├── scenarios.json # 原始场景
│ ├── raw.json # 加密原始数据(可选)
│ └── data.json # 解密后的数据
│
├── results/ # 计算结果
│ └── offset_results.json # 偏移量和匹配结果
│
├── visualizations/ # 可视化图表
│ ├── 01_matching_overview.png # 匹配总览(6子图)
│ ├── 02_vector_field.png # 向量场
│ └── 03_obstacles_comparison.png # 障碍物对比(3子图)
│
└── output/ # 最终输出
├── scenario/
│ └── scenarios_offset.json # 偏移后的场景
└── map/
└── <map_name>_offset/ # 偏移后的地图目录
├── base_map.bin # 偏移后的地图
├── sim_map.bin # Dreamview 显示用
├── routing_map.bin # 路由地图
└── metaInfo.json # 元信息
如果有加密的 input/raw.json:
python3 src/step0_decrypt_raw_data.py输出: input/data.json
使用匈牙利算法匹配障碍物并计算偏移:
python3 src/step1_calculate_offset.py输出: results/offset_results.json
示例结果:
{
"transformation": {
"translation": {"x": 8993.72, "y": 8996.94},
"rotation_degrees": -0.53
},
"accuracy": {
"num_matches": 36,
"mean_error": 3.73,
"std_error": 1.46
}
}python3 src/visualize.py输出:
visualizations/01_matching_overview.png- 6子图总览(原始对比、偏移后、误差热图等)visualizations/02_vector_field.png- 变换向量场visualizations/03_obstacles_comparison.png- 障碍物对比(3子图)
python3 src/step2_apply_offset_to_map.py \
/path/to/input/base_map.bin \
output/base_map_offset.bin \
--format binary处理的地图元素:
- Lanes(车道)
- Roads(道路)
- Junctions(路口)
- Crosswalks(人行横道)
- Traffic Signals(信号灯)
- Stop Signs(停止标志)
# 只包含匹配的障碍物(默认)
python3 src/step3_create_scenario.py -o output/scenarios_new.json
# 包含所有障碍物
python3 src/step3_create_scenario.py -o output/scenarios_all.json --all-objects特性:
- ✅ 连续的障碍物 ID(1, 2, 3...)
- ✅ 统一的命名(vehicle_1, object_2...)
- ✅ 保留原始 ID 在 properties 中
- ✅ 自动类型映射
# 自动生成 sim_map 和 routing_map,并组织为 ready-to-use 格式
python3 src/step4_organize_outputs.py或使用统一的地图生成工具:
python3 src/map_generator.py --map_dir output/map/my_map输出:
output/scenario/scenarios_offset.jsonoutput/map/<map_name>_offset/- 完整的地图目录
cp -r output/map/<map_name>_offset /apollo_workspace/modules/map/data/- 启动 Dreamview:
bash scripts/bootstrap.sh - 打开浏览器: http://localhost:8888
- 选择地图:
<map_name>_offset - 加载场景:
scenarios_offset.json
# 只计算偏移
python3 src/step1_calculate_offset.py
# 只生成可视化
python3 src/visualize.py
# 只生成 sim_map
python3 src/map_generator.py --map_dir output/map/my_map --no-routingpython3 src/step2_apply_offset_to_map.py \
input.bin output.bin \
--offset-x 9000.0 \
--offset-y 9000.0 \
--rotation 0.0 \
--format binary编辑 src/step1_calculate_offset.py:
matches = match_obstacles_hungarian(
scenarios_obs, data_obs,
initial_offset=(dx_init, dy_init),
max_distance=50.0, # 最大匹配距离(米)
dimension_weight=100.0 # 尺寸差异惩罚权重
)编辑 src/visualize.py 或通过命令行参数:
python3 src/visualize.py \
--results results/offset_results.json \
--output visualizationspython3 src/map_generator.py \
--map_dir output/map/my_map \
--map_filename base_map.bin \
--no-sim # 不生成 sim_map
--no-routing # 不生成 routing_map查看 results/offset_results.json 中的 accuracy 字段:
mean_error< 5m:优秀 ✅mean_error5-10m:良好⚠️ mean_error> 10m:需要检查 ❌
同时查看 visualizations/ 中的图表进行可视化验证。
可能原因:
- data.json 中有新增的障碍物
- 坐标差异超过阈值(默认 50m)
- 尺寸差异过大
检查 results/offset_results.json 中的 unmatched 字段。
sim_map 失败:
# 需要先编译
cd /apollo_workspace
bazel build //modules/map/tools:sim_map_generatorrouting_map 失败:
# 需要编译 routing 模块
bazel build //modules/routing/...脚本已自动配置中文字体。如果仍有问题:
- 检查字体文件:
utils/simhei.ttf是否存在 - 测试字体:
python3 utils/test_font.py - 查看详细说明:
docs/README_FONT.md
- 输入: Apollo HD Map (text
.txt或 binary.bin) - 输出: 同上(可通过
--format指定) - 版本: Apollo 10.0+
# 1. 构建成本矩阵
cost = 坐标距离 + 100 × 尺寸差异
# 2. 初始偏移估计
offset = 目标中心 - 源中心
# 3. 最优匹配
src_indices, dst_indices = linear_sum_assignment(cost_matrix)
# 4. 变换计算(SVD求解旋转矩阵)
R, t = solve_transform(matched_points)data_pos = R × scenarios_pos + t
其中:
R - 旋转矩阵(2×2)
t - 平移向量(dx, dy)
详见 docs/CHANGELOG_v2.md
- ✅ 重构代码,避免重复
- ✅ 统一可视化模块
- ✅ 统一地图生成模块
- ✅ 优化目录结构
- ✅ 简化文档
- ✅ 初始版本
- ✅ 匈牙利算法匹配
- ✅ 完整可视化支持
- ✅ Apollo 10.0 地图支持
基于 Apollo 项目,遵循 Apache License 2.0
💡 提示: 强烈建议先查看可视化图表验证匹配质量,再应用到实际地图!