使用 SUMO 的交叉口速度引导

系列文章目录

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

SUMO轨迹图的绘制和traci接口的简单使用

SUMO利用转弯率构建车流rou文件

sumo仿真netgenerate使用

文章目录

目录

前言

二、仿真场景搭建

1.SUMO仿真场景搭建

2.车速引导算法实现

1.功能函数实现:

2.速度引导控制主程序实现:

三、程序结果分析

结论分析


前言

最近,本人由于项目上和一些实际上的学习需求,本文利用SUMO仿真平台对交叉口速度引导进行了一定的实践。


一、交叉口速度引导公式推算

根据车辆的速度、信号相位等信息,基本可以将车辆经过交叉口的速度引导情景概括为以下几类:

①绿灯匀速通过

phase = green

t_g >d/v _0

②绿灯加速通过

phase = green

\frac{d_u-(v_{max}^{2}-v_{0}^{2})/2a}{v_{max}^{2}}+\frac{v_{max}-v_0}{a}<t_g<d/v_0

③绿灯减速通过

phase = green

 t_g<\frac{d_u-(v_{max}^{2}-v_{0}^{2})/2a}{v_{max}^{2}}+\frac{v_{max}-v_0}{a}

t_g+t_r<\frac{d_u-(v_{min}^{2}-v_{0}^{2})/2a_d}{v_{min}^{2}}+\frac{v_{min}-v_0}{a_d}

④绿灯停车

phase = green

  t_g<\frac{d_u-(v_{max}^{2}-v_{0}^{2})/2a}{v_{max}^{2}}+\frac{v_{max}-v_0}{a}

t_g+t_r > \frac{d-(v_{min}^{2}-v_0^{2})}{v_{min}}+\frac{v_{min}-v_0}{a_d}

⑤红灯匀速通过

phase = red

t_r<d/v_0<t_g+t_r

⑥红灯加速通过

phase = red

\frac{d_u-(v_{max}^{2}-v_{0}^{2})/2a}{v_{max}^{2}}+\frac{v_{max}-v_0}{a}<t_g+t_r<d/v_0

⑦红灯减速通过

phase = red

d/v_0<t_r <\frac{d_u-(v_{min}^{2}-v_0^2)/2a_d}{v_{min}}+\frac{v_{min}-v_0}{a_d}

⑧红灯停车

phase = red

t_r > \frac{d-(v_{max}^2-v_0^2)/2a_d}{v_{min}}+\frac{v_{min}-v_0}{a_d}

下面对于上述八种情况对于引导速度的计算过程

①绿灯匀速通过:

车辆能够匀速通过,如果车辆行驶速度较低,不仅不利于交叉口的通行效率提升,也提升了整体燃油消耗。

因此如果车辆速度<经济速度:

v_{guide}=v_{eco}

如果车辆速度大于经济速度:

v_{guide}=v_0

②红灯匀速通过:

v_{guide}=v_0

③加速通过:

v_{guide}=v_0+aT_a-\sqrt{a^2T_a^2+2v_0T-2aL}

④减速通过:

v_{guide}=v_0+a_dT_d-\sqrt{a_d^2T_d^2+2v_0T-2a_dL}

⑤停车通过:

v_{guide} = v_{min}

二、仿真场景搭建

1.SUMO仿真场景搭建

由于本文所进行构建的场景为工程场景,需要使用项目地址的路网,所以本文利用OSM真实路网构建仿真场景。为了能够更加便利地构建真实道路网络,这里使用SUMO自带的OSM web wizard工具,自动生成真实路网。

 

点击generate即可自动生成路网,以及车流文件,但是本文中所使用的算法仅为一阶段算法,不考虑车辆排队和车辆之间的相互作用,因此实际运用过程中,还需要对车流做进一步 调整。构建完成的路网如下:

仿真车流为项目道路,双向车流,车流量为60辆/小时 

 

2.车速引导算法实现

1.功能函数实现:

①信号周期计算:

def cycle_time(tls_id):
    tls_logic = traci.trafficlight.getAllProgramLogics(tls_id)#获取下一信号交叉口的控制方案
    current_phase = tls_logic[0].currentPhaseIndex#获取信号相位traci.simulation.getCurrentTime()/1000#获取当前仿真时间
    cycle_time = 0#周期时长初始化
    for i in  range(len(tls_logic[0].phases)):
        cycle_time += tls_logic[0].phases[i].duration#将控制方案中各相位的控制方案累加获得周期长
    return cycle_time

