P.S. 重点看几个API接口的调用就好
1. Quick Start_快速上手
1.1 Create Engine_创建引擎
import cityflow
eng = cityflow.Engine(config_path, thread_num=1)
config_path
:config文件地址thread_num
:线程个数
1.1.1 Arguments in config file_Config文件中的参数
-
interval
:仿真中每一步的用时。举例:当interval=0.5时,意味着仿真中每一步后系统会前进0.5秒。如果一辆汽车的速度为10m/s,则一步之后该车会移动10*0.5=5米。
-
seed
:随机种子。 -
dir
:根目录,所有文件的地址会基于此目录。 -
roadnetFile
:roadnet的文件地址。 -
flowFile
:flow的文件地址。 -
rlTrafficLight
:是否通过python API启动对交通灯的控制。如果设置成false
,定义在roadnet文件中的默认交通灯计划将会被启用。 -
saveReplay
:是否保存仿真过程用于回放。如果设置成true
,需要用到roadnetLogFile
和replayLogFile
。 -
roadnetLogFile
:roadnet的回放文件地址。这是一个特殊的roadnet文件用于回放,与roadnetFile不一样。 -
replayLogFile
:回放日志的文件地址。该文件包含了仿真中每一步的车辆位置信息和交通灯状况。 -
laneChange
:是否启用换道。默认值为false。
提示
可运行的roadnet和flow的样例文件可以在examples
文件夹中找到。
你可以使用tools/generate_grid_scenario.py
来生成网状路网和交通流文件。
例如,你可以通过下行代码来生成附带预定义的交通信号计划的2x3的路网,和相应的交通流文件
python generate_grid_scenario.py 2 3 --roadnetFile roadnet.json --flowFile flow.json --dir . -- tlPlan
1.1.2 Sample config file_Config文件样例
{
"interval": 1.0,
"seed": 0,
"dir": "data/",
"roadnetFile": "roadnet/testcase_roadnet_3x3.json",
"flowFile": "flow/testcase_flow_3x3.json",
"rlTrafficLight": false,
"saveReplay": true,
"roadnetLogFile": "frontend/web/testcase_roadnet_3x3.json",
"replayLogFile": "frontend/web/testcase_replay_3x3.txt"
}
1.2 Simulation_仿真
仿真中进行下一步只需要使用命令eng.next_step()
1.3 Data Access API_数据操纵接口
-
get_vehicle_count()
:获取全部正在行驶的车辆数目,返回int -
get_vehicles(include_waiting=False)
:获取所有车辆的ID,如果include_waiting=True则包含车道中停驶的车辆,返回所有车辆的ID列表 -
get_lane_vehicle_count()
:获取每条车道上正在行驶的车辆数目,返回一个字典(key为车道ID,value为ID对应车道上的车辆数目) -
get_lane_waiting_vehicle_count()
:获取每条车道上停驶的车辆数目(车辆当前速度小于0.1m/s则被认为是等待状态),返回一个字典(key为车道ID,value为ID对应车道上的车辆数目) -
get_lane_vehicles()
:获取每条车道上的车辆ID,返回一个字典(key为车道ID,value为ID对应车道上的车辆数目) -
get_vehicle_info(vehicle_id)
:返回一个字典,包含指定id车辆的信息running
:车辆是否正在行驶speed
:该车的速度distance
:该车在当前车道或连接车道上行驶的距离drivable
:当前可行驶的车道(连接车道)的IDroad
:当前道路的ID(如果该车正行驶在车道上)intersection
:下一个路口的ID(如果该车正行驶在车道上)route
:返回一串字符串,包含车辆行驶路线的各道路ID
-
get_vehicle_speed()
:获取各车辆的速度,返回一个字典(key为车辆ID,value为ID对应的车辆速度) -
get_vehicle_distance()
:获取各车辆在当前道路上行驶的距离(key为车辆ID,value为ID对应的车辆速度) -
get_leader(vehicle_id)
:返回指定ID车辆的前面一辆车的ID,如果不存在则返回空字符串 -
get_current_time()
:获取当前仿真时间(秒),返回double -
get_average_travel_time()
:获取车辆平均旅行时间(秒),返回double
1.4 Control API_控制接口
-
set_tl_phase(intersection_id, phase_id)
:- 设置intersection_id的交通灯相位为phase_id,只工作在rlTrafficLight设置为True时。
- intersection_id因已被定义在roadentFile文件中
- phase_id是数组’lightphases’的交通相位的索引,定义在roadnetFile文件中
-
set_vehicle_speed(vehicle_id, speed)
:- 设置vehicle_id的速度为speed
- 车辆必须遵守基础规则来避免碰撞,所以实际速度可能与设置的speed不同
-
reset(seed=False)
:- 重置仿真环境(清除所有车辆,使仿真环境的时间归零)
- 重置随机种子(当seed设置为True)
- 该操作不会清除旧的回放文件,反而会新增回放至replayLogFile
-
snapshot()
:- 创建当前仿真状态的快照文件
- 会生成一个Archive对象,随后可以对此加载
- 可以使用Archive对象的dump方法来将此保存至文件中
-
load(archive)
:- 加载一个Archive对象并恢复对应的仿真状态
-
load_from_file(path)
:-
加载由dump方法创建的快照文件并恢复对应的仿真状态
-
完整过程的保留和加载文件如下:
archive = eng.snapshot() # create an archive object archive.dump("save.json") # if you want to save the snapshot to a file # do something eng.load(archive) # load 'archive' and the simulation will start from the status when 'archive' is created # or if you want to load from 'save.json' eng.load_from_file("save.json")
-
-
set_random_seed(seed)
:- 设置随机发生器的种子为seed
-
set_vehicle_route(vehicle_id, route)
:- 改变车辆的行驶路线
- route是一个包含道路ID的列表(不包括当前列表)
- 如果route是可用并可以被连接时返回True
1.5 Other API_其他接口
set_replay_file(replay_file)
:- replay_file应该是基于配置文件中的dir相关的路径
- 当你希望查看特定episode来进行调试时,这个命令非常有用
- 该API只工作于当配置文件中的saveReplay设置为true
set_save_replay(open)
:- 打开或关闭回放保存功能
- 设置open为False时,停止回放保存
- 设置open为True时,启用回放保存
- 该API只工作于当配置文件中的saveReplay设置为true
2. Roadnet File Format_路网文件格式
Roadnet
文件定义了路网结构,CityFlow中的路网主要由交叉口和道路组成(可以看做是图形的节点和边线)。
road
:道路代表从一个交叉路口到另一个交叉路口的方向性道路,具有特定的道路属性。一条路可能包含多条车道。intersection
:交叉路口就是道路的交叉点。一个路口包含多种连接方式。每种连接方式连接着该交叉口的两条道路,并可由交通信号控制。roadlink
:一条道路连接可能包含多种lanelink
行车线,每条行车线代表着一条车道的驶入道路和一条车道的驶出道路的特定路径。
现在让我们看一个路网文件的示例,我们将解释每个组件的含义。放松,如果你熟悉现代道路网络,领域的定义是相当直接明了的。对于下面的 json 文件,[]
意味着这个字段是一个数组,但是我们只显示一个对象作为演示。
{
"intersections": [
{
// id of the intersection
"id": "intersection_1_0",
// coordinate of center of intersection
"point": {
"x": 0,
"y": 0
},
// width of the intersection
"width": 10,
// roads connected to the intersection
"roads": [
"road_1",
"road_2"
],
// roadLinks of the intersection
"roadLinks": [
{
// 'turn_left', 'turn_right', 'go_straight'
"type": "go_straight",
// id of starting road
"startRoad": "road_1",
// id of ending road
"endRoad": "road_2",
// lanelinks of roadlink
"laneLinks": [
{
// from startRoad's startLaneIndex lane to endRoad's endLaneIndex lane
"startLaneIndex": 0,
"endLaneIndex": 1,
// points along the laneLink which describe the shape of laneLink
"points": [
{
"x": -10,
"y": 2
},
{
"x": 10,
"y": -2
}
]
}
]
}
],
// traffic light plan of the intersection
"trafficLight": {
"lightphases": [
{
// default duration of the phase
"time": 30,
// available roadLinks of current phase, index is the no. of roadlinks defined above.
"availableRoadLinks": [
0,
2
]
}
]
},
// true if it's a peripheral intersection (if it only connects to one road)
"virtual": false
}
],
"roads": [
{
// id of road
"id": "road_1",
// id of start intersection
"startIntersection": "intersection_1",
// id of end intersection
"endIntersection": "intersection_2",
// points along the road which describe the shape of the road
"points": [
{
"x": -200,
"y": 0
},
{
"x": 0,
"y": 0
}
],
// property of each lane
"lanes": [
{
"width": 4,
"maxSpeed": 16.67
}
]
}
]
}
·
你可以转换SUMO
路网文件转换至CityFlow
格式通过使用tools/Converterconverter.py
文件
python coverter.py --sumonet atlanta_sumo.net.xml --cityflownet atlanta_cityflow.json
3. Flow File Format_交通流文件格式
Flow
文件定义了交通流。每个交通流包含了以下字段:
vehicle
:length
:车辆的长度width
:车辆的宽度maxPosAcc
:最大加速度(m/s)maxNegAcc
:最大减速度(m/s)usualPosAcc
:一般加速度(m/s)usualNegAcc
:一般减速度(m/s)minGap
:与临近前车的最小可接受间隙(m)maxSpeed
:最大行驶速度(m/s)headwayTime
: 与前车保持前进的理想跟车时间(m),保持当前速度*理想跟车时间等于间隙
route
:定义了路线,所有的车辆都将沿着这条路线前进。指定了出发地和目的地,路由器将选择性地连接其中的一些锚点,自动规划最短路径。interval
:定义连续车辆的间隔(s)。如果间隔太小,车辆可能会因为堵塞而无法进入道路,将其扣留直到有足够的行车空间再进行放行操作。startTime
:endTime
:交通流将会在startTime
和endTime
之间生成车辆(s),都为闭区间。
4. Replay_重播
4.1 Start_开始
- 进入
frontend
文件夹并在浏览器中打开index.html
。 - 选择路网日志文件(由配置文件中由
roadnetLogFile
字段定义文件路径,而不是road netFile文件),等待它被加载。加载完成后,信息框中将显示一条消息。 - 选择重播文件(由配置文件中的
replayLogFile
字段定义文件路径)。 - 选择图表数据文件(可选,请参阅下面的Chart部分)。
- 点击
Start
按钮开始重播。
4.2 Control_控制
- 使用鼠标导航。支持拖动和鼠标滚轮缩放。
- 移动控制框中的滑块来调整重播速度。你也可以按键盘上的
1
来减速或者按2
来加速。 - 按下控制台中的
Pause
按钮来暂停/恢复。您也可以双击地图来暂停和恢复。 - 在键盘上按
[
或]
键向前或向后运行一步。 - 要重新启动重播,只需再次按下
Start
按钮。 debug
选项允许在鼠标悬停期间显示车辆、道路和交叉口的 ID。这将导致重播速度变慢,因此我们建议仅将其用于调试目的。
4.3 Chart_图表
播放器支持在重播过程中同时显示图表中不同指标的变化。
为了提供所需的数据,需要一个格式如下所示的日志文件:
第一行是图表的标题。每一行代表一个时间步长,每一列代表一个特定的指标。例如,为了分别跟踪三个十字路口的通过车辆数量,我们需要三个列,每个列代表某个十字路口的通过车辆数量。在一行中,数字由一个或多个空格或制表符分隔。一列中的数字将在图表中显示为由一条线连接的点。
**注意:**确保每一行对应着正确的时间步长
4.4 Notes_其他事项
- 可以在
frontend
文件夹下,运行download_replay.py
命令来获取示例重播文件 - 如果你创建了一个新的工程文件,使用同一个
replayLogFile
目录的话,那么旧的重播文件将首先被清除 - 使用
eng.reset()
不会清除旧的重播文件,将会在紧接着上一个文件的结束接续生成新重播文件 - 你可以使用
set_replay_file
命令在运行中更改replayLogFile
文件地址