1. Lanelet2 地图概述
1.1 核心概念
Lanelet2 将道路网络表达为车道片段的组合:
- Lanelet(车道片段):左右边界围成的可通行区域,包含方向、参与者类型、区域属性、车道类型等信息
- Area(区域):停车区、绿化带、建筑物、交通岛等环境要素
- RegulatoryElement(规则元素):将交通标志、信号灯、让行规则、限速等与车道关联
应用场景:
- 路径规划:在车道拓扑图上搜索可行路线
- 规则约束:推断通行权限、变道规则、限速、路口约束
- 定位匹配:将车辆位姿匹配到车道,获取沿程坐标
2. OSM XML 基础
核心元素:
<node>:点(WGS84 经纬度),可带 tag 属性<way>:有序点序列,表达线或面轮廓<relation>:多个元素的组合,表达 lanelet、multipolygon、regulatory element<tag>:键值对属性
2.1 坐标与单位
lat/lon:地理坐标(度),内部投影到局部平面(如 UTM)ele:高程(米)speed_limit:建议带单位(如50 km/h)
2.2 ID 与引用
- node/way/relation 的 ID 分别独立编号,允许重复
- 引用时用
type+ref组合唯一标识 - 解析时应使用(type, id)作为唯一键
3. 语义层映射
Lanelet2 将 OSM 元素映射为基本元素(点、线、车道、区域、规则)。
关键区别:
- 结构属性(Attributes):XML 结构定义(id、坐标、成员引用)
- 语义标签(Tags) :
<tag>定义对象含义、类型、规则
3.1 LineString ↔ OSM Way
- Lanelet2 的 LineString(线) 用
<way>表达:由若干<nd ref=.../>连接成有序折线 <way>上的type/subtype等标签决定它的角色(边界线、标志、信号灯、路面符号等)
3.2 Polygon ↔ OSM Way(带 area=yes)
- 多边形也可以用
<way>表达,但需要area=yes(仅首尾点相同并不充分也不必要;Lanelet2 使用area=yes判断)。
3.3 Lanelet ↔ OSM Relation(type=lanelet)
Lanelet2 maps 文档定义 lanelet relation 的成员角色(role)与约束:
type=lanelet的<relation>必须包含:role=left的成员:type=way,表示左边界role=right的成员:type=way,表示右边界- (可选)
role=centerline的成员:type=way,表示中心线 - (可选、可多)
role=regulatory_element的成员:type=relation,引用规则元素
- 如果 lanelet relation 的成员超出上述集合,Lanelet2 会报错(这是非常重要的"格式硬约束")。
方向性:lanelet 的"行驶方向"由左右边界的点序以及 lanelet 几何关系推断;并由
one_way(及其分参与者变体)进一步约束,详见 §5。
3.4 Area ↔ OSM Relation(type=multipolygon)
- Area 使用 OSM 的 multipolygon 表达:
<relation>带type=multipolygon。 role=outer:外边界(有序列表,可能由多个 way 拼接)。role=inner:内孔边界(同样是有序列表)。- Lanelet2 会按 inner 的顺序解析,当某条 inner linestring 的末点与下一条 inner 的首点相同时,会认为这在描述同一个孔的拼接;当不连续时,开始一个新孔。
3.5 Regulatory Element ↔ OSM Relation(type=regulatory_element)
- Regulatory element 使用 relation:
type=regulatory_element。 - relation 的成员(parameters)使用
role字符串表示其语义(例如refers/ref_line/yield/right_of_way等)。 - Lanelet2 maps 文档指出:没有 type 或 type 错误的 relation 会在解析
.osm时被忽略。
3.6 Lanelet2 基本元素与 OSM 元素映射详解
本节深入解释 Lanelet2 基本元素(点、线、多边形)与 OSM 元素之间的映射细节,这些细节对于正确理解地图数据至关重要。
3.6.1 Point 与 OSM Node 的映射
基本映射:
- Lanelet2 的 Point 用
<node>表达 lat/lon是点的几何属性(WGS84 经纬度)eletag 用于表示 z 坐标(高程),单位通常为米,表示距地球椭球面的高度
Node 的语义标签 :
Node 可以带有 type tag 来标注特殊语义点(这些点仍然是 linestring 的组成部分,但带有额外的语义信息):
type=begin:标记虚线 dash 的起始点(沿 linestring 方向)type=end:标记虚线 dash 的结束点type=pole:标记护栏/围栏的立柱位置type=dot:标记点状标线
这类语义点用于高精细度可视化或更精确的规则/感知仿真,但不影响基本的几何表达。
3.6.2 LineString 与 OSM Way 的映射
基本映射:
- Lanelet2 的 LineString (线)用
<way>表达 - way 由有序的
<nd ref=.../>连接成折线
关键概念:中心线语义 (官方文档明确强调)
Linestrings are generally characterized by their centerline.
核心要点:
- Way 默认代表对象的中心线,而非边缘或轮廓
- 车道边界线 (
type=line_thin):way 为标线中心轴 - 护栏 (
type=guard_rail):way 为护栏中轴线 - 墙体 (
type=wall):way 为墙体中轴线
Width 和 Height 的语义:
-
width(单位:米):描述对象在垂直于 way 方向的宽度- way 仍然代表中心线(不是边缘)
- 例如:
type=wall, width=0.3表示墙体宽 30cm,way 是墙体中轴
-
height(单位:米):描述对象在垂直方向的高度- 特殊语义:way 代表对象的下沿/最低边(与 width 不同!)
- 例如:
type=traffic_sign, height=0.8表示标志牌高 80cm,way 是标志底边 - 注意:这里的 height 是对象自身高度,不是离地高度(离地高度应通过 z 坐标/ele 表达)
轮廓表达的例外情况 :
对于某些对象(如 traffic_sign、traffic_light),可以用以下两种方式表达:
- 轮廓方式:way 包含多个点围成多边形轮廓(通常用于精确建模)
- 两点线段方式 :way 只有两个点
- 首点 = 对象左边缘
- 末点 = 对象右边缘
- 配合
heighttag 表达对象尺寸
建议:用两点线段方式时,确保 way 只有两个点,避免与轮廓方式混淆。
3.6.3 Polygon 与 OSM Way 的映射
单个多边形:
- Lanelet2 的 Polygon (多边形)用
<way>+area=yestag 表达 - 重要 :仅凭首尾点相同不足以判定为多边形(也不是必要条件)
- Lanelet2 使用
area=yestag 明确判断该 way 是否为多边形
带孔的复杂多边形:
- 使用
type=multipolygon的 relation 表达(详见 §3.4)
3.6.4 Attributes 与 Tags 的区别(重要)
理解这个区别对于正确理解 Lanelet2 数据模型至关重要:
| 属性类型 | 定义位置 | 示例 | 作用 |
|---|---|---|---|
| Attributes | OSM XML 结构 | id, lat, lon, ref, role, type(member 的 type) | 定义对象的结构关系 |
| Tags | <tag k=... v=.../> |
type(tag 的 type), subtype, location, speed_limit | 定义对象的语义 |
易混淆点:
<member type='way' ...>:这里的type是 attribute(表示成员类型)<tag k='type' v='lanelet'/>:这里的type是 tag(表示语义类型)- 两者完全不同,不要混淆
实例对比:
xml
<!-- Attribute 示例:id, lat, lon 是结构属性 -->
<node id='1001' lat='49.0' lon='8.4' />
<!-- Tag 示例:type/subtype 是语义属性 -->
<way id='2001'>
<nd ref='1001' />
<nd ref='1002' />
<tag k='type' v='line_thin' />
<tag k='subtype' v='solid' />
</way>
<!-- Member 的 type attribute vs Tag 的 type -->
<relation id='3001'>
<member type='way' ref='2001' role='left' /> <!-- type 是 attribute -->
<tag k='type' v='lanelet' /> <!-- type 是 tag -->
</relation>
3.6.5 基本元素映射总结表
| Lanelet2 基本元素 | OSM 元素 | 关键标识 | 几何语义 |
|---|---|---|---|
| Point | <node> |
lat, lon, (ele) | 点坐标 |
| LineString | <way> |
有序 <nd> 序列 |
默认为中心线 |
| Polygon | <way> |
area=yes tag |
闭合区域 |
| Lanelet | <relation> |
type=lanelet tag |
左右边界围成的车道片段 |
| Area | <relation> |
type=multipolygon tag |
外边界 + 内孔 |
| RegulatoryElement | <relation> |
type=regulatory_element tag |
规则元素 |
4. "最小可用"Lanelet2-OSM
如果你只想最快把一张 Lanelet2-OSM 地图读进来并用于规划/定位,至少确保:
- 有 lanelet relation:
<relation><tag k='type' v='lanelet'/> ...</relation> - 每个 lanelet relation 至少有
left/right两个边界 way 成员(role 必须正确) - 车道边界 way 带
type(例如line_thin/curbstone/road_border/virtual),否则 Lanelet2 很可能默认"不可变道" - lanelet 上的
subtype/location/one_way/participant:*至少能推断出:- 行驶方向(one_way)
- 允许参与者(participant)
- 限速(speed_limit 或基于 location/subtype 的默认推断,或 regulatory element)
- 路口规则(红绿灯/让行/停止线/限速牌)用 regulatory element 关联到 lanelet
4.1 一个"最小 lanelet"的 OSM/XML 示例
下面示例只展示 Lanelet2-OSM 的结构:两个边界 way + 一个 lanelet relation(真实地图需要更多点、更合理的几何与规则元素)。
xml
<osm version='0.6' generator='example'>
<node id='1' lat='49.0000000' lon='8.0000000' />
<node id='2' lat='49.0000100' lon='8.0000000' />
<node id='3' lat='49.0000000' lon='8.0000100' />
<node id='4' lat='49.0000100' lon='8.0000100' />
<way id='10'>
<nd ref='1' /><nd ref='2' />
<tag k='type' v='line_thin' />
<tag k='subtype' v='solid' />
</way>
<way id='11'>
<nd ref='3' /><nd ref='4' />
<tag k='type' v='line_thin' />
<tag k='subtype' v='dashed' />
</way>
<relation id='100'>
<member type='way' ref='10' role='left' />
<member type='way' ref='11' role='right' />
<tag k='type' v='lanelet' />
<tag k='subtype' v='road' />
<tag k='location' v='urban' />
<tag k='one_way' v='yes' />
<tag k='region' v='de' />
</relation>
</osm>
5. Lanelet / Area 的标签
这一部分来自 LaneletAndAreaTagging.md,强调一个核心原则。
5.0 自洽性原则
核心要求:每个 Lanelet/Area 必须包含完整交通规则,无需依赖相邻元素。
必须可确定的信息:
- 行驶方向 :通过
one_way确定,默认单向 - 通行参与者 :通过
subtype+location推断或participant:*指定 - 限速:通过标签、规则元素或默认值确定
设计目的:
- 避免推断歧义,保证数据一致性
- 支持独立解析和分布式处理
- 提高鲁棒性
5.1 关键标签:subtype 与 location
subtype:描述 lanelet 的类型(road/highway/bicycle_lane/crosswalk/...)location:区分 urban / nonurban(影响默认限速等)
文档给出"默认推断表"(注意:最终解释依赖所选 TrafficRules 实现):
subtype=road, location=urban:城市道路(车辆与自行车,城市默认限速)subtype=highway:高速(通常仅车辆,不同地区默认/建议限速不同)subtype=bicycle_lane:自行车道(自行车)subtype=walkway/crosswalk:人行相关(行人)- 以及 bus_lane、play_street、shared_walkway、stairs 等
5.2 覆盖机制:participant:* 与 speed_limit*
需显式覆盖默认推断时,使用以下标签:
交通参与者覆盖 (官方文档明确强调):
- 使用格式:
participant:<participant>=yes/no(例如participant:vehicle:bus=yes) - 关键约束 (官方原文用词:"ignored"):
- 一旦使用任何一个交通参与者覆盖标签,subtype/location 的推断将被完全忽略
- 所有未显式设置的交通参与者默认为 no(不允许通行)
- 必须逐个显式设置允许通行的交通参与者
示例:
participant:vehicle:bus=yes
participant:vehicle:taxi=yes
participant:pedestrian=yes
含义:只允许公交车、出租车和行人通行,其他所有交通参与者(如私家车、货车、自行车)都不允许
可用的交通参与者类型(层级结构):
vehicle(影响所有机动车参与者) 或vehicle:car或vehicle:car:electricvehicle:car:combustion
vehicle:busvehicle:truckvehicle:motorcyclevehicle:taxivehicle:emergency
pedestrianbicycle
重要规则:
vehicletag 不能与任何vehicle:xxxtag 组合使用- 如果定义了任何一个
vehicle:xxxtag,所有其他vehicle:xxxtag 必须单独设置
限速覆盖:
speed_limit:值可带单位(如50 km/h),无单位默认 km/hspeed_limit_mandatory:yes/no(默认 yes)- 也可以按参与者细分:
speed_limit:<participant>、speed_limit_mandatory:<participant> - 注意:限速也可能被 regulatory elements 覆盖(例如 speed_limit regulatory element)
官方建议 :
尽量避免使用覆盖机制。更清晰的方式是:
- 创建新的
TrafficRule类来支持未涵盖的道路类型 - 使用规则元素 (
RegulatoryElement) 表达特殊规则
5.3 方向性:one_way 与 one_way:<participant>
- Lanelet 默认"单向"。
one_way=no表示双向。- 可按参与者细分:
one_way:bicycle=no等。 one_way与one_way:xxx不能混用。- 行人默认可双向(除非覆盖)。
5.4 其他可选标签
来自文档的常见建议:
road_name:道路名称road_surface:路面类型(asphalt/concrete/dirt...)region:ISO 3166-2 国家/地区代码(例如de),TrafficRules 可能据此确认适用性
5.5 TrafficRules 机制与覆盖优先级
Lanelet2 采用"数据与解释分离"的设计:地图数据(tags)只表达"是什么"(描述性),而 TrafficRules 实现负责"如何解释"(规则引擎)。
TrafficRules 的作用:
- TrafficRules 是 Lanelet2 的规则解释引擎,位于
lanelet2_traffic_rules库 - 同一份地图数据,在不同国家/地区的 TrafficRules 实现下可能得到不同的解释
- 例如:
subtype=road, location=urban在德国可能推断为 50 km/h 限速,在美国可能是不同值
覆盖优先级链(从高到低):
┌─────────────────────────────────────────┐
│ 1. Regulatory Element(最高优先级) │
│ - speed_limit regulatory element │
│ - traffic_light regulatory element │
│ - right_of_way regulatory element等 │
├─────────────────────────────────────────┤
│ 2. Lanelet 显式覆盖 Tags │
│ - speed_limit=60 km/h │
│ - participant:vehicle:bus=yes │
│ - one_way:bicycle=no │
├─────────────────────────────────────────┤
│ 3. subtype/location 默认推断 │
│ - 依赖 TrafficRules 实现 │
│ - 不同国家/地区可能不同 │
└─────────────────────────────────────────┘
实例说明 :
假设某 lanelet 有以下标签:
subtype=road
location=urban
speed_limit=60 km/h
并且被一个 speed_limit regulatory element 引用,该元素指定 sign_type=30 km/h。
最终生效的限速为 30 km/h(regulatory element 优先级最高)。
region tag 的作用:
regiontag(如region=de、region=cn)用于标识地图所属的国家/地区- TrafficRules 实现可以通过
region判断是否适用(例如德国规则要求region=de) - 建议:同一地图内统一使用相同的 region,避免跨地区混用导致规则冲突
交通参与者覆盖的"全有或全无"原则 :
一旦使用任何一个 participant:xxx=yes:
- subtype/location 的交通参与者推断被完全忽略
- 所有未设置的交通参与者默认为 no
- 必须逐个显式设置所有允许的交通参与者
5.6 兼容性提示:布尔值写法
官方文档多使用 yes/no 表达布尔值;但在 mapping_example.osm 中,one_way 出现了 false(与 no 等价的语义)。这说明在实际数据链路中你可能会遇到 true/false 与 yes/no 混用:
- 做解析器/校验器时,建议把
yes/true/1视为真,把no/false/0视为假(并在导出时统一成一种写法)。 - 做建图规范时,建议团队统一为
yes/no(更贴近 OSM 生态习惯)。
6. Linestring(OSM Way)标签:边界/符号/标志/信号灯
本节来自 LinestringTagging.md,并结合示例文件中出现的类型做解释。
6.1 车道边界(Lane Boundary)类型与变道推断
Lanelet2 用边界线的 type/subtype 来判断能否变道;若无法判断,默认不可变道。
典型边界类型(文档表格):
| type | subtype | 含义 | 默认变道 |
|---|---|---|---|
| line_thin | solid | 实线 | 否 |
| line_thin | dashed | 虚线 | 是 |
| line_thin | dashed_solid | 左虚右实 | 左→右可变(从虚线侧跨越) |
| line_thin | solid_dashed | 左实右虚 | 右→左可变 |
| line_thin | solid_solid | 双实线 | 否 |
| line_thick | 同上 | 粗线同理 | 依 subtype |
| curbstone | high | 高路沿 | 否 |
| curbstone | low | 低路沿(可跨越) | 否(注意:可跨越 ≠ 允许变道) |
| virtual | - | 非物理边界(多用于路口) | 否 |
| road_border | - | 道路边界(通常是可通行区域的边界) | 否 |
6.1.1 强制覆盖变道(lane_change)
如果你不满意默认推断,可用:
lane_change=yes(双向可变)或lane_change:left=<yes/no>与lane_change:right=<yes/no>(必须两者都设)
这在"线型看起来不允许变道但业务想允许"的场景很常用;反之也可用来禁止虚线变道。
6.1.2 其他常见边界类型
这些类型默认都表示不可变道/不可跨越(具体可通行性仍依 TrafficRules 与几何):
guard_rail, wall, fence, keepout, jersey_barrier, gate, door, rail 等。
6.2 可选几何尺寸标签:width / height
当线表示的是"有宽度/高度"的实体(护栏、墙、标志牌等):
width:单位 m,linestring 表示对象中心线height:单位 m,linestring 表示对象的下沿/最低边temporary=yes/no:施工临时标线color:标线颜色(默认 white)
6.2.1 "虚线的每一段"如何表达(Individual Dashes)
Lanelet2 文档指出:虚线在几何上通常仍用一条连续折线表达,会丢失"每一段 dash 的起止位置"。若要保留,可在 dash 的起止点打点(OSM node),并用 node 的 type 标注:
type=begin:某一段 dash 的开始点(沿 linestring 方向)type=end:某一段 dash 的结束点- 也可扩展:
type=pole(护栏/围栏的立柱点)、type=dot(点状标线)
这类 node 是"附加语义点",常用于高精细可视化或更精确的规则/感知仿真。
6.3 路面符号(Symbols)
文档给出常见符号表达方式:
- 箭头:
type=arrow+subtype=left/right/straight/... - 其他:
stop_line,zig-zag,lift_gate,bump, 以及30/50/70等限速文字
符号既可用轮廓(多点)表示,也可用中心线(两点)表示;用中心线时建议仅两点以免与轮廓混淆。
6.4 交通标志(Traffic Signs)
type=traffic_signsubtype=<region+编号>:ISO 3166 区域码 + 交通标志编号- 示例(文档):
subtype=de206(德国 stop),或subtype=usR1-1(美国 stop)
- 示例(文档):
几何表示:
- 可用多边形轮廓表示(way 多点)
- 或用折线表示(way 的首点为标志左下边缘,末点为右下边缘),可配合
height表示标志尺寸;注意:height在此语境是标志自身高度,不是离地高度(离地高度应通过 z/ele 或其他约定表达)。
6.5 交通信号灯(Traffic Lights)
type=traffic_lightsubtype可描述灯型:red_yellow_green/red_yellow/red/ ...- 同样可用轮廓或折线表达
7. RegulatoryElement(规则元素)
7.1 核心约束
双向引用(重要):
- 规则元素与 lanelet/area 必须相互引用
- 单向引用会导致规则失效
示例:
xml
<!-- 正确:双向引用 -->
<relation id='100'> <!-- lanelet -->
<member type='way' ref='10' role='left' />
<member type='way' ref='11' role='right' />
<member type='relation' ref='200' role='regulatory_element' /> <!-- 引用规则 -->
<tag k='type' v='lanelet' />
</relation>
<relation id='200'> <!-- regulatory element -->
<member type='relation' ref='100' role='yield' /> <!-- 引用 lanelet -->
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='right_of_way' />
</relation>
<!-- 错误:仅单向引用 -->
<relation id='100'> <!-- lanelet,缺少对规则的引用 -->
<member type='way' ref='10' role='left' />
<member type='way' ref='11' role='right' />
<!-- 缺少 regulatory_element 成员! -->
<tag k='type' v='lanelet' />
</relation>
<relation id='200'> <!-- regulatory element -->
<member type='relation' ref='100' role='yield' />
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='right_of_way' />
</relation>
通用标签:
Regulatory element relation:
type=regulatory_element(缺失时 Lanelet2 写回.osm会补齐)subtype:基本类型之一:traffic_signtraffic_lightspeed_limitright_of_wayall_way_stop
可选标签(默认值以粗体为准):
dynamic(yes/no):动态规则(详见 §7.1.1)fallback(yes/no):低优先级规则(详见 §7.1.1)
7.1.1 Dynamic 与 Fallback 的实际应用
Dynamic 规则(dynamic=yes):
定义:表示此规则元素的含义可能根据条件变化(官方原文:"might change its meaning based on a condition")。
典型应用场景:
-
可变限速:
- 电子显示屏限速(雨天降速、雪天降速)
- 示例:晴天 80 km/h,雨天 60 km/h
-
时段限制:
- 公交专用道(7-9点、17-19点限制)
- 示例:工作日早晚高峰仅公交/出租车可用,其他时段所有车辆可用
-
临时封路:
- 施工期间封闭
- 活动/赛事期间临时改道
处理建议:
- 地图数据 :标记
dynamic=yes,表达"规则会变",但不在地图中硬编码具体条件 - 运行时:TrafficRules 需要外部输入(当前时间/天气/V2X 信息等)来解析当前有效规则
- Lanelet2 默认行为 :默认 TrafficRules 实现会忽略
dynamic=yes的规则(需自定义 TrafficRules 才能处理)
示例:
xml
<relation id='300'>
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='speed_limit' />
<tag k='sign_type' v='80 km/h' /> <!-- 基准值,实际由外部系统提供 -->
<tag k='dynamic' v='yes' /> <!-- 标记为动态规则 -->
</relation>
Fallback 规则(fallback=yes):
定义:表示此规则元素的优先级低于其他规则元素(官方原文:"has a lower priority than another Regulatory Element")。
典型应用场景:
-
路口备用规则:
- 主规则:信号灯(
fallback=no) - 备用规则:让行规则(
fallback=yes),仅当信号灯故障时生效
- 主规则:信号灯(
-
限速备用:
- 主规则:电子限速牌(
fallback=no) - 备用规则:固定限速牌(
fallback=yes),仅当电子牌故障时生效
- 主规则:电子限速牌(
处理逻辑:
- 同一 lanelet 可能被多个 regulatory element 引用(一个主规则 + 多个 fallback 规则)
- TrafficRules 应优先解析
fallback=no的规则 - 当主规则不可用/不适用时(如信号灯状态未知、电子牌离线),启用
fallback=yes的规则
示例:
xml
<!-- 主规则:信号灯 -->
<relation id='400'>
<member type='way' ref='...' role='refers' />
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='traffic_light' />
<tag k='fallback' v='no' /> <!-- 默认值,可省略 -->
</relation>
<!-- 备用规则:让行 -->
<relation id='401'>
<member type='relation' ref='...' role='yield' />
<member type='relation' ref='...' role='right_of_way' />
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='right_of_way' />
<tag k='fallback' v='yes' /> <!-- 低优先级,信号灯故障时生效 -->
</relation>
<!-- 受控 lanelet 引用两个规则 -->
<relation id='500'>
<member type='way' ref='...' role='left' />
<member type='way' ref='...' role='right' />
<member type='relation' ref='400' role='regulatory_element' /> <!-- 主规则 -->
<member type='relation' ref='401' role='regulatory_element' /> <!-- 备用规则 -->
<tag k='type' v='lanelet' />
</relation>
7.2 parameters(成员)与通用 role
Regulatory element 的成员称为 parameters,通过 <member ... role='...'/> 表达。通用 role:
refers:规则来源(标志/信号灯等)cancels:规则结束标志(若适用)ref_line:规则生效/停止线(常为 stop_line 线)cancel_line:规则失效线(若适用)
7.2.1 role 是"字符串协议"
Regulatory element 的 role 本质上是字符串协议:TrafficRules/相关算法会按约定字符串查找参数。因此:
- role 名称必须与文档/实现一致(例如
ref_line不是refline) - 建图时建议复用官方文档中的 role 字符串;新增自定义 role 时需要同步实现对应的 TrafficRule/RegulatoryElement 逻辑
7.3 常见规则元素的结构
下面给出文档中的典型结构(并在 §9 对应到 mapping_example.osm 的真实片段)。
7.3.1 Traffic Light(subtype=traffic_light)
refers:信号灯(通常是type=traffic_light的 way)ref_line:停止线(可选;缺失时默认为 lanelet/area 末端)
官方示例:
xml
<relation id='1'>
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='traffic_light' />
<member type='way' ref='2' role='ref_line' />
<member type='way' ref='3' role='refers' />
</relation>
7.3.2 Speed Limit(subtype=speed_limit)
两种方式:
- 由限速牌构成:
refers指向type=traffic_sign的 way,TrafficRules 从 traffic_sign 的subtype解释出具体限速。 - 非标志来源:在 regulatory element 上用
sign_typetag 直接写速度(值带单位,如50 km/h;无单位默认 km/h)。
官方示例(由标志构成):
xml
<relation id='1'>
<tag k='subtype' v='speed_limit' />
<tag k='type' v='regulatory_element' />
<member type='way' ref='2' role='refers' />
</relation>
7.3.3 Traffic Sign(subtype=traffic_sign)
通用交通标志规则(不限于限速):
refers:构成规则的标志cancels:结束标志(如"解除禁止超车")ref_line/cancel_line:精确定义生效/失效位置
文档还强调:若 ref_line/cancel_line 与所引用 lanelet/area 有交点,则规则生效区间可按交点裁切;否则规则可能作用于整条 lanelet/area(具体实现依 TrafficRules)。
7.3.4 Right of Way(subtype=right_of_way)
用于修改路口默认"先到先行"的规则。roles:
yield:需要让行的 lanelet(member type=relation,引用 lanelet relation)right_of_way:拥有优先权的 lanelet(同上)ref_line:让行 lanelet 的停车/让行线(可选;缺失则为 yield lanelet 末端)
重要一致性约束:被 right_of_way 规则引用到的 lanelet,通常也需要在 lanelet 自身通过
role=regulatory_element引用该规则元素(形成双向关联),文档明确指出这一点。
7.3.5 All Way Stop(subtype=all_way_stop)
四向停止等场景:让行顺序取决于到达顺序与路线。
roles:
yield:所有可能需要让行的 lanelet(通常是路口各入口 lanelet)refers:构成规则的 stop 标志牌ref_line:每个 yield lanelet 对应的停止线
关键约束(官方文档明确强调):
为了避免停止线与 lanelet 的匹配歧义,All Way Stop 规则元素的 ref_line 必须满足以下条件之一:
- 所有 yield lanelet 都没有 ref_line(停止位置默认为 lanelet 末端)
- 每个 yield lanelet 恰好对应一个 ref_line ,且
ref_line的顺序与yieldlanelet 的顺序一一对应
错误示例:
xml
<!-- 错误:4个 yield lanelet 但只有2个 ref_line,无法确定对应关系 -->
<relation id='600'>
<member type='relation' ref='701' role='yield' />
<member type='relation' ref='702' role='yield' />
<member type='relation' ref='703' role='yield' />
<member type='relation' ref='704' role='yield' />
<member type='way' ref='510' role='ref_line' /> <!-- 缺少2个 -->
<member type='way' ref='511' role='ref_line' />
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='all_way_stop' />
</relation>
正确示例:
xml
<!-- 正确:4个 yield lanelet 对应4个 ref_line,顺序一致 -->
<relation id='600'>
<member type='relation' ref='701' role='yield' /> <!-- 对应 ref_line 510 -->
<member type='relation' ref='702' role='yield' /> <!-- 对应 ref_line 511 -->
<member type='relation' ref='703' role='yield' /> <!-- 对应 ref_line 512 -->
<member type='relation' ref='704' role='yield' /> <!-- 对应 ref_line 513 -->
<member type='way' ref='510' role='ref_line' />
<member type='way' ref='511' role='ref_line' />
<member type='way' ref='512' role='ref_line' />
<member type='way' ref='513' role='ref_line' />
<tag k='type' v='regulatory_element' />
<tag k='subtype' v='all_way_stop' />
</relation>
官方原文强调(RegulatoryElementTagging.md):
"To avoid confusion when matching lanelets and stop lines, an All Way Stop regelem is only valid if either no lanelet has a stop line or all lanelets have exactly one."
7.4 常见规则元素组合错误
基于官方文档和实践经验,以下是最常见的 regulatory element 使用错误:
| 错误类型 | 表现 | 排查方法 | 正确做法 |
|---|---|---|---|
| 错误1:单向引用 | TrafficRules 未发现规则 | 检查 lanelet 是否包含 role=regulatory_element 成员 |
确保双向引用(见 §7.1) |
| 错误2:ref_line 不相交 | 停止线位置推断失败 | 检查 ref_line 与 yield lanelet 是否有交点 | ref_line 应横跨或至少触及 lanelet 几何 |
| 错误3:All Way Stop 匹配失败 | 解析错误或停止线对应错误 | 检查 yield lanelet 数量与 ref_line 数量 | 要么全无 ref_line,要么数量、顺序一致(见 §7.3.5) |
| 错误4:traffic_sign subtype 无法解释 | 限速/禁令未生效 | 检查 TrafficRules 是否支持该 subtype | 使用 sign_type tag 作为兜底(见 §7.3.2) |
| 错误5:多个规则冲突 | 规则优先级不明确 | 检查是否有多个非 fallback 规则作用于同一 lanelet | 使用 fallback=yes 明确优先级(见 §7.1.1) |
| 错误6:dynamic 规则被忽略 | 动态限速未生效 | 检查 TrafficRules 是否实现了 dynamic 规则处理 | 默认 TrafficRules 会忽略 dynamic,需自定义实现 |
错误诊断示例:
场景:限速规则未生效
排查步骤:
-
检查 regulatory element 是否被 lanelet 引用
bash# 在 .osm 文件中搜索 lanelet relation,查看是否包含该 regulatory element grep -A 20 "relation id='<lanelet_id>'" map.osm | grep "regulatory_element" -
检查 traffic_sign subtype 是否可解释
bash# 查看 traffic_sign 的 subtype grep -A 5 "way id='<sign_id>'" map.osm | grep "subtype" # 确认 TrafficRules 是否支持该 subtype,或使用 sign_type 兜底 -
检查是否有多个限速规则冲突
bash# 查找所有引用该 lanelet 的 speed_limit 规则 grep -B 5 "ref='<lanelet_id>'" map.osm | grep "speed_limit"
8. 格式硬约束
- lanelet 成员仅限:
left/right/centerline(way)和regulatory_element(relation) - Area 使用
type=multipolygon,按点连接顺序解析孔洞 - relation 必须有正确的
type,否则被忽略 - Tag key 使用小写
8.1 共享边界与车道拓扑
核心机制 :相邻车道共享边界 way,一个车道的 right 同时是另一个的 left。
影响:
- 变道图建立(左右邻接关系)
- 边界连续性保证
- 变道规则推断(根据共享边界的线型)
9. 官方示例解读
样例文件:
mapping_example.osm:完整示例(lanelet/multipolygon/regulatory_element等)mapping_example-debug.osm:调试输出(routing_cost、拓扑关系)
官方路径:
- GitHub仓库:Lanelet2/lanelet2_maps
- 示例文件位置:
lanelet2_maps/res/mapping_example.osm - 完整URL:https://github.com/fzi-forschungszentrum-informatik/Lanelet2/blob/master/lanelet2_maps/res/mapping_example.osm
9.1 全局统计(快速建立直觉)
mapping_example.osm:
- 元素数量:
node=2258, way=1141, relation=456 - 地理范围(WGS84):lat 约
49.0018~49.0111,lon 约8.4119~8.4588 - 出现的 tag keys(按 node/way/relation 汇总):
type/subtype/location/region/one_way/participant:*,以及ele、fallback
mapping_example-debug.osm:
- 元素数量:
node=328, way=436 - 主要 tag keys:
relation,relation_reverse,routing_cost,routing_cost_reverse(用于表达路由图边/代价)
9.2 这个样例里有哪些 lanelet / area / rules?
relation(按 type/subtype)的主要分布:
- lanelet:
subtype=road(最多)subtype=bicycle_lane/crosswalk/highway/rail/walkway等
- multipolygon:
vegetation/walkway/parking/traffic_island/building/exit/keepout等
- regulatory_element:
traffic_lightright_of_wayspeed_limit
9.3 lanelet relation 的成员形态(与 lanelet2_maps 规则一致)
在 mapping_example.osm 中,lanelet 的成员 role 统计(可见其结构非常"规整"):
left:371 次right:371 次regulatory_element:26 次centerline:未出现(说明本样例不依赖 centerline;Lanelet2 可在需要时生成/推导)
示例片段(节选,实际见文件):
xml
<relation id='45216'>
<member type='way' ref='43978' role='left' />
<member type='way' ref='43974' role='right' />
<tag k='location' v='urban' />
<tag k='one_way' v='yes' />
<tag k='region' v='de' />
<tag k='subtype' v='road' />
<tag k='type' v='lanelet' />
</relation>
9.4 线要素(ways)的类型
本样例中 <way> 的 type/subtype 组合:
- 边界/道路结构:
road_border,curbstone(low/high),wall,fence,guard_rail,virtual - 车道线:
line_thin(solid/dashed),line_thick(solid/dashed),以及dashed_solid/solid_dashed - 停止线:
stop_line - 行人/自行车标线:
pedestrian_marking,zebra_marking,bike_marking - 交通标志:
traffic_sign(subtype=de205/de301/de274_1/...) - 信号灯:
traffic_light(subtype=red_yellow_green/...) - 路面符号:
symbol(subtype=30)(例如道路上画的"30"限速字样)
它们决定了可行驶走廊边界、是否允许变道、路口停止位置与信号灯约束来源。
9.5 regulatory element 的真实结构
9.5.1 traffic_light regulatory element
样例中可见:
ref_line指向某条 way(停止线)refers指向 1~N 条信号灯 way(type=traffic_light)
例如(节选):
xml
<relation id='45218'>
<member type='way' ref='43606' role='ref_line' />
<member type='way' ref='49639' role='refers' />
<member type='way' ref='44960' role='refers' />
<tag k='subtype' v='traffic_light' />
<tag k='type' v='regulatory_element' />
</relation>
9.5.2 right_of_way regulatory element
样例中可见:
ref_line:停止/让行线refers:让行/优先标志牌(type=traffic_sign的 way)yield/right_of_way:直接引用 lanelet relation(member type=relation)fallback=yes:低优先级(例如"信号灯坏了才用")
(节选):
xml
<relation id='45230'>
<member type='way' ref='43584' role='ref_line' />
<member type='way' ref='85773' role='refers' />
<member type='relation' ref='44968' role='right_of_way' />
<member type='relation' ref='45014' role='yield' />
<tag k='fallback' v='yes' />
<tag k='subtype' v='right_of_way' />
<tag k='type' v='regulatory_element' />
</relation>
9.5.3 speed_limit regulatory element
样例中 speed_limit 规则元素非常精简:只用 refers 指向一个限速牌:
xml
<relation id='45390'>
<member type='way' ref='44952' role='refers' />
<tag k='subtype' v='speed_limit' />
<tag k='type' v='regulatory_element' />
</relation>
对应的限速牌 way(节选):
xml
<way id='44952'>
<tag k='subtype' v='de274_1' />
<tag k='type' v='traffic_sign' />
</way>
TrafficRules 会根据 traffic_sign.subtype(地区+编号)解释出具体限速(或你也可以用 sign_type 在规则元素上直接写速度值,见 §7.3.2)。
10. 自动驾驶应用
10.1 几何层
- 边界:定义可通行空间和变道约束
- 线型:决定横向可达性(实线不可变道,虚线可变道)
- 环境要素:标识不可通行区域
规划器用途:参考线、横向边界、代价地图
10.2 拓扑层
路由图构建:
- Successor:前后继关系
- Left/Right:左右邻接(变道)
- Merging/Splitting:汇入分流
10.3 规则层
关键规则:
participant:*:通行参与者one_way*:行驶方向speed_limit:速度约束traffic_light:信号灯与停止线right_of_way:让行/先行规则
规划器用途:停止线约束、通行权判断、速度上限
11. 制作地图实践建议
11.1 标签一致性
- Tag key 使用小写
region与 traffic sign subtype 匹配- 严格遵守 lanelet 成员角色规范
- 保持规则元素与 lanelet 双向引用
11.2 变道语义
- 默认按边界线型推断
- 使用
lane_change显式覆盖
11.3 限速表达优先级
- speed_limit regulatory element(推荐)
- lanelet 的 speed_limit 属性
- 默认推断(不推荐)
免责声明
本文档仅供技术学习和交流使用,内容基于作者对Lanelet2地图格式和OpenStreetMap规范的个人理解和分析整理。
重要提示:
- 本文档不代表Lanelet2官方文档或OpenStreetMap官方规范
- 文档内容为个人学习整理,仅供参考
- Lanelet2是开源项目,遵循BSD 3-Clause许可证,版权归原作者所有
- OpenStreetMap数据遵循ODbL许可协议
- 实际使用Lanelet2时应参考官方文档:
- Lanelet2: https://github.com/fzi-forschungszentrum-informatik/Lanelet2
- OpenStreetMap Wiki: https://wiki.openstreetmap.org/
- 文档内容可能存在理解偏差或过时信息,欢迎指正
- 不同版本的Lanelet2和TrafficRules实现可能存在差异,请以实际使用版本为准
- 因使用本文档产生的任何后果由使用者自行承担
参考来源:
- Lanelet2 官方文档(LaneletAndAreaTagging、LinestringTagging、RegulatoryElementTagging)
- Lanelet2 maps 映射规则
- OpenStreetMap Wiki