②获取交叉口各相位进口道信息:

def incoming_lane(tls_id):
    logic = traci.trafficlight.getAllProgramLogics(tls_id)#获取控制方案
    in_lane = traci.trafficlight.getControlledLanes(tls_id)
    program = logic[0]
    phase = {}#定义空相位
    for i in range(len(program.phases)):#遍历信号相位
        if i%2 ==0:#因为相位中间存在黄灯信号,所以绿灯信号全为双数
            phase[i] = program.phases[i].state#信号为logic格式,.state是其中的具体信号控制方案
    incoming_lanes_all = {}#定义进口车道集
    for i in phase:#遍历相位
        incoming_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])
                #print(incoming_lanes)
            k = k+1
        incoming_lanes_all[i] = incoming_lanes#将每一相位的车道保存
    return incoming_lanes_all

③获取下一绿灯相位开始时间和结束时间

def next_green(vehicle_id):
    data = traci.vehicle.getNextTLS(vehicle_id)#获取下一信号交叉口信息
    tls_id_1 = data[0][0]#获取交叉口id
    in_lane = incoming_lane(tls_id_1)#获取各相位进口道
    cycle = cycle_time(tls_id_1)#获取周期时长
    current_lane = traci.vehicle.getLaneID(vehicle_id)#获取车辆所在车道
  
    signal_state_1 = data[0][3]#获取当前车道信号状态
    phases = traci.trafficlight.getAllProgramLogics(tls_id_1)[0].phases#获取信号相位
    phases_num  = len(phases)#获取相位数
    remaining_time = traci.trafficlight.getNextSwitch(tls_id_1) - traci.simulation.getCurrentTime()/1000 #获取当前信号相位剩余时间
    
    if current_lane in in_lane[0]:#如果当前车道为相位0通行相位,则绿灯相位为0
        green_phase = 0
        #print(green_phase)
        
        
    elif current_lane in in_lane[2]:#如果当前车道为相位2通行相位,则绿灯相位为2
        green_phase = 2
        #print(green_phase)
        
    elif current_lane[0:8] == 'cluster':
        print(current_lane)
        green_phase = 0
        
        
    else :
        print("绿灯相位读取错误")
        green_phase = 0
    current_phase = traci.trafficlight.getPhase(tls_id_1)
    
    
    if signal_state_1 == 'g' or signal_state_1 == 'G':#如果当前相位为绿灯
        next_g_start = cycle - traci.trafficlight.getPhaseDuration(tls_id_1) + remaining_time#下一绿灯开始时间为周期长-当前相位周期时长+相位剩余时间
        next_g_end = cycle + remaining_time#下一绿灯结束时间为周期长加相位剩余时间
        
        
    elif signal_state_1 == 'r' or signal_state_1 == 'y':
        
        if green_phase == 0 :
            if current_phase == 1:#如果为黄灯相位
                next_g_start = remaining_time+phases[2].duration+phases[3].duration#下一绿灯开始为剩余时间+下一相位+下一相位
                next_g_end = next_g_start + phases[0].duration
            elif current_phase == 2:
                next_g_start = remaining_time + phases[3].duration
                next_g_end = next_g_start + phases[0].duration
            elif current_phase == 3:
                next_g_start = remaining_time
                next_g_end = next_g_start + phases[0].duration
                
                
            elif current_phase == 0:
                next_g_start = remaining_time + phases[1].duration
                next_g_end = remaining_time + phases[1].duration + phases[2].duration
                
                
        if green_phase == 2:#如果绿灯相位为相位2
            if current_phase == 3:
                next_g_start = remaining_time+phases[0].duration+phases[1].duration
                next_g_end = next_g_start + phases[2].duration
            elif current_phase == 0:
                next_g_start = remaining_time+phases[1].duration
                next_g_end = next_g_start + phases[2].duration
            elif current_phase == 1:
                next_g_start = remaining_time
                next_g_end = next_g_start + phases[2].duration
                
                
                
    return next_g_start,next_g_end

④建议速度计算:

