跳转到内容

AI 场景生成:描述一句话,拿到经过验证的场景

手写一个场景,意味着要为每个角色逐个指定道路、车道、触发条件和运动参数。AI 生成让你只需要描述这个动作——生成的草稿会先在仿真器里跑一遍并接受校验,然后才会出现在你的画布上。整个流程在浏览器中运行,使用你自己的 API key

这是做出一个可运行场景最短的路径:画一条车道,放两辆车,说一句你想要发生的事:

Vehicle2 cuts in front of Vehicle1.

从空白画布到跑起来的加塞场景:手绘一条车道,放置两辆车,输入一句话,生成的场景经过校验、应用并播放——然后打开幽灵轨迹回看,把时间线拖回加塞瞬间,手动微调一个事件,再跑一次。

只需要五步:

  1. 用 Lane 工具画一条车道,再从汉堡菜单切换到 Scenario 模式。
  2. Add actor 在车道上放置两辆车
  3. 打开 AI 面板(LOGIC 卡片上的 AI 按钮),输入你想要的动作。点击画布上的某个角色可以直接插入它的名字。
  4. 点击 Generate。 通过校验的结果会作为普通的阶段和事件应用到画布上——按 ▶ 即可查看效果。
  5. 手动调整它。 生成的事件和你自己写的没有区别,可以随意编辑。在演示视频里,这次运行被打开幽灵轨迹重新回放,时间线被拖回加塞发生的瞬间,某个事件在编辑器里被微调之后再次播放。

生成结果没有任何特殊之处:跳转时间线、修改速度或触发条件、添加失败条件、导出 .xosc——和处理你自己手写的场景完全一样。你也可以继续用对话的方式调整它,见下文用文字继续修改

同样的流程放到一张导入的 OpenDRIVE 路网上——这里用的是 CARLA Town05 地图,配上一段更长的请求:一次带急刹的超车加塞。

Vehicle2 comes up behind the Ego in the same lane, moves to the left lane, overtakes the Ego, and cuts back into the Ego’s lane soon after passing, leaving only a small gap. Immediately after cutting in, Vehicle2 brakes to 20 km/h. The Ego follows and keeps a safe distance.

一镜到底,CARLA Town05 地图:导入路网,放置两辆车,描述这次超车动作,生成的场景通过全部四道关卡,回放结果为 PASS。
  1. 你放置角色并输入请求。你摆放车辆的位置会被当作一个固定条件——模型被明确告知不能挪动它。
  2. 模型给出答案:一份包含阶段、事件、动作和触发条件的故事板,用的是 drawtonomy 内部的结构化格式,而不是原始 XML。
  3. 四道关卡校验这份答案(见下文)。任何一道关卡没通过,都会被转成一份具体的错误清单——哪个字段、错在哪里、该怎么改——发回给模型重试,最多三次。
  4. 通过校验的草稿被应用到画布上,成为普通的阶段和事件。没有跑过仿真的内容不会被应用,除非你明确要求这么做。

生成后的结果面板:四个绿色的关卡状态点、时间线中生成的阶段,以及下方的修改输入框

关卡显示名称检查内容
1Syntax(语法)答案能否被解析,是否符合故事板的结构规范——必填字段是否齐全、动作和触发类型是否已知。
2Logic(逻辑)车道 ID 是否存在于地图上、行驶方向是否一致、触发条件能否被满足,以及这个动作是否符合当前道路的实际形状。
3Run(运行)场景是否能被 esmini 真正执行——编译为 WebAssembly,在你的浏览器里跑一遍。从未触发的事件、卡死的角色、碰撞和冲出车道,都会在这一步暴露。
4Meaning(语义)记录下来的运动轨迹是否符合请求描述的动作。就算仿真跑得很干净,一次从未真正越过车道线的”加塞”依然会在这里被判定不通过。

第 4 关是对录制轨迹的几何校验,不是让语言模型自己给出的第二次主观判断。如果你要求的是一次加塞,那就必须真的有车越线切入。

四道关卡之外,还有一次独立的语义复核:把生成的故事板和你的原始描述对照阅读,指出可能存在的问题——这一步可以中止自动应用,把决定权交还给你(此时按钮变为 Apply with concerns)。语义复核只是提示性的;真正的硬性门槛是四道关卡。

  • 具体的问题——哪个字段、错在哪里、怎么修——会直接回传给模型,模型据此重新生成。绝大多数请求在第一次或第二次尝试就能通过。
  • 整个过程是可见的:面板会计数当前是第几次尝试,并标出所处的阶段,从 “Asking the AI…”“Checking it matches your request…”,点开 Details 能看到每一道关卡的完整过程。
  • 如果某个请求最终还是需要你出手调整,面板会给出 Try again 按钮,草稿会继续留在时间线上可见,任何未经过完整校验就被应用的场景都会有明显标注——已验证的场景和未验证的场景永远不会被混淆。

成功生成后的结果面板:已应用的场景,以及下方的语义复核结果说明

