简介#
本教程展示了如何借助 osmWebWizard 创建一个简单的港口仿真。本教程包含以下步骤:
- 从 osmWebWizard.py 开始
- 使用 netedit 修订和调整路网
- 代理数据及其查找方式
- 乘客 / 巴士
- 集装箱
- 卡车,滚装船 (RoRo)
- 船舶
- 示例
有用链接#
文档:
创建一个简单的港口仿真#
osmWebWizard#
打开 osmWebWizard.py
python <SUMO_HOME>/tools/osmWebWizard.py
Note
构成场景的所有文件都会在工作目录的子文件夹中创建,文件夹名为当前时间戳(例如 build.bat 重新生成随机需求。
浏览器窗口将会打开。在左侧,您可以看到地图;在右侧,您可以找到您的位置和一些选项。首先,浏览地图以找到正确的港口。

在我们的案例中,它是德国吕贝克港的斯堪的纳维亚码头 (Skandinavienkai)。这里有渡轮(客运)和货船(集装箱运输)。

路网生成#
现在看一下右侧。您可以选择屏幕上可见的整个区域,或者通过选择选项 Select Area 来选择一个区域。
同时选择 Add Polygons 和 Import Public Transport 选项,以便将这些信息直接从 OSM 导入到我们的路网中。
需求生成#
需求由需求生成面板定义。您可以通过点击汽车图标来激活此面板。在这里,您可以选择港口区域需要的每种代理。如果您有任何特殊的港口车辆,如起重机或堆高机,您无法在此处创建它们。关于可能的实现方法将在下文稍作描述。 OSM Web Wizard 会生成随机需求,更多信息请参阅 osmWebWizard 的文档。
对于我们的场景,我们选择 cars、trucks、pedestrians、trains,当然还有 ships。

选择完所有需要的代理后,按下 Generate Scenario 按钮。
完整的场景会自动生成。场景生成需要几秒钟或几分钟(取决于场景的大小等因素)。场景生成过程完成后,sumo-gui 将启动,按下播放按钮即可开始仿真。
这就是我们的场景!但它看起来有点奇怪,因为水道非常大,所以我们首先需要放大以找到港口(在南部某处)。

这是我们的港口:(带有额外的多边形以便更好地概览港口。)

但如您所见,并非所有码头都与水道相连,如果您仔细观察,会发现更多需要修复的地方。因此,让我们打开 netedit 来校正路网。

路网编辑#
现在我们打开 netedit 来校正这些部分。您可以从 sumo-gui 中使用快捷键 Ctrl + T 打开它。
Netedit:#

1) 缩短水道,只保留最初选定的区域。#
使用检查模式 (I):定位超出区域的水道,并将这些双向边在港口的适当位置和可删除的部分分开。为此,在边应被分割的位置右键单击该边。

使用选择模式 (S):选择远离港口的水道并删除它们。
| 之前 | 之后 |
![]() |
![]() |
2) 删除所有多余的部分#
使用选择模式 (S):选择所有多余的边并删除它们。
| 之前 | 之后 |
![]() |
![]() |
3) 添加码头与水道之间缺失的连接#
使用检查模式 (I):在要添加连接到码头的位置将水道边在两个方向上分割。

使用边模式 (E):将码头与水道边(双向道路)连接。

使用检查模式 (I):选择新边并设置 allow = ship
4) 更改港口区域的道路 vClasses#
这是我们的主要港口区域。

如果您查看边的 "allow" 参数,您会看到它们有不同的允许 vClass。我们倾向于让所有边具有相同的允许 vClass(卡车、乘用车、行人、快递、出租车和巴士)。
使用选择模式 (S):选择所有道路(火车轨道除外)。
使用检查模式 (I):在左侧打开 allow 选项并更改允许的 vClass。

5) 火车轨道#
osmWebWizard 从 OSM 导入的火车轨道只有一个方向。 使用 netedit 或 netconvert 添加双向轨道。
Netconvert:#
使用 netconvert 及选项 railway.topology.all-bidi
或者
Netedit:#
使用选择模式 (S):选择所有火车轨道。
使用检查模式 (I):右键单击轨道 -> edge operations -> add reverse direction for edge
使用连接模式 (C):检查并调整轨道之间的连接(如果所有轨道的扩展类型都是 right 而不是 center,可能更容易控制)。
6) 创建公交站和集装箱停靠点#
使用 netedit 的附加模式 (A)。
选择 busStop 或 containerStop 并定义一个名称。然后将停靠点放置在一条边上。

