SUMO TraCI使用示例:TraCIPedCrossing

本文介绍如何使用SUMO交通仿真软件及其接口TraCI进行行人过马路仿真,并提供了一个具体的示例代码,演示了如何控制红绿灯信号来确保行人安全通过交叉口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

严正声明:本文系作者davidhopper原创,未经许可,不得转载。

SUMO全称Simulation of Urban Mobility,是一个开源、微观、多模态交通仿真模拟软件。TraCI是“Traffic Control Interface”(交通控制接口)的缩写,包含在SUMO内部, 可以通过访问正在执行的道路交通仿真情景,获取仿真对象的值并“在线”操纵其行为。简而言之,TraCI是一个用于外部算法在线操作SUMO仿真器的接口工具。本文以TraCIPedCrossing为例,简介TraCI的使用方法。
使用该示例之前,请按照我的博客Ubuntu 16.04系统中SUMO安装方法及简单示例安装SUMO并配置环境变量SUMO_HOME,参照另一篇博客Ubuntu 16.04系统中基于OSM创建并运行SUMO网络模型,将SUMO源代码中的data目录复制到/usr/share/sumo目录。

一、将示例代码TraCIPedCrossing复制到工作目录

如果使用apt-get方法安装SUMO,则示例代码TraCIPedCrossing默认位于/usr/share/doc/sumo-doc/tutorial目录,使用Ctrl+Alt+T打开一个命令终端,通过如下命令将其复制到你自己的工作目录(我使用~/code/sumo-exercise):

# 进入示例目录
cd /usr/share/doc/sumo-doc/tutorial

# 将traci_pedestrian_crossing目录复制到~/code/sumo-exercise目录
# ~/code/sumo-exercise目录是我的工作目录,你可以根据需要选择其他目录
cp -r traci_pedestrian_crossing ~/code/sumo-exercise

# 进入traci_pedestrian_crossing目录
cd ~/code/sumo-exercise/traci_pedestrian_crossing

# 刚复制过来的目录中有几个gz压缩包,需要将其解压
gzip -d runner.py.gz
gzip -d data/viewsettings.xml.gz

二、运行示例

在命令行终端中执行如下命令,运行示例:

python runner.py 

此时会弹出一个SUMO-GUI窗口,点击其中的绿色播放按钮,即可看到行人过马路的仿真场景:
1

三、信号逻辑及runner.py代码解释

TraCIPedCrossing示例中,行人过马路的红绿灯信号逻辑如下所示(见data/pedcrossing.tll.xml):

<tlLogic id="C" type="static" programID="custom" offset="0">
     <phase duration="100000" state="GGGGr"/> <!-- do not switch vehicle phase automatically -->
     <phase duration="4" state="yyyyr"/>
     <phase duration="10" state="rrrrG"/>
     <phase duration="10" state="rrrrr"/> <!-- give pedestrians time to clear the intersection -->
</tlLogic>

默认状态是"GGGGr"phase = 0)表示由绿灯转换为红灯,绿灯时间100000秒,表明该状态不会自动切换至其他状态。状态中的小写字母表示车流必须减速
状态"yyyyr"phase = 1)表示由黄灯转换为红灯,黄灯持续时间4秒;
状态"rrrrG"phase = 2)表示由红灯转换为绿灯,红灯持续时间10秒;
状态"rrrrr"phase = 3)表示由红灯持续状态,维持时间10秒,用于行人完全通过交叉路口。
上述状态除了phase = 0切换到phase = 1需要人工指定外,其余情况都会在每个状态指定的持续时间后自动切换到后续状态。
我个人认为:phase = 2phase = 3写反了,正确的信号逻辑应该如下所示:

<tlLogic id="C" type="static" programID="custom" offset="0">
     <phase duration="100000" state="GGGGy"/> <!-- do not switch vehicle phase automatically -->
     <phase duration="4" state="yyyyr"/>
     <phase duration="10" state="rrrrr"/>
     <phase duration="10" state="rrrrG"/> <!-- give pedestrians time to clear the intersection -->
