关于 roadrunner-rrhd-authoring
roadrunner-rrhd-authoring 是用于通过 MATLAB 的 roadrunnerHDMap API 构建 RRHD 地图实体的技能,面向地图转换器开发者及需要创建合成道路或自定义地图的用户。它提供可复用的几何算法、实体构造模式和写入前验证规则。
主要功能
- 01构建车道、边界和路口等实体
- 02提供对齐与中心线生成算法
- 03处理端点吸附和闭环拆分
- 04参考已验证的 RRHD API 属性
- 05写入前检查几何与空间规则
适用场景
- 01从零创建合成道路地图
- 02将转换后的数据组装为 RRHD
- 03添加车道标线、标志和停车区
- 04排查 RRHD 构造错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill roadrunner-rrhd-authoring安装后在 Claude Code 中输入/roadrunner-rrhd-authoring确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/alignmentRules.mdapiReference.mddeduplicateBoundaries.mdjunctionPolygon.mdleftGapFilter.mdorthogonalSplit.mdresolveHeights.mdsnapEndpoints.mdsplitClosedGeometry.mdsynthesizeCenterLine.mdvalidateMap.mdscripts/detectAlignment.mresolveHeightConflicts.msnapConnectedEndpoints.mvalidateRRHD.m详细介绍
RRHD 编写技能
在 MATLAB 中直接使用 roadrunnerHDMap API 构建 RoadRunner HD Map(.rrhd)实体。提供可从任何来源构建 RRHD 的通用构建模块,包括合成场景、转换后的地图数据或自定义格式。
适用场景
- 从头开始构建 RRHD 地图(合成场景、测试道路)
- 从转换后的地图数据组装 RRHD 实体(Lanelet2、HERE、NDS、OpenDRIVE、自定义格式)
- 需要可复用的几何算法:对齐检测、中心线合成、路口多边形、端点吸附、闭环拆分
- 向 HD Map 添加车道、边界、标线、路口、标志、护栏或停车区域
- 需要经过验证的
roadrunner.hdmap.*类/属性参考和构建模式 - 调试 RRHD 构建错误(属性名称错误、对齐问题)
在地图转换流水线中的作用
此技能提供与格式无关的 RRHD 构建模式,供任何转换器技能调用:
| 可复用构建模块 | 参考 | 使用方 |
|---|---|---|
| 对齐检测(Forward/Backward) | alignmentRules.md | 任何包含共用/相向边界的转换器 |
| 中心线合成(重采样 + 求平均) | synthesizeCenterLine.md | 任何根据边界对推导车道的转换器 |
| 路口多边形构建 | junctionPolygon.md | 任何根据拓扑推断路口的转换器 |
| 闭环拆分 | splitClosedGeometry.md、orthogonalSplit.md | 任何处理环形/椭圆道路的转换器 |
| 左侧间隙拓扑筛选 | leftGapFilter.md | 任何包含节点匹配拓扑的转换器 |
| 端点吸附 | snapEndpoints.md | 任何包含拓扑连接的转换器 |
| 高度冲突消解 | resolveHeights.md | 任何包含重叠车道的转换器 |
| 边界去重 | deduplicateBoundaries.md | 任何来源中包含共用/相向边界的转换器 |
| RRHD 对象 API 模式 | apiReference.md | 任何构建 roadrunner.hdmap.* 对象的代码 |
| 强制验证门禁 | validateMap.md | 任何在调用 write() 前运行的转换器 |
技能边界
此技能负责(与格式无关的 RRHD 构建):
| 职责 | 描述 |
|---|---|
roadrunner.hdmap.* API | 类/属性参考、构造模式、类型规则 |
| 几何算法 | 对齐、中心线、重采样、正交拆分、吸附 |
| 路口多边形 | 外边界追踪、boundary()、convhull 技术 |
| 验证/强制检查 | 空间检查、对齐验证、几何尺寸 |
| 实体构建 | 车道、边界、标线、路口、护栏、标志、信号灯、停车区域 |
| 导入选项 | roadrunnerHDMapImportOptions、构建选项、桥梁检测 |
转换器技能负责(特定于源格式):
| 职责 | 描述 |
|---|---|
| 源数据解析 | 读取 XML/protobuf/JSON,提取节点/道路/关系 |
| 坐标投影 | 纬度/经度 → ENU、map_projector_info.yaml、local_x/local_y |
| 拓扑提取 | 节点匹配、相向方向筛选、左侧间隙筛选 |
| 路口检测 | 根据标签进行 BFS 聚类、回退扇入/扇出、增加车道 |
| 语义映射 | 源子类型 → RRHD LaneType、标线资源、标志代码 |
| 发现与完整性 | 扫描所有元素、报告未映射项、确保没有内容被丢弃 |
判定规则:
- “如何构建此 RRHD 对象?” → RRHD 编写技能
- “如何从我的源格式中提取数据?” → 转换器技能
不适用场景
- 转换 Lanelet2 .osm 文件——请使用
roadrunner-convert-lanelet2-to-rrhd(它会调用此技能) - 查找标线/标志/护栏的资源路径——请使用
roadrunner-asset-mapping - 将完成的 .rrhd 导入 RoadRunner——请使用
roadrunner-import-scene - 以交互方式编辑现有 RoadRunner 场景(此技能会编写 .rrhd 文件,而非编辑场景)
关键规则
- 执行代码时始终写入 .m 文件。切勿将多行 MATLAB 代码直接放入
evaluate_matlab_code。请写入.m文件,通过run_matlab_file运行,出错时再编辑。例外:如果用户要求“展示模式”或表示“不要执行”,则直接展示代码,无需写入文件。 - 只读取任务所需的特定参考资料——不要一开始就读取所有参考资料。查询属性时使用 apiReference.md,其他参考资料仅在直接相关时读取。
- 只构建用户要求的内容。除非明确要求,否则不要添加额外的车道、路口或对象。
rrMap = roadrunnerHDMap;必须放在首位——在使用任何roadrunner.hdmap.*前加载命名空间。- 先创建再赋值——切勿传入构造函数参数(
RelativeAssetPath和AlignedReference除外)。 - 空类型化数组——使用
ClassName.empty,不要使用[]。 - 所有几何数据必须为 Nx3——始终包含 Z 列(若为平面几何,默认值为 0)。
- 在调用
write()前运行强制检查关卡——对齐、空间和几何检查均为必需。 - **轨迹地图(闭环椭圆/赛道):省略拓扑结构(不设 Predecessors/Successors),省略标线属性(不设 ParametricAttribution),省略 Z 轴起伏。**仅使用自然高程。参见 references/orthogonalSplit.md。
关键 API 规则
使用任何 roadrunner.hdmap.* 类之前,必须先创建 roadrunnerHDMap 对象(延迟加载命名空间):
rrMap = roadrunnerHDMap; % REQUIRED — loads the namespace
先创建再赋值——切勿传入构造函数参数(两个类的 Name=Value 参数除外):
ref = roadrunner.hdmap.Reference;
ref.ID = "myID"; % assign after creation
Name=Value 构造函数——只有 RelativeAssetPath 和 AlignedReference 接受 Name=Value:
rap = roadrunner.hdmap.RelativeAssetPath(AssetPath="Assets/Markings/StopLine.rrlms");
ar = roadrunner.hdmap.AlignedReference(Reference=ref, Alignment="Forward");
% WRONG: positional args error with "A name is expected"
空类型化数组——类型化属性切勿使用 []:
lane.Predecessors = roadrunner.hdmap.AlignedReference.empty; % CORRECT
lane.Predecessors = []; % WRONG: "Value must be of type AlignedReference"
已验证的属性名称(R2025a+)
完整的已验证类/属性表请参阅 references/apiReference.md。以下是容易出错的要点:
| 常见错误 | 正确写法 |
|---|---|
LeftBoundary | LeftLaneBoundary |
RightBoundary | RightLaneBoundary |
Speed | Value(int32) |
Unit = "KPH" | VelocityUnit = "Kph" |
ParametricAttrib | ParametricAttribution |
pa.Value = mr | pa.MarkingReference = mr |
pa.StartFraction/EndFraction | pa.Span = [0 1](double 数组) |
JunctionPhase/Phase(直接使用) | Configurations(包含嵌套 .Phases 的 JunctionConfiguration 数组) |
roadrunnerHDMap("file.rrhd") | rrMap = roadrunnerHDMap; read(rrMap, "file.rrhd") |
| Nx2 几何 | Nx3 几何(始终包含 Z 列) |
cm.CurveMarkingTypeID | cm.MarkingTypeReference |
b.BarrierTypeID | b.BarrierTypeReference |
s.SignTypeID | s.SignTypeReference |
s.BoundingBox | s.Geometry(接受 GeoOrientedBoundingBox) |
bb.Position | bb.Center(1x3 double) |
bb.Orientation | bb.GeoOrientation([h,p,r] double 数组) |
pg.OuterRing | pg.ExteriorRing(Nx3 double) |
bt.AssetPath | bt.ExtrusionPath(仅适用于 BarrierType) |
roadrunner.hdmap.GeoOrientation | 不是类——直接使用 [h,p,r] double 数组 |
Lane.Predecessors = [] | Lane.Predecessors = roadrunner.hdmap.AlignedReference.empty |
lb.ParametricAttributes = [] | 无法清除——没有标线时跳过赋值 |
RelativeAssetPath("path") | RelativeAssetPath(AssetPath="path")——必须使用 Name=Value |
AlignedReference(ref, "Fwd") | AlignedReference(Reference=ref, Alignment="Forward") |
Junction.Geometry = polygon | Junction.Geometry = multiPolygon(包装为 MultiPolygon) |
MarkingReference.MarkingID = 5 | MarkingReference.MarkingID = ref(Reference 对象,不是数值) |
SpeedLimit.Velocity | SpeedLimit.Value(int32)+ .VelocityUnit = "Kph" |
合成场景构建
车道宽度和几何
标准车道宽度:3.7m(美国高速公路)。通过沿垂直于车道中心线方向的方向偏移来计算边界位置。
相邻车道之间的共用边界
相邻车道必须共用边界几何。 N 号车道的右边界与 N+1 号车道的左边界是同一个对象。对于 N 条车道,创建 N+1 个边界。
LB_0 (left edge)
───────────────────
│ Lane_1 │ left=LB_0(Fwd), right=LB_1(Fwd)
───────────────────
LB_1 (shared)
───────────────────
│ Lane_2 │ left=LB_1(Fwd), right=LB_2(Fwd)
───────────────────
LB_2 (right edge)
对齐规则
完整规则、示意图和绿色路面调试说明请参阅 references/alignmentRules.md。
对齐方式用于指定边界几何方向与车道几何方向之间的关系:
- 方向相同 →
"Forward" - 方向相反 →
"Backward"
算法选择:
- 地图转换(已知左右侧,例如来自 Lanelet2 角色)→ 使用下方的基于点积的方法
- 合成场景(需根据几何确定左右侧)→ 使用 references/alignmentRules.md 中的多点空间验证
基于点积的算法(用于转换——左右侧已知):
lDir = leftPts(end,:) - leftPts(1,:);
rDir = rightPts(end,:) - rightPts(1,:);
dp = dot(lDir(1:2)/(norm(lDir(1:2))+1e-10), rDir(1:2)/(norm(rDir(1:2))+1e-10));
if dp >= -0.3
% Normal: both boundaries go same direction
leftAlign = "Forward"; rightAlign = "Forward";
else
% Opposing boundaries: use proximity to determine which is backward
d_ls_re = norm(leftPts(1,1:2) - rightPts(end,1:2));
d_ls_rs = norm(leftPts(1,1:2) - rightPts(1,1:2));
if d_ls_re < d_ls_rs
leftAlign = "Forward"; rightAlign = "Backward";
else
leftAlign = "Backward"; rightAlign = "Forward";
end
end
阈值使用 -0.3(而不是 0),以处理边界略微弯曲的车道;这类车道可能产生小幅负点积,但方向并非真正相反。
左右侧空间验证(用于需要验证左右侧的合成场景):
nSamples = min(5, size(centerGeom,1)-1);
sampleIdx = round(linspace(2, size(centerGeom,1)-1, nSamples));
leftOnLeft = 0;
for si = 1:numel(sampleIdx)
idx = sampleIdx(si);
localTan = centerGeom(min(idx+1,end),1:2) - centerGeom(max(idx-1,1),1:2);
localTan = localTan / norm(localTan);
localLeftN = [-localTan(2), localTan(1)];
distsL = vecnorm(leftBndGeom(:,1:2) - centerGeom(idx,1:2), 2, 2);
[~, closestL] = min(distsL);
toBndL = leftBndGeom(closestL,1:2) - centerGeom(idx,1:2);
if dot(toBndL, localLeftN) > 0, leftOnLeft = leftOnLeft + 1; end
end
assert(leftOnLeft >= numel(sampleIdx)/2, ...
'Left boundary is spatially on the RIGHT — swap boundaries or fix assignment');
对齐方向错误或左右侧互换会导致出现绿色草地而不是路面。
标准标线资源
| 标线 ID | 资源路径 |
|---|---|
SolidSingleWhite | Assets/Markings/SolidSingleWhite.rrlms |
DashedSingleWhite | Assets/Markings/DashedSingleWhite.rrlms |
SolidDoubleYellow | Assets/Markings/SolidDoubleYellow.rrlms |
DashedSolidYellow | Assets/Markings/DashedSolidYellow.rrlms |
SolidDashedYellow | Assets/Markings/SolidDashedYellow.rrlms |
多车道道路配方
- 计算 N 条车道中心线(以
laneWidth为间隔均匀分布) - 计算 N+1 条边界线(道路边缘及各车道对之间的分界线)
- 分配共享边界——同向车道:车道 i 使用
left=LB_(i-1)、right=LB_i。对向车道:交换 left/right(驾驶员的左侧朝向道路边缘,而不是道路中心) - 通过点积检测方向对齐情况(边界方向与车道相同 → Forward,相反 → Backward)
- 应用标线(边缘:
SolidSingleWhite,分隔线:SolidDoubleYellow,车道分隔线:DashedSingleWhite) - 连接拓扑(如果有多个路段,使用 pred/succ 连接)
- 组装地图并写入
仅适用于转换后的地图的附加步骤(合成场景请跳过):
- 左侧间隙拓扑筛选器——参见 references/leftGapFilter.md
- 对齐相连的端点——参见 scripts/snapConnectedEndpoints.m
- 解决高度冲突——参见 scripts/resolveHeightConflicts.m
- 去重边界——参见 references/deduplicateBoundaries.md
完整的双车道道路示例
rrMap = roadrunnerHDMap;
w = 3.7;
% Lane Markings
lm1 = roadrunner.hdmap.LaneMarking; lm1.ID = "SolidWhite";
rap1 = roadrunner.hdmap.RelativeAssetPath; rap1.AssetPath = "Assets/Markings/SolidSingleWhite.rrlms";
lm1.AssetPath = rap1;
lm2 = roadrunner.hdmap.LaneMarking; lm2.ID = "DashedWhite";
rap2 = roadrunner.hdmap.RelativeAssetPath; rap2.AssetPath = "Assets/Markings/DashedSingleWhite.rrlms";
lm2.AssetPath = rap2;
% Boundaries (3 for 2 lanes)
lb = roadrunner.hdmap.LaneBoundary;
lb(2) = roadrunner.hdmap.LaneBoundary;
lb(3) = roadrunner.hdmap.LaneBoundary;
lb(1).ID = "LB_0"; lb(1).Geometry = [0 w 0; 100 w 0];
lb(2).ID = "LB_1"; lb(2).Geometry = [0 0 0; 100 0 0];
lb(3).ID = "LB_2"; lb(3).Geometry = [0 -w 0; 100 -w 0];
% Markings on boundaries
for i = [1 3] % solid on edges
pa = roadrunner.hdmap.ParametricAttribution; pa.Span = [0 1];
ref = roadrunner.hdmap.Reference; ref.ID = "SolidWhite";
mr = roadrunner.hdmap.MarkingReference; mr.MarkingID = ref; mr.FlipLaterally = false;
pa.MarkingReference = mr;
lb(i).ParametricAttributes = pa;
end
pa = roadrunner.hdmap.ParametricAttribution; pa.Span = [0 1];
ref = roadrunner.hdmap.Reference; ref.ID = "DashedWhite";
mr = roadrunner.hdmap.MarkingReference; mr.MarkingID = ref; mr.FlipLaterally = false;
pa.MarkingReference = mr;
lb(2).ParametricAttributes = pa;
% Lanes
ln = roadrunner.hdmap.Lane;
ln(2) = roadrunner.hdmap.Lane;
ln(1).ID = "Lane_1"; ln(1).Geometry = [0 w/2 0; 100 w/2 0];
ln(1).TravelDirection = "Forward"; ln(1).LaneType = "Driving";
ln(2).ID = "Lane_2"; ln(2).Geometry = [0 -w/2 0; 100 -w/2 0];
ln(2).TravelDirection = "Forward"; ln(2).LaneType = "Driving";
% Assign boundaries with alignment
bndIDs = ["LB_0","LB_1","LB_2"];
for i = 1:2
arL = roadrunner.hdmap.AlignedReference;
refL = roadrunner.hdmap.Reference; refL.ID = bndIDs(i);
arL.Reference = refL; arL.Alignment = "Forward";
ln(i).LeftLaneBoundary = arL;
arR = roadrunner.hdmap.AlignedReference;
refR = roadrunner.hdmap.Reference; refR.ID = bndIDs(i+1);
arR.Reference = refR; arR.Alignment = "Forward";
ln(i).RightLaneBoundary = arR;
end
% Assemble and write
rrMap.Lanes = ln;
rrMap.LaneBoundaries = lb;
rrMap.LaneMarkings = [lm1 lm2];
write(rrMap, "two_lane_road.rrhd");
强制检查关卡(在 write() 之前必须执行)
在写入任何多车道地图之前,运行此验证代码块。请勿跳过。如果任何检查失败,请先修复问题(运行相应的后处理步骤),然后再执行 write()。
%% --- ENFORCEMENT: Topology — no excessive connections (left-gap filter applied) ---
lanes = rrMap.Lanes;
nExcessiveJunc = 0;
for i = 1:numel(lanes)
nConn = numel(lanes(i).Predecessors) + numel(lanes(i).Successors);
if nConn > 4 % junction lanes should have at most ~4 (multi-lane merge/diverge)
nExcessiveJunc = nExcessiveJunc + 1;
end
end
if nExcessiveJunc > 0
warning('TOPOLOGY WARNING: %d lanes have >4 connections — run left-gap filter (references/leftGapFilter.md)', nExcessiveJunc);
end
fprintf('Topology check: %d lanes with >4 connections\n', nExcessiveJunc);
%% --- ENFORCEMENT: Alignment computed (not all Forward) ---
if numel(lanes) > 2
nFwd = 0; nBwd = 0;
for i = 1:numel(lanes)
if lanes(i).LeftLaneBoundary.Alignment == "Forward", nFwd = nFwd+1;
else, nBwd = nBwd+1; end
if lanes(i).RightLaneBoundary.Alignment == "Forward", nFwd = nFwd+1;
else, nBwd = nBwd+1; end
end
assert(nBwd > 0 || numel(lanes) <= 2, ...
'ALIGNMENT ERROR: All boundaries Forward for %d lanes — compute dot product per lane.', numel(lanes));
fprintf('Alignment: %d Forward, %d Backward — OK\n', nFwd, nBwd);
end
%% --- ENFORCEMENT: Left boundary spatially on left ---
bnds = rrMap.LaneBoundaries;
bndMap = containers.Map;
for i = 1:numel(bnds), bndMap(bnds(i).ID) = bnds(i).Geometry; end
nBadSide = 0;
for i = 1:numel(lanes)
lGeom = lanes(i).Geometry;
lDir = lGeom(end,1:2) - lGeom(1,1:2);
lDir = lDir / norm(lDir);
leftN = [-lDir(2), lDir(1)];
leftBndID = lanes(i).LeftLaneBoundary.Reference.ID;
if bndMap.isKey(leftBndID)
leftBndGeom = bndMap(leftBndID);
toBnd = mean(leftBndGeom(:,1:2)) - mean(lGeom(:,1:2));
if dot(toBnd, leftN) < 0, nBadSide = nBadSide + 1; end
end
end
assert(nBadSide == 0, ...
'SPATIAL ERROR: %d lanes have left boundary on wrong side — fix alignment algorithm.', nBadSide);
fprintf('Spatial left-side check: PASS\n');
%% --- ENFORCEMENT: Geometry is Nx3 ---
bnds = rrMap.LaneBoundaries;
for i = 1:numel(bnds)
assert(size(bnds(i).Geometry, 2) == 3, ...
'Boundary %s geometry must be Nx3 (got Nx%d)', bnds(i).ID, size(bnds(i).Geometry,2));
end
fprintf('Geometry dimensions: PASS\n');
%% --- ENFORCEMENT: GeoReference set ---
assert(any(rrMap.GeoReference ~= 0), 'GeoReference is [0,0] — set lat/lon origin');
fprintf('GeoReference: PASS\n');
%% --- ENFORCEMENT: No duplicate boundaries (deduplication applied) ---
bnds = rrMap.LaneBoundaries;
nDupBnd = 0;
for i = 1:numel(bnds)
for j = i+1:numel(bnds)
g1 = bnds(i).Geometry; g2 = bnds(j).Geometry;
if size(g1,1) ~= size(g2,1), continue; end
if max(vecnorm(g1 - flipud(g2), 2, 2)) < 0.001
nDupBnd = nDupBnd + 1; break;
end
end
if nDupBnd > 5, break; end % early exit for performance
end
if nDupBnd > 0
warning('DEDUP WARNING: Found reversed-duplicate boundaries — run deduplicateBoundaries (references/deduplicateBoundaries.md)');
end
fprintf('Boundary deduplication check: %d duplicates found\n', nDupBnd);
后处理(必须按顺序在 write() 之前执行)
左侧间隙拓扑筛选器(转换后的地图必须执行)
移除由共享边界端点节点导致的错误前驱/后继连接。对于具有多个后继(或前驱)的每条车道,计算左边界间隙——如果任一连接的间隙小于 3m,且其他连接的间隙大于 3m,则移除较远的连接。**如果不执行此步骤,路口车道的连接数量会多出 2 到 4 倍。**参见 references/leftGapFilter.md。
端点对齐
对于相连的车道(pred/succ),将后继车道的起点对齐到前驱车道的终点。参见 scripts/snapConnectedEndpoints.m 和 references/snapEndpoints.md。
高度冲突解决
Z 坐标相同且互不相连的重叠车道会产生草地伪影。使用图着色法分配 Z 高度层级。参见 scripts/resolveHeightConflicts.m 和 references/resolveHeights.md。
边界去重(转换后的地图必须执行)
从为对向车道分别分配边界对象的源格式(Lanelet2、HERE、NDS 等)构建地图时,扫描所有边界对,查找几何形状相同的边界(正向或反向,容差为 1mm)。合并重复项,并以翻转后的对齐方向更新车道引用。**如果不执行此步骤,共享边界会渲染出重复的标线。**参见 references/deduplicateBoundaries.md。
其他实体类型
所有实体类(Signs、Signals、Barriers、Parking、CurveMarkings、StencilMarkings、StaticObjects、LaneGroups)的属性说明,请参见 references/apiReference.md 中的类/属性表。按任务查阅的关键参考资料:
主要功能
| 功能 | 用途 |
|---|---|
roadrunnerHDMap | 创建 HD Map 对象(加载命名空间) |
read(rrMap, file) | 读取现有的 .rrhd 文件 |
write(rrMap, file) | 将 HD Map 写入 .rrhd 文件 |
roadrunner.hdmap.Lane | 车道实体(Geometry、TravelDirection、LaneType) |
roadrunner.hdmap.LaneBoundary | 边界实体(Geometry、ParametricAttributes) |
roadrunner.hdmap.LaneMarking | 标线定义(ID、AssetPath) |
roadrunner.hdmap.Junction | 路口区域(Geometry 为 MultiPolygon) |
roadrunner.hdmap.AlignedReference | 带对齐信息的参考对象(Name=Value 构造方式) |
roadrunner.hdmap.RelativeAssetPath | 资源路径包装器(Name=Value 构造方式) |
roadrunner.hdmap.ParametricAttribution | 标线放置方式(Span、MarkingReference) |
已知限制
- SignalTypes/Signals 在 MATLAB 中经过 RRHD 写入/读取后会保留,但 RoadRunner 会在导入场景时静默忽略它们——信号不会显示在 RoadRunner 场景中
- RoadRunner 无法渲染首尾相连的车道;请使用 N 路正交算法进行拆分(参见 references/orthogonalSplit.md)
- Geometry 必须始终为 Nx3(若为平面,则包含 Z=0)
- 对于赛道地图(闭环椭圆形赛道):省略拓扑(Predecessors/Successors)、Z 方向的凸起和标线属性(ParametricAttribution)——参见 orthogonalSplit.md 中的赛道专用指南
约定
- 对
roadrunner.hdmap.*对象始终采用先创建、后赋值的模式 - 使用
RelativeAssetPath(AssetPath="...")和AlignedReference(Reference=ref, Alignment="...")——仅使用 Name=Value 方式 - 对于类型化空数组,使用
ClassName.empty,切勿使用[] - 所有几何数据均为带 Z 列的 Nx3(平坦地形的默认值为 0)
- 共享边界:每条边界使用一个对象,多个车道通过不同的对齐信息引用该对象
版权所有 2026 The MathWorks, Inc.