创建仿真场景:一个逐步示例

在这篇教程中,我们将逐步演示如何构建真实的仿真环境。

OSM 地图导出

第一步,我们需要获取真实的地图信息。我们可以通过 OpenStreetMap 来获取感兴趣的区域。 在选择了感兴趣的区域并进行框选后,我们可以导出地图,如下图所示:

osm_export

此时我们会得到一个 *.osm 文件,我们将其重命名为 berlin.osm,并保存在 TSHub-berlin

OSM 转换为 Net 和 Polygon

在获得了 berlin.osm 文件之后,我们可以使用 scenario_build 函数根据该文件生成 *.net.xml*.poly.xml 文件,用于后续的仿真。 以下是转换的核心代码,完整的例子可以在 osm_build.py 中找到:

from tshub.sumo_tools.osm_build import scenario_build

osm_file = "berlin.osm"
output_directory = "./"
scenario_build(
    osm_file=osm_file,
    output_directory=output_directory
)

运行上述代码后,我们将分别得到 berlin.net.xmlberlin.poly.xml 文件(参见 osm_berlin)。这样就完成了 OSM 数据的转换。 我们可以使用 sumo-gui 进行可视化,如下图所示:

sumo_net

Note

实际中,我们需要根据实际情况修改车道数、车道速度等相关属性。 直接从 OpenStreetMap` 上获取的信息可能不完全准确。 同时,还需要去除掉头,否则车辆可能无法驶出路网。

添加背景图片(选择)

在完成地图转换后,为了使可视化结果更加美观,我们可以添加背景图片。 我们可以根据导出时的经纬度信息(或使用 sumo-gui 查看经纬度),在地图上找到对应的区域,并将其保存为图片。

Note

截图的区域需要包含比例尺,以便我们后面调节图片的尺寸。

保存图片后,我们在 netedit 中打开路网并导入图片。首先,查看下载图片的原始大小,并在插入后修改为原始图像大小。

background_view_setting

设置完成后,在比例尺的位置绘制一个车道,然后查看此车道的长度和比例尺的长度。在本例中,比例尺长度为 50 米,绘制的车道长度为 87 米,因此我们需要修改图片的长和宽。 对于本例,图像的长度为 1553 像素,宽度为 838 像素。

\[\frac{1553}{x} = \frac{838}{y} = \frac{87}{50}\]

解上述方程,最后得到新图像的长度为 892.5 像素,宽度为 481.6 像素。 将其设为新图像的长度和宽度。最后,调整 centerXcenterY,我们就可以在原始路网上添加背景图片了。

sumonet_background

添加背景图片后,我们创建一个新的 viewsettings 来保存可视化的一些设置:

<viewsettings>
    <scheme name="standard"/>
    <viewport zoom="100" x="280" y="245" angle="0.00"/>
    <delay value="50"/>
    <decal file="background.png" centerX="280" centerY="245" width="892.52873" height="481.609195" rotation="-1.00"/>
</viewsettings>

最后,我们只需要在 sumocfg 文件中加入 viewsettings

<configuration>
    <input>
        <net-file value="berlin.net.xml"/>
        <additional-files value="berlin.poly.xml"/>
        <gui-settings-file value="viewsettings.xml"/>
    </input>
</configuration>

有关插入背景图像的更多信息,请参考 Import a background image and set scale in NETEDIT : SUMO

Note

这里背景图片可能会和路网有一些不能完全对齐。 但是这里背景图只是用作可视化,完全不影响最终的仿真结果。

创建探测器和信号灯输出文件

在完成了路网的创建后,我们可以为该路网生成「探测器」和「信号灯输出」。有关这两部分内容的详细信息,请参考以下文档:

完整的脚本文件可以在 TLS Additional Files 中找到。

创建车流

到目前为止,我们已经完成了静态路网的编辑。最后,我们需要在路网上生成车流。有关车辆生成的详细信息,请参考 TSHub-生成车流。 在这里,我们只需要指定时间段、每个时间段每个边缘(edge)进入的车辆数量以及转向概率等参数。以下是部分生成车流的示例参数:

generate_route(
    sumo_net=sumo_net,
    interval=[5,5,5],
    edge_flow_per_minute={
        '65040946#0': [8, 8, 8],
        '24242838#0': [8, 8, 8],
        '1152723807': [7, 7, 7],
        '-32938173#2': [7, 7, 7],
        '-1147648945#1': [10, 10, 13],
        '-1152723815': [10, 10, 7],
        '-1105574288#1': [10, 10, 9],
        '-23755718#2': [10, 10, 7]
    },  # 每分钟每个边缘的车辆数量
    edge_turndef={
        '24242838#0__24242838#5': [0.7, 0.7, 0.8],
        '24242838#5__1105574288#0': [0.9, 0.9, 0.9],
    },
    veh_type={
        'ego': {'color':'26, 188, 156', 'probability':0.3},
        'background': {'color':'155, 89, 182', 'speed':15, 'probability':0.7},
    },
    output_trip=current_file_path('./testflow.trip.xml'),
    output_turndef=current_file_path('./testflow.turndefs.xml'),
    output_route=current_file_path('../env/berlin.rou.xml'),
    interpolate_flow=False,
    interpolate_turndef=False,
)

完整的脚本文件可以在 Berlin-generate_routes 中找到。 至此我们完成了场景的创建,仿真界面如下所示:

create_scenario_flow