0%

OpenSCENARIO笔记

OpenScenario1.0

为了实现自动驾驶场景设计的标准化,德国自动化及测量系统标准协会(ASAM)推出了OpenX系列标准。

例如OpenDrive标准用于描述场景静态信息的路网,OpenCRG描述路面信息,而OpenSCENARIO则是用来描述动态场景的。

这里会对学习到的OpenSCENARIO 1.0(下称OSC)相关内容进行记录。那之后ASAM也发布了OSC的1.1和1.2版,相关笔记会更新在后面。

部分翻译根据个人理解做了调整,一切以英文为准(特别的,“/概念名称”是我认为相对值得一提但没有采用的官方文档翻译;更特别的,这官方中文真够烂的)。

参考:


OSC场景基本概念/方案

场景的基础概念是“谁,在哪里,做什么”,即实体路网上根据故事板定义的一组指令进行交互

场景定义的五个基本概念(Concept/方案)是:

  • Entity实体,车辆行人等参与者。
  • RoadNetwork路网,静态的场景元素,包括OpenDRIVE、交通信号、环境模型等。
  • StroyBoard故事板/场景剧本,完整的动态描述。
  • 另有两个内容:ParameterDeclaration参数声明Catalog目录,将在将来用到时提及。

场景构成

OSC通过StoryBoard描述整个场景的完整内容,它有下述构成:

  • Story:故事,即最高层次的场景描述单位;至少1个。
    • Act:幕,包含了触发开始条件(和触发结束条件,可选),只有触发时下述内容才会执行;至少1个。
      • ManeuverGroup:操作组,明确交互主体和交互动作,即连接Entity和Maneuver;至少1个。
        • Actors:角色,即被影响的实体。
          • EntityRef:被引用实体,即被影响的实体列表;至少0个(因为操作组有可能并不影响实体)。
        • CatalogReference:可被重复使用的内容;至少0个。
        • Maneuver:操作,即事件组,包含若干事件;至少0个。
          • Event:事件,有触发开始条件;至少1个。
            • Action:动作,与场景产生交互,例如改变天气、改变设置、定位车辆;至少1个。

以上的所有内容都被称为StoryBoardElement(故事板元素/场景剧本要素)。

StoryBoard


故事板元素状态及其状态机

StoryBoardElement拥有3种状态,即为StoryBoardElementState(故事板元素状态):

  • StandBy(standByState):待机状态
  • Running(runningState):运行状态
    • 不同的StoryBoardElement会在不同情况时结束这一状态,具体可见官方文档
  • Complete(completeState):完成状态
    • 值得一提,如果要重置回待机状态,需要其父级StoryBoardElement重新启动

对于在这3种状态中切换,有4种Transition(转换):

  • Start(startTransition):启动转换
  • End(endTransition):结束转换
    • 当这个Transition返回否定结果时,会回到StandBy,否则进入Complete
  • Stop(stopTransition):停止转换
    • 和上一个不同,无论是StandBy和Running,这个Transition都会让故事板元素状态变为Complete。
  • Skip:跳过

State


Entity简介

Entity有两类:

  • 车辆行人等(根据类型不同拥有不同的Property属性)
  • 其他物体(与OpenDRIVE中的对象类相同)

Entity默认拥有一个Controller(控制器),用于接收来自控制算法之类的指令。

此外,Entity的实例会被分为两种:

  • 某一单个Entity实例
  • 被称为EntitySelection的一组Entity

EntitySelection被选实体

EntitySelection是将场景中已经存在的若干Entity进行快速分组。

这样分组,是为了能一同在其他地方被引用(例如批量生成Entity实例,并执行相同的动作)。


Trigger触发器与Condition条件

在Act以及Event中,都需要使用这两种主要的Trigger(触发器)来控制流程的启停:StartTriggerStopTrigger
StartTrigger将故事板元素从standByState切换到runningState;而StopTrigger将其从其他状态(待机或运行)切换到completeState。

一个Trigger的结果是一个T/F值,这是由它所含有的Condition(条件)以逻辑运算共同决定的。

为此,OSC将Condition的逻辑运算设计成这样:

  1. ①若干Condition关联成为一个ConditionGroup(条件组);ConditionGroup的结果为所有Condition结果之和/AND
  2. ②若干ConditionGroup一同放入一个Trigger中;Trigger的结果为所有ConditionGroup结果之或/OR

有关StartTrigger

拥有StartTrigger的故事板元素:

  • Act
  • Event

没有StartTrigger的故事板元素,例如ManeuverGroup和Maneuver,它们会继承父级的StartTrigger,也就是从Act中继承;具体表现也就是当Act启动后,其底下的ManeuverGroup都会自动启动。

但是,如果拥有自己的StartTrigger,那它们的启动就要满足它们自己的Condition;而如果它们的父级Act不在runningState(运行状态),则不能启动,这是不言自明的。

此外,Story也不需要startTrigger,毕竟在仿真启动时它就自然被启动了。

有关StopTrigger

拥有StopTrigger的故事板元素:

  • Story
  • Act

同StartTrigger,其他故事板元素会继承父级的StopTrigger;但有所不同的是,一旦父级故事板元素停止了(进入completeState),无论自己有没有StartTrigger,它底下的所有故事板元素同样都要立刻停止。

Condition简介

Condition有3个属性:

  • name:标识名
  • delay:延迟,从触发conditionEdge到返回True结果之间的时间差
  • conditionEdge:条件边缘,其有4种类型:
    • rising:上升沿,逻辑表达式从False向True跳转的瞬间返回True,否则一直返回False
    • falling:下降沿,逻辑表达式从True向False跳转的瞬间返回True,否则一直返回False
    • risingOrFalling:上升或下降沿,逻辑表达式一旦变化就返回True,否则一直返回False
    • none:无,直接返回逻辑表达式结果

和2个元素,会与conditionEdge有关联:

  • byEntityCondition:与实体有关的条件,即该Condition的逻辑表达式与某些实体有关,有2个元素:
    • triggerringEntities:说明与哪些Entity有关
    • entityCondition:具体的Condition逻辑表达
  • byValueCondition:与数据有关的条件,即该逻辑表达式和非实体的数据,比如信号灯信息等有关

操作、事件与动作

正如上文所述,ManeuverGroup主要包含Actors和Maneuver这两部分。前者决定哪些Entity会被影响,而后者描述具体是什么Action影响(以及是怎么被触发Event的)。

特别的,Actors元素拥有一个属性selectTriggeringEntities(选择触发实体)。当其为真时,之前提到的byEntityCondition的triggerringEntities中的所有Entity,都会在Condition为真时被加入到Actors中。

Action动作

对于Action有以下3种分类,各自的下层元素具体可见官方文档:

  • PrivateAction:专属动作,必须被分配给Entity实例,一般用于描述车辆运动。
  • GloabalAction:全局动作,用于修改场景内容,包括改变环境、增删Entity等。
  • UserDefinedAction:用户自定义动作。

动作会应用在2种场合中:

  • Init初始化阶段,设置各种对象的初始状态
  • Event里,在其被触发时执行

当同时执行的Action在修改相同的数据,此时就可能会被认为是冲突了。根据冲突两者的类型不同,不同的冲突会有不同的处理方式,但一般而言,后出现的Action会覆盖前一个Action(意味着触发了它的stopTrigger)。


OSC 1.1

1.1版本相对1.0进行了下述调整:

  • 支持了逻辑场景,即对参数进行随机或步进等设置而自动生成变体场景
  • 更灵活的操作模型,例如数字运算和逻辑表达
  • 兼容更多的路网格式,比如地理坐标系统
  • 更好的测试支持,比如变量范围约束
  • 变量和属性声明的变动

此外,1.1版的用户指南(User Guild)也更加详细地描述了OSC的相关内容,对原本的逻辑进行了补充。

结构

OSC的程序结构应分为三部分:

  • OSC模型实例(OSC Model Instance),即OSC相关数据存储的实例
  • OSC导演(OSC Director),即将OSC模型实例中的数据解释出来的模块
  • 模拟器内核(Simulator Core),即OSC模型之外的所有仿真元素集合的模拟器,包括路网、实体、环境等

可见,OSC导演通过解释OSC模型实例的方式去描述场景动态,以此修改模拟器内核里的相关元素以实现仿真。

重用机制

参数

参数的命名规则是:

  • 必须以英文字母(a-z,A-Z)或下划线(_)开头
  • 大小写敏感
  • 可以包含数字(意思是参数名只能是大小写字母、数字和下划线的组合)

参数的声明:

1
2
3
4
<ParameterDeclarations>
<ParameterDeclaration name = "x" value = "5"/>
<ParameterDeclaration name = "y" value = "7"/>
</ParameterDeclarations>

表达式

OSC1.1的参数表达式格式为:
${Expr}


泛化参数设置指北

在这里记录了一般常用的泛化用参数。

  • 速度
    • 主车初速度<ParameterDeclaration name="$egoV_InitSpeed" parameterType="double" value="17">
    • 其他车初速度<ParameterDeclaration name="$xxV_InitSpeed" parameterType="double" value="17">
  • 触发器
    • 距离<ParameterDeclaration name="$xxV_XxxDistance" parameterType="double" value="0">
    • 时间<ParameterDeclaration name="$xxV_XxxTime" parameterType="double" value="0">
  • 天气
  • 车辆类型
    • 颜色<ParameterDeclaration name="$xxV_ColorCode" value="#000000">
      • <Property name="model_color" value="#000000">
      • 常用颜色代码:红色#FF6347,蓝色#6495ED,白色#FFFFFF