要点初见:⽤Python进⾏微观交通模型仿真——基于SUMO的
伯克利开源项⽬FlowPro。。。
后续拓展:
通俗来讲,微观交通模型仿真就是从车辆个体的视⾓(看动画)进⾏交通流仿真,对车辆个体随时间、空间的变化进⾏跟踪描述。常⽤的微观交通仿真⽅法包括在Matlab中建⽴元胞⾃动机模型、在Vissim中画车道调参数。但前者存在仿真系统太简易粗糙,不⾜以体现复杂的交通影响因素;后者⼜存在太依赖GUI界⾯,COM接⼝编程只⽀持⾼版本正版(这东西贼难搞)、C++编程,只能获得车辆通过设定的检测点的时空坐标⽽⾮各个时刻各车辆的坐标,让后续能进⾏的坐标分析操作变得很局限。
但就博主在Github上寻(现成的)微观交通模型元胞⾃动机代码到快要绝望的时候,Flow Project冒了出来,这是⼀个由加州⼤学伯克利分校的移动传感实验室使⽤亚马逊AWS机器学习研究基⾦,基于SUMO开发出的⽤于交通微观模拟的深度强化学习和控制实验的计算框架,不仅开源,开发语⾔还是当下⽕热的Python,依赖的操作系统还是Ubuntu。博主仔细研读了⼀下项⽬源码、Document,真是相见恨晚,让⼈忍不住想说:
Talk is cheap,show me the code. 先放链接:
本博⽂主要从对Flow Project的介绍、Flow Project的安装、⽤Python运⾏模型输出坐标三个部分进⾏介绍,附加博主改源码增加改变车⾝长度功能的⽅法介绍。
1  Flow Project的介绍
Flow Project是基于开源框架SUMO的⼆次开发项⽬(其也可基于收费软件Aimsun、强化学习库RLlib,此⽂中暂不介绍),SUMO 的全称Simulation of Urban Mobility,是⼀款欧洲开源的微观交通仿真框架,但开源的另⼀⾯也意味着放养、不更新……所以单论SUMO 相⽐于Vissim不仅功能少⽽且还难⽤。
SUMO有个知名(难⽤)的Python接⼝TraCI(Traffic Control Interface),这个久远的接⼝博主⾄今也还没研究懂,但从源码中可以看出Flow Project的开发者们恰恰是利⽤这个接⼝,对SUMO进⾏了⼆次封装,从⽽让我们能通过短短⼏⼗⾏可读性强的Python代码创建出功能齐全的微观异质交通流仿真模型。Flow Project的核⼼在于完美接⼊强化学习,但Flow Project在仿真有⼈车辆上也完全绰绰有余,还能加⼊强化学习的⾃动驾驶车辆,可拓展性⾮常强,博主未来也会继续研究该项⽬。
在Ubuntu系统中运⾏Flow Project,仿真界⾯⼤概如下:
2  Flow Project的安装
(1)下载Flow Project项⽬:
cd flow
(2)安装anaconda2(参考anaconda官⽹),之后在flow⽬录下创建专属运⾏环境并安装依赖:
conda env create -l
source activate flow
(3)安装Flow Project和SUMO:
pip install -e .
./scripts/setup_sumo_ubuntu1404.sh(对于Ubuntu 14.04)
./scripts/setup_sumo_ubuntu1604.sh(对于Ubuntu 16.04)
./scripts/setup_sumo_ubuntu1804.sh(对于Ubuntu 18.04)
./scripts/setup_sumo_osx.sh(对于Mac)
检查SUMO是否安装成功:
which sumo
能运行python的软件sumo --version
启动SUMO图形界⾯:
sumo-gui
如果系统显⽰未到相关命令,则运⾏source ~/.bashrc或打开⼀个新的Terminal来更新环境变量。
(4)检查flow是否安装成功:
source activate flow
python examples/sumo/sugiyama.py
这步⼤概率是不成功的,或是在重启后再运⾏不成功,会发⽣没法激活flow的问题亦或Python版本导致的报错,因为博主系统默认的python版本是/usr/bin下的Python2.7,但Flow Project⼜是依赖anaconda⽬录下的python3.5,⽽随便改系统的环境变量⼜容易把很多框架的依赖弄崩。博主到的解决⽅法是:在每次开机第⼀次运⾏Flow Project的脚本前运⾏如下三句话(第三⾏的UBUNTU改成你的home⽬录名):
export PATH=/usr/local/anaconda2/bin:$PATH
source activate flow
export PYTHONPATH="/home/UBUNTU/.conda/envs/flow/lib/python3.5/site-packages:$PYTHONPATH"
这之后在flow⽬录下的Terminal中输⼊python examples/sumo/sugiyama.py或examples/sumo/下的其他脚本即可成功运⾏仿真,这也意味着你的flow安装好了,欢迎来到⽤Python进⾏交通流仿真的时代~
3  ⽤Python运⾏模型、输出坐标
从官⽅新⼿教程中可以看到,仿真的核⼼在于examples/sumo/⽬录下的脚本,笔者就以该⽬录下的单向N车道⾼速公路仿真创建脚本highway.py的更改、拓展为例,介绍如何⽤Python运⾏仿真并输出各时刻各车辆在道路上的坐标。
Flow Project中的道路形态有限,新道路的创建应该是基于SUMO底层进⾏定制,还有待未来研究。就在官⽅给出的⼏种道路形态中,N车道⾼速公路是较简单的⼀个模型,原脚本的运⾏效果如上⽂中仿真图像介绍部分。但博主因为论⽂研究需要,对该脚本进⾏了爆改:
(1)改源码增加改变车⾝长度的功能
def add(self,
veh_id,
length=5,
acceleration_controller=(SimCarFollowingController, {}),
lane_change_controller=(SimLaneChangeController, {}),
routing_controller=None,
initial_speed=0,
num_vehicles=1,
car_following_params=None,
lane_change_params=None):
"""Add a sequence of vehicles to the list of vehicles in the network.
Parameters
-
---------
veh_id : str
base vehicle ID for the vehicles (will be appended by a number)
acceleration_controller : tup, optional
1st element: flow-specified acceleration controller
2nd element: controller parameters (may be set to None to maintain
default parameters)
lane_change_controller : tup, optional
1st element: flow-specified lane-changer controller
2nd element: controller parameters (may be set to None to maintain
default parameters)
routing_controller : tup, optional
1st element: flow-specified routing controller
2nd element: controller parameters (may be set to None to maintain
default parameters)
initial_speed : float, optional
initial speed of the vehicles being added (in m/s)
num_vehicles : int, optional
number of vehicles of this type to be added to the network
car_following_params : params.SumoCarFollowingParams
Params object specifying attributes for Sumo car following model.
lane_change_params : params.SumoLaneChangeParams
Params object specifying attributes for Sumo lane changing model.
"""
if car_following_params is None:
# FIXME: depends on simulator
car_following_params = SumoCarFollowingParams()
if lane_change_params is None:
# FIXME: depends on simulator
lane_change_params = SumoLaneChangeParams()
type_params = {}
type_params.update(car_ller_params)
type_params.update(lane_ller_params)
# If a vehicle is not sumo or RL, let the minGap be zero so that it
# does not tamper with the dynamics of the controller
if acceleration_controller[0] != SimCarFollowingController \
and acceleration_controller[0] != RLController:
type_params["minGap"] = 0.0
type_params['length'] = length
# This dict will be used when trying to introduce new vehicles into
# the network via a Flow. It is passed to the vehicle kernel object
# during environment instantiation.
{"length": length,
"acceleration_controller": acceleration_controller,
"lane_change_controller": lane_change_controller,
"routing_controller": routing_controller,
"initial_speed": initial_speed,
"car_following_params": car_following_params,
"lane_change_params": lane_change_params}
# TODO: delete?
self.initial.append({
"veh_id":
veh_id,
"length":
length,
"acceleration_controller":
acceleration_controller,
"lane_change_controller":
lane_change_controller,
"routing_controller":
routing_controller,
"initial_speed":
initial_speed,
"num_vehicles":
num_vehicles,
"car_following_params":
car_following_params,
"lane_change_params":
lane_change_params
})
# This is used to return the actual headways from the vehicles class.        # It is passed to the vehicle kernel class during environment
# instantiation.
self.minGap[veh_id] = type_params["minGap"]
for i in range(num_vehicles):
v_id = veh_id + '_%d' % i
# add the vehicle to the list of vehicle ids
self.ids.append(v_id)
self.__vehicles[v_id] = dict()
# specify the type
self.__vehicles[v_id]["type"] = veh_id
# update the number of vehicles
self.num_vehicles += 1
if acceleration_controller[0] == RLController:
self.num_rl_vehicles += 1
# increase the number of unique types of vehicles in the network, and
# add the type to the list of types
self.num_types += 1
这样就可以在Python⽂件中改变输⼊车辆的长度了。
(2)让我们来更改Python脚本吧:
先看⼀下highway.py改后的全貌:
"""Example of an open multi-lane network with human-driven vehicles."""
llers import IDMController, SimLaneChangeController, ContinuousRouter, RLController
xperiment import Experiment
params import SumoParams, EnvParams, \
NetParams, InitialConfig, InFlows, SumoLaneChangeParams, SumoCarFollowingParams
params import VehicleParams
vs.loop.lane_changing import LaneChangeAccelEnv, \
ADDITIONAL_ENV_PARAMS
from flow.scenarios.highway import HighwayScenario, ADDITIONAL_NET_PARAMS
#params import SimParams
def highway_example(render=None):
"""
Perform a simulation of vehicles on a highway.
Parameters
----------
render : bool, optional
specifies whether to use the gui during execution
Returns
-
------
exp: periment.Experiment
A non-rl experiment demonstrating the performance of human-driven
vehicles on a figure eight.
"""
sim_params = SumoParams(restart_instance=True, sim_step=0.1, emission_path="./data/",render=True, sight_radius=30, pxpm=3, show_radius=True)
if render is not None:
der = render
vehicles = VehicleParams()
vehicles.add(
veh_id="rlcar",# Lincoln MKC 4552*1864*1654
length = 4.552,
acceleration_controller=(RLController, {}),
car_following_params=SumoCarFollowingParams(
speed_mode="obey_safe_speed",
),
initial_speed=0,
num_vehicles=1)
vehicles.add(
veh_id="humancar",# Volkswagen LAVIDA 4670*1806*1474 max:120km/h

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。