fvdm 跟驰模型 matlab仿真_SUMO仿真案例

该博客介绍了如何在MATLAB中使用SUMO进行fvdm跟驰模型和车道换道的微观仿真,以优化交通效率。作者复刻了一篇关于间歇式公交专用道的研究,模拟了三车道场景,控制单车辆行为,并实现了基于拥堵情况的社会车辆换道和跟驰策略。仿真平台的搭建和车辆控制策略,包括跟驰规则(加速、减速、慢启动、随机慢化)和换道规则(相邻车道空间、安全距离)进行了详细说明。

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

fb200be532427c1705a312ee463b780d.png

本次复刻的论文是《停靠站附近间歇式公交专用道适用条件研究》,发表在华东交通大学学报,时间为2020年。

首先简要介绍这篇文章,间歇式公交专用道(IBL)允许社会车辆行驶在公交车道上,能够有效的提升车辆的通行效率,基于IBL的研究,这篇文章主要优化了车辆跟驰规则和换道规则,建立了三车道元胞自动机车辆换道模型。这次基于SUMO的微观仿真,对单车进行逐一控制,在简化这篇文章模型的同时,完成了仿真平台的搭建。最终达到的效果简单概括即是,在车联网的环境下,社会车辆基于拥堵状况及时换道并且不影响公交车的通行,在同一车道上车辆采取跟驰策略,最终提升通行效率。

一、道路文件的产生

文章中模拟路段为200m,不考虑交叉口,车道数为3,本次复刻不考虑公交车的到站停靠。画出三车道路段如下图并保存为buslane.net.xml文件。

158f8689062a9d0d8ce98f7c6626f6bc.png
netedit绘图

二、车辆文件的产生

车辆文件buslane.rou.xml由vehicle_generate.py文件产生。包括三部分,分别为车辆本身、车辆类型和路线。本次仿真中涉及两类车辆,分别为社会车辆和公交车,其车辆属性取值由文章给出如下。

13dffa4dcc98953438584d15e37e9cab.png
车辆类型参数

由此可写出.rou.xml文件中的车辆类型为

<vType id="bus" accel="2" decel="2" length="10" maxSpeed="12" guiShape="bus"/>
<vType id="car" accel="4" decel="4" length="5" maxSpeed="20" guiShape="passenger"/>

SUMO中最右侧、中间和左侧车道定义分别为0,1,2,公交车只行驶在最右侧车道,本次仿真中公交车流量约为100pcu/h,最右侧、中间和左侧车道的社会车辆流量分别约为3600pcu/h,1500pcu/h,1500pcu/h,通过循环,可以控制车辆生成的数量;本次的车辆路线唯一。

三、主控制文件

主控制文件为mainFunction.py,总仿真时间为3600s,通过多次调用traci接口,实现每个仿真步长(1s)控制车道上每辆车的效果。主控制函数如下。注意其中的run函数,在每步仿真中,它真正发挥作用从而实现单车控制。

if __name__ == "__main__":
    options = get_options()

    if options.nogui:
        sumoBinary = checkBinary('sumo')
    else:
        sumoBinary = checkBinary('sumo-gui')

    traci.start([sumoBinary, "-c", "C:/Users/liqin/Desktop/buslane/buslane.sumocfg", "--tripinfo-output",
                 "tripinfo.xml"])  # 多次调用
    for step in range(0, 3600):
        while traci.simulation.getMinExpectedNumber() > 0:
            traci.simulationStep()
            run()
    traci.close()
    sys.stdout.flush()

run函数具体代码如下图,其中驾驶员反应时间为0.5s。根据这篇文章中的解释,驾驶员的换道行为一般受到换道动机和换道条件的制约,因此需要决策是否需要换道。若进行换道,则采取SUMO内部的换道模型,利用traci.vehicle.changeLane进行控制;若不进行换道,则采用文章中的跟驰规则,生成下一时刻的车辆速度与位置。

def run():
    for carID in traci.vehicle.getIDList():
        p = 0.5 #驾驶员反应时间
        if traci.vehicle.getLanePosition(carID): #车辆在车道上进行控制
            lane = traci.vehicle.getLaneID(carID)
            changeLane = controlModel(carID).changeLane()
            if lane == "gneE1_0":#如果在最右侧车道
                if changeLane[0]:#如果进行换道,则换至中间车道,换道时间为10s,下同
                    traci.vehicle.changeLane(carID, 1, 10)
                else:#如果不进行换道,则更新速度与位置,下同
                    speed_next = controlModel(carID).speed_generate()
                    traci.vehicle.setSpeed(carID, speed_next)
                    traci.vehicle.moveTo(carID, lane, speed_next*(1+p)+traci.vehicle.getLanePosition(carID))
            elif lane == "gneE1_2":#如果在最左侧车道
                if changeLane[0]:
                    traci.vehicle.changeLane(carID, 1, 10)
                else:
                    speed_next = controlModel(carID).speed_generate()
                    traci.vehicle.setSpeed(carID, speed_next)
                    traci.vehicle.moveTo(carID, lane, speed_next*(1+p)+traci.vehicle.getLanePosition(carID))
            elif lane == "gneE1_1":#如果在最中间车道
                if changeLane[0]:
                    if changeLane[1]:
                        traci.vehicle.changeLane(carID, 2, 10)
                    elif changeLane[2]:
                        traci.vehicle.changeLane(carID, 0, 10)
                else:
                    speed_next = controlModel(carID).speed_generate()
                    traci.vehicle.setSpeed(carID, speed_next)
                    traci.vehicle.moveTo(carID, lane, speed_next*(1+p) + traci.vehicle.getLanePosition(carID))

四、跟驰规则与换道规则

文章中的跟驰规则与换道规则定义在controlModel.py文件中,定义类controlModel。根据主控制文件发现,我们主要要返回的是两点,一是是否要进行换道的决策(布尔值),二是下一时刻的速度值。在这里我们分开讨论。

跟驰规则,返回下一时刻的车辆速度值,用speed_generate函数生成。根据文章内容,跟驰规则主要分为加速过程、减速过程、慢启动现象、随机慢化四个部分,有了下一时刻的速度,下一时刻的位置更新就好求解了。在这四个部分中,获取当前车道的前车id、相邻车道的前车id和相邻车道的后车id是十分重要的,相邻车道的前后车id的寻找思路相同,因此以下只列举找到同车道前车id和后车id的代码,利用遍历可得。寻找相邻车道的前后车id时,注意中间车道的相邻车道有两个,因此需要分别找到其相邻两个车道的前车id。

    #得到前车id
    def frontCar(self):
        m= 200
        vehicle_frontCarID=""
        for carID in traci.vehicle.getIDList():#找到车辆的前车
            lanePosition = traci.vehicle.getLanePosition(carID)
            if traci.vehicle.getLaneID(carID) == self
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值