</tlLogic>

参照如下代码块中的注释,了解TraCI的一般调用过程:

# 为兼容python 2.7所做的措施
from __future__ import absolute_import
from __future__ import print_function

# 导入相关包
import os
import sys
import optparse
import subprocess
import random


# 本脚本文件所在的目录
THISDIR = os.path.dirname(__file__)

# 需要从$SUMO_HOME/tools目录导入相关包,为此需要先设置环境变量SUMO_HOME,
# 若未设置,请设置之。
try:
    # tutorial in tests
    sys.path.append(os.path.join(THISDIR, '..', '..', '..', '..', "tools"))
    # tutorial in docs
    sys.path.append(os.path.join(os.environ.get("SUMO_HOME", os.path.join(
        THISDIR, "..", "..", "..")), "tools"))  
    import traci
    from sumolib import checkBinary  # noqa
    import randomTrips
except ImportError:
    sys.exit(
        "please declare environment variable 'SUMO_HOME' as the root directory of your sumo installation (it should contain folders 'bin', 'tools' and 'docs')")

# 车辆的最短绿灯时间
MIN_GREEN_TIME = 15
# 红绿灯仿真计划的初始状态,参见'pedcrossing.tll.xml'    
VEHICLE_GREEN_PHASE = 0
# 红绿灯的ID(仅包含一个),默认情况下它与受控交叉路口的ID相同。
TLSID = 'C'

# 受控交叉口的人行横道边界
WALKINGAREAS = [':C_w0', ':C_w1']
CROSSINGS = [':C_c0']

# TraCI控制主循环过程
def run():   
    # 记录允许车辆通行的绿灯持续时间    
    greenTimeSoFar = 0

    # 行人过马路按钮是否按下
    activeRequest = False

    # 主循环。在每个仿真步骤中执行某些操作,直到场景中没有新的车辆加入或现有车辆行驶
    while traci.simulation.getMinExpectedNumber() > 0:
        traci.simulationStep()

        # 如果车辆的绿灯时间超过最短绿灯时间,则确定是否有等待过马路的行人,并切换信号灯状态
        if not activeRequest:
            activeRequest = checkWaitingPersons()
        if traci.trafficlight.getPhase(TLSID) == VEHICLE_GREEN_PHASE:
            greenTimeSoFar += 1
            if greenTimeSoFar > MIN_GREEN_TIME:

                # 检测行人是否按下了过马路按钮
                if activeRequest:
                    # 信号灯切换至另一个状态,即非绿灯状态
                    # VEHICLE_GREEN_PHASE + 1表明切换到黄灯转红灯状态
                    traci.trafficlight.setPhase(
                        TLSID, VEHICLE_GREEN_PHASE + 1)
                    # 复位相关变量
                    activeRequest = False
                    greenTimeSoFar = 0

    sys.stdout.flush()
    traci.close()

# 检测是否有行人需要过马路
def checkWaitingPersons():

    # 检测路口两侧的行人
    for edge in WALKINGAREAS:
        peds = traci.edge.getLastStepPersonIDs(edge)

        # 检测是否有人在路口等待
        # 我们假设行人在等待1秒后,才按下过马路按钮
        for ped in peds:
            if (traci.person.getWaitingTime(ped) == 1 and
                    traci.person.getNextEdge(ped) in CROSSINGS):
                print("%s pushes the button" % ped)
                return True
    return False

# 定义本脚本文件及从命令行中解析得到的参数
def get_options():

    optParser = optparse.OptionParser()
    # 增加一个"--nogui"选项,默认值为False,即默认使用图形化界面
    optParser.add_option("--nogui", action="store_true",
                         default=False, help="run the commandline version of sumo")
    options, args = optParser.parse_args()
    return options


