关于 roadrunner-import-scene
roadrunner-import-scene 是用于将地图文件载入 RoadRunner 场景的 MATLAB 技能,适合需要可视化、验证或构建地图的工作。它支持 RoadRunner HD Map 与 OpenDRIVE,并提供依据地图内容配置构建选项的流程。
主要功能
- 01导入 .rrhd 和 .xodr 文件
- 02创建新场景并保存
- 03将源文件复制到项目目录
- 04按地图内容设置构建选项
- 05保留地图中的路口几何
适用场景
- 01在 RoadRunner 中查看 .rrhd 地图
- 02导入 OpenDRIVE 地图
- 03验证转换后的地图
- 04根据路口和闭环道路配置构建
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill roadrunner-import-scene安装后在 Claude Code 中输入/roadrunner-import-scene确认已加载。
附带文件manifest.yaml
详细介绍
RoadRunner 场景导入
将地图文件导入 RoadRunner 场景,以便进行可视化、验证和构建。
适用场景
- 将
.rrhd文件导入 RoadRunner 进行可视化验证 - 将 OpenDRIVE
.xodr文件导入 RoadRunner - 验证 Lanelet2 转 RRHD 或其他转换后的地图
- 配置构建选项(沥青路面、桥梁检测、保留交叉口)
不适用场景
- 启动 RoadRunner 或管理项目——使用
roadrunner-core - 构建 RRHD 地图内容——使用
roadrunner-rrhd-authoring - 将 Lanelet2 转换为 RRHD——使用
roadrunner-convert-lanelet2-to-rrhd - 查找资产路径——使用
roadrunner-asset-mapping
关键规则
- **执行代码时始终写入
.m文件。**切勿将多行 MATLAB 代码直接放入evaluate_matlab_code。应写入.m文件,使用run_matlab_file运行,出错时进行修改。例外:如果用户要求“展示模式”或表示“不要执行”,则直接内联展示代码,不要写入文件。 - **需要来自
roadrunner-core的rrApp。**不要在此技能中启动或连接 RoadRunner。如果rrApp不存在,请先调用roadrunner-core。 - **始终将文件复制到项目文件夹。**在每个导入工作流中明确使用
status(rrApp).Project.Filename和copyfile(),切勿省略或将其隐藏在变量后。 - **始终显式设置
bridgeOpts.IsEnabled = true。**切勿依赖构造函数默认值来自动检测桥梁。 - **在
importScene前运行强制检查。**必须检查文件位置、扩展名和构建选项。 - **默认先加载再构建。**使用
ImportStep="Load",除非用户明确要求完整构建。 - **对于转换后的地图,绝不能将
DetectAsphaltSurfaces = true硬编码。**务必先检查 RRHD 是否具有闭环拓扑。闭环网络(大多数 Lanelet2 转换结果)必须使用DetectAsphaltSurfaces = false——沥青检测会填充环路内部。 - **存在交叉口时,务必予以保留。**如果
tempMap.Junctions非空,则必须设置overlapOpts.IsEnabled = true、overlapOpts.PreserveJunctionLanes = true和overlapOpts.PreserveJunctionShape = true。切勿依赖 RoadRunner 的自动检测重新推断交叉口——这会丢弃已有的几何形状。
前置条件
- 必须存在有效的
rrApp句柄(由roadrunner-core技能生成) - 必须已打开 RoadRunner 项目
- 如果
rrApp不存在,请先调用roadrunner-core启动并连接
**连接、启动和项目生命周期由 roadrunner-core 管理。**本技能假定 rrApp 已可用。
导入工作流
步骤 1:创建新场景
为避免数据过时,导入前务必创建新场景:
newScene(rrApp);
步骤 2:将文件复制到项目中(必需——始终明确展示)
RoadRunner 要求导入的文件位于项目文件夹中。生成的代码中必须始终包含以下确切模式——切勿假定文件已在项目文件夹中,也不要将其隐藏在变量后:
st = status(rrApp);
projectFolder = st.Project.Filename;
[~, fileName, ext] = fileparts(sourceFile);
destFile = fullfile(projectFolder, fileName + ext);
copyfile(sourceFile, destFile);
绝不能省略 copyfile() 调用或 status(rrApp).Project.Filename 查询。即使在其他位置定义了 destFile 变量,每个导入工作流中也必须明确展示项目路径的获取操作和文件复制操作。
步骤 3:导入地图
RoadRunner HD 地图(.rrhd)
仅加载(构建前检查 RRHD 视图):
importOpts = roadrunnerHDMapImportOptions;
importOpts.ImportStep = "Load";
importScene(rrApp, destFile, "RoadRunner HD Map", importOpts);
完整导入并构建(使用条件逻辑——绝不能将沥青或交叉口设置硬编码):
不要复制固定模板。务必使用下方的“条件构建选项”部分,根据 RRHD 内容确定正确设置。强制检查会拒绝对 RRHD 文件硬编码 DetectAsphaltSurfaces = true。
**重要:**启用桥梁自动检测时,必须始终显式写入 bridgeOpts.IsEnabled = true。不要依赖构造函数默认值——生成的代码中必须包含这一行。
条件构建选项(强制 — 根据地图内容应用)
选择构建选项前,请先检查 RRHD 内容。以下规则决定何时启用或禁用特定设置:
| 条件 | 操作 | 原因 |
|---|---|---|
RRHD 中没有 Junctions(为空或为零) | 设置 overlapOpts.IsEnabled = false | 如果没有明确的交叉口定义,重叠检测就只会使用几何信息,从而产生错误的分组 |
| 闭环道路网络(车道形成环路) | 设置 buildOpts.DetectAsphaltSurfaces = false | 沥青检测会填充闭环内部,从而生成不需要的路面多边形 |
RRHD 中存在明确的 Junctions | 设置 overlapOpts.PreserveJunctionLanes = true 和 overlapOpts.PreserveJunctionShape = true | 保留创作的交叉口几何形状和车道连接关系,而不是根据几何信息重新推断 |
示例:使用可识别交叉口的选项进行导入:
importOpts = roadrunnerHDMapImportOptions;
buildOpts = roadrunnerHDMapBuildOptions;
buildOpts.ClearSceneOfExistingData = true;
% Read RRHD to inspect content before build
tempMap = roadrunnerHDMap;
read(tempMap, destFile);
% Conditional: asphalt surfaces
hasClosedLoops = false; % Detect from lane topology (any lane chain forming a cycle)
if hasClosedLoops
buildOpts.DetectAsphaltSurfaces = false;
else
buildOpts.DetectAsphaltSurfaces = true;
end
% Conditional: overlap groups / junctions
overlapOpts = enableOverlapGroupsOptions;
if isempty(tempMap.Junctions) || numel(tempMap.Junctions) == 0
overlapOpts.IsEnabled = false;
else
overlapOpts.IsEnabled = true;
overlapOpts.PreserveJunctionLanes = true;
overlapOpts.PreserveJunctionShape = true;
end
buildOpts.EnableOverlapGroupsOptions = overlapOpts;
bridgeOpts = autoDetectBridgesOptions;
bridgeOpts.IsEnabled = true;
buildOpts.AutoDetectBridgesOptions = bridgeOpts;
importOpts.BuildOptions = buildOpts;
importScene(rrApp, destFile, "RoadRunner HD Map", importOpts);
OpenDRIVE (.xodr)
importOpts = openDriveImportOptions;
importOpts.ImportSignals = true;
importOpts.ImportObjects = true;
importScene(rrApp, destFile, "OpenDRIVE", importOpts);
步骤 4:保存场景
[~, sceneName] = fileparts(sourceFile);
saveScene(rrApp, sceneName);
导入选项参考
roadrunnerHDMapImportOptions
| 属性 | 描述 |
|---|---|
ImportStep | "Load"(仅 RRHD 视图)或 "Unspecified"(完整加载并构建) |
LoadOptions | roadrunnerHDMapLoadOptions — 偏移量、投影 |
BuildOptions | roadrunnerHDMapBuildOptions — 构建配置 |
roadrunnerHDMapBuildOptions
| 属性 | 描述 | 默认值 |
|---|---|---|
ClearSceneOfExistingData | 移除现有场景内容 | 自动 |
DetectAsphaltSurfaces | 生成路面 | 自动 |
FitCrossSections | 拟合车道横截面 | 自动 |
CurvatureBlend | 曲率混合系数 | 自动 |
UseLaneGroups | 对车道分组以便编辑(R2024a+) | 自动 |
CombineTransitionLanes | 合并过渡车道(R2025a+) | 自动 |
AutoDetectBridgesOptions | autoDetectBridgesOptions 对象 | 自动 |
EnableOverlapGroupsOptions | enableOverlapGroupsOptions 对象(交叉口) | 自动 |
FixUnrealisticRoadElevation | 修正 HD 数据源中的高程突变 | 自动 |
FixInconsistentLaneConnections | 移除不符合物理规律的车道连接 | 自动 |
enableOverlapGroupsOptions
| 属性 | 描述 | 默认值 |
|---|---|---|
IsEnabled | 使用交叉口位置信息(false = 几何重叠) | 自动 |
PreserveJunctionLanes | 保留导入地图中的原始交叉口车道 | 自动 |
PreserveJunctionShape | 保留导入地图中的交叉口多边形几何形状 | 自动 |
GroupName | 重叠组的名称 | 自动 |
openDriveImportOptions
| 属性 | 描述 |
|---|---|
ImportSignals | 导入交通信号灯 |
ImportObjects | 导入静态对象 |
LaneOptions | 车道转换设置 |
Offset | 场景位置偏移量 |
Projection | 地理空间投影 |
ImportRegion | 区域筛选器(R2024a+) |
支持的格式
| 格式名称 | 文件类型 | 起始版本 |
|---|---|---|
"RoadRunner HD Map" | .rrhd | R2022b |
"OpenDRIVE" | .xodr | R2022a |
"HERE HD Map" | (目录) | R2024a |
"TomTom HD Map" | (目录) | R2024b |
默认行为
当用户要求“导入地图”或“加载到 RoadRunner”时:
- 确保
rrApp存在(如果不存在,则调用roadrunner-core) - 创建新场景(从空白场景开始)
- 将文件复制到项目的 Assets 文件夹
- 使用仅加载(
ImportStep="Load")进行导入,以便用户检查 RRHD 视图 - 使用文件名作为场景名称保存场景
仅当用户明确要求构建,或 RRHD 视图已通过检查后,才执行完整构建(使用 BuildOptions)。
构建时,始终先检查 RRHD 内容,并应用上文“条件构建选项”部分中的条件选项。检查地图内容前,切勿使用固定或硬编码的构建选项。
主要功能
| 功能 | 用途 |
|---|---|
newScene(rrApp) | 创建全新场景(清空现有内容) |
status(rrApp) | 获取项目信息(.Project.Filename) |
importScene(rrApp, file, format, opts) | 将地图文件导入场景 |
saveScene(rrApp, name) | 保存当前场景 |
roadrunnerHDMapImportOptions | 创建导入选项(设置 ImportStep、BuildOptions) |
roadrunnerHDMapBuildOptions | 创建构建选项(沥青、桥梁、交叉路口) |
autoDetectBridgesOptions | 桥梁检测设置(IsEnabled) |
enableOverlapGroupsOptions | 交叉路口保留设置(PreserveJunctionLanes、PreserveJunctionShape) |
openDriveImportOptions | OpenDRIVE 专用导入选项 |
强制检查关卡(必须 — 在导入前运行)
调用 importScene 前,必须执行这些检查。不要跳过。
%% --- ENFORCEMENT: RoadRunner is connected ---
try
st = status(rrApp);
assert(~isempty(st.Project.Filename), 'No project open');
fprintf('RoadRunner connected, project: %s\n', st.Project.Filename);
catch
error('RoadRunner:NotConnected', ...
'No RoadRunner instance connected. Run the Connection Strategy block first.');
end
%% --- ENFORCEMENT: File is inside project folder ---
projectFolder = st.Project.Filename;
assert(startsWith(destFile, projectFolder) || isfile(destFile), ...
'Import file must be inside the project folder. Copy it first.');
fprintf('File location check: PASS\n');
%% --- ENFORCEMENT: File extension matches format ---
[~, ~, ext] = fileparts(destFile);
if formatName == "RoadRunner HD Map"
assert(ext == ".rrhd", 'Expected .rrhd file for RoadRunner HD Map format');
elseif formatName == "OpenDRIVE"
assert(ext == ".xodr", 'Expected .xodr file for OpenDRIVE format');
end
fprintf('Format check: PASS\n');
%% --- ENFORCEMENT: Build options match RRHD content (MANDATORY for .rrhd) ---
if ext == ".rrhd"
tempMap = roadrunnerHDMap;
read(tempMap, destFile);
% Junction preservation check
if ~isempty(tempMap.Junctions) && numel(tempMap.Junctions) > 0
assert(exist('overlapOpts','var') == 1 && overlapOpts.IsEnabled == true ...
&& overlapOpts.PreserveJunctionLanes == true ...
&& overlapOpts.PreserveJunctionShape == true, ...
'RRHD has %d junctions — you MUST enable PreserveJunctionLanes and PreserveJunctionShape.', ...
numel(tempMap.Junctions));
fprintf('Junction preservation check: PASS (%d junctions preserved)\n', numel(tempMap.Junctions));
end
% Closed-loop / asphalt check — detect topology cycles (multi-lane or self-loop)
hasClosedLoop = false;
lanes = tempMap.Lanes;
nLanes = numel(lanes);
laneIDs = cell(1, nLanes);
for li2 = 1:nLanes, laneIDs{li2} = char(lanes(li2).ID); end
laneIDSet = containers.Map(laneIDs, num2cell(1:nLanes));
% BFS from each lane: if we revisit a lane, there's a cycle
visited = false(1, numel(lanes));
for startIdx = 1:numel(lanes)
if visited(startIdx), continue; end
queue = startIdx; seen = false(1, numel(lanes)); seen(startIdx) = true;
while ~isempty(queue)
ci = queue(1); queue(1) = [];
visited(ci) = true;
succs = lanes(ci).Successors;
for si = 1:numel(succs)
sid = char(succs(si).Reference.ID);
if laneIDSet.isKey(sid)
ni = laneIDSet(sid);
if ni == startIdx
hasClosedLoop = true; break;
end
if ~seen(ni), seen(ni) = true; queue(end+1) = ni; end
end
end
if hasClosedLoop, break; end
end
if hasClosedLoop, break; end
end
if hasClosedLoop
assert(buildOpts.DetectAsphaltSurfaces == false, ...
'DetectAsphaltSurfaces must be false for closed-loop maps (fills interior). Set it explicitly.');
fprintf('Asphalt detection check: PASS (disabled for closed-loop)\n');
else
fprintf('Asphalt detection check: PASS (no closed-loop detected)\n');
end
end
约定
- 始终准确指定格式名称字符串:
"RoadRunner HD Map"、"OpenDRIVE" - 使用
SOS形式确保 IIR 稳定性(BuildOptions会在内部处理) - 明确展示所有文件暂存代码(
status、fileparts、fullfile、copyfile) - 多面板图形使用
tiledlayout/nexttile(不要使用subplot) - 将
destFile固定为项目文件夹路径 — 导入时绝不使用临时路径或相对路径
Copyright 2026 The MathWorks, Inc.