当前位置:   article > 正文

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

traci.vehicle.moveto

fb200be532427c1705a312ee463b780d.png

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

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

一、道路文件的产生

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

158f8689062a9d0d8ce98f7c6626f6bc.png
netedit绘图

二、车辆文件的产生

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

13dffa4dcc98953438584d15e37e9cab.png
车辆类型参数

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

  1. <vType id="bus" accel="2" decel="2" length="10" maxSpeed="12" guiShape="bus"/>
  2. <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函数,在每步仿真中,它真正发挥作用从而实现单车控制。

  1. if __name__ == "__main__":
  2. options = get_options()
  3. if options.nogui:
  4. sumoBinary = checkBinary('sumo')
  5. else:
  6. sumoBinary = checkBinary('sumo-gui')
  7. traci.start([sumoBinary, "-c", "C:/Users/liqin/Desktop/buslane/buslane.sumocfg", "--tripinfo-output",
  8. "tripinfo.xml"]) # 多次调用
  9. for step in range(0, 3600):
  10. while traci.simulation.getMinExpectedNumber() > 0:
  11. traci.simulationStep()
  12. run()
  13. traci.close()
  14. sys.stdout.flush()

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

  1. def run():
  2. for carID in traci.vehicle.getIDList():
  3. p = 0.5 #驾驶员反应时间
  4. if traci.vehicle.getLanePosition(carID): #车辆在车道上进行控制
  5. lane = traci.vehicle.getLaneID(carID)
  6. changeLane = controlModel(carID).changeLane()
  7. if lane == "gneE1_0":#如果在最右侧车道
  8. if changeLane[0]:#如果进行换道,则换至中间车道,换道时间为10s,下同
  9. traci.vehicle.changeLane(carID, 1, 10)
  10. else:#如果不进行换道,则更新速度与位置,下同
  11. speed_next = controlModel(carID).speed_generate()
  12. traci.vehicle.setSpeed(carID, speed_next)
  13. traci.vehicle.moveTo(carID, lane, speed_next*(1+p)+traci.vehicle.getLanePosition(carID))
  14. elif lane == "gneE1_2":#如果在最左侧车道
  15. if changeLane[0]:
  16. traci.vehicle.changeLane(carID, 1, 10)
  17. else:
  18. speed_next = controlModel(carID).speed_generate()
  19. traci.vehicle.setSpeed(carID, speed_next)
  20. traci.vehicle.moveTo(carID, lane, speed_next*(1+p)+traci.vehicle.getLanePosition(carID))
  21. elif lane == "gneE1_1":#如果在最中间车道
  22. if changeLane[0]:
  23. if changeLane[1]:
  24. traci.vehicle.changeLane(carID, 2, 10)
  25. elif changeLane[2]:
  26. traci.vehicle.changeLane(carID, 0, 10)
  27. else:
  28. speed_next = controlModel(carID).speed_generate()
  29. traci.vehicle.setSpeed(carID, speed_next)
  30. 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。

  1. #得到前车id
  2. def frontCar(self):
  3. m= 200
  4. vehicle_frontCarID=""
  5. for carID in traci.vehicle.getIDList():#找到车辆的前车
  6. lanePosition = traci.vehicle.getLanePosition(carID)
  7. if traci.vehicle.getLaneID(carID) == se
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/645534
推荐阅读
相关标签
  

闽ICP备14008679号