模型能看到你地图上的哪些信息

Section titled “模型能看到你地图上的哪些信息”

生成过程建立在你导入的真实地图之上,而不是凭空猜测:

  • 道路与车道——道路 ID、车道 ID 与类型、行驶方向、哪些车道相邻,以及从驾驶员视角看哪条车道在左、哪条在右。
  • 你已经完成的摆放——每辆车所在的道路、车道和位置,这些都被标记为固定条件。
  • 这条路能容纳什么——每个角色前方还剩多少道路,从而决定哪些速度、哪种场景时长是可行的。如果你要求的速度这条路根本装不下,面板会在 Fitted to the road 下明确说明,而不是悄悄替你改掉。

车辆可以被放置在行车道以及各类匝道(入口匝道、出口匝道、上匝道、下匝道、连接匝道)上;行人可以放在人行道、人行横道和路肩上。判断”哪里能放”用的是同一套规则,所以你手动能画出来的位置,和 AI 能提议的位置,两者始终保持一致。

输入到 AI 面板中的提示词,上方以标签形式列出了已放置的角色

自我车辆(Ego)始终是被测对象

Section titled “自我车辆(Ego)始终是被测对象”

drawtonomy 把 Ego 车辆当作被测试的对象,而不是又一个可以随意编排脚本的角色。在上面的演示中,生成的故事板里没有任何一条指令让 Ego 减速——请求里只写了”The Ego follows and keeps a safe distance.”(Ego 跟随并保持安全距离)。你看到的刹车动作,其实是参考巡航控制器对红色车加塞和减速做出的真实反应:

速度
红色车(脚本控制)60 km/h → 20 km/h,在稳定进入车道 0.7 秒后开始
Ego(非脚本控制)40 km/h → 21 km/h,保持 10 m 跟车距离

这正是一个有效测试应该有的样子:刺激条件写死在脚本里,而你要测量的是系统的响应。响应如何被转化为通过或失败的判定,见结束条件与失败条件

加塞瞬间:红色车稳定进入 Ego 所在车道并开始刹车

场景被应用之后,同一个输入框会变成一个修改框:不需要重新生成整个场景,直接描述你想要的改动即可。修改会以有针对性的局部编辑方式应用——调整某个速度、某个触发阈值、增删某个事件、场景结束时间——你手动编辑过的部分不会被覆盖。

单纯的数值指令甚至不需要调用模型。比如 “Set Vehicle2 to 40 km/h” 这种只涉及一个角色、一个数字和一个单位的请求,drawtonomy 会直接解析处理,面板会注明这次没有调用 AI。其余存在歧义的请求才会交给模型处理。

生成器目前能表达哪些动作,以及请求超出这个范围时会发生什么:

  • 完整的动作词汇表——变速、变道、横向偏移、瞬移、保持距离和轨迹跟随,触发方式包括仿真时间、相对距离、时间车头间距、速度,或另一个事件的状态。生成的所有内容最终都落地为普通的阶段和事件,所以词汇表之外的需求,用手动编辑就能补上。
  • 看不见的重试过程——一个请求可能一次就成功,也可能需要最多三次尝试,每一次都会被关卡纠正。最终出现在画布上的,是通过校验的那一次尝试。
  • 与道路长度匹配的运行时长——场景时长由动作类型、速度和前方道路长度共同推算得出,所以每次运行都会正好在你拥有的路面上跑完。想要更长?在修改框里提出来,它会作为一次局部编辑被应用。
  • 给动作留出足够的道路空间——一次超车需要空间。给角色留出大约 30 m 或更长的一段路,求解器才有发挥的余地。

生成功能使用你自己的 API key,所以请求算在你自己的账号和配额上。密钥保存在你的浏览器里,直接发送给你选择的服务商——它不会经过 drawtonomy 的服务器,也不会被写入任何文件或日志。

在场景编辑器中打开 AI 面板,点击底部的 API key

AI 面板中的 API key 一栏:服务商下拉菜单(设为 Anthropic)、密钥输入框和 Clear 按钮

  1. 选择一个服务商——Anthropic(默认)、OpenAI (ChatGPT)Gemini
  2. 粘贴密钥并点击 Save。之后该输入框会显示 Replace key,并出现一个 Clear 按钮用于重新删除它。
  3. 密钥按服务商分别记忆,所以切换服务商不会丢掉另一个服务商的密钥。

Anthropic Console 中创建(Settings → API keys → Create Key)。这需要一个带有 API 额度的 Anthropic 账号;Claude 的订阅套餐和 API 访问权限是两回事。

面板会明确指出原因,而不是无声地失败:

你看到的提示该怎么做
The key was rejected检查密钥是否有效、是否具备 API 访问权限——以及是否限定在单个 workspace 内(见上文)。
The API is rate limiting this key稍等片刻,点击 Try again
The API is temporarily unavailable服务商一侧的临时故障,稍后重试即可。