A modified version of CityFlow, which is compatible with original CityFlow configs and input (but not fully tested), and support dynamic lanes (lanes can set different outgoing directions dynamically). You can find formal definition of dynamic lanes in [1].
Added or updated functions:
Engine.init
: added two new arguments.log_file
set path to save running logs about Engine, which is used to debug CityFlowlog_level
set debug log level
get_roadlink_vehicle_count
: get vehicle count based on a roadlink. return a list of four integer,[ingoing lane number, total vehicle number on all ingoing lanes, outgoing lane number, total vehicle number on all outgoing lanes]
.intersection_id
the corresponding intersection of the roadlinkroadlink_index
roadlink index
get_roadlink_waiting_vehicle_count
: same as above, except vehicle number is changed to waiting vehicle number (speed < 0.1).get_average_delay
: get total average delay of all vehicles.get_road_average_delay
get average delay of all roads. return dict { road_name: delay }. the average delay of a road means the average delay for all vehicles during passing this road.get_direction_change_lanes
: get names of direction change lanes and its available direction. return dict { direction_change_lane_name: [available_directions] }.get_direction_change_lane_direction
: input name of a direction change lane, output its current direction.set_log_file
: set new log file position. Used for debug and test.road_file
new road file pathreplay_file
new replay file pathmove_data
default false, whether move current file to new location.
set_lane_direction
: set new direction for direction change lanes.lane
: lane namedirection
: direction name
To set a lane as direction change, we only need to modify the road network definition in roadnet.json
. In the roadLinks
definition for intersections, if a lane exists in multiple roadlinks, i.e. different roadlinks have same roadLink.LaneLink.startLaneIndex = X
then lane X
becomes a direction change lane. Refer to examples/directionchange/roadnet.json
, lane index 2 of road road_0_1_0
is a direction change lane, and its available directions are go straight and turn left.
Known problems: the environment is not robust enough and sometimes may crash (in my experiments, 0.3% crash rate in 24000 step simulation). The probability is not high, but may be annoying when training long epochs and many agents. I tried to fix the problem but failed, so I used a wrapper to catch crash and re-generate a new environment automatically to avoid unexpected exception.
[1] | Dynamic Lane Traffic Signal Control with Group Attention and Multi-Timescale Reinforcement Learning |
CityFlow is a multi-agent reinforcement learning environment for large-scale city traffic scenario.
Checkout these features!
- A microscopic traffic simulator which simulates the behavior of each vehicle, providing highest level detail of traffic evolution.
- Supports flexible definitions for road network and traffic flow
- Provides friendly python interface for reinforcement learning
- Fast! Elaborately designed data structure and simulation algorithm with multithreading. Capable of simulating city-wide traffic. See the performance comparison with SUMO [2].
Performance comparison between CityFlow with different number of threads (1, 2, 4, 8) and SUMO. From small 1x1 grid roadnet to city-level 30x30 roadnet. Even faster when you need to interact with the simulator through python API.
- PressLight: Learning Max Pressure Control to Coordinate Traffic Signals in Arterial Network (KDD 2019)
- CoLight: Learning Network-level Cooperation for Traffic Signal Control
- Traffic Signal Control Benchmark
- TSCC2050: A Traffic Signal Control Game by Tianrang Intelligence (in Chinese) [3]
[2] | SUMO home page |
[3] | Tianrang Intelligence home page |