场景生成

把场景从硬编码代码改成可采样、可批量、可复现的数据。 核心是一个中间表示(IR):ScenarioSpec,由它编译出 OpenSCENARIO。

1. 工作流程

graph LR A[ScenarioSpec IR] --> B[osc_builder] B --> C[.xosc 文件] A --> D[scenario_validator] C --> D D --> E[结构 + 语义校验]

2. 工具参数

2.1 generate_scenario_from_template

参数 类型 默认值 说明
template string cut_in 模板名,见第 3 节
n int 1 生成数量
seed int None 随机种子;相同种子结果可复现
out_dir string llm/output/scenarios 输出目录
params_json string {} 覆盖模板默认参数

2.2 validate_scenario

参数 类型 默认值 说明
file_path string 必填 待校验的 .xosc 文件

3. 15 个场景模板

模板 场景含义 实体数 主要触发
lead_brake 前车急刹 3 时间
lead_stationary 前车静止 2 时间
cut_in 危险切入 4 时间、时距、速度、到达
cut_in_then_brake 加塞后急刹 3 时间(变道、急刹分阶段)
crossing_hazard 行人/车辆横穿 2 时间、距离
low_overlap 前方低重叠率目标 3 时间、距离、速度、到达
wrong_way 逆行 2 时间、距离
unprotected_turn 路口无保护通行(需 Town10HD_Opt) 3 时间、距离
merge_turn 路口汇入转向(需 Town10HD_Opt) 3 时间、距离
dense_lane_change 三车道路段连续变道 4 时间
junction_light 路口信号冲突 3 时间、速度、距离
close_follow 近距跟驰(TTC 触发减速) 2 TTC
overtake 超车(变道 + 相对速度) 3 时间、距离、到达
evasive_swerve 紧急避让(轨迹跟随) 3 时间
signal_phase 红绿灯相位(红灯等待→切绿→起步) 2 信号灯、时间

4. 对话示例

列出所有可用的场景模板
用 cut_in 模板生成一个场景,随机种子设为 42
生成 20 个前车急刹的场景,每个参数在合理范围内随机
校验刚才生成的场景文件

4.1 文字直达场景

网页聊天框输入与快捷按钮相同的文字,会先命中本地意图表,直接执行对应工具, 不经过大模型(离线、无 API Key 也能用):

IDM 跟驰                    -> run_scenario_in_carla(template="lead_brake", duration=18)
红绿灯相位演示              -> run_traffic_light_demo(map_name="Town03")
红绿灯模板                  -> run_scenario_in_carla(template="signal_phase", map_name="Town03")
播放 lead_brake 模板        -> run_scenario_in_carla(template="lead_brake")
在 Town04 跑匝道汇入        -> scenario_highway_ramp(ramp_type="on", map_name="Town04")

还可以顺带指定截图时刻、时长与红灯时长:IDM 跟驰,截图 6,12,15、 红绿灯相位演示,红灯 8 秒。模板名与按钮文字的完整对照见 New Features 第 7 节。

4.2 自然语言 → 模板 + 参数

无法确定模板时,可先调用语义解析:

plan_scenario("旁边车加塞到我前面后立刻急刹")
{"template": "cut_in_then_brake", "confidence": 0.95,
 "params": {}, "required_map": null, "needs_clarification": false}

find_scenario_templates(query, top_k=3) 额外返回候选及得分,用于判断是否存在歧义:

cut_in_then_brake  9.5
cut_in             3.2
lead_brake         2.5

输入会先归一化(繁体、全角、语气词、单位写法),再参与匹配; decision 取 execute / choose / clarify,分别表示直接执行、候选择一、追问澄清。

槽位、加权与歧义判定的细节见 New Features。

5. 代码示例

5.1 批量生成

from scenario_templates import build
from osc_builder import write_scenario

# 同一个模板 + 不同种子 = 参数区间内的不同场景,结构一致
for seed in range(20):
    spec = build("lead_brake", seed=seed)
    write_scenario(spec, "output/lead_brake_%02d.xosc" % seed)

5.2 覆盖参数

spec = build("cut_in", seed=1, params={"delay": 3.0, "gap": 12.0})

5.3 指纹去重

from scenario_ir import ScenarioSpec

seen = set()
for seed in range(100):
    spec = build("cut_in", seed=seed)
    fp = spec.fingerprint()          # 场景结构性指纹
    if fp in seen:
        continue                      # 重复场景跳过
    seen.add(fp)

6. ScenarioSpec 字段

字段 说明
entities 实体列表(车辆/行人),含初始位置与速度
behaviors 行为列表(26 类,如变速、变道、跟驰)
triggers 触发列表(10 类,如时间、距离、时距)
fingerprint() 场景指纹,用于批量去重

7. 校验内容

层次 检查项
结构 用 scenariogeneration 往返解析,确认 XML 合法
语义 实体数量、车道有效性、速度范围、触发可达性等 8 项

输出示例

✅ 场景校验通过
   文件:llm/output/scenarios/cut_in_0000.xosc
   实体:4 个(3 车辆 + 1 行人)
   行为:5 个
   触发:4 个
   统计:时长 30.0s,最大速度 13.0 m/s

8. OpenSCENARIO 版本

默认输出 OSC 1.1,可指定 1.0 / 1.1 / 1.2 / 1.3:

write_scenario(spec, "out.xosc", osc_minor_version=2)
版本 差异
1.0 目标速度标签为 AbsoluteSpeed
1.1+ 目标速度标签为 AbsoluteTargetSpeed,支持 override

若播放器只支持 1.0,需要改默认值并补行人 model 定义。

9. 实测

项目 结果
OSC 生成器往返解析 4 场景 × 4 版本 = 16/16 通过
模板编译与校验 8/8 通过,同 seed 指纹一致
批量生成 50 个 6.86 s,80 个混合 10.89 s,重复 0