ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SUMO交通仿真入门:从零构建十字路口与Python自动化

SUMO交通仿真入门:从零构建十字路口与Python自动化 简介交通仿真是城市规划和智能交通系统研究的关键技术它通过计算机模型模拟真实交通流为优化决策提供数据支持。其核心原理在于对车辆、道路、信号灯等微观元素的建模与交互计算。这项技术的价值在于能以极低的成本和风险在虚拟环境中测试交通管控策略、自动驾驶算法及路网规划方案广泛应用于交通工程、自动驾驶测试和城市规划领域。本文以开源微观交通流仿真器SUMO为例通过一个包含交通信号灯的十字路口构建实例详细拆解了其核心工具链和工作流程。文中不仅介绍了如何使用NETEDIT绘制路网、编写XML配置文件定义车流还重点展示了如何利用Python脚本如sumolib库实现出行需求的自动化生成与路径计算有效融入了Python脚本和自动化流程等热词为初学者提供了一条从手动操作到编程集成的清晰实践路径。1. 项目概述从零开始理解SUMO交通仿真如果你对城市交通规划、自动驾驶算法测试或者仅仅是交通流理论感兴趣那么SUMOSimulation of Urban MObility这个开源工具你一定绕不开。我第一次接触SUMO是在一个研究智能交通信号灯的项目里当时被它强大的可定制性和免费开源的特点所吸引。简单来说SUMO就是一个微观交通流仿真器它能模拟道路上每一辆车的移动、变道、跟车、停车等行为让你在电脑上就能构建一个虚拟的交通世界用来测试你的新想法而无需承担在真实道路上实验的成本和风险。这个“简单示例”项目就是带你快速上手SUMO完成一次从无到有的基础仿真。无论你是交通工程的学生、算法工程师还是城市规划的爱好者通过这个示例你都能掌握SUMO仿真的核心流程如何定义路网、如何生成车流、如何运行仿真并查看结果。整个过程就像搭积木我们将从最基础的“道路”和“车辆”这两块积木开始。别被“仿真”这个词吓到SUMO提供了丰富的图形化工具和相对友好的XML配置文件格式只要跟着步骤走你很快就能看到车辆在你定义的道路上跑起来。2. 核心工具链与工作流程拆解在动手之前我们需要先理清SUMO仿真的几个核心组成部分和它们之间的关系。SUMO不是一个单一的软件而是一个工具套件。理解这个工具链能让你在后续操作中知其然更知其所以然。2.1 核心工具介绍SUMO的核心工具主要包括以下几个它们各自承担着仿真流水线上的不同任务NETEDIT这是SUMO的图形化路网编辑器也是我们最常打交道的工具。你可以用它像画图一样绘制道路、交叉口、车道设置交通信号灯。对于新手来说它是创建和修改路网最直观的方式。它的本质是生成一个描述路网拓扑结构的XML文件通常以.net.xml结尾。NETCONVERT路网转换器。SUMO的仿真内核需要特定格式的路网文件。NETCONVERT负责将其他格式的路网数据如OpenStreetMap导出的.osm文件转换成SUMO可识别的.net.xml格式。即使你使用NETEDIT最终保存时它也是调用了NETCONVERT来完成格式生成。所以它是路网处理的“幕后功臣”。DUAROUTER路径分配器。在仿真中车辆不是随机乱跑的它们需要从A点出发计划一条路径到达B点。DUAROUTER可以根据你提供的出行需求哪辆车、何时、从哪到哪以及路网状况为车辆计算出一条或多条可能的路径。它解决了“车往哪里开”的问题。SUMO-GUI带图形界面的仿真主程序。这是我们最终“看戏”的地方。它加载路网文件.net.xml和车辆文件.rou.xml以图形化方式实时展示仿真过程。你可以暂停、加速、减速并查看每辆车的实时信息。SUMO无图形界面的仿真主程序命令行版本。功能和SUMO-GUI一样但不显示图形界面。它通常用于批量自动化仿真、需要大量计算资源的场景或者集成到其他脚本中。它的输出是各种数据文件供后续分析使用。2.2 标准仿真工作流一个典型的SUMO仿真项目遵循以下工作流理解这个流程对排查问题至关重要第一步获取或创建路网.net.xml。这是仿真的舞台。你可以用NETEDIT从头画也可以用NETCONVERT导入现有的地图数据如从OpenStreetMap下载。第二步定义出行需求.rou.xml。这是舞台上的演员和剧本。你需要定义有哪些车辆、它们何时何地出现、要去往何处。这个文件通常手动编写XML或通过randomTrips.py等Python工具辅助生成。第三步可选路径计算。如果你在出行需求中只定义了起点和终点那么你需要使用DUAROUTER结合路网文件为所有车辆计算出具体的行驶路径生成一个包含路径信息的新的.rou.xml文件。第四步编写仿真配置文件.sumocfg。这是一个“总指挥”文件。它非常简单主要作用是指定本次仿真要使用哪个路网文件net-file、哪个车辆文件route-files以及仿真要运行多长时间time-to-teleport等参数。第五步运行仿真。使用SUMO-GUI打开.sumocfg文件或者用SUMO命令执行它仿真就开始了。这个流程的核心思想是“数据驱动”所有元素都通过配置文件定义使得仿真过程高度可重复、可自动化。接下来我们就按照这个流程一步步实现我们的第一个简单示例。3. 从零构建一个十字路口仿真我们从一个最简单的场景开始一个标准的十字路口有东西、南北两条道路相交路口设有交通信号灯。我们将看到车辆从四面八方驶来按照信号灯的指示通过路口。3.1 使用NETEDIT绘制基础路网首先打开NETEDIT。在Windows上你可以在开始菜单找到它在Linux/macOS上在终端输入netedit即可。创建道路在左侧模式选择栏选择“Edge Mode”边模式即道路模式。在中间的空白画布上从左到右水平画一条线这代表东西向的道路。松开鼠标后会弹出一个对话框让你设置道路ID我们可以输入east_west。同理从上到下垂直画一条线作为南北向道路ID设为north_south。你会发现在两条道路相交的地方SUMO自动为我们创建了一个交叉口Junction。检查并修改交叉口类型点击左侧的“Inspection Mode”检查模式箭头图标然后点击交叉口中心。右侧的信息栏会显示交叉口的属性。关键的属性是Type类型。默认可能是priority优先权规则即没有信号灯靠右方来车让行等规则控制。我们需要把它改为交通信号灯控制。将Type的下拉菜单选择为traffic_light。你会发现交叉口中心出现了一个浅色的方框这表示信号灯控制器已经就位。设置车道和道路属性再次点击我们画的道路east_west。在信息栏你可以看到Num lanes车道数默认是1。我们可以把它改为2表示这是一条双向两车道实际上SUMO中一条“Edge”代表一个方向所以我们画的east_west目前只是从西向东的方向。我们需要补充从东向西的道路。不过对于这个简单示例单车道足以说明问题。我们暂时保持单车道。你可以顺便修改一下Speed最高速度比如设为13.89 m/s (约50 km/h)。补充反向道路在真实路网中道路通常是双向的。我们回到“Edge Mode”按住Ctrl键或根据NETEDIT提示的修饰键从东向西即从east_west道路的终点拖向起点画一条线。SUMO会自动识别这是创建一条反向道路并建议ID为east_west的反向链接。这样我们就有了完整的双向道路。对north_south也进行同样的操作。注意NETEDIT中直接画一条线创建的“Edge”是单向的。创建双向道路的标准做法是先画一个方向然后按住修饰键如Ctrl从终点画回起点。这是一个非常容易踩坑的点新手常常仿真时发现车只能往一个方向开原因就在这里。保存路网点击菜单File - Save Network As...将路网保存为simple_cross.net.xml。NETEDIT会提示你选择保存位置并调用NETCONVERT进行最终生成。这个.net.xml文件就是我们的舞台。3.2 手动编写车辆需求文件有了路网我们需要车辆。我们创建一个最简单的车辆需求文件。打开文本编辑器如VS Code、Notepad新建一个文件保存为simple_flow.rou.xml。routes !-- 首先定义车辆类型类似于定义“车型” -- vType idcar accel2.6 decel4.5 sigma0.5 length5.0 maxSpeed13.89/ !-- 定义一条从西向东的行驶路径 -- route idroute_we edgeseast_west/ !-- 注意这里的edges值必须和路网文件中的Edge ID完全一致 -- !-- 定义一条从北向南的行驶路径 -- route idroute_ns edgesnorth_south/ !-- 生成车辆按照时间表在路径上生成车辆 -- flow idflow_we typecar routeroute_we begin0 end3600 period5/ flow idflow_ns typecar routeroute_ns begin0 end3600 period7/ /routes我来解释一下这个文件vType: 定义了一种车辆类型ID为car。accel是加速度decel是减速度sigma是驾驶员“不完美”程度0为机器人1非常随机length是车长maxSpeed是最高速度。这些参数直接影响跟车、换道等微观行为模型。route: 定义了一条路径。id是路径名edges是路径所经过的道路ID序列。我们这里非常简单只经过一条路。例如route_we路径就是沿着east_west这条边从西走到东。flow: 这是一个“流”生成器比单独定义每一辆车更方便。id是流的名称type指定车辆类型route指定使用的路径begin和end定义了流产生的起止仿真时间单位秒period表示每隔多少秒产生一辆车。所以flow_we会在仿真开始后的3600秒内每隔5秒在route_we的起点即east_west的西端生成一辆car类型的小车。实操心得在编写edges属性时务必确保其值与.net.xml路网文件中的Edge ID完全一致包括大小写。这是最常见的错误来源之一。一个检查方法是使用SUMO提供的netdump工具命令如netdump simple_cross.net.xml来列出路网中所有的Edge ID。3.3 创建仿真配置文件现在我们需要一个“总指挥”文件把路网和车辆需求结合起来。新建一个文本文件保存为simple_cross.sumocfg。configuration input net-file valuesimple_cross.net.xml/ route-files valuesimple_flow.rou.xml/ /input time begin value0/ end value3600/ !-- 仿真运行3600秒即1小时 -- step-length value0.1/ !-- 仿真步长0.1秒值越小越精细但计算越慢 -- /time processing time-to-teleport value-1/ !-- 设置为-1禁止车辆“瞬移”有助于发现路径错误 -- /processing /configuration这个文件非常直观它告诉SUMO仿真从0秒开始到3600秒结束每一步模拟0.1秒的现实时间。使用的路网是simple_cross.net.xml车辆数据来自simple_flow.rou.xml。time-to-teleport是一个有用的调试参数如果车辆因为路径问题卡住经过一段时间默认300秒后会被“瞬移”到终点。我们设为-1禁用此功能这样一旦有车卡住仿真会停滞我们能立刻发现问题。3.4 运行与观察仿真万事俱备只欠运行。你有两种方式运行图形化运行推荐新手打开SUMO-GUI在启动界面直接点击“Open Simulation...”按钮选择我们刚创建的simple_cross.sumocfg文件。或者在命令行中导航到文件所在目录执行sumo-gui -c simple_cross.sumocfg程序加载后点击界面上的“运行”按钮绿色三角。你应该能看到车辆从西边和北边生成并驶向交叉口。由于我们之前将交叉口类型设为了traffic_light车辆会在路口根据信号灯等待或通行。SUMO-GUI默认会为新的信号灯交叉口生成一个简单的固定配时方案。无界面运行如果你不需要看画面只想快速运行或集成到脚本中可以使用命令行版本的SUMOsumo -c simple_cross.sumocfg运行后没有图形界面但会在终端输出日志信息。这种方式通常用于批量测试或后台计算。在SUMO-GUI中你可以通过鼠标悬停在车辆、车道或信号灯上来查看详细信息。你可以通过“Settings”菜单调整仿真速度加快或减慢。这是一个最简单的可运行仿真它验证了你的SUMO环境、路网和基础交通流生成都是正常的。4. 进阶使用Python脚本自动化流程手动编辑XML文件对于简单场景还行但一旦路网变复杂、交通需求多样化手动编写就非常低效且容易出错。SUMO的一大优势是与Python的深度集成。我们可以用Python脚本自动化整个流程从生成路网到创建复杂车流。4.1 利用sumolib和traci库SUMO主要提供两个Python库sumolib用于读写和处理SUMO的配置文件、路网文件等。它可以在仿真之外使用用于准备工作。traci(Traffic Control Interface)用于在仿真运行过程中与SUMO仿真内核进行实时交互。你可以用它来获取车辆位置、速度动态改变信号灯配时甚至控制单个车辆是进行自动驾驶算法、交通控制策略研究的核心工具。首先确保安装了这些库。如果你通过包管理器如apt, brew安装了SUMO它们可能已包含。也可以通过pip安装pip install sumolib traci注意版本需与SUMO匹配。4.2 示例自动生成随机车流我们写一个Python脚本替代之前手动编写simple_flow.rou.xml的过程实现更灵活的车流生成。#!/usr/bin/env python3 import os import sys import subprocess import random # 假设sumo的tools目录在环境变量中否则需要指定路径 SUMO_HOME os.environ.get(SUMO_HOME, /usr/share/sumo) # Linux常见路径 # Windows示例: SUMO_HOME rC:\Program Files (x86)\Eclipse\Sumo tools os.path.join(SUMO_HOME, tools) # 将tools目录加入Python路径以便导入sumolib if tools not in sys.path: sys.path.append(tools) # 现在可以导入sumolib try: import sumolib except ImportError: print(无法导入sumolib请检查SUMO_HOME环境变量或路径设置。) sys.exit(1) def generate_random_trips(net_file, output_route_file, num_trips100, begin0, end3600): 为一个给定的路网生成随机出行需求。 参数: net_file: 输入的路网文件 (.net.xml) output_route_file: 输出的车辆路径文件 (.rou.xml) num_trips: 要生成的出行数量 begin: 仿真开始时间 end: 仿真结束时间 # 1. 读取路网 net sumolib.net.readNet(net_file) # 2. 获取所有可能的边缘道路ID edges net.getEdges() edge_ids [edge.getID() for edge in edges if edge.allows(passenger)] # 只允许小车的道路 if len(edge_ids) 2: print(路网中可用于生成出行的道路太少。) return # 3. 生成XML内容 xml_content [routes] # 定义车辆类型 xml_content.append( vType idcar accel2.6 decel4.5 sigma0.5 length5.0 maxSpeed13.89/) # 为每次出行生成随机起点和终点 for i in range(num_trips): # 随机选择起点和终点边缘确保它们不同 from_edge random.choice(edge_ids) to_edge random.choice(edge_ids) while to_edge from_edge and len(edge_ids) 1: # 避免起点终点相同 to_edge random.choice(edge_ids) # 随机生成出发时间均匀分布在[begin, end]区间内 depart_time random.uniform(begin, end) # 出发时间保留一位小数更符合仿真步长 depart_time round(depart_time, 1) # 创建车辆定义 # 注意这里我们直接指定了edges但更严谨的做法是调用DUAROUTER计算路径 # 这里为了简单假设车辆直接从起点边开到终点边如果可达 xml_content.append(f vehicle idveh{i} typecar depart{depart_time}) xml_content.append(f route edges{from_edge} {to_edge}/) xml_content.append( /vehicle) xml_content.append(/routes) # 4. 写入文件 with open(output_route_file, w, encodingutf-8) as f: f.write(\n.join(xml_content)) print(f已生成 {num_trips} 个随机出行需求保存至 {output_route_file}) print(f**注意此简单脚本直接指定了路径 edges\{from_edge} {to_edge}\。) print(f 在实际复杂路网中这可能导致路径无效。下一步应使用DUAROUTER计算真实路径。) def run_duarouter(net_file, trip_file, output_route_file): 使用DUAROUTER为出行需求文件计算实际路径。 # 构建DUAROUTER命令 duarouter_cmd [ duarouter, --net-file, net_file, --route-files, trip_file, --output-file, output_route_file, --ignore-errors, # 忽略一些不严重的错误 --remove-loops, # 移除路径中的循环 ] print(f正在运行DUAROUTER计算路径...) try: result subprocess.run(duarouter_cmd, checkTrue, capture_outputTrue, textTrue) print(DUAROUTER运行成功。) # 可以解析输出这里简单显示 if result.stdout: print(result.stdout[-500:]) # 打印最后500字符通常包含总结信息 except subprocess.CalledProcessError as e: print(fDUAROUTER运行失败返回码: {e.returncode}) print(f错误输出:\n{e.stderr}) sys.exit(1) except FileNotFoundError: print(未找到duarouter命令。请确保SUMO二进制目录已添加到系统PATH环境变量中。) sys.exit(1) if __name__ __main__: # 文件路径 NET_FILE simple_cross.net.xml # 上一步生成的路网 TRIP_FILE random_trips.trip.xml # 中间文件仅包含出行需求起终点、时间 ROUTE_FILE random_flow.rou.xml # 最终文件包含计算后的完整路径 # 步骤1生成随机出行需求仅起终点 generate_random_trips(NET_FILE, TRIP_FILE, num_trips50, begin0, end1000) # 步骤2使用DUAROUTER根据路网计算实际可行路径 run_duarouter(NET_FILE, TRIP_FILE, ROUTE_FILE) print(f\n下一步) print(f1. 修改你的配置文件 (.sumocfg)将 route-files 指向新生成的 {ROUTE_FILE}。) print(f2. 运行仿真sumo-gui -c your_config.sumocfg)这个脚本做了两件事generate_random_trips函数读取路网文件随机选择起点和终点道路生成包含50个出行需求的random_trips.trip.xml文件。这个文件只有“谁、何时、从哪到哪”的信息没有具体路径。run_duarouter函数调用SUMO的duarouter程序根据路网拓扑结构为random_trips.trip.xml中的每一个出行需求计算出一条合理的行驶路径并输出最终的random_flow.rou.xml文件。注意事项直接拼接起点和终点Edge ID作为路径如脚本中简单示例所示在复杂路网中几乎一定会失败因为车辆可能无法直接从一个Edge到达另一个Edge。最佳实践永远是使用DUAROUTER或类似的路径分配器来计算路径。上面的脚本演示了标准的“先生成出行需求Trip再计算路径Route”的两步流程。运行这个脚本后你会得到一个新的random_flow.rou.xml文件。修改之前的simple_cross.sumocfg将route-files valuesimple_flow.rou.xml/改为route-files valuerandom_flow.rou.xml/再用SUMO-GUI打开你会看到车辆从随机的边缘出现驶向随机的目的地行为更加丰富。5. 仿真输出分析与可视化仿真跑起来了但如何评估结果呢SUMO可以输出丰富的仿真数据我们需要学会收集和解读它们。5.1 配置输出文件首先我们需要在配置文件中告诉SUMO我们想要哪些数据。修改simple_cross.sumocfg在configuration标签内添加output部分configuration input net-file valuesimple_cross.net.xml/ route-files valuerandom_flow.rou.xml/ /input time begin value0/ end value3600/ step-length value0.1/ /time processing time-to-teleport value-1/ /processing !-- 新增输出配置 -- output !-- 输出车辆轨迹数据非常详细可用于后续深度分析 -- fcd-output valuefcd_output.xml/ !-- 输出车道级别的检测器数据如流量、密度、速度 -- lanearea-output valuelanearea_output.xml/ !-- 输出车辆行程信息如每辆车的行驶时间、路程、等待时间等 -- tripinfo-output valuetripinfo_output.xml/ !-- 输出排队长度信息 -- queue-output valuequeue_output.xml/ /output /configuration重新运行仿真使用sumo而非sumo-gui以更快完成结束后会在目录下生成一系列XML输出文件。这些文件是纯文本格式虽然可读但不直观。我们需要借助工具将其可视化或进行统计。5.2 使用plot_summary.py进行基本分析SUMO的tools目录下自带了许多有用的Python工具。其中一个叫plot_summary.py的脚本可以快速从tripinfo_output.xml中提取并绘制关键绩效指标KPIs。在命令行中确保当前目录在输出文件所在处且SUMO的tools目录在Python路径中运行python3 /path/to/sumo/tools/output/plot_summary.py tripinfo_output.xml这个脚本会生成一个HTML文件如plot_summary.html用浏览器打开它你会看到一系列图表包括行程时间分布所有车辆完成行程所用时间的直方图。行驶速度分布车辆平均速度的分布。等待时间分布车辆在等待速度低于某个阈值上花费的时间。时间序列图随着仿真时间推移平均速度、总车辆数等的变化。这些图表能让你快速对仿真系统的整体运行效率有一个宏观把握。例如如果平均行程时间非常长或者等待时间占比很高说明你的路网设计或信号配时可能存在瓶颈。5.3 使用traceExporter.py可视化轨迹fcd_output.xml文件包含了所有车辆每一仿真步长的位置、速度信息数据量很大。我们可以用traceExporter.py脚本将其转换为KML格式用于Google Earth或GPX格式。python3 /path/to/sumo/tools/traceExporter.py --fcd-input fcd_output.xml --net-input simple_cross.net.xml --output-prefix vehicle_traces --kml运行后会产生一个vehicle_traces.kml文件。在Google Earth中打开这个文件你可以看到所有车辆的运行轨迹动画在真实的地球模型上回放虽然地理位置是虚拟的。这对于向非技术人员展示仿真效果非常有用。5.4 自定义数据处理与分析对于更深入的分析你需要自己编写Python脚本解析这些XML输出。以tripinfo_output.xml为例使用Python的xml.etree.ElementTree库可以轻松提取数据import xml.etree.ElementTree as ET import pandas as pd tree ET.parse(tripinfo_output.xml) root tree.getroot() data [] for tripinfo in root.findall(tripinfo): veh_id tripinfo.get(id) depart float(tripinfo.get(depart)) arrival float(tripinfo.get(arrival)) duration float(tripinfo.get(duration)) route_length float(tripinfo.get(routeLength)) waiting_time float(tripinfo.get(waitingTime)) data.append([veh_id, depart, arrival, duration, route_length, waiting_time]) df pd.DataFrame(data, columns[vehicle_id, depart, arrival, duration, distance, waiting_time]) print(df.describe()) # 查看统计数据概览 print(f\n平均行程时间: {df[duration].mean():.2f} 秒) print(f平均等待时间占比: {(df[waiting_time].sum() / df[duration].sum() * 100):.2f}%)这段代码将行程信息读入Pandas DataFrame方便你进行任何自定义的统计分析、过滤和可视化。这是科研和工程中从仿真数据挖掘价值的关键一步。6. 常见问题与排查技巧实录在实际操作中你一定会遇到各种报错和意想不到的行为。这里记录了几个最常见的问题和我的排查经验。6.1 车辆不移动或瞬间消失这是新手遇到最多的问题。症状车辆生成后原地不动或者出现一下立刻消失。可能原因及排查路径Route错误这是最可能的原因。检查你的.rou.xml文件中route标签的edges属性。确保其包含的Edge ID序列在路网文件.net.xml中确实存在且首尾相连构成一条可达路径。使用sumolib检查路径连通性或先用DUAROUTER生成路径。车辆起始位置无效对于vehicle如果指定了departPos出发位置确保该位置在起点Edge的长度范围内。仿真步长与车辆插入如果depart时间是小数而仿真步长step-length较大可能导致车辆在“两帧之间”被插入看起来像没动。确保depart时间是仿真步长的整数倍或使用departtriggered等属性。禁用了瞬移如果你在配置中设置了time-to-teleport value-1/且车辆路径真的有问题仿真会卡住。可以暂时将其设为正值如300看错误日志中是否有车辆因无法到达目的地而被移除的警告。排查技巧在SUMO-GUI中运行仿真时打开“Settings - View Settings”在“Vehicle”标签下勾选“Show route”。这样每辆车上会显示一条细线代表其预定路径。如果这条线是红色的或者根本没有线就说明路径有问题。这是最直观的调试方法。6.2 交叉口通行异常无信号灯时症状在没有信号灯的交叉口typepriority车辆互相卡死谁也不让谁。可能原因SUMO的优先权规则right-of-way rules基于道路的“优先级”属性。默认情况下所有道路优先级相同。在同等优先级下来自右方的车辆拥有路权靠右行驶规则。解决方案检查道路优先级在NETEDIT中选中连接交叉口的某条道路Edge在属性面板中查看Priority。提高主干道的优先级如设为2或3降低支路的优先级保持为1。高优先级道路上的车辆在交叉口拥有优先通行权。添加让行标志在NETEDIT的“Additional Mode”下可以选择添加stop或yield标志到特定的车道连接Lane-to-lane connection上强制某些方向的车流让行。改用交通信号灯对于复杂的无信号灯交叉口手动调整优先级和让行规则可能很繁琐。不如直接将其类型改为traffic_light让信号灯来管理冲突。6.3 交通信号灯配时修改SUMO自动生成的信号灯配时非常简单通常只是几个相位循环。要修改它找到信号灯文件当你保存含交通信号灯的路网时NETEDIT会同时生成一个额外的.tll.xml文件Traffic Light Logic。或者你可以使用netedit打开路网在“Inspection Mode”下点击信号灯交叉口在属性中直接编辑tlType和programID或者导出逻辑文件。理解配时结构一个信号灯逻辑包含多个phase相位。每个相位有duration持续时间秒和state状态字符串。状态字符串由字符组成每个字符对应交叉口的一个具体车道连接字符含义如G绿灯、g绿灯但即将变红、r红灯、y黄灯、s停车让行等。手动或编程修改你可以直接用文本编辑器修改.tll.xml文件调整相位顺序和时长。更强大的方式是在仿真中通过traci库动态调整配时实现自适应信号控制。6.4 性能优化与大规模仿真当你的路网变得很大成千上万个节点和边车辆数上万时仿真速度可能会变慢。增大仿真步长在配置文件中将step-length value0.1/增加到0.5或1.0。这会降低仿真的时间精度但能显著提高速度。对于宏观交通流研究步长1秒通常可以接受。关闭不必要的输出如非必要不要在配置文件中启用fcd-output等详细输出它们会写入大量数据严重拖慢仿真并占用磁盘空间。只开启你真正需要的数据输出。使用无界面模式sumosumo-gui的图形渲染本身会消耗大量资源。进行批量测试或参数寻优时务必使用命令行版本的sumo。简化车辆模型使用更简单的跟驰模型在vType中设置carFollowModel例如“IDM”比默认的“Krauss”计算量稍小。但要注意模型行为的变化。分区仿真对于超大规模城市仿真可以考虑将路网划分为多个区域分别仿真再处理边界交通流。但这属于高级话题需要复杂的设置。我个人在跑一个中等城市约2000个节点5000条边的仿真时如果开启全轨迹输出仿真速度可能比实时慢10倍以上。关闭详细输出后通常能达到实时速度的2-5倍。性能优化是一个在精度和速度之间的权衡过程需要根据你的具体研究目标来调整。本文还有配套的精品资源点击获取
返回列表