FMI#
目前正在进行通过利用 libsumo 为 SUMO 构建 FMI v2 支持的工作。
目标#
最初的目标是构建一个原型,该原型能够通过 libsumocpp 加载和运行 SUMO 仿真,同时支持部分选定的 libsumo 函数。
目前,这些函数包括(参见 src/fmi/modelDescription.xml 中的 ScalarVariables):
- vehicle.getIDCount
- vehicle.moveToXY
- vehicle.getParameterWithKey
- vehicle.getLaneID
- vehicle.getPosition
Note
libsumo 函数目前是为原型手动添加的。有计划为 FMI 自动生成可用的 libsumo 函数。
架构#
构建功能化仿真单元 (Functional Mockup Unit, FMU) 的当前架构如下(相应的源代码位于 src/fmi)。
FMU 用法#
由于 FMI 标准第 2 版 的限制(例如,输出标量变量不能直接赋予参数),我们实现了一种有状态的方法。
例如,如果我们需要车辆的当前位置,我们会检索 vehicle.getPosition 标量变量的(输出)值。
然而,由于上述 FMI v2 的限制,我们首先需要为 vehicle.getPosition 设置输入参数值,即车辆 ID。
为此,我们在检索输出变量值之前,利用通用的 setGetterParameters 输入标量变量,如下 Python 代码片段所示:
fmu.setString([valueRefs['setGetterParameters']], ["ego"])
resultList = fmu.getString([valueRefs['vehicle.getPosition']])
请注意,setGetterParameters 顾名思义,是一个通用的全能输入标量变量,用于为随后的输出标量变量值的检索设置输入参数。
在有多个输入参数的情况下,例如对于 vehicle.getParameterWithKey,参数值需要用空格分隔符连接成单个字符串。
同样,输出值也以相同的分隔符作为连接字符串返回:
fmu.setString([valueRefs['setGetterParameters']], ["ego meaningOfLife"])
resultList = fmu.getString([valueRefs['vehicle.getParameterWithKey']])
key = resultList[0].decode('UTF-8').split()[0]
value = resultList[0].decode('UTF-8').split()[1]
这种将值作为连接字符串传递的约定源于 FMI v2 的限制,即尚不支持向量和其他复杂数据类型。
使用 Python 连接 SUMO FMU#
FMPy Python 包可用于模拟和验证 FMU,是将 SUMO FMU 与 Python 连接的推荐方式。 在 Linux 上安装 FMPy 的方法如下:
`
python -m pip install fmpy
开始使用 FMPy 的一种简单方法是查看位于 tests/complex/fmi 的 SUMO fmi 测试套件的 runner.py(上面的代码片段也可以在这里找到)。
