SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案

文章目录

  • 前言
  • 一、Traci接口是什么
  • 二、获取方法
    • 1.建立路网、车流和检测器
    • 2.调用traci接口,启动仿真
    • 3.获取车道转向信息
    • 4.通过E2检测器获得车道信息
    • 5.获取每个相位放行车道信息
  • 总结


前言

本人小白,blog仅供记录本人的以下学习过程和结果,仅供大家参考学习。欢迎交流指正。


一、Traci接口是什么

traci是微观交通流仿真软件的交通控制接口,全称为”Traffic Control Interface“。SUMO 本身可以实现很多实际交通场景的模拟。当 SUMO 被用作智能交通控制算法的测试平台时,需要其与外界程序/算法实现很好的互动,例如用户自定义的控制算法可以从 SUMO 获取实时交通信息,然后对其中车辆状态、信号灯状态等进行实时控制。TraCI 就是实现这类互动的接口。

作用:获取 SUMO 交通模拟环境中的数据,并实时修改、控制。

二、获取方法

1.建立路网、车流和检测器

建立路网、车流等基础操作较为常见,不做过多介绍,这里简单介绍一下我所使用的检测器的布设方法。
SUMO安装包中自带了检测器的自动布设工具,可以一键生成道路检测器,如下图所示,分别是自动生成E1,E2,E3类型检测器的方法。
在这里插入图片描述
上述自动布设工具的使用需要将路网文件和.py工具至于同一目录下或添加较为完整的文件路径,具体的调用命令为:

python generateTLSE2Detectors.py -n sumo.net.xml -o E2.add.xml

这样就会生成一个E2.add.xml的检测器文件,在sumocfg中需要在中加入这一该文件(如下图所示),不然无法调用刚才生成的E2检测器
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第1张图片
完整的路网如下图所示:
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第2张图片

2.调用traci接口,启动仿真

代码如下(示例):

import os
import sys
import optparse
import random
from sumolib import checkBinary  # noqa
import traci  # noqa
import pandas as pd

if 'SUMO_HOME' in os.environ:
    tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
    sys.path.append(tools)
else:
    sys.exit("please declare environment variable 'SUMO_HOME'")
    
sumocfg_file = "demo.sumocfg"#这里输入仿真的cfg文件
if__show__gui =True
if not if__show__gui :
    sumoBinary = checkBinary('sumo')
else :
    sumoBinary = checkBinary('sumo-gui')
 
traci.start([sumoBinary, "-c", sumocfg_file])#这里通过traci接口启动仿真程序

程序启动成功后,在cfg界面中点击启动按钮,会获得一条反馈
在这里插入图片描述

3.获取车道转向信息

在进行信号控制方面的研究时,可能需要获取每个相位放行的车道的转向信息,并根据车道转向进行车道属性计算。由于traci自带的接口获取的信息包含一定的其他无效信息(如下图所示),这里对信息提出一种过滤方案,如下所示
在这里插入图片描述

代码如下(示例):

def get_dir(lane_list):#传入需要判断的车道信息
    dir = {}
    for lane in lane_list:
        if len(traci.lane.getLinks(lane)) == 2:#因为例子中只有直右一种双向车道,所以这样定义
            dir[lane] = 'sr'
        elif len(traci.lane.getLinks(lane)) == 1:#如果为单转向车道
            if traci.lane.getLinks(lane)[0][7] !=0:#并且最后一项不为0,如果为0则为junction内车道
                dir[lane] = traci.lane.getLinks(lane)[0][6]#该项为车道的转向信息
    dir_d = pd.DataFrame.from_dict(dir,orient='index')#将dir转换为dataframe格式
    dir_d.rename(columns={0:"dir"},inplace = True)
                
    return dir_d

获取到的信息格式如下:
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第3张图片


4.通过E2检测器获得车道信息

E2检测器对应着显示中类似于交叉口的摄像头的同能,能够获得检测信号范围内的车辆排队长度、道路占用率等信息。由于在实际运用过程中,使用接口获得单条数据不利于信息的处理,本文提出一种信息获取方法。

def get_info(decid):#传入检测器id信息
    quene_lenth={}#定义排队长度
    occ = {}#定义占有率
    lane_length = {}#定义车道长度
    for dets in decid:#遍历检测器
        lane_id = traci.lanearea.getLaneID(dets)#通过检测器获取车道id
        lane_length[lane_id] = traci.lane.getLength(lane_id)#获取车道长度并记录
        quene_lenth[lane_id] = traci.lanearea.getJamLengthMeters(dets)#获取排队长度并记录
        occ[lane_id] = traci.lanearea.getLastStepOccupancy(dets)#获取占有率并记录
    quene_lenth_d = pd.DataFrame.from_dict(quene_lenth,orient='index')#将排队长度转换为dataframe
    quene_lenth_d.rename(columns={0:"quene_lenth"},inplace = True)#更改数据标签
    occ_d = pd.DataFrame.from_dict(occ,orient='index')
    occ_d.rename(columns={0:"occ"},inplace = True)
    lane_length_d = pd.DataFrame.from_dict(lane_length,orient='index')
    lane_length_d.rename(columns={0:"length"},inplace = True)
    data = pd.concat([quene_lenth_d,occ_d,lane_length_d],axis=1)#融合获取的数据信息
    
    return data

获取到的交叉口信息如下所示
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第4张图片
通过pandas操作可以将上述获得的信息融合:
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第5张图片

5.获取每个相位放行车道信息

由于traci.trafficlight.getphase无法直接获取每个相位的放行信息,这里通过遍历信号灯的控制方案,获得每一相位的控制方案,选择‘G’的车道,并记录,构成放行车道信息,具体如下所示:
通过Traci接口获取到的信号方案如下所示:
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第6张图片

logic = traci.trafficlight.getAllProgramLogics("gneJ0")#获取控制方案
program = logic[1]
phase = {}#定义空相位	
for i in range(len(program)):#遍历信号相位
    if i%2 ==0:#因为相位中间存在黄灯信号,所以绿灯信号全为双数
        phase[i] = program[i].state#信号为logic格式,.state是其中的具体信号控制方案
incoming_lanes_all = {}#定义进口车道集
outcoming_lanes_all = {}#定义出口车道集
for i in phase:#遍历相位
    incoming_lanes = []#定义进口空车道
    outcoming_lanes = []#定义空出口车道
    k = 0#控制相位数
    print(phase[i])
    for j in phase[i]:
        print(k)
        if j =='G':#将’G‘对应的车道记录下来
            print(k)
            incoming_lanes.append(in_lane[k])
            outcoming_lanes.append(out_lane[k])
            print(incoming_lanes)
        k = k+1
    incoming_lanes_all[i] = incoming_lanes#将每一相位的车道保存
    outcoming_lanes_all[i] = outcoming_lanes

通过上述代码获取的进口车道信息和出口车道信息如下所示:
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第7张图片
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第8张图片
与信号控制接口获取的信息一致
SUMO使用E2检测器获取信号交叉口车道信息和信号控制方案_第9张图片

总结

本文主要介绍了本人在学习过程中一些利用traci接口获取交通流信息和交叉口信息的一些方式方法,仅供大家参考,如果有什么疑问或意见,欢迎评论区或私信交流讨论。

你可能感兴趣的:(sumo,python,交通物流)