赞
踩
前文链接:要点初见:用Python进行微观交通模型仿真——基于SUMO的伯克利开源项目Flow Project初探与拓展
前文链接中是博主先前写TRB论文时根据个人研究所写的Flow Project介绍、代码解释以及初步的功能拓展方法介绍,简单说就是一个能用python设计运行微观交通流仿真、方便在微观交通流中进行强化学习(Reinforcement Learning)的好东西(官方链接:https://github.com/flow-project/flow)。最近写毕业论文又捡起了Flow Project用来做微观交通流仿真,安装运行了Flow官方Github上的master分支代码(最新flow版本:flow0.5.0)后发现这新版本仍然没有实现众多仿真时必要的功能,譬如每个车辆的长宽等参数定制、每条道路的行驶速度等参数定制等等。其实这些功能都是SUMO中已有的,只需要一点衔接就能在Flow中实现这些功能,Flow作为SUMO的二次开发框架可能更集中于强化学习部分的功能开发,故在基础功能开发方面未有深入。
本文不会具体介绍这些功能衔接的具体实现(想了解可以将highway_newfunc分支的代码覆盖至master分支,并用VSCode之类的IDE查看Source Control-CHANGES),本文主要是给出链接、介绍优化后的Flow超简单安装方法、介绍此次拓展出的功能,并分析示例代码(test0205.py)。本文的运行环境是 Ubuntu16.04, anaconda 4.6.11。
**************************************************************
注意:修改flow/flow中的源码后需要重新运行python setup.py develop对项目进行rebuild,Flow核心中部分的代码需要rebuild才会生效,例如flow/flow/core/kernel/simulation/、flow/flow/core/experiment.py,部分核心代码不需要rebuild也能生效,例如flow/flow/core/kernel/network/,但每次修改源码后运行python setup.py develop能避免改动未生效。
**************************************************************
不多废话,此处是在Flow(2021.2.8 master分支)上实现了这些功能衔接的代码链接(注意是highway_newfunc分支而非master分支):
Github 链接:https://github.com/BingLiHanShuang/flow/tree/highway_newfunc
百度网盘链接:https://pan.baidu.com/s/1GD3gb5sHthAzTBpvM0JTSw 提取码:59pe
此处展示通过git下载并切换至本分支所需的命令:
1、git clone https://github.com/BingLiHanShuang/flow.git
2、cd flow
3、git checkout highway_newfunc
切换至highway_newfunc分支后,Flow安装起来相比master分支更简单!具体方法如下(此时在flow目录下,需提前安装好anaconda)(参考Flow官方文档:https://flow.readthedocs.io/en/latest/flow_setup.html):
1、pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple(更适合中国宝宝体质)
2、conda env create -f environment.yml
3、pip install -r requirements.txt
4、安装sumo:根据自己的系统运行如下对应的脚本
Ubuntu 14.04:
运行flow/scripts/setup_sumo_ubuntu1404.sh
Ubuntu 16.04:
运行flow/scripts/setup_sumo_ubuntu1604.sh
Ubuntu 18.04:
运行flow/scripts/setup_sumo_ubuntu1804.sh
Mac:
运行flow/scripts/setup_sumo_osx.sh
5、运行如下命令测试sumo是否安装成功:
which sumo
sumo --version
sumo-gui
6、conda activate flow_new2
7、python setup.py develop(此步骤若运行timeout超时可多次运行)
Flow的本质实际上是通过代码自动化撰写SUMO相关的xml等文件、设定Flow参数,并调用SUMO中的Python接口TraCI从而实现SUMO仿真:前者主要由example/exp_configs里的python脚本实现,后者估摸着是由simulate.py实现。先前在stackoverflow上博主曾询问了Flow是否能实现定制每条道路单独速度的问题(https://stackoverflow.com/questions/56901221/can-we-choose-max-and-min-speeds-for-each-traffic-lane-in-flow-project),得到的回答说是可以直接单独调用TraCI实现该功能,实际上博主尝试后发现暂时还无法介入Flow调用TraCI的层面进行功能实现,但可以从撰写xml文件(即前文所述的衔接)的角度入手进行源码修改从而将SUMO中已有的功能移植到flow中。
本highway_newfunc分支修改的文件如下:
1、flow/environment.yml
2、flow/README.md
3、flow/requirements.txt
4、flow/examples/exp_configs/non_rl/test0205.py
5、flow/core/params.py
6、flow/core/kernel/network/traci.py
7、flow/networks/highway.py
本highway_newfunc分支主要实现的功能如下:
1、改进了Flow安装方法,解决了一个依赖库的版本bug:在conda env create时pip应先被安装再安装其他库。而redis需>=3.3.2才能符合environment.yml中某个库的依赖。(具体哪个忘了……)
2、为VehicleParams类增加了length、width、height和vClass参数,即可在Flow代码中添加车辆时设定该种车辆的长、宽、高、车辆类型,这些设定能在SUMO仿真中直观生效。车辆类型默认为passenger,具体内容选择可在该链接中查询: https://sumo.dlr.de/docs/Definition_of_Vehicles,_Vehicle_Types,_and_Routes.html#abstract_vehicle_class。未来还能为VehicleParams类添加的参数可以参考这个链接:https://sumo.dlr.de/docs/Definition_of_Vehicles,_Vehicle_Types,_and_Routes.html#available_vtype_attributes
3、在highway路网中增加了lane_list参数(其他路网中未添加,若想添加请参考flow/flow/networks/highway.py),即可为每个edge上的每条lane单独设定专门的行驶速度上限、禁行的车辆种类名单。SUMO中的道路(lane)是建立在edge(出发边缘)上的。禁行的车辆种类名单的书写格式为“A”或“A B C 等等”,A的内容需从上文车辆类型的具体内容链接中选取,不同种类由空格隔开。未来还能为每条道路添加的参数可以参考这个链接:https://sumo.dlr.de/docs/Networks/PlainXML.html#lane-specific_definitions
4、为TraCIKernelNetwork类增加了width参数,即可设定整个仿真中的道路宽度,同样能在SUMO仿真中直观生效。未来如果想定制每个edge中每条lane的宽度,方法可以参考3中lane_list的修改方法对源码进行修改。
5、增加了对如上4项功能的示例代码flow/examples/exp_configs/non_rl/test0205.py,也是博主毕业论文的仿真基础……目前未写测试,待问问Flow官方看不看的上这个拓展版本。
6、以上所有拓展内容都是可选的,仿真不设置上述内容一样可跑。
示例代码flow/examples/exp_configs/non_rl/test0205.py的运行方法:
1、新开一个Terminal窗口,切换到flow项目目录下
2、conda deactivate
3、source activate flow_new2
4、export PYTHONPATH="/home/hongyong/.conda/envs/flow_new2/lib/python3.7/site-packages:$PYTHONPATH"
5、python examples/simulate.py test0205 --gen_emission
输出结果:
- /home/hongyong/.conda/envs/flow_new2/lib/python3.7/site-packages/numpy/core/fromnumeric.py:3335: RuntimeWarning: Mean of empty slice.
-
- out=out, **kwargs)
-
- /home/hongyong/.conda/envs/flow_new2/lib/python3.7/site-packages/numpy/core/_methods.py:161: RuntimeWarning: invalid value encountered in double_scalars
-
- ret = ret.dtype.type(ret / rcount)
-
- Round 0, return: -0.1
-
- ./data/test0205_20210208-1735491612776949.4998093-0_emission.csv ./data
-
- Average, std returns: -0.1, 0.0
-
- Average, std velocities: nan, nan
-
- Average, std outflows: 2030.4, 0.0
-
- Total time: 220.84119844436646
-
- steps/second: 48.04350433419724
运行生成的文件:
flow/data/test0205.json
flow/data/test0205_20210208-1735491612776949.4998093-0_emission.csv (237.8 MB, 研究Flow仿真的核心所在,但太大了所以git pull前和json文件一起删了)
先给出全貌:
- """Example of an open multi-lane network with human-driven vehicles."""
-
- import traci
- from flow.core.kernel.vehicle import KernelVehicle
- from flow.core.kernel.vehicle import TraCIVehicle
- from flow.core.kernel import Kernel
- from flow.core.params import SimParams
-
- from flow.controllers import IDMController, SimLaneChangeController, RLController
- from flow.core.params import SumoParams, EnvParams, NetParams, InitialConfig, SumoLaneChangeParams, SumoCarFollowingParams
- from flow.core.params import VehicleParams, InFlows
- from flow.envs.ring.lane_change_accel import ADDITIONAL_ENV_PARAMS
- from flow.networks.highway import HighwayNetwork, ADDITIONAL_NET_PARAMS
- from flow.envs import LaneChangeAccelEnv
-
- vehicles = VehicleParams()
-
- vehicles.add(
- veh_id="rlcar",# Lincoln MKC 4552*1864*1654 THIS IS TYPE NAME
- length = 4.552,
- width = 1.864,
- height = 1.654,
- vClass = "passenger",
- #color = "1,0,0",
- acceleration_controller=(RLController, {}),
- car_following_params=SumoCarFollowingParams(
- speed_mode="obey_safe_speed",
- max_speed=33.333,
- accel=2.6, #Wait changed
- decel=4.5,
- sigma=0.5,
- tau=1.0,
- min_gap=2.5,
- speed_factor=1.0,
- speed_dev=0.1,
- impatience=0.5,
- car_follow_model="IDM"
- ),
- lane_change_params=SumoLaneChangeParams(
- lane_change_mode="only_speed_gain_safe",# no_lc_safe, Disable all SUMO lane changing but still handle safety checks (collision avoidance and safety-gap enforcement) in the simulation.
- model="SL2015",
- lc_sublane=2.0,
- ),
- num_vehicles=0)
-
- vehicles.add(
- veh_id="humancar",# Volkswagen LAVIDA 4670*1806*1474 max:120km/h
- length = 4.67,
- width = 1.806,
- height = 1.474,
- vClass = "passenger",
- #v0 : desirable velocity, in m/s (default: 30) in flow/flow/controllers/car_following_models.py 352
- acceleration_controller=(IDMController,{'v0':32}),# desirable velocity 115km/h
- car_following_params=SumoCarFollowingParams(
- speed_mode="obey_safe_speed", # default
- max_speed=33.333,
- accel=2.6, #Wait changed
- decel=4.5,
- sigma=0.5,
- tau=1.0,
- min_gap=2.5,
- speed_factor=1.0,
- speed_dev=0.1,
- impatience=0.5,
- car_follow_model="IDM"
- ),
- lane_change_params=SumoLaneChangeParams(
- lane_change_mode="only_speed_gain_safe",# sumo_default, only_speed_gain_safe, only_strategic_safe, only_cooperative_safe
- model="SL2015", # Lane-changing model for sublane-simulation [https://sumo.dlr.de/docs/Definition_of_Vehicles,_Vehicle_Types,_and_Routes.html] [https://sumo.dlr.de/docs/Simulation/SublaneModel.html]
- lc_sublane=2.0, # The eagerness for using the configured lateral alignment within the lane. Higher values result in increased willingness to sacrifice speed for alignment. default: 1.0, range [0-inf]
- ),
- num_vehicles=0)
-
- vehicles.add(
- veh_id="humanbus",# YUTONG ZK6826BEV 8245*2500*3240 max:100km/h
- length = 8.245,
- width = 2.500,
- height = 3.240,
- vClass = "bus",
- color = "1,1,0",
- acceleration_controller=(IDMController, {'v0':26.4}),# 95km/h
- car_following_params=SumoCarFollowingParams(
- speed_mode="obey_safe_speed", # default
- max_speed=27.778,
- accel=2.6, #Wait changed
- decel=4.5,
- sigma=0.5,
- tau=1.0,
- min_gap=2.5,
- speed_factor=1.0,
- speed_dev=0.1,
- impatience=0.5,
- car_follow_model="IDM"
- ),
- lane_change_params=SumoLaneChangeParams(
- lane_change_mode="only_speed_gain_safe",
- model="SL2015",
- lc_sublane=2.0,
- ),
- num_vehicles=0)
-
- vehicles.add(
- veh_id="humantruck",# FOTON BJ5319XXY-AB 12000*2550*3950 max:100km/h
- length = 12,
- width = 2.550,
- height = 3.950,
- vClass = "truck",
- color = "0,1,0",
- acceleration_controller=(IDMController, {'v0':25}),# 90km/h
- car_following_params=SumoCarFollowingParams(
- speed_mode="obey_safe_speed", # default
- max_speed=27.778,
- accel=2.6, #Wait changed
- decel=4.5,
- sigma=0.5,
- tau=1.0,
- min_gap=2.5,
- speed_factor=1.0,
- speed_dev=0.1,
- impatience=0.5,
- car_follow_model="IDM"
- ),
- lane_change_params=SumoLaneChangeParams(
- lane_change_mode="only_speed_gain_safe",
- model="SL2015",
- lc_sublane=2.0,
- ),
- num_vehicles=0)
-
- env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS)
-
- inflow = InFlows()
- inflow.add(
- veh_type="rlcar",
- edge="highway_0",
- #probability=0.025,# 0.25 probability for emitting a vehicle each second (not together with vehsPerHour or period)
- vehs_per_hour=120,#250
- depart_lane=3,# the index of the lane, starting with rightmost=0
- depart_speed=30)
-
- inflow.add(
- veh_type="humancar",
- edge="highway_0",
- #probability=0.85,# 0.25 probability for emitting a vehicle each second (not together with vehsPerHour or period)
- vehs_per_hour=2500,#15000
- depart_lane="random",#free random allowed best first
- depart_speed=30)
-
- inflow.add(
- veh_type="humanbus",
- edge="highway_0",
- #probability=0.1,
- vehs_per_hour=486,#486
- depart_lane="random",
- depart_speed=26.4)
-
- inflow.add(
- veh_type="humantruck",
- edge="highway_0",
- #probability=0.05,
- vehs_per_hour=486,#486
- depart_lane="random",
- depart_speed=25)
-
- flow_params = dict(
- # name of the experiment
- exp_tag='test0205',
-
- # name of the flow environment the experiment is running on
- env_name=LaneChangeAccelEnv,
-
- # name of the network class the experiment is running on
- network=HighwayNetwork,
-
- # simulator that is used by the experiment
- simulator='traci',
-
- # sumo-related parameters (see flow.core.params.SumoParams)
- #sim=SumoParams(
- #render=True,
- #lateral_resolution=1.0,
- #),
- sim=SumoParams(
- restart_instance=True,
- sim_step=0.1, # seconds per simulation step, default
- emission_path="./data/",
- render=True, # delegate rendering to sumo-gui for back-compatibility(Color)
- lateral_resolution=3.75,
- sight_radius=120, # sets the radius of observation for RL vehicles (meter)
- pxpm=3, # specifies rendering resolution (pixel / meter)
- show_radius=True # specifies whether to render the radius of RL observation
- #save_render=True # specifies whether to save rendering data to disk
- ),
-
- # environment related parameters (see flow.core.params.EnvParams)
- env=EnvParams(
- horizon=5000, # number of steps per rollouts
- additional_params=ADDITIONAL_ENV_PARAMS.copy(),
- ),
-
- # network-related parameters (see flow.core.params.NetParams and the
- # network's documentation or ADDITIONAL_NET_PARAMS component)
- net=NetParams(
- inflows=inflow,
- #additional_params=ADDITIONAL_NET_PARAMS.copy(),
- additional_params={
- 'length': 6000,
- 'width': 3.75,
- 'lanes': 4,# highway_0_0(right) highway_0_3(left)
- 'speed_limit': 33.333,
- 'num_edges': 1,
- # 'lane_list': {}, # must available
- 'lane_list': {'0': # edge index
- [
- {
- 'index': '0', # 0(right) n-1(left)
- 'speed': '27.778'
- },
- {
- 'index': '1',
- 'speed': '27.778'
- },
- {
- 'index': '3',
- 'speed': '33.333',
- 'disallow': "bus truck"
- }
- ]
- }, #In the order of edges index
- "use_ghost_edge": False,
- "ghost_speed_limit": 25,
- "boundary_cell_length": 500
- },
- ),
-
- # vehicles to be placed in the network at the start of a rollout (see
- # flow.core.params.VehicleParams)
- veh=vehicles,
-
- # parameters specifying the positioning of vehicles upon initialization/
- # reset (see flow.core.params.InitialConfig)
- initial=InitialConfig(
- spacing="uniform",
- shuffle=True,
- ),
- )
单步分解可以参考文首的前文链接,里面有非常详细的介绍啦。此处主要介绍与本文拓展有关的部分:
- vehicles.add(
- veh_id="humanbus",# YUTONG ZK6826BEV 8245*2500*3240 max:100km/h
- length = 8.245,
- width = 2.500,
- height = 3.240,
- vClass = "bus",
- color = "1,1,0",
- acceleration_controller=(IDMController, {'v0':26.4}),# 95km/h
- car_following_params=SumoCarFollowingParams(
- speed_mode="obey_safe_speed", # default
- max_speed=27.778,
- accel=2.6, #Wait changed
- decel=4.5,
- sigma=0.5,
- tau=1.0,
- min_gap=2.5,
- speed_factor=1.0,
- speed_dev=0.1,
- impatience=0.5,
- car_follow_model="IDM"
- ),
- lane_change_params=SumoLaneChangeParams(
- lane_change_mode="only_speed_gain_safe",
- model="SL2015",
- lc_sublane=2.0,
- ),
- num_vehicles=0)
以大客车的添加为例,你可以自由设定它的长、宽、高、车辆种类啦。在SUMO仿真中的效果图如下(即图中的黄色车辆,右侧是其SUMO参数界面):
- net=NetParams(
- inflows=inflow,
- #additional_params=ADDITIONAL_NET_PARAMS.copy(),
- additional_params={
- 'length': 6000,
- 'width': 3.75,
- 'lanes': 4,# highway_0_0(right) highway_0_3(left)
- 'speed_limit': 33.333,
- 'num_edges': 1,
- # 'lane_list': {}, # must available
- 'lane_list': {'0': # edge index
- [
- {
- 'index': '0', # 0(right) n-1(left)
- 'speed': '27.778'
- },
- {
- 'index': '1',
- 'speed': '27.778'
- },
- {
- 'index': '3',
- 'speed': '33.333',
- 'disallow': "bus truck"
- }
- ]
- }, #In the order of edges index
- "use_ghost_edge": False,
- "ghost_speed_limit": 25,
- "boundary_cell_length": 500
- },
- ),
可以看到,上述代码中将道路宽度设定为3.75m,通过lane_list为index为0(edge的index可能需要参考源码中读取edge的顺序)的edge上的0、1、3号道路(Flow中0号道路是edge最右侧那条)分别定制了最高限速,并为3号道路定制了禁行bus和truck的规则。在SUMO仿真中的0到3号道路的参数图如下:
建议大家在该示例代码的基础上进行修改开发,如果需要在其他路网(例如下图Flow官方示例中魔幻的minicity)中实现这些功能,如文首所说可以将highway_newfunc分支的代码覆盖至master分支,并用VSCode之类的IDE查看Source Control-CHANGES,从而对其他路网进行类似的修改(主要还是修改flow/flow/networks中的文件)。
欢迎交流讨论!对Flow Project有更深入的疑惑可以在stackoverflow的专题链接中提问(带上flow-project的标签,回的挺快):https://stackoverflow.com/questions/tagged/flow-project
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。