添加完所有需要的停靠点后,将它们保存为附加文件(例如 stops.add.xml)。
Note
如果代理需要前往一个停靠点,但该停靠点所在的边没有通行权限,您可以为停靠点使用接入车道。 更多信息请参见 公共交通。
这些是我们场景的停靠点:(H=busStop, C=containerStop)

如果路网现在正确,请保存路网。在场景文件夹(对我们来说:build.bat,以创建适合自定义路网的新需求。您可以运行文件 run.bat 来重新启动仿真。

在这里您可以看到,在我们的场景中,船只太多了。因此,是时候更深入地研究需求了。
需求#
在我们编辑需求之前,最好先收集一些关于它的信息。如果您幸运的话,可以直接从港口获得这些数据。否则,也有一些方法可以获得近似值。对于船舶,可以查看自动识别系统 (AIS) 的数据。有很多免费来源,您可以获得有关船舶及其动向的信息。通常,您可以从港口网站和当地物流公司找到有关港口的信息。有关客运的信息可以从 OpenStreetMap 以及当地的公共交通和渡轮公司获取。
需求编辑#
如果您只想要一个非常简单的场景(没有集装箱),那么您只需更改文件 build.bat 中的 Through Traffic Factor 和 count,并生成一个更好的简单需求。更多信息请参见 osmWebWizard。
如果您想要一个更复杂的场景,请首先删除生成的需求。:-)
在本教程中,我们模拟一小时,包括一艘集装箱船、一艘客船、一列火车以及大量卡车、汽车、集装箱和乘客。我们还需要一辆巴士来运送乘客,因为在这个港口,客运码头和码头之间没有连接。对于集装箱运输,我们需要某种拖车/堆高机来将集装箱从火车站移动到码头。
以下是我们要插入的所有代理的列表:
1 艘客船,包含:
20 辆乘用车:随船到达并前往客运码头
20 辆乘用车:从客运码头出发并前往客船
20 名行人:随船到达并前往客运码头
20 名行人:从客运码头出发并前往客船
1 艘集装箱船,包含:
25 辆卡车:从火车站到船
25 辆卡车:从船到火车站
1 列火车,包含:
15 个集装箱:从火车到船
15 个集装箱:从船到火车
1 辆巴士:用于客运码头和客船之间的乘客运输
5 辆拖车/堆高机:用于火车和船之间的集装箱运输
创建需求文件#
首先,我们需要对 vTypes 进行一些调整,以添加必要的容量来装载足够的集装箱和人员。创建一个文件并为 vTypes 添加以下定义:
<vType id="type_ship" vClass="ship" containerCapacity="25" personCapacity="20"/>
<vType id="type_train" vClass="rail" containerCapacity="15"/>
<vType id="type_truck_taxi" vClass="truck" containerCapacity="1" personCapacity="1" loadingDuration="30.0"/>
<vType id="type_truck" vClass="truck" containerCapacity="1" loadingDuration="30.0"/>
<vType id="type_car" vClass="passenger"/>
<vType id="type_bus_taxi" vClass="bus" personCapacity="20"/>
<vType id="type_passenger" vClass="pedestrian"/>
火车#
将火车的行程添加到港口并返回。
<trip id="train" type="type_train" depart="0" departLane="best" from="149084838#0" to="-149084838#0" via="29497609">
<stop containerStop="containerStop_trainstation" duration="100"/>
</trip>
船舶#
有两种可能的方式来定义船舶。要么通过定义完整的路线,要么使用行程定义:
<vehicle id="ferry" depart="0.00" departPos="0" line="ferry" type="type_ship" color="0,255,0">
<route edges="-127071510.253116 127071510"/>
<stop busStop="busStop_waterway" duration="100"/>
</vehicle>
<trip id="containership" type="type_ship" depart="0" departLane="best" from="-5005413" to="5005413.18170" via="gneE2">
<stop containerStop="containerStop_waterway" duration="100"/>
</trip>
乘用车#
对于乘用车,我们使用流定义:
<flow id="passengercartoship" begin="0" end="200" number="20" type="type_car" from="39549605" to="-128042010" via="619566331">
<stop busStop="busStop_pier" until="800.00"/>
</flow>
<flow id="passengercarfromship" begin="730" end="750" number="20" type="type_car" from="-277007518" to="39549605" via="-197841302"/>
堆高机#
由于 SUMO 中没有实现堆高机,我们使用配备出租车设备的卡车。在这里,我们给它们 containerCapacity="1" 和 loadingDuration="30.0"(出租车设备还需要 personCapacity="1",因为目前没有它无法正常工作)。
<flow id="stapler" begin="0" end="0" number="5" type="type_truck_taxi">
<param key="has.taxi.device" value="true"/>
<route edges="276781727#9"/>
<stop containerStop="containerStop_truck_trainstation" duration="10.00"/>
</flow>
集装箱#
对于集装箱,我们使用 containerFlow 定义:
<containerFlow id="containerfromship" begin="triggered" number="15" color="255,0,0">
<transport from="-5005413" containerStop="containerStop_waterway" lines="containership"/>
<tranship containerStop="containerStop_pier"/>
<transport containerStop="containerStop_truck_trainstation" lines="taxi"/>
<tranship containerStop="containerStop_trainstation"/>
<transport to="-149084838#0" lines="train"/>
</containerFlow>
<containerFlow id="containertoship" begin="triggered" number="15" color="255,0,255">
<transport from="149084838#0" containerStop="containerStop_trainstation" lines="train"/>
<tranship containerStop="containerStop_truck_trainstation"/>
<transport containerStop="containerStop_pier" lines="taxi"/>
<tranship containerStop="containerStop_waterway"/>
<transport to="5005413.18170" lines="containership"/>
</containerFlow>
卡车和汽车#
对于卡车和汽车,我们使用流定义:
<flow id="passengercartoship" begin="0" end="200" number="20" type="type_car" from="39549605" to="-128042010" via="619566331">
<stop busStop="busStop_pier" until="800.00"/>
</flow>
<flow id="trucktoship" begin="0" end="200" number="20" type="type_truck" from="39549605" to="-277007500#0" via="619566331">
<stop containerStop="containerStop_pier" until="970.00"/>
</flow>
<flow id="passengercarfromship" begin="730" end="750" number="20" type="type_car" from="-277007518" to="84630550" via="-197841302"/>
<flow id="truckfromship" begin="870" end="920" number="20" type="type_truck" from="277007496#0" to="84630550" via="-197841302"/>
巴士#
考虑巴士的 line 属性。
<trip id="bus" type="type_bus_taxi" depart="0" departLane="best" from="-197841302" via="-128042010" to="-197841302" line="bus">
<stop busStop="busStop_busstation_terminal" until="300.00"/>
<stop busStop="busStop_pier" until="750.00"/>
<stop busStop="busStop_busstation_terminal" until="900.00"/>
</trip>
人员#
对于人员,我们使用流定义:
<personFlow id="pedestrianfromship" begin="triggered" number="20" color="0,255,0">
<ride from="-127071510.253116" busStop="busStop_waterway" lines="ferry"/>
<walk busStop="busStop_waterway"/>
<walk busStop="busStop_pier"/>
<ride busStop="busStop_busstation_terminal" lines="bus"/>
<walk busStop="busStop_passenger_terminal"/>
</personFlow>
<personFlow id="pedestriantoship" begin="0" end="200" number="20">
<walk from="-596327078#2" busStop="busStop_passenger_terminal"/>
<walk busStop="busStop_busstation_terminal"/>
<ride busStop="busStop_pier" lines="bus"/>
<walk busStop="busStop_waterway"/>
<ride to="127071510" lines="ferry"/>
</personFlow>
示例#
您可以在 Github 上找到德国吕贝克港斯堪的纳维亚码头的场景文件。
另外还有两个更简单的港口场景:




