最近有位做智能交通课题的师弟问我,在Ubuntu 22.04上到底怎么把SUMO完整装起来,还要跑通第一个交通仿真。他说照网上的教程折腾了一整天,不是缺依赖就是版本对不上,最后连sumo-gui都启动不了。说实话,这类问题我自己也踩过不少坑,尤其SUMO这工具表面看安装简单,实际用起来文件格式、环境变量、工具链哪一环出错都够喝一壶。所以这次干脆把从全新系统到跑通第一个仿真的整个流程整理成一篇保姆级笔记,尽量说人话,把命令、参数、文件含义和报错排查都讲透。无论你是做车联网研究、搞自动驾驶仿真,还是课堂上第一次接触交通仿真的学生,照着这篇走都能把环境搭起来,并理解SUMO的基本工作方式。
1. 项目导读:SUMO能做什么,这套教程解决什么问题
1.1 SUMO到底是什么
SUMO全称Simulation of Urban MObility,是一款开源、微观、多模态的交通仿真软件。所谓"微观",意思是它把每一辆车当作独立个体建模,车有自己的长度、最大速度、期望速度、跟车行为等,而不是像宏观模型那样只看整体车流密度。你可以把SUMO理解成"交通世界里的模拟城市":先在软件里画出一张路网,给定每条路的车道数、限速、通行方向,再注入一批车辆,设置它们的出发时间、起点和终点,SUMO就会按照跟驰模型逐秒推演每辆车的运动状态。
它在学术界和工业界的应用非常广泛:城市交通规划、信号灯配时优化、网联车与车路协同仿真、自动驾驶算法测试等。很多自动驾驶模拟链路也会把SUMO作为背景交通生成器。换句话说,SUMO是很多交通相关研究的基础工具,学会它能让你在后续课题里省去大量从零造轮子的时间。
1.2 为什么选择Ubuntu 22.04做仿真环境
Windows上其实也有SUMO安装包,很多教程也基于Windows,但我在实际项目里更推荐Linux环境。原因有三个:第一,SUMO大量配套工具是Python脚本,Linux下的Python环境更干净,依赖冲突更少;第二,后续你想做批量仿真、调用TraCI接口做二次开发时,Linux下的进程调度和脚本环境都更顺手;第三,很多涉及SUMO的科研项目代码默认就在Linux环境下,提前用Ubuntu能避免"换环境就要改代码"的尴尬。
Ubuntu 22.04 LTS是当前生命周期较长的稳定版本,软件仓库里自带SUMO,安装非常简单。即便你需要自己编译最新版,22.04的依赖库也都能直接装上,不用折腾老版本的兼容问题。所以这篇教程就以22.04为基准,其他Debian系发行版逻辑类似,但是命令可能会有差异。
1.3 这套教程的学习路径
读完这篇文章你会经历三个阶段:装环境、建场景、看结果。第一阶段把SUMO本体和工具链装好,第二阶段用netedit画一个简单十字路口,用脚本生成车流,第三阶段把仿真跑起来,并读取输出文件分析平均旅行时间和等待时间。整体不需要任何交通工程专业基础,只要会基本Linux命令就能跟下来。遇到看不懂的术语不用慌,我会在关键点做解释,同时也会分享一些常规文档里不会写的避坑经验。
2. 环境准备与安装方案选型
2.1 检查Ubuntu环境基础
动手之前,先确认你的系统版本和基本硬件。在终端执行:
cat /etc/os-release | grep VERSION看到VERSION_ID="22.04"就说明系统版本正确。内存方面,SUMO本身不太苛求,跑小场景2GB内存都够,但后面如果要做大规模城市路网仿真,建议至少8GB。因为SUMO在运行时会为每辆车维护运动状态对象,车辆数上万以后内存消耗会明显上升。硬盘不用特别准备,SUMO本体加工具链加起来不到1GB,给/tmp留点空间编译就够了,源码编译时临时文件会占用不少。
另外,确保系统里已有基本工具和git。没有的话先装:
sudo apt update sudo apt install -y build-essential git cmake python3 python3-pipPython在后面生成车流、分析结果时都要用,建议先把python3和pip装好。build-essential和cmake这两个包,如果你不打算源码编译SUMO,其实可以不装,但我习惯提前备好,避免后面临时缺环境。
2.2 安装方式的取舍:apt包管理器 vs 源码编译
SUMO的安装方式主要两种。第一种是用Ubuntu官方源的apt install sumo,优点是快、省心、依赖自动处理,缺点是版本可能比官方最新版滞后一些。对于大多数人,尤其是只想先把流程跑通的学生和研究者,我强烈建议用apt方式,没必要一上来就折腾源码编译。
第二种是源码编译安装,适合需要SUMO新特性、想修改源码、或者需要特定版本做对比实验的人。源码编译的好处是版本可控、能自定义优化选项,坏处是耗时长、依赖坑多,对新手不太友好。我的建议是先apt装上,等用熟了确实有需求再去编译最新版。
注意:无论哪种方式,都不要混用。比如你先用apt装了SUMO,后来又编译了一个新版覆盖,PATH里两个版本共存,很容易出现sumo命令是旧的、Python库是新的这种"版本分裂"问题。我的习惯是:日常用apt版本,特殊需求在单独目录编译并手动指定路径,不去动系统默认安装。
2.3 推荐大众方案:apt安装的完整流程
apt安装SUMO其实就一条命令,但包要选对:
sudo apt install -y sumo sumo-tools sumo-doc我解释一下为什么是这三个包。sumo是主程序,提供sumo(命令行仿真器)和sumo-gui(图形仿真器);sumo-tools提供大量辅助Python脚本,比如后面要用的randomTrips.py;sumo-doc是离线文档,包括HTML手册与示例文件,对排查问题很有用。有些人只装sumo,结果找不到randomTrips.py,就是因为漏了sumo-tools。
安装完成后,先验证一下基本命令是否在PATH里:
which sumo sumo-gui sumo --version正常情况下你会看到类似sumo Version 1.18.0的输出。如果which没有任何输出,说明安装路径有问题,但Ubuntu的apt一般会把可执行文件装到/usr/bin下,通常不会出现这个问题。如果确实找不到,可以执行dpkg -L sumo | grep bin/看看实际路径。
2.4 进阶方案:源码编译安装SUMO
如果你确实需要从源码编译,我把跑通的流程放这里。先安装编译依赖:
sudo apt install -y libxerces-c-dev libproj-dev libfox-1.6-dev libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxft-dev libxext-dev libopenscenegraph-dev然后下载源码并编译:
git clone --recursive https://github.com/eclipse-sumo/sumo.git cd sumo mkdir build/cmake-build && cd build/cmake-build cmake ../.. make -j$(nproc)--recursive参数一定要带,SUMO的部分子模块是通过submodule引入的,漏了会导致编译时找不到文件。cmake阶段如果报缺库,根据提示apt install对应的-dev包补上即可。编译完的二进制在bin目录下,运行方式为./bin/sumo-gui --version。另外源码编译方式下SUMO_HOME要指向源码根目录,这个后面再细说。
3. 安装后的环境配置与验证
3.1 配置SUMO_HOME环境变量
SUMO的很多Python辅助脚本会读取环境变量SUMO_HOME来定位工具目录。不设置的话,直接运行python3 tools/randomTrips.py很可能会报环境变量相关的错误。所以装完第一步就是配环境变量。
先确认SUMO的安装目录,apt方式下SUMO_HOME一般是/usr/share/sumo。可以用下面这条命令验证:
ls /usr/share/sumo/tools/randomTrips.py如果没有这个文件,多半是sumo-tools没装好,重装一下:sudo apt install --reinstall sumo-tools。确认路径存在后,把它写入~/.bashrc:
echo 'export SUMO_HOME=/usr/share/sumo' >> ~/.bashrc echo 'export PATH=$PATH:$SUMO_HOME/bin' >> ~/.bashrc source ~/.bashrc源码编译方式的话,把SUMO_HOME指向源码根目录,比如/home/你的用户名/sumo。验证是否生效:
echo $SUMO_HOME ls $SUMO_HOME/tools/randomTrips.py3.2 验证安装是否完整
环境变量配好后,再跑一次完整验证。命令行仿真用sumo --version,图形界面可以用sumo-gui --version(这个命令只打印版本,不弹窗口,适合无图形终端)。工具脚本的验证可以找一下randomTrips.py:
ls $SUMO_HOME/tools/randomTrips.py我还会建议在一个临时目录里跑一遍SUMO自带的示例来确认整体链路。比如/usr/share/sumo/tests/sumo/basic_usage下有一些可运行的场景。直接进到里面执行sumo -c data/restart.sumocfg,能正常跑完就说明核心功能没问题。
3.3 理解SUMO核心命令行工具
配置好环境后,先别急着建场景,建议花五分钟认识一下SUMO的几个核心程序:
- sumo:纯命令行仿真器,适合批量仿真、无图形环境、远程服务器上跑数据。
- sumo-gui:带图形界面的仿真器,能实时看到车辆移动、信号灯变化,适合调试和演示。
- netedit:路网编辑器,可视化绘制道路、信号灯、检测器,是后续创建自定义路网最常用的工具。
除了程序,tools目录下还有大量脚本,比如randomTrips.py(随机生成车流)、netgenerate(用参数生成抽象路网)、traceExporter(把轨迹导出成其他格式)。这些脚本极大扩展了SUMO的可用性,创建第一个仿真时就会用到randomTrips.py。
4. 从零搭建第一个交通仿真场景
4.1 先搞懂SUMO的三大核心文件
在动手之前,必须把SUMO的文件体系讲清楚,因为绝大多数仿真报错都出在文件类型混乱上。一个基本SUMO项目至少包含三个文件:
- 路网文件(.net.xml):描述道路拓扑、车道数、限速、连接关系、信号灯位置等,是仿真的骨架。它由netedit或netgenerate生成,一般不会手写。
- 车流文件(.rou.xml):描述车辆类型、每辆车的出发时间、出发路线。可以是手写XML,但通常由randomTrips.py生成。
- 仿真配置文件(.sumocfg):把上面两个文件组合起来,并指定仿真起止时间、输出文件等。这才是你每次运行sumo时传入的参数对象。
你可以把三者类比成一个实验:路网是实验台,车流是实验样本,配置文件是实验方案。缺了任何一个,sumo都不知道你要仿真什么。下面我逐个创建。
4.2 用netedit可视化绘制路网
先用netedit创建一个简单但又有代表性的路网:一个十字路口。这对第一次接触SUMO的人来说,比直接生成一张城市路网更容易理解"节点-边-连接"的概念。
在终端启动netedit:
netedit界面打开后,你会看到一个网格平面,左下角有模式选择按钮。要建路网,首先要放节点(junction)。选择"road"相关工具,在画布上点击几个点作为道路端点。这里我建议先放四个外沿点,再在中间放一个中心点作为交叉口。
接下来把外沿点和中心点连起来。在netedit里选"edge"工具,从一个外沿点拖到中心点,一条道路就生成了。默认每条路是单向还是双向、单车道还是双车道,可以在右侧属性面板调整。想快点的话,保持默认也行。
画完后,需要给节点和边做一点基础设置。最关键的是外沿节点要设为"dead end"类型,这样车辆到边界后不会报"失去连接"。选中每个外沿节点,在右侧属性面板把type改为deadEnd。中心节点保持默认的trafficLight或priority即可,这样十字路口会自动有信号灯或让行规则。
保存时千万注意:文件类型要选择"SUMO XML",扩展名写成demo.net.xml。不要把扩展名写成.xml或.net,SUMO对文件名后缀有约定,不符合约定很多工具会拒绝读取。保存路径建议放在~/sumo_demo目录下,方便管理。
4.3 用randomTrips.py自动生成车流
路网有了,接下来生成车流。SUMO官方推荐的方式是用randomTrips.py脚本,它会随机在路网里选择起点和终点,按指定频率生成车流文件。命令如下:
cd ~/sumo_demo python3 $SUMO_HOME/tools/randomTrips.py -n demo.net.xml -e 100 -p 2 -o demo.rou.xml参数解释:-n指定路网文件;-e 100表示仿真结束时间为100秒,脚本会在这段时间内分配出发时间;-p 2表示平均每2秒出现一辆车;-o指定输出文件。
生成的demo.rou.xml里每辆车大概长这样:
<trip id="0" depart="0.00" from="gneE1" to="gneE3"/>id是车辆编号,depart是出发时间,from和to是起点和终点边。这里用的是trip元素,SUMO在加载时会自动为每辆车计算合理路线,所以直接作为route-files使用即可。如果你希望预先计算好完整的固定路线,可以再用duarouter处理trip文件,但对第一个仿真完全不需要。
提示:randomTrips.py默认认为路网上所有边都可用。如果你的路网里有禁行边或单向边,脚本可能会报一些警告,通常不影响运行。如果报"Error: No connection between...",说明路网拓扑有问题,回到netedit检查边是否连通。
4.4 编写仿真配置文件与运行
最后写一个.sumocfg文件把路网和车流串起来。用你习惯的编辑器,这里以nano示例:
nano demo.sumo.cfg内容如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <input> <net-file value="demo.net.xml"/> <route-files value="demo.rou.xml"/> </input> <time> <begin value="0"/> <end value="110"/> </time> <processing> <threads value="2"/> </processing> </configuration>说明一下:net-file和route-files指定前面生成的两个文件;begin和end控制仿真起止时间,end建议比车流生成窗口长一点,比如车流到100秒结束,仿真到110秒,让最后一辆车有足够时间离开路网;threads是并行计算线程数,小场景随便设,大场景可以设为CPU核数。
配置好后运行:
sumo -c demo.sumo.cfg终端会滚动输出仿真信息,最后停在一个统计总览。如果没有任何报错,恭喜你,第一个交通仿真已经成功跑通了。
想看动画的话,用GUI版本:
sumo-gui -c demo.sumo.cfg窗口弹出后,底部有一排仿真控制按钮。点最左侧的绿色播放按钮,仿真就会开始跑,你会看到小车从路网边缘进入,在十字路口根据信号灯或让行规则通过。速度滑块可以调整播放速度,默认1倍速,可以拉到4倍或更高快速观察。在画面上右键某辆车,能查看它的速度、加速度、所在道路等信息,适合调试时定位问题。
5. 把仿真结果读出来并分析
5.1 开启结果输出
跑通仿真只是开始,做研究必然要分析数据。SUMO默认不在终端打印每辆车的详细信息,你需要在配置里加输出项。在demo.sumo.cfg中加入<output>部分:
<output> <tripinfo-output value="demo.tripinfo.xml"/> <vehroute-output value="demo.vehroute.xml"/> </output>tripinfo.xml记录每辆车的出行信息,包括出发时间、到达时间、旅行时间、总等待时间、行驶距离等;vehroute.xml记录每辆车实际走的路线。重新运行sumo -c demo.sumo.cfg后,目录里会多出这两个XML文件。
打开demo.tripinfo.xml,你会看到类似这样的条目:
<tripinfo id="0" depart="0.00" departEdge="gneE1" departPos="5.00" arrival="8.42" arrivalEdge="gneE3" duration="8.42" routeLength="173.21" timeLoss="1.15"/>id是车辆编号,duration是该车从出发到到达的总用时,timeLoss是行程中因信号灯、拥堵导致的延误时间。这两个指标最常用。
5.2 解读关键指标
不管你是做信号灯优化还是路线规划,下面几个口径都要搞清楚:
- duration(旅行时间):车辆从出发到进入目的地边的总时间,是评价路网效率的核心指标。
- timeLoss(时间损失):车辆因排队、减速而额外损失的时间,反映拥堵程度。它是duration减去理论最短行驶时间得到的近似值。
- routeLength(行驶距离):车辆实际行驶距离,可用于判断是否绕路。
- departDelay(出发延迟):车流文件中设置的启动延迟,在没有排队的仿真中通常为0。
如果想看整个路网的平均水平,可以写个极简Python脚本统计。在终端执行:
python3 -c " import xml.etree.ElementTree as ET tree = ET.parse('demo.tripinfo.xml') trips = tree.getroot().findall('tripinfo') durations = [float(t.get('duration')) for t in trips] time_losses = [float(t.get('timeLoss')) for t in trips] print('车辆数:', len(trips)) print('平均旅行时间:', sum(durations)/len(durations), '秒') print('平均时间损失:', sum(time_losses)/len(time_losses), '秒') "这个模板很实用,你可以把它套用到任何SUMO tripinfo输出上。
5.3 导出车辆轨迹与做图表(可选)
如果要做更深入的轨迹分析,SUMO还能输出每辆车在每个时间步的精确位置。配置里加一行:
<fcd-output value="demo.fcd.xml"/>FCD输出会非常大,小场景也有几千行XML。它能记录每辆车在每一秒的x、y坐标、速度、角度,是后期画轨迹热力图、分析拥堵形成过程的素材。用Python的xml解析或pandas读取都行。这里要提醒一句:大规模场景的fcd文件可能达到几个GB,建议只在需要时再开,并且用完后及时删除。
6. 常见问题与避坑实录
6.1 高频报错速查表
我把自己和朋友们在安装运行中遇到最多的几类问题整理成了表格,基本能覆盖新人阶段的坑:
| 症状 | 大概率原因 | 处理办法 |
|---|---|---|
| 运行sumo提示command not found | PATH没有包含可执行文件路径 | 执行which sumo,没有则重新安装或手动添加PATH |
| randomTrips.py提示环境变量问题 | SUMO_HOME未设置或路径不对 | echo $SUMO_HOME确认,补写.bashrc后source |
| sumo加载cfg时报找不到net-file | cfg里文件名或相对路径写错 | 检查文件是否存在,建议cfg和net/rou放同一目录 |
| Error: The edge ... has no connection | 路网中车道连接不全 | 打开netedit检查边与边的连接关系 |
| Error: Vehicle ... needs a departure edge | 车流起点不在路网内或外沿节点类型不对 | 确认外沿节点是deadEnd,且边的方向正确 |
| 双击sumo-gui启动没反应 | 缺图形库或远程环境无显示服务 | 桌面版不要用sudo运行;远程环境按6.2处理 |
| netedit保存后sumo拒绝加载 | 文件扩展名不是.net.xml | 另存为SUMO XML格式,并命名xxx.net.xml |
表格里有个问题值得单独说:很多人在Windows上装过SUMO,转到Linux后习惯去找安装目录,其实apt方式已经把可执行文件放进了系统PATH,没必要手动指定路径,反而SUMO_HOME这个变量特别容易被忽略。还有一种情况是系统里有多个Python版本,导致randomTrips.py用了另一个解释器,报一些奇怪的import错误,这时候用python3显式指定更保险。
6.2 图形界面无法启动的处理
这个问题的典型场景是在服务器或无桌面的Ubuntu上装了SUMO,运行sumo-gui却没反应。最简单的排查是:确认本机确实是桌面版,并且没有用sudo运行sumo-gui,因为root用户可能找不到桌面显示器。如果是在虚拟机里,确认虚拟机的显卡驱动和显示服务正常。
如果是在远程开发机上做实验,可以选择不依赖图形界面的方案:直接用sumo命令行跑仿真、分析输出文件;如果确实需要图形界面,可以通过远程桌面或X11转发进入图形会话后再启动sumo-gui,具体取决于你的远程环境。这里额外提醒一句,不要为了图省事去改系统安全配置,保持默认的安全策略才是最稳妥的。
6.3 数据文件报错的排查思路
SUMO的报错信息通常很直白,但新手容易被一堆英文吓到。我的排查经验分三步:第一步,只看第一行报错,SUMO绝大多数错误在第一个Error之后就终止了,后面的堆栈是辅助信息;第二步,检查涉及的文件路径是否存在、扩展名是否符合约定;第三步,用sumo -c demo.sumo.cfg --no-warnings忽略warning,只看真正的error。
还有一个非常实用的小技巧:在cfg里加<processing><ignore-route-errors value="true"/></processing>可以让sumo跳过某些车流错误继续运行,这对调试很有用。但正式跑数据时要关掉,否则结果统计会缺样本,影响结论准确性。
7. 一些心里话与进阶扩展建议
这篇教程到这里,你已经能跑通一个最简单的SUMO仿真了。我个人在后来的项目里越来越觉得,SUMO最大的价值不在于"装好了能运行",而在于它给了你一个完全可控的交通实验台。你可以随意改动路网结构、信号灯配时、车辆类型和流量,然后在几十秒内看到结果差异。这种快速迭代能力,是真实道路实验完全不具备的。
如果接下来想深入,我的建议是优先掌握三块内容。一是TraCI接口,它能让你用Python实时控制和读取SUMO里的车辆、信号灯,是做强化学习控制、自适应信号优化的入口;二是additional文件机制,你可以给路网添加检测器、公交线路、行人等,让场景更贴近真实;三是netedit的高级功能,比如编辑交叉口转向关系、设置车道级别参数,这些能极大提升你构建复杂路网的效率。
最后再分享一个我自己的小习惯:每次新建仿真项目,我都会建一个独立目录,把net.xml、rou.xml、cfg和输出文件分门别类放好,并写一个简单的run.sh脚本来启动仿真。这样不仅目录干净,后面的批量仿真,比如改一个参数连续跑50次,也容易自动化。希望这篇保姆级教程能帮你少走弯路,尽快把SUMO跑起来。