# 本脚本文件主入口
if __name__ == "__main__":

    # 获取程序运行的参数
    options = get_options()

    # 确定是调用sumo还是sumo-gui
    if options.nogui:
        sumoBinary = checkBinary('sumo')
    else:
        sumoBinary = checkBinary('sumo-gui')

    net = 'pedcrossing.net.xml'
    # 借助工具软件netconvert,从普通的xml输入构建多模态网络
    subprocess.call([checkBinary('netconvert'),
                     '-c', os.path.join('data', 'pedcrossing.netccfg'),
                     '--output-file', net],
                    stdout=sys.stdout, stderr=sys.stderr)

    # 随机生成仿真中的行人
    randomTrips.main(randomTrips.get_options([
        '--net-file', net,
        '--output-trip-file', 'pedestrians.trip.xml',
        '--seed', '42',  # make runs reproducible
        '--pedestrians',
        '--prefix', 'ped',
        # prevent trips that start and end on the same edge
        '--min-distance', '1',
        '--trip-attributes', 'departPos="random" arrivalPos="random"',
        '--binomial', '4',
        '--period', '35']))

    # 这是启动TraCI的一般方法。sumo作为子进程启动,然后使用本脚本文件连接该子进程  
    traci.start([sumoBinary, '-c', os.path.join('data', 'run.sumocfg')])
    # 调用TraCI控制主循环过程
    run()
### SUMO 中行人通行道交叉设计的实现方法 #### 行人过街仿真的基本原理 SUMO 的 Traffic Control Interface (TraCI) 提供了一种机制,允许用户实时控制和监控仿真过程中的各种对象,包括车辆、信号灯以及行人。通过 TraCI 接口,可以动态调整行人的路径规划及其与其他交通参与者的交互方式[^1]。 #### 配置行人过街场景的关键要素 为了在 SUMO 中实现行人通行道交叉的设计与仿真,需完成以下几个方面的配置: 1. **定义路网结构** 路网文件(通常是 `.net.xml` 文件)应包含行人专用通道的信息。这可以通过 NETEDIT 工具手动编辑或将 OpenStreetMap 数据导入 SUMO 来自动生成带有斑马线和其他设施的地图[^2]。 2. **设置行人属性** 在需求文件(`.rou.xml` 或其他类似的输入数据文件)中指定行人的出发位置、目的地以及其他相关参数,例如行走速度等特性。这些信息决定了行人如何移动并通过特定区域。 3. **应用逻辑控制策略** 利用 Python API 结合 TraCI 功能编写脚本来管理复杂的事件序列,比如检测是否有车接近路口从而决定是否让行人安全穿越马路。具体来说,“TraCIPedCrossing示例展示了怎样监听即将到达十字路口附近的汽车状态,并据此暂停或者放行等待中的步行者群体。 4. **验证与优化方案效果** 借助可视化界面观察整个系统的运作情况;同时记录重要指标用于后续分析评估不同设计方案的效果差异。如果发现某些地方存在瓶颈,则可进一步微调相应规则直至达到满意的结果为止。 以下是基于上述描述的一个简化版代码片段展示如何利用 TraCI 控制行人穿过街道的过程: ```python import traci def control_pedestrian_crossing(): step = 0 while step < 1000: traci.simulationStep() # 获取靠近交叉口的所有车辆ID列表 vehicle_ids = traci.lane.getLastStepVehicleIDs("lane_id_for_check") if not vehicle_ids: # 如果没有车辆则允许行人通过 traci.person.setSpeed('ped_ID', 1.5) # 设置正常步速 else: # 否则减速甚至停止直到道路清空 current_speed = traci.person.getSpeed('ped_ID') new_speed = max(0, current_speed - 0.1) traci.person.setSpeed('ped_ID', new_speed) step += 1 if __name__ == "__main__": try: traci.start(['sumo-gui', "-c", "your_config.sumocfg"]) control_pedestrian_crossing() finally: traci.close() ``` 此段伪代码仅作为概念证明用途,在实际部署前可能还需要考虑更多细节因素来增强鲁棒性和用户体验感等方面的表现。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值