def advise_speed(vehicle_id,next_g_start,next_g_end):
    min_speed = 2.0#最小速度
    max_speed = traci.vehicle.getAllowedSpeed(vehicle_id)#道路通行最大速度
    acc = traci.vehicle.getAccel(vehicle_id)#加速度
    dec = -traci.vehicle.getDecel(vehicle_id)#减速度
    distance = traci.vehicle.getNextTLS(vehicle_id)[0][2]#车辆距离交叉口距离
    speed_now = traci.vehicle.getSpeed(vehicle_id)#当前车辆速度
    phase_now = traci.vehicle.getNextTLS(vehicle_id)[0][3]#下一交叉口相位
    if phase_now == 'G' or phase_now == 'g':#如果相位为绿灯
        remaining_time = traci.trafficlight.getNextSwitch(traci.vehicle.getNextTLS(vehicle_id)[0][0]) - traci.simulation.getCurrentTime()/1000
        if remaining_time > distance/(speed_now+0.01):#绿灯匀速通过
            speed_advise = speed_now
            traci.vehicle.setColor(vehicle_id,(0,255,0))#设置颜色为绿色
            print('speed_now:',speed_now)
            print(speed_advise,'绿灯匀速通过')
            
            
        elif remaining_time > ((distance-(max_speed**2-speed_now**2)/(2*acc))/max_speed + (max_speed-speed_now)/acc) and remaining_time<distance/(speed_now+0.0000000001):
            discriminant = acc**2*remaining_time**2+2*acc*speed_now*remaining_time-2*acc*distance #计算方程判别式
            accTime = (acc*remaining_time-math.sqrt(discriminant))/acc
            speed_advise = speed_now+accTime*acc #绿灯加速通过
            traci.vehicle.setColor(vehicle_id,(255,0,255))#设置颜色为粉色
            print('speed_now:',speed_now)
            print(speed_advise,'绿灯加速通过')
            
        elif remaining_time <= ((distance-(max_speed**2-speed_now**2)/(2*acc))/max_speed + (max_speed-speed_now)/acc) and next_g_start < ((distance-(min_speed**2-speed_now**2)/(2*dec))/min_speed + (min_speed-speed_now)/dec) :
            discriminant_1 = dec**2*next_g_start**2+2*dec*speed_now*next_g_start-2*dec*distance
            decTime_1 = (dec*next_g_start+math.sqrt(discriminant_1))/dec
            speed_advise_1 = speed_now + decTime_1*dec#绿灯减速通行   最大速度
            
            discriminant_2 = dec**2*next_g_end**2+2*dec*speed_now*next_g_end-2*dec*distance
            decTime_2 = (dec*next_g_end+math.sqrt(discriminant_2))/dec
            speed_advise_2 = speed_now + decTime_2*dec#绿灯减速通行  最小速度
            
            speed_advise = (speed_advise_1+speed_advise_2)/2# 确保车辆能够通过
            
            traci.vehicle.setColor(vehicle_id,(0,255,255))#设置颜色为蓝色
            
            print(traci.simulation.getCurrentTime()/1000)
            print('speed_now:',speed_now)
            print(speed_advise_1,speed_advise_2,'绿灯减速通行')
        
        
        elif remaining_time <= ((distance-(max_speed**2-speed_now**2)/(2*acc))/max_speed + (max_speed-speed_now)/acc) and next_g_start >= ((distance-(min_speed**2-speed_now**2)/(2*dec))/min_speed + (min_speed-speed_now)/dec) :
            discriminant = dec**2*next_g_start**2+2*dec*speed_now*next_g_start-2*dec*distance
            decTime = (dec*next_g_start+math.sqrt(discriminant))/dec
            speed_advise = speed_now + decTime*dec#绿灯减速停车
            if speed_advise<min_speed:
                speed_advise = min_speed
            
            traci.vehicle.setColor(vehicle_id,(255,0,0))#设置为红色
            print('speed_now:',speed_now)
            print(speed_advise,'绿灯减速停车')
            
    if phase_now == 'r' or phase_now == 'y':
        if next_g_start< distance/(speed_now+0.01) and next_g_end> distance/(speed_now+0.01):
            if distance/(speed_now+0.01)-next_g_start < 2:
                speed_advise = distance/(next_g_start+3)
                print('略微减速')
            else:
                speed_advise = speed_now #红灯匀速通行
            traci.vehicle.setColor(vehicle_id,(255,255,255))#设置颜色为白色
            print('speed_now:',speed_now)
            print(speed_advise,'红灯匀速通过')
            
            
        elif next_g_start < distance / (speed_now+0.0000001) and next_g_start > ((distance-(max_speed**2-speed_now**2)/(2*acc))/max_speed + (max_speed-speed_now)/acc):
            discriminant = dec**2*next_g_start**2+2*dec*speed_now*next_g_start-2*dec*distance #计算方程判别式
            decTime = (dec*next_g_start+math.sqrt(discriminant))/dec
            speed_advise = speed_now + decTime*dec#红灯减速通行
            traci.vehicle.setColor(vehicle_id,(0,0,255))#设置颜色为蓝色
            print('speed_now:',speed_now)
            print(speed_advise,'红灯减速通过')
            
            
        elif next_g_end>((distance-(max_speed**2-speed_now**2)/(2*acc))/max_speed + (max_speed-speed_now)/acc) and next_g_end<distance/(speed_now+0.00000001):
            discriminant = acc**2*next_g_end**2+2*acc*speed_now*next_g_end-2*acc*distance #计算方程判别式
            accTime = (acc*next_g_end-math.sqrt(discriminant))/acc
            speed_advise = speed_now+accTime*acc #红灯加速通过
            traci.vehicle.setColor(vehicle_id,(255,0,255))#设置颜色为粉色
            print('speed_now:',speed_now)
            print(speed_advise,'红灯加速通过')
            print(traci.simulation.getCurrentTime()/1000)
            
            
        else :
            print('红灯减速停车')
            speed_advise = min_speed
            traci.vehicle.setColor(vehicle_id,(255,0,0))#设置为红色
        
    
    return speed_advise

2.速度引导控制主程序实现:

while traci.simulation.getMinExpectedNumber() > 0:
    traci.simulationStep()
    for vehicle_id in traci.vehicle.getIDList():
        traci.vehicle.setMaxSpeed(vehicle_id,16.67)
        allowed_speed = traci.vehicle.getAllowedSpeed(vehicle_id)#获取路网允许速度

            
        if traci.vehicle.getNextTLS(vehicle_id) != ():#确保车辆下一交叉口信息不为空
            if traci.vehicle.getNextTLS(vehicle_id)[0][2] < 210: #车辆进入交叉口停止线210m范围内
                next_g_start , next_g_end =  next_green(vehicle_id)#获取下一绿灯开始时间、结束时间
                distance = traci.vehicle.getNextTLS(vehicle_id)[0][2]#获取距离交叉口停止线的距离
                speed_adv = advise_speed(vehicle_id,next_g_start,next_g_end)#获取引导速度
                traci.vehicle.setSpeed(vehicle_id,speed_adv)#对车辆速度进行控制
                
                
            elif traci.vehicle.getNextTLS(vehicle_id)[0][2] > 220:#车辆距离交叉口大于220m时,控制车辆按照正常速度行驶
                traci.vehicle.setColor(vehicle_id,(255,255,0))
                traci.vehicle.setSpeed(vehicle_id,allowed_speed)
                
        elif traci.vehicle.getNextTLS(vehicle_id) == ():#如果车辆即将离开路网,控制车辆按允许速度行驶
            print(vehicle_id,'结束')
            traci.vehicle.setColor(vehicle_id,(255,255,0))
            traci.vehicle.setSpeed(vehicle_id,allowed_speed)#对车辆速度进行控制
                

三、程序结果分析

仿真结果:

优化前后行程时间,技术参数表

 

arrivalSpeed

行程时间

等待时间

启停次数

timeLoss

优化后

13.92

469.93

0.00

0.00

129.93

优化前

13.64

425.48

49.59

3.31

85.58

优化前后步均燃油消耗量及污染物

 

CO2

CO

HC

Nox

PMx

fuel

优化后

13963.28786

21.5826697

0

124.2140218

2.719787913

5.919309

优化前

14829.80422

22.3261729

0

129.304049

2.773325695

6.28883

仿真图像:

车辆运动轨迹图:

正向车流

优化前:

优化后:

逆向车流:

优化前:


优化后:

速度-距离图:

优化前:

优化后:

结论分析

        本文所提出的车辆速度引导算法可以在不考虑排队车辆和车辆间相互影响的情况下,显著减少车辆的启停次数和排队等待时间,但是由于SUMO仿真默认按照较高的速度行驶,速度引导算法为了使车辆能够顺利通过,部分场景使用了较低的引导速度,所以行程时间和timeloss并没有显著下降。

       下一阶段算法的设计将考虑排队长度、车辆间的相互影响,队列的信号优化等方面,可以使得算法的使用场景更加广阔,实用性更强。如果有朋友对这一方面感兴趣,欢迎交流讨论。

物联沃分享整理
物联沃-IOTWORD物联网 » 使用 SUMO 的交叉口速度引导

发表评论