├── _config.yml ├── flow ├── core │ ├── kernel │ │ ├── network │ │ │ ├── scenario_data_check │ │ │ └── __init__.py │ │ ├── __init__.py │ │ ├── vehicle │ │ │ └── __init__.py │ │ ├── simulation │ │ │ ├── __init__.py │ │ │ └── base.py │ │ ├── scenario │ │ │ └── __init__.py │ │ └── traffic_light │ │ │ ├── __init__.py │ │ │ ├── aimsun.py │ │ │ ├── traci.py │ │ │ └── base.py │ └── __init__.py ├── utils │ ├── aimsun │ │ ├── __init__.py │ │ ├── Aimsun_Flow.ang │ │ ├── small_template.ang │ │ └── constants.py │ ├── __init__.py │ ├── exceptions.py │ ├── leaderboard │ │ ├── run.py │ │ ├── solution.py.template │ │ └── Dockerfile │ └── flow_warnings.py ├── benchmarks │ ├── __init__.py │ ├── descriptions │ │ ├── figureeight0.yml │ │ ├── figureeight1.yml │ │ ├── figureeight2.yml │ │ ├── merge0.yml │ │ ├── grid0.yml │ │ ├── grid1.yml │ │ ├── merge1.yml │ │ ├── merge2.yml │ │ ├── bottleneck0.yml │ │ ├── bottleneck2.yml │ │ └── bottleneck1.yml │ ├── run_all_benchmarks.sh │ ├── baselines │ │ ├── merge012.py │ │ ├── figureeight012.py │ │ ├── grid1.py │ │ ├── grid0.py │ │ ├── bottleneck0.py │ │ ├── bottleneck1.py │ │ └── bottleneck2.py │ ├── figureeight2.py │ ├── figureeight0.py │ └── figureeight1.py ├── envs │ ├── ring │ │ └── __init__.py │ ├── multiagent │ │ ├── ring │ │ │ └── __init__.py │ │ └── __init__.py │ ├── base_env.py │ ├── loop │ │ ├── loop_accel.py │ │ ├── lane_changing.py │ │ └── wave_attenuation.py │ ├── bottleneck_env.py │ ├── green_wave_env.py │ ├── __init__.py │ └── test.py ├── version.py ├── visualize │ ├── __init__.py │ └── plot_ray_results.py ├── __init__.py ├── renderer │ └── __init__.py ├── scenarios │ ├── base.py │ ├── base_scenario.py │ ├── minicity.py │ ├── bay_bridge.py │ ├── loop.py │ ├── ring.py │ ├── merge.py │ ├── bay_bridge_toll.py │ ├── highway.py │ ├── multi_ring.py │ ├── multi_loop.py │ ├── bottleneck.py │ ├── highway_ramps.py │ ├── grid.py │ ├── traffic_light_grid.py │ ├── figure_eight.py │ └── __init__.py ├── multiagent_envs │ ├── multiagent_env.py │ ├── loop │ │ ├── loop_accel.py │ │ └── wave_attenuation.py │ ├── highway.py │ ├── traffic_light_grid.py │ └── __init__.py ├── controllers │ ├── lane_change_controllers.py │ ├── rlcontroller.py │ ├── base_routing_controller.py │ ├── __init__.py │ └── base_lane_changing_controller.py ├── config.py └── networks │ └── __init__.py ├── setup.cfg ├── tests ├── __init__.py ├── fast_tests │ ├── __init__.py │ └── test_files │ │ └── params-collide.pkl ├── slow_tests │ ├── __init__.py │ └── test_baselines.py └── stress_tests │ ├── stress_test_start.py │ └── stress_test_rl.py ├── examples ├── __init__.py ├── exp_scripts │ ├── compute_210_calibration.py │ └── bottleneck_density_sweep_capacity_diagram.py ├── exp_configs │ ├── non_rl │ │ ├── aimsun_template.py │ │ ├── ring.py │ │ ├── figure_eight.py │ │ ├── minicity.py │ │ ├── highway.py │ │ ├── merge.py │ │ ├── bottleneck.py │ │ └── highway_single.py │ └── rl │ │ └── singleagent │ │ ├── singleagent_figure_eight.py │ │ └── singleagent_ring.py └── simulate.py ├── docs ├── img │ ├── grid.gif │ ├── merge.gif │ ├── highway.gif │ ├── minicity.gif │ ├── sugiyama.gif │ ├── bay_bridge.gif │ ├── flow-logo.jpg │ ├── bottlenecks.gif │ ├── figure_eight.gif │ └── two_rings_one_merge.gif ├── source │ ├── modules.rst │ ├── flow.scenarios.rst │ ├── tutorials.rst │ ├── flow.renderer.rst │ ├── flow.rst │ ├── flow.envs.bay_bridge.rst │ ├── flow.visualize.rst │ ├── intro.rst │ ├── flow.core.rst │ ├── flow.utils.aimsun.rst │ ├── flow.core.kernel.rst │ ├── flow.envs.rst │ ├── flow.utils.rst │ ├── regression.rst │ ├── index.rst │ ├── multiagent.rst │ ├── flow.controllers.rst │ ├── flow.benchmarks.rst │ ├── rendering.rst │ └── visualizing.rst ├── README.md ├── sumo-depart-time-issue.md ├── libsumo_mac.md ├── cluster_setup.md ├── Fail-safes.md └── Docker_Tutorial.md ├── tutorials ├── networks │ └── test_template.ang └── README.md ├── .readthedocs.yml ├── scripts ├── setup_aimsun.sh ├── sumo_patch.txt ├── setup_sumo_ubuntu1604.sh ├── setup_sumo_ubuntu1804.sh ├── setup_sumo_ubuntu1404.sh ├── setup_sumo_osx.sh ├── sync_s3.py ├── departure_time_issue.patch └── benchmark_autoscale.yaml ├── CODEOWNERS ├── requirements.txt ├── .coveragerc ├── .github ├── ISSUE_TEMPLATE │ ├── question.md │ ├── feature.md │ └── bug.md └── PULL_REQUEST_TEMPLATE.md ├── environment.yml ├── README.md ├── LICENSE.md ├── Dockerfile ├── setup.py ├── .gitignore ├── .travis.yml └── CODE_OF_CONDUCT.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /flow/core/kernel/network/scenario_data_check: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | exclude = .git,*migrations* 3 | max-line-length = 119 4 | -------------------------------------------------------------------------------- /flow/core/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for core is created.""" 2 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure nose tests can be run from front page.""" 2 | -------------------------------------------------------------------------------- /examples/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure that the examples documentation builds.""" 2 | -------------------------------------------------------------------------------- /flow/utils/aimsun/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for Aimsun is created.""" 2 | -------------------------------------------------------------------------------- /tests/fast_tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure nose tests can be run from front page.""" 2 | -------------------------------------------------------------------------------- /tests/slow_tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure nose tests can be run from front page.""" 2 | -------------------------------------------------------------------------------- /flow/benchmarks/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for benchmarks is created.""" 2 | -------------------------------------------------------------------------------- /flow/envs/ring/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for the ring env is created.""" 2 | -------------------------------------------------------------------------------- /flow/version.py: -------------------------------------------------------------------------------- 1 | """Specifies the current version number of Flow.""" 2 | 3 | __version__ = "0.5.0.dev" 4 | -------------------------------------------------------------------------------- /flow/visualize/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for visualizers is created.""" 2 | -------------------------------------------------------------------------------- /docs/img/grid.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/grid.gif -------------------------------------------------------------------------------- /docs/img/merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/merge.gif -------------------------------------------------------------------------------- /flow/envs/multiagent/ring/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for multi-agent envs is created.""" 2 | -------------------------------------------------------------------------------- /docs/img/highway.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/highway.gif -------------------------------------------------------------------------------- /docs/img/minicity.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/minicity.gif -------------------------------------------------------------------------------- /docs/img/sugiyama.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/sugiyama.gif -------------------------------------------------------------------------------- /docs/img/bay_bridge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/bay_bridge.gif -------------------------------------------------------------------------------- /docs/img/flow-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/flow-logo.jpg -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | Code Documentation 2 | =================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | 7 | flow 8 | -------------------------------------------------------------------------------- /docs/img/bottlenecks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/bottlenecks.gif -------------------------------------------------------------------------------- /docs/img/figure_eight.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/figure_eight.gif -------------------------------------------------------------------------------- /docs/img/two_rings_one_merge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/docs/img/two_rings_one_merge.gif -------------------------------------------------------------------------------- /flow/utils/aimsun/Aimsun_Flow.ang: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/flow/utils/aimsun/Aimsun_Flow.ang -------------------------------------------------------------------------------- /flow/utils/aimsun/small_template.ang: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/flow/utils/aimsun/small_template.ang -------------------------------------------------------------------------------- /tutorials/networks/test_template.ang: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/tutorials/networks/test_template.ang -------------------------------------------------------------------------------- /tests/fast_tests/test_files/params-collide.pkl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengyuan-zhou/Multi-agent-RL-traffic-light-control/HEAD/tests/fast_tests/test_files/params-collide.pkl -------------------------------------------------------------------------------- /flow/core/kernel/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for kernel is created.""" 2 | 3 | from flow.core.kernel.kernel import Kernel 4 | 5 | __all__ = ["Kernel"] 6 | -------------------------------------------------------------------------------- /docs/source/flow.scenarios.rst: -------------------------------------------------------------------------------- 1 | flow.networks package 2 | ====================== 3 | 4 | .. automodule:: flow.networks 5 | :members: 6 | :undoc-members: 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /flow/__init__.py: -------------------------------------------------------------------------------- 1 | """Returns features of the Flow repository (e.g. version number).""" 2 | 3 | from .version import __version__ as v 4 | 5 | # flow repo version number 6 | __version__ = v 7 | -------------------------------------------------------------------------------- /flow/utils/__init__.py: -------------------------------------------------------------------------------- 1 | """empty init file to ensure documentation for utils is created.""" 2 | 3 | from flow.utils.exceptions import FatalFlowError 4 | 5 | __all__ = ['FatalFlowError'] 6 | -------------------------------------------------------------------------------- /flow/renderer/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for the renderer is created.""" 2 | 3 | from flow.renderer.pyglet_renderer import PygletRenderer 4 | 5 | __all__ = ['PygletRenderer'] 6 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | build: 2 | image: latest 3 | 4 | python: 5 | version: 3.6 6 | pip_install: true 7 | extra_requirements: ['docs', 'all'] 8 | 9 | # Don't build any extra formats 10 | formats: [] 11 | -------------------------------------------------------------------------------- /flow/utils/exceptions.py: -------------------------------------------------------------------------------- 1 | """Flow-specific exceptions.""" 2 | 3 | 4 | class FatalFlowError(Exception): 5 | """Exception class for Flow errors which do not allow for continuation.""" 6 | 7 | def __init__(self, msg): 8 | Exception.__init__(self, msg) 9 | -------------------------------------------------------------------------------- /docs/source/tutorials.rst: -------------------------------------------------------------------------------- 1 | Tutorials 2 | ========= 3 | Tutorials for learning how to use Flow are available, both on GitHub 4 | and as part of this documentation. 5 | 6 | 7 | .. toctree:: 8 | :maxdepth: 1 9 | :caption: Links: 10 | 11 | GitHub Tutorials -------------------------------------------------------------------------------- /docs/source/flow.renderer.rst: -------------------------------------------------------------------------------- 1 | flow.renderer package 2 | ===================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | flow.renderer.pyglet_renderer module 8 | ------------------------------------ 9 | 10 | .. automodule:: flow.renderer.pyglet_renderer 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | This is the documentation folder for flow documentation. 2 | 3 | Idea: fill this folder with instructions and links for 4 | how to write documentation. 5 | 6 | Preliminary content: a link to the Dropbox Paper page 7 | I wrote concerning an [introduction to documentation](https://paper.dropbox.com/doc/introduction-to-documentation-K4b8Bm3ukikqaKx7LAU9w) 8 | -------------------------------------------------------------------------------- /flow/envs/base_env.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/base.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.base import Env as BaseEnv 7 | 8 | 9 | @deprecated('flow.envs.base_env', 'flow.envs.base.Env') 10 | class Env(BaseEnv): 11 | """See parent class.""" 12 | 13 | pass 14 | -------------------------------------------------------------------------------- /flow/core/kernel/vehicle/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for the vehicle class is created.""" 2 | 3 | from flow.core.kernel.vehicle.base import KernelVehicle 4 | from flow.core.kernel.vehicle.traci import TraCIVehicle 5 | from flow.core.kernel.vehicle.aimsun import AimsunKernelVehicle 6 | 7 | 8 | __all__ = ['KernelVehicle', 'TraCIVehicle', 'AimsunKernelVehicle'] 9 | -------------------------------------------------------------------------------- /flow/core/kernel/network/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for the network is created.""" 2 | 3 | from flow.core.kernel.network.base import BaseKernelNetwork 4 | from flow.core.kernel.network.traci import TraCIKernelNetwork 5 | from flow.core.kernel.network.aimsun import AimsunKernelNetwork 6 | 7 | __all__ = ["BaseKernelNetwork", "TraCIKernelNetwork", "AimsunKernelNetwork"] 8 | -------------------------------------------------------------------------------- /flow/scenarios/base.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/base.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.base import Network 7 | 8 | 9 | @deprecated('flow.scenarios.base', 10 | 'flow.networks.base.Network') 11 | class Scenario(Network): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/utils/leaderboard/run.py: -------------------------------------------------------------------------------- 1 | """Runner for flow/utils/leaderboard/evaluate.py/evaluate_policy.""" 2 | 3 | from solution import BENCHMARK, get_actions, get_states 4 | from evaluate import evaluate_policy 5 | 6 | # Evaluate the solution 7 | mean, stdev = evaluate_policy( 8 | benchmark=BENCHMARK, _get_actions=get_actions, _get_states=get_states) 9 | # Print results 10 | print(mean, stdev) 11 | -------------------------------------------------------------------------------- /flow/core/kernel/simulation/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for the simulation is created.""" 2 | 3 | from flow.core.kernel.simulation.base import KernelSimulation 4 | from flow.core.kernel.simulation.traci import TraCISimulation 5 | from flow.core.kernel.simulation.aimsun import AimsunKernelSimulation 6 | 7 | 8 | __all__ = ['KernelSimulation', 'TraCISimulation', 'AimsunKernelSimulation'] 9 | -------------------------------------------------------------------------------- /flow/envs/loop/loop_accel.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/ring/accel.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.ring.accel import AccelEnv as AEnv 7 | 8 | 9 | @deprecated('flow.envs.loop.accel', 10 | 'flow.envs.ring.accel.AccelEnv') 11 | class AccelEnv(AEnv): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/scenarios/base_scenario.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/scenarios/base.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.base import Network 7 | 8 | 9 | @deprecated('flow.scenarios.base_scenario', 10 | 'flow.networks.base.Network') 11 | class Scenario(Network): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/core/kernel/scenario/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to handle deprecations.""" 2 | 3 | import warnings 4 | from flow.core.kernel.network import * # noqa: F401,F403 5 | 6 | warnings.simplefilter('always', PendingDeprecationWarning) 7 | warnings.warn( 8 | "flow.core.kernel.scenario will be deprecated in a future release. Please " 9 | "use flow.core.kernel.network instead.", 10 | PendingDeprecationWarning 11 | ) 12 | -------------------------------------------------------------------------------- /docs/source/flow.rst: -------------------------------------------------------------------------------- 1 | flow package 2 | ============ 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | flow.benchmarks 10 | flow.controllers 11 | flow.core 12 | flow.envs 13 | flow.networks 14 | flow.utils 15 | flow.visualize 16 | flow.renderer 17 | 18 | Module contents 19 | --------------- 20 | 21 | .. automodule:: flow 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | -------------------------------------------------------------------------------- /flow/scenarios/minicity.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/minicity.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.minicity import MiniCityNetwork 7 | 8 | 9 | @deprecated('flow.scenarios.minicity', 10 | 'flow.networks.minicity.MiniCityNetwork') 11 | class MiniCityScenario(MiniCityNetwork): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/core/kernel/traffic_light/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for traffic lights is created.""" 2 | 3 | from flow.core.kernel.traffic_light.base import KernelTrafficLight 4 | from flow.core.kernel.traffic_light.traci import TraCITrafficLight 5 | from flow.core.kernel.traffic_light.aimsun import AimsunKernelTrafficLight 6 | 7 | 8 | __all__ = ["KernelTrafficLight", "TraCITrafficLight", 9 | "AimsunKernelTrafficLight"] 10 | -------------------------------------------------------------------------------- /flow/multiagent_envs/multiagent_env.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/multiagent/base.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.multiagent.base import MultiEnv as MAEnv 7 | 8 | 9 | @deprecated('flow.multiagent_envs.multiagent_env', 10 | 'flow.envs.multiagent.base.MultiEnv') 11 | class MultiEnv(MAEnv): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/scenarios/bay_bridge.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/bay_bridge.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.bay_bridge import BayBridgeNetwork 7 | 8 | 9 | @deprecated('flow.scenarios.bay_bridge', 10 | 'flow.networks.bay_bridge.BayBridgeNetwork') 11 | class BayBridgeScenario(BayBridgeNetwork): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /scripts/setup_aimsun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # allows you to access python 2.7.4 which is needed for creating the aimsun_flow environment 4 | conda config --append channels https://repo.anaconda.com/pkgs/free 5 | conda config --append channels https://repo.anaconda.com/pkgs/pro 6 | 7 | # create the conda environment 8 | conda create -y -n aimsun_flow python=2.7.4 9 | 10 | # install numpy within the environment 11 | source activate aimsun_flow 12 | pip install numpy 13 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/figureeight0.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Figure Eight - 0 4 | yt_string: SoA_7fPJEG8 5 | description: A toy model of intersection. A portion of vehicles are treated as CAVs with the objective of regulating the flow of vehicles through the intersection of a figure eight in order to improve system-level velocities.
13 humans, 1 CAV, S=(28,), A=(1,), T=1500. -------------------------------------------------------------------------------- /flow/scenarios/loop.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/ring.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.ring import RingNetwork 7 | from flow.networks.ring import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.loop', 11 | 'flow.networks.ring.RingNetwork') 12 | class LoopScenario(RingNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/scenarios/ring.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/ring.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.ring import RingNetwork 7 | from flow.networks.ring import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.ring', 11 | 'flow.networks.ring.RingNetwork') 12 | class RingScenario(RingNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/scenarios/merge.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/merge.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.merge import MergeNetwork 7 | from flow.networks.merge import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.merge', 11 | 'flow.networks.merge.MergeNetwork') 12 | class MergeScenario(MergeNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /docs/source/flow.envs.bay_bridge.rst: -------------------------------------------------------------------------------- 1 | flow.envs.bay\_bridge package 2 | ============================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | flow.envs.bay\_bridge module 8 | --------------------------------- 9 | 10 | .. automodule:: flow.envs.bay_bridge 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | 16 | Module contents 17 | --------------- 18 | 19 | .. automodule:: flow.envs.bay_bridge 20 | :members: 21 | :undoc-members: 22 | :show-inheritance: 23 | -------------------------------------------------------------------------------- /flow/scenarios/bay_bridge_toll.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/bay_bridge_toll.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.bay_bridge_toll import BayBridgeTollNetwork 7 | 8 | 9 | @deprecated('flow.scenarios.bay_bridge_toll', 10 | 'flow.networks.bay_bridge_toll.BayBridgeTollNetwork') 11 | class BayBridgeTollScenario(BayBridgeTollNetwork): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /docs/source/flow.visualize.rst: -------------------------------------------------------------------------------- 1 | flow.visualize package 2 | ====================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | 8 | flow.visualize.visualizer\_rllib module 9 | --------------------------------------- 10 | 11 | .. automodule:: flow.visualize.visualizer_rllib 12 | :members: 13 | :undoc-members: 14 | :show-inheritance: 15 | 16 | 17 | Module contents 18 | --------------- 19 | 20 | .. automodule:: flow.visualize 21 | :members: 22 | :undoc-members: 23 | :show-inheritance: 24 | -------------------------------------------------------------------------------- /flow/multiagent_envs/loop/loop_accel.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/multiagent/ring/accel.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.multiagent.ring.accel import AdversarialAccelEnv as MAAEnv 7 | 8 | 9 | @deprecated('flow.multiagent_envs.loop.loop_accel', 10 | 'flow.envs.multiagent.ring.accel.AdversarialAccelEnv') 11 | class AdversarialAccelEnv(MAAEnv): 12 | """See parent class.""" 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /flow/scenarios/highway.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/highway.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.highway import HighwayNetwork 7 | from flow.networks.highway import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.highway', 11 | 'flow.networks.highway.HighwayNetwork') 12 | class HighwayScenario(HighwayNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/figureeight1.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Figure Eight - 1 4 | yt_string: SoA_7fPJEG8 # TODO: need to find video for figureeight1 5 | description: A toy model of intersection. A portion of vehicles are treated as CAVs with the objective of regulating the flow of vehicles through the intersection of a figure eight in order to improve system-level velocities.
7 humans, 7 CAVs, S=(28,), A=(7,), T=1500. -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/figureeight2.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Figure Eight - 2 4 | yt_string: SoA_7fPJEG8 # TODO: need to find video for figureeight2 5 | description: A toy model of intersection. A portion of vehicles are treated as CAVs with the objective of regulating the flow of vehicles through the intersection of a figure eight in order to improve system-level velocities.
0 human, 14 CAVs, S=(28,), A=(14,), T=1500. -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/merge0.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Merge - 0 4 | yt_string: dfe0NNt0cCA 5 | description: "Controlling shockwaves from on-ramp merges: In a mixed-autonomy setting, a percentage of vehicles in the main highway of a merge network are tasked with the objective of dissipating the formation and propagation of stop-and-go waves from locally observable information.
10% CAV penetration rate, S=(25,), A=(5,), T=750." -------------------------------------------------------------------------------- /flow/scenarios/multi_ring.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/multi_ring.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.multi_ring import MultiRingNetwork 7 | from flow.networks.multi_ring import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.multi_ring', 11 | 'flow.networks.multi_ring.RingNetwork') 12 | class MultiRingScenario(MultiRingNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/grid0.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Grid - 0 4 | yt_string: null # TODO: find video 5 | description: "Improving traffic signal timing schedules: Traffic lights in a an idealized representation of a city with a grid-like structure such as Manhattan are controlled in intervals of 2 seconds, with the objective of minimizing delays for drivers.
3x3 grid (9 traffic lights), inflow = 300 veh/hour/lane S=(339,), A=(9,), T=400." -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/grid1.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Grid - 1 4 | yt_string: null # TODO: find video 5 | description: "Improving traffic signal timing schedules: Traffic lights in a an idealized representation of a city with a grid-like structure such as Manhattan are controlled in intervals of 2 seconds, with the objective of minimizing delays for drivers.
5x5 grid (25 traffic lights), inflow = 300 veh/hour/lane S=(915,), A=(25,), T=400." -------------------------------------------------------------------------------- /flow/scenarios/multi_loop.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/multi_ring.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.multi_ring import MultiRingNetwork 7 | from flow.networks.multi_ring import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.multi_loop', 11 | 'flow.networks.multi_ring.MultiRingNetwork') 12 | class MultiLoopScenario(MultiRingNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/scenarios/bottleneck.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/bottleneck.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.bottleneck import BottleneckNetwork 7 | from flow.networks.bottleneck import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.bottleneck', 11 | 'flow.networks.bottleneck.BottleneckNetwork') 12 | class BottleneckScenario(BottleneckNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in the repo. 5 | * @eugenevinitsky @AboudyKreidieh @kjang96 6 | 7 | # Order is important. The last matching pattern has the most precedence. 8 | # So if a pull request only touches javascript files, only these owners 9 | # will be requested to review. 10 | # *.js @octocat @github/js 11 | 12 | # You can also use email addresses if you prefer. 13 | docs/* @nskh 14 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/merge1.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Merge - 1 4 | yt_string: dfe0NNt0cCA # TODO: find video for merge1 5 | description: "Controlling shockwaves from on-ramp merges: In a mixed-autonomy setting, a percentage of vehicles in the main highway of a merge network are tasked with the objective of dissipating the formation and propagation of stop-and-go waves from locally observable information.
25% CAV penetration rate, S=(65,), A=(13,), T=750." -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/merge2.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Merge - 2 4 | yt_string: dfe0NNt0cCA # TODO: find video for merge2 5 | description: "Controlling shockwaves from on-ramp merges: In a mixed-autonomy setting, a percentage of vehicles in the main highway of a merge network are tasked with the objective of dissipating the formation and propagation of stop-and-go waves from locally observable information.
25% CAV penetration rate, S=(65,), A=(13,), T=750." -------------------------------------------------------------------------------- /flow/utils/leaderboard/solution.py.template: -------------------------------------------------------------------------------- 1 | """ 2 | A solution should include: 3 | 1. Benchmark network; 4 | 2. get_actions() method; 5 | 3. get_states() method. 6 | """ 7 | 8 | # Specify benchmark network below. 9 | BENCHMARK = "" # Benchmark name goes here... 10 | 11 | 12 | # Specify get_action() method below. 13 | def get_actions(state): 14 | # get_actions() code goes here... 15 | return 16 | 17 | 18 | # Specify get_state() method below. 19 | def get_states(env, **kwargs): 20 | # get_states() code goes here... 21 | return 22 | -------------------------------------------------------------------------------- /flow/scenarios/highway_ramps.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/highway_ramps.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.highway_ramps import HighwayRampsNetwork 7 | from flow.networks.highway_ramps import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.highway_ramps', 11 | 'flow.networks.highway_ramps.HighwayRampsNetwork') 12 | class HighwayRampsScenario(HighwayRampsNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | gym==0.14.0 2 | numpy==1.18.4 3 | scipy==1.1.0 4 | lxml==4.4.1 5 | pyprind==2.11.2 6 | nose2==0.8.0 7 | six==1.11.0 8 | path.py 9 | joblib==0.10.3 10 | python-dateutil==2.7.3 11 | cached_property 12 | pyglet==1.3.2 13 | matplotlib==3.1.0 14 | imutils==0.5.1 15 | numpydoc 16 | ray==0.8.0 17 | opencv-python 18 | dill 19 | lz4 20 | setproctitle 21 | psutil 22 | opencv-python 23 | boto3==1.10.45 24 | redis~=2.10.6 25 | pandas==0.24.2 26 | plotly==2.4.0 27 | tabulate 28 | tensorflow==1.15.2 29 | awscli==1.16.309 30 | torch==1.4.0 31 | pytz 32 | tensorboardX 33 | -------------------------------------------------------------------------------- /flow/multiagent_envs/highway.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/multiagent/highway.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.multiagent.highway import MultiAgentHighwayPOEnv as MAHPOEnv 7 | from flow.envs.multiagent.highway import ADDITIONAL_ENV_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.multiagent_envs.highway', 11 | 'flow.envs.multiagent.highway.MultiAgentHighwayPOEnv') 12 | class MultiAgentHighwayPOEnv(MAHPOEnv): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/scenarios/grid.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/traffic_light_grid.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.traffic_light_grid import TrafficLightGridNetwork 7 | from flow.networks.traffic_light_grid import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.grid', 11 | 'flow.networks.traffic_light_grid.TrafficLightGridNetwork') 12 | class SimpleGridScenario(TrafficLightGridNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | omit = 3 | */python?.?/* 4 | */site-packages/nose/* 5 | *__init__* 6 | */scripts/* 7 | */setup.py 8 | */flow/utils/shflags 9 | *dummy_server.py 10 | *aimsun.py 11 | *aimsun/run.py 12 | *aimsun/api.py 13 | *aimsun/generate.py 14 | *aimsun/load.py 15 | *flow/multiagent_* 16 | *flow/singleagent_* 17 | 18 | exclude_lines = 19 | if __name__ == .__main__.: 20 | raise NotImplementedError 21 | @ray.remote 22 | @abstractmethod 23 | def policy_mapping_fn* 24 | def main(args)* 25 | pragma: no cover 26 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/bottleneck0.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Bottleneck - 0 4 | yt_string: null # TODO: find video 5 | description: "Maximizing throughput in a bottleneck structure: The goal of this problem is to learn to avoid the capacity drop that is characteristic to bottleneck structures in transportation networks, and maximize the total outflow in a mixed-autonomy setting.
4 lanes, inflow = 1900 veh/hour, 10% CAV penetration, no vehicles are allowed to lane change, S=(141,), A=(20,), T=1000." -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/bottleneck2.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Bottleneck - 2 4 | yt_string: null # TODO: find video 5 | description: "Maximizing throughput in a bottleneck structure: The goal of this problem is to learn to avoid the capacity drop that is characteristic to bottleneck structures in transportation networks, and maximize the total outflow in a mixed-autonomy setting.
8 lanes, inflow = 3800 veh/hour, 10% CAV penetration, no vehicles are allowed to lane change, S=(281,), A=(40,), T=1000." -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Technical question 3 | title: DO NOT POST THIS. 4 | about: If you have a question or run into some problem with Flow (e.g. during the installation or when running an example) 5 | 6 | --- 7 | 8 | PLEASE DO NOT ASK YOUR QUESTIONS HERE ON GITHUB! 9 | 10 | If you have a question or run into some problem (e.g. during installation or when running an example) 11 | with Flow, please direct your technical questions to Stack Overflow using the "flow-project" tag. 12 | 13 | link: https://stackoverflow.com/questions/tagged/flow-project 14 | tag: flow-project 15 | -------------------------------------------------------------------------------- /flow/scenarios/traffic_light_grid.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/traffic_light_grid.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.traffic_light_grid import TrafficLightGridNetwork 7 | from flow.networks.traffic_light_grid import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.traffic_light_grid', 11 | 'flow.networks.traffic_light_grid.TrafficLightGridNetwork') 12 | class TrafficLightGridScenario(TrafficLightGridNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | labels: feature request 4 | about: You can request a feature to be added to Flow 5 | 6 | --- 7 | 8 | 16 | 17 | ## Feature Description 18 | 19 | Please provide: 20 | 21 | - Clear description of the feature 22 | - Description of what you expect 23 | - [optional] Any other context (e.g. pictures) 24 | -------------------------------------------------------------------------------- /flow/benchmarks/descriptions/bottleneck1.yml: -------------------------------------------------------------------------------- 1 | email: kanaad@berkeley.edu 2 | explanation_link: https://github.com/flow-project/flow/tree/master/flow/benchmarks 3 | name: Bottleneck - 1 4 | yt_string: null # TODO: find video 5 | description: "Maximizing throughput in a bottleneck structure: The goal of this problem is to learn to avoid the capacity drop that is characteristic to bottleneck structures in transportation networks, and maximize the total outflow in a mixed-autonomy setting.
4 lanes, inflow = 1900 veh/hour, 10% CAV penetration, the human drivers follow the standard lane changing model in the simulator, S=(141,), A=(20,), T=1000." -------------------------------------------------------------------------------- /flow/multiagent_envs/traffic_light_grid.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/multiagent/traffic_light_grid.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.multiagent.traffic_light_grid import MultiTrafficLightGridPOEnv as MTLGPOEnv 7 | from flow.envs.multiagent.traffic_light_grid import ADDITIONAL_ENV_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.multiagent_envs.traffic_light_grid', 11 | 'flow.envs.multiagent.traffic_light_grid.MultiEnv') 12 | class MultiTrafficLightGridPOEnv(MTLGPOEnv): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/multiagent_envs/loop/wave_attenuation.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/multiagent/traffic_light_grid.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.multiagent.ring.wave_attenuation import MultiWaveAttenuationPOEnv as MWAPOEnv 7 | from flow.envs.multiagent.ring.wave_attenuation import ADDITIONAL_ENV_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.multiagent_envs.loop.wave_attenuation', 11 | 'flow.envs.multiagent.ring.wave_attenuation.MultiWaveAttenuationPOEnv') 12 | class MultiWaveAttenuationPOEnv(MWAPOEnv): 13 | """See parent class.""" 14 | 15 | pass 16 | -------------------------------------------------------------------------------- /flow/multiagent_envs/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for multi-agent envs is created.""" 2 | 3 | from flow.multiagent_envs.multiagent_env import MultiEnv 4 | from flow.multiagent_envs.loop.wave_attenuation import \ 5 | MultiWaveAttenuationPOEnv 6 | from flow.multiagent_envs.loop.loop_accel import AdversarialAccelEnv 7 | from flow.multiagent_envs.traffic_light_grid import MultiTrafficLightGridPOEnv 8 | from flow.multiagent_envs.highway import MultiAgentHighwayPOEnv 9 | 10 | __all__ = [ 11 | 'MultiEnv', 12 | 'AdversarialAccelEnv', 13 | 'MultiWaveAttenuationPOEnv', 14 | 'MultiTrafficLightGridPOEnv', 15 | 'MultiAgentHighwayPOEnv' 16 | ] 17 | -------------------------------------------------------------------------------- /scripts/sumo_patch.txt: -------------------------------------------------------------------------------- 1 | --- ../../../sumo-nightly/tools/build/version.py 2017-08-24 16:42:43.000000000 -0700 2 | +++ ../../sumo/tools/build/version.py 2017-09-21 12:40:49.000000000 -0700 3 | @@ -126,7 +126,7 @@ 4 | # svnFile is newer. lets update the revision number 5 | try: 6 | svnInfo = subprocess.check_output(['svn', 'info', sumoSrc]) 7 | - svnRevision = int(re.search('Revision: (\d*)', repr(svnInfo)).group(1)) 8 | + svnRevision = int(re.search('Revision: (\d*)', svnInfo).group(1)) 9 | except: 10 | svnRevision = parseRevision(svnFile) 11 | create_version_file(versionFile, svnRevision, svnFile) 12 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: flow 2 | 3 | dependencies: 4 | - python==3.7.3 5 | - pip: 6 | - scipy==1.1.0 7 | - lxml==4.4.1 8 | - six==1.11.0 9 | - path.py 10 | - python-dateutil==2.7.3 11 | - pip>=18.0 12 | - tensorflow==1.15.2 13 | - setuptools==41.0.0 14 | - plotly==2.4.0 15 | - gym==0.14.0 16 | - pyprind==2.11.2 17 | - nose2==0.8.0 18 | - cached_property 19 | - joblib==0.10.3 20 | - matplotlib==3.0.0 21 | - dill 22 | - lz4 23 | - ray==0.8.0 24 | - setproctitle 25 | - psutil 26 | - opencv-python 27 | - boto3==1.10.45 28 | - redis~=2.10.6 29 | -------------------------------------------------------------------------------- /docs/sumo-depart-time-issue.md: -------------------------------------------------------------------------------- 1 | ### SUMO Depart Time Issue: 2 | 3 | Issue: When running a long experiment the following error may occur: 4 | 5 | 6 | 1. Find your SUMO installation directory (should be in your bash config and be named something like: `sumo-0.27.1`) 7 | 2. Open `/src/traci-server/TraCIServerAPI_Vehicle.cpp` and go to line 1200 8 | 3. Change the line from: 9 | 4. ```return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.";``` 10 | to: 11 | ```vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep();``` 12 | 5. ./configure and make to rebuild 13 | 14 | Essentially, we're forcing SUMO to add the car at the current time if it detects that you've specified a time in the past. -------------------------------------------------------------------------------- /flow/scenarios/figure_eight.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/networks/figure_eight.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.networks.figure_eight import FigureEightNetwork 7 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS # noqa: F401 8 | 9 | 10 | @deprecated('flow.scenarios.figure_eight', 11 | 'flow.networks.figure_eight.FigureEightNetwork') 12 | class FigureEightScenario(FigureEightNetwork): 13 | """See parent class.""" 14 | 15 | pass 16 | 17 | 18 | @deprecated('flow.scenarios.figure_eight', 19 | 'flow.networks.figure_eight.FigureEightNetwork') 20 | class Figure8Scenario(FigureEightNetwork): 21 | """See parent class.""" 22 | 23 | pass 24 | -------------------------------------------------------------------------------- /flow/envs/loop/lane_changing.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/ring/lane_change_accel.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.ring.lane_change_accel import LaneChangeAccelEnv as LCEnv 7 | from flow.envs.ring.lane_change_accel import LaneChangeAccelPOEnv as LCPOEnv 8 | 9 | 10 | @deprecated('flow.envs.loop.lane_changing', 11 | 'flow.envs.ring.lane_change_accel.LaneChangeAccelEnv') 12 | class LaneChangeAccelEnv(LCEnv): 13 | """See parent class.""" 14 | 15 | pass 16 | 17 | 18 | @deprecated('flow.envs.loop.lane_changing', 19 | 'flow.envs.ring.lane_change_accel.LaneChangeAccelPOEnv') 20 | class LaneChangeAccelPOEnv(LCPOEnv): 21 | """See parent class.""" 22 | 23 | pass 24 | -------------------------------------------------------------------------------- /flow/envs/loop/wave_attenuation.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/ring/wave_attenuation.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.ring.wave_attenuation import WaveAttenuationEnv as WAEnv 7 | from flow.envs.ring.wave_attenuation import WaveAttenuationPOEnv as WAPOEnv 8 | 9 | 10 | @deprecated('flow.envs.loop.wave_attenuation', 11 | 'flow.envs.ring.wave_attenuation.WaveAttenuationEnv') 12 | class WaveAttenuationEnv(WAEnv): 13 | """See parent class.""" 14 | 15 | pass 16 | 17 | 18 | @deprecated('flow.envs.loop.wave_attenuation', 19 | 'flow.envs.ring.wave_attenuation.WaveAttenuationPOEnv') 20 | class WaveAttenuationPOEnv(WAPOEnv): 21 | """See parent class.""" 22 | 23 | pass 24 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ## Pull request information 12 | 13 | - **Status**: ? (ready to merge / in development) 14 | - **Kind of changes**: ? (bug fix / new feature / documentation...) 15 | - **Related PR or issue**: ? (optional) 16 | 17 | ## Description 18 | 19 | 20 | 21 | 22 | ? (general description) 23 | -------------------------------------------------------------------------------- /docs/libsumo_mac.md: -------------------------------------------------------------------------------- 1 | # How to install Libsumo for Mac OS 2 | 3 | This is adapted from an email exchange with the SUMO staff. 4 | 5 | 6 | 7 | To install libsumo requires re-building and installing SUMO from source. 8 | 9 | ## Steps 10 | 11 | - **Install swig:** ```brew install swig``` 12 | - **Clone the repo:** ```git clone https://github.com/eclipse/sumo.git``` 13 | - **Create a “cmake-build” directory inside sumo/build/ and navigate to it:** ```mkdir build/cmake-build && cd build/cmake-build``` 14 | 15 | **The next 3 steps are inside that directory** 16 | 17 | - ```cmake ../..``` 18 | - ```make``` 19 | - ```make install``` 20 | 21 | ## Additional Notes 22 | - You can test if libsumo has been built looking at (./testlibsumo) inside the sumo/bin/ directory. 23 | - Bear in mind to use libsumo with the same Python version with which CMake built SUMO. -------------------------------------------------------------------------------- /flow/controllers/lane_change_controllers.py: -------------------------------------------------------------------------------- 1 | """Contains a list of custom lane change controllers.""" 2 | 3 | from flow.controllers.base_lane_changing_controller import \ 4 | BaseLaneChangeController 5 | 6 | 7 | class SimLaneChangeController(BaseLaneChangeController): 8 | """A controller used to enforce sumo lane-change dynamics on a vehicle. 9 | 10 | Usage: See base class for usage example. 11 | """ 12 | 13 | def get_lane_change_action(self, env): 14 | """See parent class.""" 15 | return None 16 | 17 | 18 | class StaticLaneChanger(BaseLaneChangeController): 19 | """A lane-changing model used to keep a vehicle in the same lane. 20 | 21 | Usage: See base class for usage example. 22 | """ 23 | 24 | def get_lane_change_action(self, env): 25 | """See parent class.""" 26 | return 0 27 | -------------------------------------------------------------------------------- /scripts/setup_sumo_ubuntu1604.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Installing system dependencies for SUMO" 3 | sudo apt-get update 4 | sudo apt-get install -y cmake swig libgtest-dev python-pygame python-scipy 5 | sudo apt-get install -y autoconf libtool pkg-config libgdal-dev libxerces-c-dev 6 | sudo apt-get install -y libproj-dev libfox-1.6-dev libxml2-dev libxslt1-dev 7 | sudo apt-get install -y build-essential curl unzip flex bison python python-dev 8 | sudo apt-get install -y python3-dev 9 | sudo pip3 install cmake cython 10 | 11 | echo "Installing sumo binaries" 12 | mkdir -p $HOME/sumo_binaries/bin 13 | pushd $HOME/sumo_binaries/bin 14 | wget https://akreidieh.s3.amazonaws.com/sumo/flow-0.4.0/binaries-ubuntu1604.tar.xz 15 | tar -xf binaries-ubuntu1604.tar.xz 16 | rm binaries-ubuntu1604.tar.xz 17 | chmod +x * 18 | popd 19 | echo 'export PATH="$HOME/sumo_binaries/bin:$PATH"' >> ~/.bashrc 20 | echo 'export SUMO_HOME="$HOME/sumo_binaries/bin"' >> ~/.bashrc 21 | -------------------------------------------------------------------------------- /scripts/setup_sumo_ubuntu1804.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Installing system dependencies for SUMO" 4 | sudo apt-get update 5 | sudo apt-get install -y cmake swig libgtest-dev python-pygame python-scipy 6 | sudo apt-get install -y autoconf libtool pkg-config libgdal-dev libxerces-c-dev 7 | sudo apt-get install -y libproj-dev libfox-1.6-dev libxml2-dev libxslt1-dev 8 | sudo apt-get install -y build-essential curl unzip flex bison python python-dev 9 | sudo apt-get install -y python3-dev 10 | sudo pip3 install cmake cython 11 | 12 | echo "Installing sumo binaries" 13 | mkdir -p $HOME/sumo_binaries/bin 14 | pushd $HOME/sumo_binaries/bin 15 | wget https://akreidieh.s3.amazonaws.com/sumo/flow-0.4.0/binaries-ubuntu1804.tar.xz 16 | tar -xf binaries-ubuntu1804.tar.xz 17 | rm binaries-ubuntu1804.tar.xz 18 | chmod +x * 19 | popd 20 | echo 'export PATH="$HOME/sumo_binaries/bin:$PATH"' >> ~/.bashrc 21 | echo 'export SUMO_HOME="$HOME/sumo_binaries/bin"' >> ~/.bashrc 22 | -------------------------------------------------------------------------------- /scripts/setup_sumo_ubuntu1404.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Installing system dependencies for open-ai baselines" 3 | sudo apt-get update && sudo apt-get install cmake libopenmpi-dev python3-dev zlib1g-dev 4 | echo "Installing system dependencies for SUMO" 5 | sudo apt-get update 6 | sudo apt-get install -y subversion autoconf build-essential libtool 7 | sudo apt-get install -y libxerces-c3.1 libxerces-c3-dev libproj-dev 8 | sudo apt-get install -y proj-bin proj-data libgdal1-dev libfox-1.6-0 9 | sudo apt-get install -y libfox-1.6-dev 10 | 11 | echo "Installing sumo binaries" 12 | mkdir -p $HOME/sumo_binaries/bin 13 | pushd $HOME/sumo_binaries/bin 14 | wget https://akreidieh.s3.amazonaws.com/sumo/flow-0.4.0/binaries-ubuntu1404.tar.xz 15 | tar -xf binaries-ubuntu1404.tar.xz 16 | rm binaries-ubuntu1404.tar.xz 17 | chmod +x * 18 | popd 19 | echo 'export PATH="$HOME/sumo_binaries/bin:$PATH"' >> ~/.bashrc 20 | echo 'export SUMO_HOME="$HOME/sumo_binaries/bin"' >> ~/.bashrc 21 | -------------------------------------------------------------------------------- /flow/envs/bottleneck_env.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/bottleneck.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.bottleneck import BottleneckEnv as BEnv 7 | from flow.envs.bottleneck import BottleneckAccelEnv as BAEnv 8 | from flow.envs.bottleneck import BottleneckDesiredVelocityEnv as BDVEnv 9 | 10 | 11 | @deprecated('flow.envs.bottleneck_env', 12 | 'flow.envs.bottleneck.BottleneckEnv') 13 | class BottleneckEnv(BEnv): 14 | """See parent class.""" 15 | 16 | pass 17 | 18 | 19 | @deprecated('flow.envs.bottleneck_env', 20 | 'flow.envs.bottleneck.BottleneckAccelEnv') 21 | class BottleNeckAccelEnv(BAEnv): 22 | """See parent class.""" 23 | 24 | pass 25 | 26 | 27 | @deprecated('flow.envs.bottleneck_env', 28 | 'flow.envs.bottleneck.BottleneckDesiredVelocityEnv') 29 | class DesiredVelocityEnv(BDVEnv): 30 | """See parent class.""" 31 | 32 | pass 33 | -------------------------------------------------------------------------------- /flow/config.py: -------------------------------------------------------------------------------- 1 | """Default config variables, which may be overridden by a user config.""" 2 | import os.path as osp 3 | import os 4 | 5 | PYTHON_COMMAND = "python" 6 | 7 | SUMO_SLEEP = 1.0 # Delay between initializing SUMO and connecting with TraCI 8 | 9 | PROJECT_PATH = osp.abspath(osp.join(osp.dirname(__file__), '..')) 10 | 11 | LOG_DIR = PROJECT_PATH + "/data" 12 | 13 | # users set both of these in their bash_rc or bash_profile 14 | # and also should run aws configure after installing awscli 15 | AWS_ACCESS_KEY = os.environ.get("AWS_ACCESS_KEY", None) 16 | 17 | AWS_ACCESS_SECRET = os.environ.get("AWS_ACCESS_SECRET", None) 18 | 19 | AWS_S3_PATH = "s3://bucket_name" 20 | 21 | # path to the Aimsun_Next main directory (required for Aimsun simulations) 22 | AIMSUN_NEXT_PATH = os.environ.get("AIMSUN_NEXT_PATH", None) 23 | 24 | 25 | # path to the aimsun_flow environment's main directory (required for Aimsun 26 | # simulations) 27 | AIMSUN_SITEPACKAGES = os.environ.get("AIMSUN_SITEPACKAGES", None) 28 | -------------------------------------------------------------------------------- /docs/source/intro.rst: -------------------------------------------------------------------------------- 1 | Introduction 2 | ---------------------- 3 | 4 | Why Flow? 5 | ********* 6 | Traffic systems can often be modeled by complex (nonlinear and coupled) dynamical systems for which classical analysis tools struggle to provide the understanding sought by transportation agencies, planners, and control engineers, mostly because of difficulty to provide analytical results on these. Deep reinforcement learning (RL) provides an opportunity to study complex traffic control problems involving interactions of humans, automated vehicles, and sensing infrastructure. The resulting control laws and emergent behaviors of the vehicles provide insight and understanding of the potential for automation of traffic through mixed fleets of autonomous and manned vehicles. 7 | 8 | Flow is a traffic control benchmarking framework. Its provides a suite of traffic control scenarios (benchmarks), tools for designing custom traffic scenarios, and integration with deep reinforcement learning and traffic microsimulation libraries. 9 | -------------------------------------------------------------------------------- /docs/source/flow.core.rst: -------------------------------------------------------------------------------- 1 | flow.core package 2 | ================= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | flow.core.kernel 10 | 11 | Submodules 12 | ---------- 13 | 14 | flow.core.experiment module 15 | --------------------------- 16 | 17 | .. automodule:: flow.core.experiment 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | 22 | flow.core.params module 23 | ----------------------- 24 | 25 | .. automodule:: flow.core.params 26 | :members: 27 | :undoc-members: 28 | :show-inheritance: 29 | 30 | flow.core.rewards module 31 | ------------------------ 32 | 33 | .. automodule:: flow.core.rewards 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | 38 | flow.core.util module 39 | --------------------- 40 | 41 | .. automodule:: flow.core.util 42 | :members: 43 | :undoc-members: 44 | :show-inheritance: 45 | 46 | 47 | Module contents 48 | --------------- 49 | 50 | .. automodule:: flow.core 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | -------------------------------------------------------------------------------- /flow/envs/green_wave_env.py: -------------------------------------------------------------------------------- 1 | """Pending deprecation file. 2 | 3 | To view the actual content, go to: flow/envs/traffic_light_grid.py 4 | """ 5 | from flow.utils.flow_warnings import deprecated 6 | from flow.envs.traffic_light_grid import TrafficLightGridEnv as TLGEnv 7 | from flow.envs.traffic_light_grid import TrafficLightGridPOEnv as TLGPOEnv 8 | from flow.envs.traffic_light_grid import TrafficLightGridTestEnv as TLGTEnv 9 | 10 | 11 | @deprecated('flow.envs.green_wave_env', 12 | 'flow.envs.traffic_light_grid.TrafficLightGridEnv') 13 | class TrafficLightGridEnv(TLGEnv): 14 | """See parent class.""" 15 | 16 | pass 17 | 18 | 19 | @deprecated('flow.envs.green_wave_env', 20 | 'flow.envs.traffic_light_grid.TrafficLightGridPOEnv') 21 | class PO_TrafficLightGridEnv(TLGPOEnv): 22 | """See parent class.""" 23 | 24 | pass 25 | 26 | 27 | @deprecated('flow.envs.green_wave_env', 28 | 'flow.envs.traffic_light_grid.TrafficLightGridTestEnv') 29 | class GreenWaveTestEnv(TLGTEnv): 30 | """See parent class.""" 31 | 32 | pass 33 | -------------------------------------------------------------------------------- /docs/source/flow.utils.aimsun.rst: -------------------------------------------------------------------------------- 1 | flow.utils.aimsun package 2 | ========================= 3 | 4 | flow.utils.aimsun.api module 5 | ---------------------------- 6 | 7 | .. automodule:: flow.utils.aimsun.api 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | flow.utils.aimsun.constants module 13 | ---------------------------------- 14 | 15 | .. automodule:: flow.utils.aimsun.constants 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | flow.utils.aimsun.generate module 21 | --------------------------------- 22 | 23 | .. automodule:: flow.utils.aimsun.generate 24 | :members: 25 | :undoc-members: 26 | :show-inheritance: 27 | 28 | flow.utils.aimsun.run module 29 | ---------------------------- 30 | 31 | .. automodule:: flow.utils.aimsun.run 32 | :members: 33 | :undoc-members: 34 | :show-inheritance: 35 | 36 | flow.utils.aimsun.struct module 37 | ------------------------------- 38 | 39 | .. automodule:: flow.utils.aimsun.struct 40 | :members: 41 | :undoc-members: 42 | :show-inheritance: 43 | -------------------------------------------------------------------------------- /docs/source/flow.core.kernel.rst: -------------------------------------------------------------------------------- 1 | flow.core.kernel package 2 | ======================== 3 | 4 | flow.core.kernel module 5 | ----------------------- 6 | 7 | .. automodule:: flow.core.kernel 8 | :members: 9 | :undoc-members: 10 | :show-inheritance: 11 | 12 | flow.core.kernel.network module 13 | -------------------------------- 14 | 15 | .. automodule:: flow.core.kernel.network 16 | :members: 17 | :undoc-members: 18 | :show-inheritance: 19 | 20 | flow.core.kernel.simulation module 21 | ---------------------------------- 22 | 23 | .. automodule:: flow.core.kernel.simulation 24 | :members: 25 | :undoc-members: 26 | :show-inheritance: 27 | 28 | flow.core.kernel.vehicle module 29 | ------------------------------- 30 | 31 | .. automodule:: flow.core.kernel.vehicle 32 | :members: 33 | :undoc-members: 34 | :show-inheritance: 35 | 36 | flow.core.kernel.traffic_light module 37 | ------------------------------------- 38 | 39 | .. automodule:: flow.core.kernel.traffic_light 40 | :members: 41 | :undoc-members: 42 | :show-inheritance: 43 | -------------------------------------------------------------------------------- /flow/envs/multiagent/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to ensure documentation for multi-agent envs is created.""" 2 | 3 | from flow.envs.multiagent.base import MultiEnv 4 | from flow.envs.multiagent.ring.wave_attenuation import \ 5 | MultiWaveAttenuationPOEnv 6 | from flow.envs.multiagent.ring.wave_attenuation import \ 7 | MultiAgentWaveAttenuationPOEnv 8 | from flow.envs.multiagent.ring.accel import AdversarialAccelEnv 9 | from flow.envs.multiagent.ring.accel import MultiAgentAccelPOEnv 10 | from flow.envs.multiagent.traffic_light_grid import MultiTrafficLightGridPOEnv 11 | from flow.envs.multiagent.highway import MultiAgentHighwayPOEnv 12 | from flow.envs.multiagent.merge import MultiAgentMergePOEnv 13 | from flow.envs.multiagent.i210 import I210MultiEnv 14 | 15 | __all__ = [ 16 | 'MultiEnv', 17 | 'AdversarialAccelEnv', 18 | 'MultiWaveAttenuationPOEnv', 19 | 'MultiTrafficLightGridPOEnv', 20 | 'MultiAgentHighwayPOEnv', 21 | 'MultiAgentAccelPOEnv', 22 | 'MultiAgentWaveAttenuationPOEnv', 23 | 'MultiAgentMergePOEnv', 24 | 'I210MultiEnv' 25 | ] 26 | -------------------------------------------------------------------------------- /docs/source/flow.envs.rst: -------------------------------------------------------------------------------- 1 | flow.envs package 2 | ================= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | flow.envs.bay_bridge 10 | 11 | Submodules 12 | ---------- 13 | 14 | flow.envs.base\_env module 15 | -------------------------- 16 | 17 | .. automodule:: flow.envs.base 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | 22 | flow.envs.bottleneck\_env module 23 | -------------------------------- 24 | 25 | .. automodule:: flow.envs.bottleneck 26 | :members: 27 | :undoc-members: 28 | :show-inheritance: 29 | 30 | flow.envs.traffic\_light\_grid module 31 | --------------------------------- 32 | 33 | .. automodule:: flow.envs.traffic_light_grid 34 | :members: 35 | :undoc-members: 36 | :show-inheritance: 37 | 38 | flow.envs.merge module 39 | ---------------------- 40 | 41 | .. automodule:: flow.envs.merge 42 | :members: 43 | :undoc-members: 44 | :show-inheritance: 45 | 46 | 47 | Module contents 48 | --------------- 49 | 50 | .. automodule:: flow.envs 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Decentralized Reinforcement Learning Traffic Light Control 2 | 3 | DQN branch contains the code for multi-agent DQN controlled intelligent traffic lights. 4 | 5 | Currently DQN branch has been approved by the original Flow community and waiting to be merged. 6 | 7 | For detailed changes compared to original Flow code, please refer to the [PR](https://github.com/flow-project/flow/pull/964) 8 | 9 | # Citing 10 | 11 | For more theoretical details such as optima proof, system design, and performance comparison, please refer and cite our [paper](https://arxiv.org/pdf/2009.01502.pdf): 12 | ``` 13 | @ARTICLE{9275391, 14 | author={P. {Zhou} and X. {Chen} and Z. {Liu} and T. {Braud} and P. {Hui} and J. {Kangasharju}}, 15 | journal={IEEE Transactions on Intelligent Transportation Systems}, 16 | title={DRLE: Decentralized Reinforcement Learning at the Edge for Traffic Light Control in the IoV}, 17 | year={2020}, 18 | doi={10.1109/TITS.2020.3035841}} 19 | ``` 20 | 21 | # Demo: 22 | https://youtu.be/p2sMtN_mW8s 23 | 24 | 25 | Original instructions, please refer to [Flow](https://flow-project.github.io/) 26 | -------------------------------------------------------------------------------- /docs/source/flow.utils.rst: -------------------------------------------------------------------------------- 1 | flow.utils package 2 | ================== 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | 9 | flow.utils.aimsun 10 | 11 | Submodules 12 | ---------- 13 | 14 | flow.utils.exceptions module 15 | ---------------------------- 16 | 17 | .. automodule:: flow.utils.exceptions 18 | :members: 19 | :undoc-members: 20 | :show-inheritance: 21 | 22 | 23 | flow.utils.flow_warnings module 24 | ------------------------------- 25 | 26 | .. automodule:: flow.utils.flow_warnings 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | 32 | 33 | flow.utils.registry module 34 | -------------------------- 35 | 36 | .. automodule:: flow.utils.registry 37 | :members: 38 | :undoc-members: 39 | :show-inheritance: 40 | 41 | 42 | flow.utils.rllib module 43 | ----------------------- 44 | 45 | .. automodule:: flow.utils.rllib 46 | :members: 47 | :undoc-members: 48 | :show-inheritance: 49 | 50 | 51 | Module contents 52 | --------------- 53 | 54 | .. automodule:: flow.utils 55 | :members: 56 | :undoc-members: 57 | :show-inheritance: 58 | -------------------------------------------------------------------------------- /scripts/setup_sumo_osx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Installing system dependencies for SUMO" 3 | # Quick check that we actually have brew, if not, lets install it 4 | command -v brew >/dev/null 2>&1 || echo >&2 "Homebrew is missing, you can install it by running \n/usr/bin/ruby -e \$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" || exit 1 5 | # script dependencies 6 | brew install wget 7 | # rllab dependencies 8 | brew install swig sdl sdl_image sdl_mixer sdl_ttf portmidi 9 | # sumo dependencies 10 | brew install Caskroom/cask/xquartz autoconf automake pkg-config libtool gdal proj xerces-c fox 11 | 12 | echo "Installing sumo binaries" 13 | mkdir -p $HOME/sumo_binaries/bin 14 | pushd $HOME/sumo_binaries/bin 15 | wget https://akreidieh.s3.amazonaws.com/sumo/flow-0.4.0/binaries-mac.tar.xz 16 | tar -xf binaries-mac.tar.xz 17 | rm binaries-mac.tar.xz 18 | chmod +x * 19 | popd 20 | export SUMO_HOME="$HOME/sumo_binaries/bin" 21 | export PATH="$SUMO_HOME:$PATH" 22 | 23 | echo 'Add the following to your ~/.bashrc:' 24 | echo '' 25 | echo 'export SUMO_HOME="$HOME/sumo_binaries/bin"' 26 | echo 'export PATH="$SUMO_HOME:$PATH"' 27 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Cathy Wu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /flow/networks/__init__.py: -------------------------------------------------------------------------------- 1 | """Contains all available networks in Flow.""" 2 | 3 | # base network class 4 | from flow.networks.base import Network 5 | 6 | # custom networks 7 | from flow.networks.bay_bridge import BayBridgeNetwork 8 | from flow.networks.bay_bridge_toll import BayBridgeTollNetwork 9 | from flow.networks.bottleneck import BottleneckNetwork 10 | from flow.networks.figure_eight import FigureEightNetwork 11 | from flow.networks.traffic_light_grid import TrafficLightGridNetwork 12 | from flow.networks.highway import HighwayNetwork 13 | from flow.networks.ring import RingNetwork 14 | from flow.networks.merge import MergeNetwork 15 | from flow.networks.multi_ring import MultiRingNetwork 16 | from flow.networks.minicity import MiniCityNetwork 17 | from flow.networks.highway_ramps import HighwayRampsNetwork 18 | from flow.networks.i210_subnetwork import I210SubNetwork 19 | 20 | __all__ = [ 21 | "Network", "BayBridgeNetwork", "BayBridgeTollNetwork", 22 | "BottleneckNetwork", "FigureEightNetwork", "TrafficLightGridNetwork", 23 | "HighwayNetwork", "RingNetwork", "MergeNetwork", "MultiRingNetwork", 24 | "MiniCityNetwork", "HighwayRampsNetwork", "I210SubNetwork" 25 | ] 26 | -------------------------------------------------------------------------------- /docs/cluster_setup.md: -------------------------------------------------------------------------------- 1 | # Setting up an rllib cluster 2 | - cd into scripts 3 | - If you haven't set up before, comment out file_mounts and setup_commands 4 | - run ray create_or_update ray_autoscale.yaml 5 | - Enter into the ~/.ssh and run ssh-keygen -y -f 6 | - Copy the resulting key and add it as a key to your github following these instructions: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/#platform-linux 7 | - Uncomment out file mount and setup_commands 8 | - Change tmp/foo to have your path and point to the desired branch 9 | - Make sure that branch is pushed up to github 10 | - Change tmp/foo2 to be the path to your ray key 11 | - run ray create_or_update ray_autoscale.yaml 12 | - Log into your cluster, change redis_address in ray.init(redis_address="ADDRESS") to the redis address output by create_or_update 13 | - Run your code! Make sure to kill the cluster when you're done 14 | 15 | ## Notes 16 | 17 | - If you want to update your branch across all workers, push it to github and 18 | rerun ray create_or_update 19 | - *Save the instructions after ray create_or_update, they're useful!* 20 | - If you see "fatal: not a tree", you need to push your branch to github 21 | - If it fails because of "stash your changes", go to the node and stash your changes -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM continuumio/miniconda3:latest 2 | MAINTAINER Fangyu Wu (fangyuwu@berkeley.edu) 3 | 4 | # System 5 | RUN apt-get update && \ 6 | apt-get -y upgrade && \ 7 | apt-get install -y \ 8 | vim \ 9 | apt-utils && \ 10 | pip install -U pip 11 | 12 | # Flow dependencies 13 | RUN cd ~ && \ 14 | conda install opencv && \ 15 | pip install tensorflow 16 | 17 | # Flow 18 | RUN cd ~ && \ 19 | git clone https://github.com/flow-project/flow.git && \ 20 | cd flow && \ 21 | git checkout v0.3.0 && \ 22 | pip install -e . 23 | 24 | # SUMO dependencies 25 | RUN apt-get install -y \ 26 | cmake \ 27 | build-essential \ 28 | swig \ 29 | libgdal-dev \ 30 | libxerces-c-dev \ 31 | libproj-dev \ 32 | libfox-1.6-dev \ 33 | libxml2-dev \ 34 | libxslt1-dev \ 35 | openjdk-8-jdk 36 | 37 | # SUMO 38 | RUN cd ~ && \ 39 | git clone --recursive https://github.com/eclipse/sumo.git && \ 40 | cd sumo && \ 41 | git checkout cbe5b73 && \ 42 | mkdir build/cmake-build && \ 43 | cd build/cmake-build && \ 44 | cmake ../.. && \ 45 | make 46 | 47 | # Ray/RLlib 48 | RUN cd ~ && \ 49 | pip install ray==0.6.2 \ 50 | psutil 51 | 52 | # Startup process 53 | RUN echo 'export SUMO_HOME="$HOME/sumo"' >> ~/.bashrc && \ 54 | echo 'export PATH="$HOME/sumo/bin:$PATH"' >> ~/.bashrc && \ 55 | echo 'export PYTHONPATH="$HOME/sumo/tools:$PYTHONPATH"' >> ~/.bashrc -------------------------------------------------------------------------------- /flow/controllers/rlcontroller.py: -------------------------------------------------------------------------------- 1 | """Contains the RLController class.""" 2 | 3 | from flow.controllers.base_controller import BaseController 4 | 5 | 6 | class RLController(BaseController): 7 | """RL Controller. 8 | 9 | Vehicles with this class specified will be stored in the list of the RL IDs 10 | in the Vehicles class. 11 | 12 | Usage: See base class for usage example. 13 | 14 | Attributes 15 | ---------- 16 | veh_id : str 17 | Vehicle ID for SUMO identification 18 | 19 | Examples 20 | -------- 21 | A set of vehicles can be instantiated as RL vehicles as follows: 22 | 23 | >>> from flow.core.params import VehicleParams 24 | >>> vehicles = VehicleParams() 25 | >>> vehicles.add(acceleration_controller=(RLController, {})) 26 | 27 | In order to collect the list of all RL vehicles in the next, run: 28 | 29 | >>> from flow.envs import Env 30 | >>> env = Env(...) 31 | >>> rl_ids = env.k.vehicle.get_rl_ids() 32 | """ 33 | 34 | def __init__(self, veh_id, car_following_params): 35 | """Instantiate an RL Controller.""" 36 | BaseController.__init__( 37 | self, 38 | veh_id, 39 | car_following_params) 40 | 41 | def get_accel(self, env): 42 | """Pass, as this is never called; required to override abstractmethod.""" 43 | pass 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | labels: bug 4 | about: You can report a bug in Flow 5 | 6 | --- 7 | 8 | 15 | 16 | ## Bug Description 17 | 18 | A clear and concise description of the bug and what you expected to happen. 19 | 20 | ## Bug Reproduce 21 | 22 | 23 | File in which the bug occurred: `file.py` 24 | 25 | The exact command that you did run that caused the bug: 26 | `command` 27 | 28 | ## Output Log 29 | 30 | 31 | Full error output log: 32 | 33 | ``` 34 | error log 35 | ``` 36 | 37 | ## Screenshots 38 | 39 | 40 | 41 | 42 | 43 | Screenshots: 44 | 45 | ![picture name](https://link/to/screenshot) 46 | 47 | ## Versions 48 | 49 | 50 | 51 | - OS: ? (For example, RedHat, macOS Mojave, ...] 52 | - Flow version: ? (run `python -c "import flow; print(flow.__version__)"`) 53 | - Flow commit number: ? (run `git log` and copy the commit number) 54 | -------------------------------------------------------------------------------- /tests/stress_tests/stress_test_start.py: -------------------------------------------------------------------------------- 1 | """Repeatedly opens up a sumo port to test for race conditions.""" 2 | from flow.controllers import IDMController, ContinuousRouter 3 | from flow.core.params import SumoParams, EnvParams, \ 4 | InitialConfig, NetParams 5 | from flow.core.params import VehicleParams 6 | from flow.envs.ring.accel import AccelEnv, ADDITIONAL_ENV_PARAMS 7 | from flow.networks.ring import RingNetwork, ADDITIONAL_NET_PARAMS 8 | import ray 9 | 10 | 11 | @ray.remote 12 | def start(): 13 | """Start a environment object with ray.""" 14 | sim_params = SumoParams(sim_step=0.1, render=False) 15 | 16 | vehicles = VehicleParams() 17 | vehicles.add( 18 | veh_id="idm", 19 | acceleration_controller=(IDMController, {}), 20 | routing_controller=(ContinuousRouter, {}), 21 | num_vehicles=22) 22 | 23 | env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) 24 | 25 | additional_net_params = ADDITIONAL_NET_PARAMS.copy() 26 | net_params = NetParams(additional_params=additional_net_params) 27 | 28 | initial_config = InitialConfig(bunching=20) 29 | 30 | network = RingNetwork( 31 | name="ring", 32 | vehicles=vehicles, 33 | net_params=net_params, 34 | initial_config=initial_config) 35 | 36 | env = AccelEnv(env_params, sim_params, network) 37 | env.close() 38 | 39 | 40 | ray.init() 41 | results = ray.get([start.remote() for i in range(10000)]) 42 | -------------------------------------------------------------------------------- /scripts/sync_s3.py: -------------------------------------------------------------------------------- 1 | """Script for syncing files form s3 down to your local machine. 2 | 3 | Code is heavily based on 4 | https://github.com/rll/rllab/blob/master/scripts/sync_s3.py 5 | """ 6 | 7 | import sys 8 | from flow import config 9 | import os 10 | import argparse 11 | sys.path.append('.') 12 | 13 | if __name__ == "__main__": 14 | parser = argparse.ArgumentParser() 15 | parser.add_argument('folder', type=str, default=None, nargs='?') 16 | parser.add_argument('--dry', action='store_true', default=False) 17 | parser.add_argument('--bare', action='store_true', default=False) 18 | args = parser.parse_args() 19 | remote_dir = config.AWS_S3_PATH 20 | local_dir = os.path.join(config.LOG_DIR, "s3") 21 | if args.folder: 22 | remote_dir = os.path.join(remote_dir, args.folder) 23 | local_dir = os.path.join(local_dir, args.folder) 24 | if args.bare: 25 | command = ( 26 | ("aws s3 sync {remote_dir} {local_dir} --exclude '*' --include " + 27 | "'*.csv' --include '*.json' --content-type \"UTF-8\"") 28 | .format(local_dir=local_dir, remote_dir=remote_dir)) 29 | else: 30 | command = ( 31 | ("aws s3 sync {remote_dir} {local_dir} --exclude '*stdout.log' " + 32 | "--exclude '*stdouterr.log' --content-type \"UTF-8\"") 33 | .format(local_dir=local_dir, remote_dir=remote_dir)) 34 | if args.dry: 35 | print(command) 36 | else: 37 | os.system(command) 38 | -------------------------------------------------------------------------------- /flow/benchmarks/run_all_benchmarks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Running all benchmarks" 3 | 4 | declare -a benchmarks=( 5 | "bottleneck0" "bottleneck1" "bottleneck2" 6 | "figureeight0" "figureeight1" "figureeight2" 7 | "grid0" "grid1" 8 | "merge0" "merge1" 9 | ) 10 | parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 11 | 12 | cd "$parent_path" 13 | 14 | dt=$(date '+%Y_%m_%d_%H%M'); 15 | echo $dt 16 | i=0 17 | for run_script in rllib/ppo_runner.py; do 18 | declare alg=`echo ${run_script} | cut -d'/' -f 2 | cut -d'_' -f 1` 19 | for benchmark in "${benchmarks[@]}"; do 20 | i=$((i+1)) 21 | echo "=====================================================================" 22 | echo "Training ${benchmark} with ${alg}" 23 | echo "ray exec ../../scripts/benchmark_autoscale.yaml \"python ./flow/flow/benchmarks/${run_script} --upload_dir=\"flow-benchmark.results/${dt}/\" --benchmark_name=${benchmark} --num_cpus 14\" --start --stop --cluster-name=all_benchmark_${benchmark}_${alg}_$dt --tmux" 24 | echo "=====================================================================" 25 | ray exec ../../scripts/benchmark_autoscale.yaml "python ./flow/flow/benchmarks/${run_script} --upload_dir=\"flow-benchmark.results/${dt}/\" --benchmark_name=${benchmark} --num_cpus 14" --start --stop --cluster-name=all_benchmark_${benchmark}_${alg}_$dt --tmux 26 | done 27 | done -------------------------------------------------------------------------------- /flow/benchmarks/baselines/merge012.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of merge without RL control. 2 | 3 | Baseline is no AVs. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.benchmarks.merge0 import flow_params 9 | 10 | 11 | def merge_baseline(num_runs, render=True): 12 | """Run script for all merge baselines. 13 | 14 | Parameters 15 | ---------- 16 | num_runs : int 17 | number of rollouts the performance of the environment is evaluated 18 | over 19 | render: bool, optional 20 | specifies whether to use the gui during execution 21 | 22 | Returns 23 | ------- 24 | flow.core.experiment.Experiment 25 | class needed to run simulations 26 | """ 27 | sim_params = flow_params['sim'] 28 | env_params = flow_params['env'] 29 | 30 | # modify the rendering to match what is requested 31 | sim_params.render = render 32 | 33 | # set the evaluation flag to True 34 | env_params.evaluate = True 35 | 36 | flow_params['env'].horizon = env_params.horizon 37 | exp = Experiment(flow_params) 38 | 39 | results = exp.run(num_runs) 40 | avg_speed = np.mean(results['returns']) 41 | 42 | return avg_speed 43 | 44 | 45 | if __name__ == '__main__': 46 | runs = 2 # number of simulations to average over 47 | res = merge_baseline(num_runs=runs, render=False) 48 | 49 | print('---------') 50 | print('The average speed across {} runs is {}'.format(runs, res)) 51 | -------------------------------------------------------------------------------- /docs/source/regression.rst: -------------------------------------------------------------------------------- 1 | Regression Testing in Flow 2 | ========================== 3 | 4 | To ensure that the four benchmarks created in Flow have consistently stable results, 5 | we have created a set of regression tests for them. The four benchmarks are shown below: 6 | 7 | .. image:: ../img/benchmarks.png 8 | :width: 500 9 | :align: center 10 | 11 | To confirm that the improvement of the benchmarks via control of the autonomous vehicles 12 | is to the expected level, we have provided scripts for training all of the benchmarks 13 | and then visualizing the results and confirming that they are within the expected bounds. 14 | 15 | To run the benchmark scripts, run 16 | 17 | :: 18 | 19 | flow/benchmarks/run_all_benchmarks.sh 20 | 21 | **WARNING: This will spin up 11 c4.4xlarge AWS EC2 instances**. 22 | Note, to do this you must have set up an AWS EC2 account. 23 | 24 | Once the benchmarks are done training, pull the results down to a folder on your local machine 25 | and then run 26 | 27 | :: 28 | 29 | flow/benchmarks/create_movies.sh 30 | 31 | This will create movies of all of the trained benchmarks and confirm that they results 32 | are within 95% of the expected improvements in velocity or outflow. 33 | 34 | Finally, to cite the benchmarks in your own work please reference: 35 | Vinitsky, E., Kreidieh, A., Le Flem, L., Kheterpal, N., Jang, K., Wu, F., ... & Bayen, A. M. (2018, October). 36 | Benchmarks for reinforcement learning in mixed-autonomy traffic. In Conference on Robot Learning (pp. 399-409). -------------------------------------------------------------------------------- /examples/exp_scripts/compute_210_calibration.py: -------------------------------------------------------------------------------- 1 | """We load the calibrated data from calibrated_values and compute how accurate it is.""" 2 | import numpy as np 3 | import pandas as pd 4 | import pickle as pkl 5 | import os 6 | 7 | if __name__ == '__main__': 8 | with open(os.path.abspath('../calibrated_values/info_dict.pkl'), 'rb') as file: 9 | data = pkl.load(file) 10 | 11 | calibrated_data = pd.read_csv('../calibrated_values/i210_sub_merge_area_reduced.csv') 12 | valid_section = calibrated_data[calibrated_data['oid'] == 8009307] 13 | speeds = valid_section['speed'].to_numpy() / 3.6 # (km/h to m/s) 14 | density = valid_section['density'] 15 | outflow = valid_section['flow'] 16 | 17 | dict_to_idx = {'oid': 0, 'ent': 1, 'flow': 2, 'ttime': 3, 18 | 'speed': 4, 'density': 5, 'lane_changes': 6, 'total_lane_changes': 7} 19 | 20 | errors = [] 21 | # compute the speed errors for a given set of params 22 | for experiment in data: 23 | merge_speed = experiment['avg_merge_speed'] 24 | # now sum it up in segments noting that the sim step is 0.8 25 | num_steps = int(120 / 0.8) 26 | 27 | step_sizes = np.arange(0, len(merge_speed), num_steps) 28 | # sum up all the slices 29 | summed_slices = np.add.reduceat(merge_speed, step_sizes) / num_steps 30 | # throw away the last point and the first point before the network is formed 31 | error = np.abs(np.mean(summed_slices[:-1] - speeds[:summed_slices.shape[0] - 1])) 32 | errors.append(error) 33 | print(errors) 34 | -------------------------------------------------------------------------------- /flow/scenarios/__init__.py: -------------------------------------------------------------------------------- 1 | """Empty init file to handle deprecations.""" 2 | 3 | # base scenario class 4 | from flow.scenarios.base import Scenario 5 | 6 | # custom scenarios 7 | from flow.scenarios.bay_bridge import BayBridgeScenario 8 | from flow.scenarios.bay_bridge_toll import BayBridgeTollScenario 9 | from flow.scenarios.bottleneck import BottleneckScenario 10 | from flow.scenarios.figure_eight import FigureEightScenario 11 | from flow.scenarios.traffic_light_grid import TrafficLightGridScenario 12 | from flow.scenarios.highway import HighwayScenario 13 | from flow.scenarios.ring import RingScenario 14 | from flow.scenarios.merge import MergeScenario 15 | from flow.scenarios.multi_ring import MultiRingScenario 16 | from flow.scenarios.minicity import MiniCityScenario 17 | from flow.scenarios.highway_ramps import HighwayRampsScenario 18 | 19 | # deprecated classes whose names have changed 20 | from flow.scenarios.figure_eight import Figure8Scenario 21 | from flow.scenarios.loop import LoopScenario 22 | from flow.scenarios.grid import SimpleGridScenario 23 | from flow.scenarios.multi_loop import MultiLoopScenario 24 | 25 | 26 | __all__ = [ 27 | "Scenario", 28 | "BayBridgeScenario", 29 | "BayBridgeTollScenario", 30 | "BottleneckScenario", 31 | "FigureEightScenario", 32 | "TrafficLightGridScenario", 33 | "HighwayScenario", 34 | "RingScenario", 35 | "MergeScenario", 36 | "MultiRingScenario", 37 | "MiniCityScenario", 38 | "HighwayRampsScenario", 39 | # deprecated classes 40 | "Figure8Scenario", 41 | "LoopScenario", 42 | "SimpleGridScenario", 43 | "MultiLoopScenario", 44 | ] 45 | -------------------------------------------------------------------------------- /flow/controllers/base_routing_controller.py: -------------------------------------------------------------------------------- 1 | """Contains the base routing controller class.""" 2 | 3 | from abc import ABCMeta, abstractmethod 4 | 5 | 6 | class BaseRouter(metaclass=ABCMeta): 7 | """Base class for routing controllers. 8 | 9 | These controllers are used to dynamically change the routes of vehicles 10 | after initialization. 11 | 12 | Usage 13 | ----- 14 | >>> from flow.core.params import VehicleParams 15 | >>> from flow.controllers import ContinuousRouter 16 | >>> vehicles = VehicleParams() 17 | >>> vehicles.add("human", routing_controller=(ContinuousRouter, {})) 18 | 19 | Note: You can replace "ContinuousRouter" with any routing controller you 20 | want. 21 | 22 | Parameters 23 | ---------- 24 | veh_id : str 25 | ID of the vehicle this controller is used for 26 | router_params : dict 27 | Dictionary of router params 28 | """ 29 | 30 | def __init__(self, veh_id, router_params): 31 | """Instantiate the base class for routing controllers.""" 32 | self.veh_id = veh_id 33 | self.router_params = router_params 34 | 35 | @abstractmethod 36 | def choose_route(self, env): 37 | """Return the routing method implemented by the controller. 38 | 39 | Parameters 40 | ---------- 41 | env : flow.envs.Env 42 | see flow/envs/base.py 43 | 44 | Returns 45 | ------- 46 | list or None 47 | The sequence of edges the vehicle should adopt. If a None value 48 | is returned, the vehicle performs no routing action in the current 49 | time step. 50 | """ 51 | pass 52 | -------------------------------------------------------------------------------- /flow/envs/__init__.py: -------------------------------------------------------------------------------- 1 | """Contains all callable environments in Flow.""" 2 | from flow.envs.base import Env 3 | from flow.envs.bay_bridge import BayBridgeEnv 4 | from flow.envs.bottleneck import BottleneckAccelEnv, BottleneckEnv, \ 5 | BottleneckDesiredVelocityEnv 6 | from flow.envs.traffic_light_grid import TrafficLightGridEnv, \ 7 | TrafficLightGridPOEnv, TrafficLightGridTestEnv, TrafficLightGridBenchmarkEnv 8 | from flow.envs.ring.lane_change_accel import LaneChangeAccelEnv, \ 9 | LaneChangeAccelPOEnv 10 | from flow.envs.ring.accel import AccelEnv 11 | from flow.envs.ring.wave_attenuation import WaveAttenuationEnv, \ 12 | WaveAttenuationPOEnv 13 | from flow.envs.merge import MergePOEnv 14 | from flow.envs.test import TestEnv 15 | 16 | # deprecated classes whose names have changed 17 | from flow.envs.bottleneck_env import BottleNeckAccelEnv 18 | from flow.envs.bottleneck_env import DesiredVelocityEnv 19 | from flow.envs.green_wave_env import PO_TrafficLightGridEnv 20 | from flow.envs.green_wave_env import GreenWaveTestEnv 21 | 22 | 23 | __all__ = [ 24 | 'Env', 25 | 'AccelEnv', 26 | 'LaneChangeAccelEnv', 27 | 'LaneChangeAccelPOEnv', 28 | 'TrafficLightGridTestEnv', 29 | 'MergePOEnv', 30 | 'BottleneckEnv', 31 | 'BottleneckAccelEnv', 32 | 'WaveAttenuationEnv', 33 | 'WaveAttenuationPOEnv', 34 | 'TrafficLightGridEnv', 35 | 'TrafficLightGridPOEnv', 36 | 'TrafficLightGridBenchmarkEnv', 37 | 'BottleneckDesiredVelocityEnv', 38 | 'TestEnv', 39 | 'BayBridgeEnv', 40 | # deprecated classes 41 | 'BottleNeckAccelEnv', 42 | 'DesiredVelocityEnv', 43 | 'PO_TrafficLightGridEnv', 44 | 'GreenWaveTestEnv', 45 | ] 46 | -------------------------------------------------------------------------------- /flow/envs/test.py: -------------------------------------------------------------------------------- 1 | """Test environment used to run simulations in the absence of autonomy.""" 2 | 3 | from flow.envs.base import Env 4 | from gym.spaces.box import Box 5 | import numpy as np 6 | 7 | 8 | class TestEnv(Env): 9 | """Test environment used to run simulations in the absence of autonomy. 10 | 11 | Required from env_params 12 | None 13 | 14 | Optional from env_params 15 | reward_fn : A reward function which takes an an input the environment 16 | class and returns a real number. 17 | 18 | States 19 | States are an empty list. 20 | 21 | Actions 22 | No actions are provided to any RL agent. 23 | 24 | Rewards 25 | The reward is zero at every step. 26 | 27 | Termination 28 | A rollout is terminated if the time horizon is reached or if two 29 | vehicles collide into one another. 30 | """ 31 | 32 | @property 33 | def action_space(self): 34 | """See parent class.""" 35 | return Box(low=0, high=0, shape=(0,), dtype=np.float32) 36 | 37 | @property 38 | def observation_space(self): 39 | """See parent class.""" 40 | return Box(low=0, high=0, shape=(0,), dtype=np.float32) 41 | 42 | def _apply_rl_actions(self, rl_actions): 43 | return 44 | 45 | def compute_reward(self, rl_actions, **kwargs): 46 | """See parent class.""" 47 | if "reward_fn" in self.env_params.additional_params: 48 | return self.env_params.additional_params["reward_fn"](self) 49 | else: 50 | return 0 51 | 52 | def get_state(self, **kwargs): 53 | """See class definition.""" 54 | return np.array([]) 55 | -------------------------------------------------------------------------------- /flow/controllers/__init__.py: -------------------------------------------------------------------------------- 1 | """Contains a list of custom controllers. 2 | 3 | These controllers can be used to modify the dynamics behavior of human-driven 4 | vehicles in the network. 5 | 6 | In addition, the RLController class can be used to add vehicles whose actions 7 | are specified by a learning (RL) agent. 8 | """ 9 | 10 | # RL controller 11 | from flow.controllers.rlcontroller import RLController 12 | 13 | # acceleration controllers 14 | from flow.controllers.base_controller import BaseController 15 | from flow.controllers.car_following_models import CFMController, \ 16 | BCMController, OVMController, LinearOVM, IDMController, \ 17 | SimCarFollowingController, LACController, GippsController, \ 18 | BandoFTLController 19 | from flow.controllers.velocity_controllers import FollowerStopper, \ 20 | PISaturation, NonLocalFollowerStopper 21 | 22 | # lane change controllers 23 | from flow.controllers.base_lane_changing_controller import \ 24 | BaseLaneChangeController 25 | from flow.controllers.lane_change_controllers import StaticLaneChanger, \ 26 | SimLaneChangeController 27 | 28 | # routing controllers 29 | from flow.controllers.base_routing_controller import BaseRouter 30 | from flow.controllers.routing_controllers import ContinuousRouter, \ 31 | GridRouter, BayBridgeRouter, I210Router 32 | 33 | __all__ = [ 34 | "RLController", "BaseController", "BaseLaneChangeController", "BaseRouter", 35 | "CFMController", "BCMController", "OVMController", "LinearOVM", 36 | "IDMController", "SimCarFollowingController", "FollowerStopper", 37 | "PISaturation", "StaticLaneChanger", "SimLaneChangeController", 38 | "ContinuousRouter", "GridRouter", "BayBridgeRouter", "LACController", 39 | "GippsController", "NonLocalFollowerStopper", "BandoFTLController", 40 | "I210Router" 41 | ] 42 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # flake8: noqa 3 | """Setup script for the Flow repository.""" 4 | from os.path import dirname, realpath 5 | from setuptools import find_packages, setup, Distribution 6 | import setuptools.command.build_ext as _build_ext 7 | import subprocess 8 | from flow.version import __version__ 9 | 10 | 11 | def _read_requirements_file(): 12 | """Return the elements in requirements.txt.""" 13 | req_file_path = '%s/requirements.txt' % dirname(realpath(__file__)) 14 | with open(req_file_path) as f: 15 | return [line.strip() for line in f] 16 | 17 | 18 | class build_ext(_build_ext.build_ext): 19 | """External buid commands.""" 20 | 21 | def run(self): 22 | """Install traci wheels.""" 23 | subprocess.check_call( 24 | ['python3','-m','pip', 'install', 25 | 'https://akreidieh.s3.amazonaws.com/sumo/flow-0.4.0/' 26 | 'sumotools-0.4.0-py3-none-any.whl']) 27 | 28 | 29 | class BinaryDistribution(Distribution): 30 | """See parent class.""" 31 | 32 | def has_ext_modules(self): 33 | """Return True for external modules.""" 34 | return True 35 | 36 | 37 | setup( 38 | name='flow', 39 | version=__version__, 40 | distclass=BinaryDistribution, 41 | cmdclass={"build_ext": build_ext}, 42 | packages=find_packages(), 43 | description=("A system for applying deep reinforcement learning and " 44 | "control to autonomous vehicles and traffic infrastructure"), 45 | long_description=open("README.md").read(), 46 | url="https://github.com/flow-project/flow", 47 | keywords=("autonomous vehicles intelligent-traffic-control" 48 | "reinforcement-learning deep-learning python"), 49 | install_requires=_read_requirements_file(), 50 | zip_safe=False, 51 | ) 52 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/aimsun_template.py: -------------------------------------------------------------------------------- 1 | """Load an already existing Aimsun template and run the simulation.""" 2 | from flow.core.params import AimsunParams, EnvParams, NetParams 3 | from flow.core.params import VehicleParams 4 | from flow.core.params import InFlows 5 | import flow.config as config 6 | from flow.envs import TestEnv 7 | from flow.networks import Network 8 | import os 9 | 10 | 11 | # no vehicles in the network 12 | vehicles = VehicleParams() 13 | 14 | # path to the imported Aimsun template 15 | template_path = os.path.join(config.PROJECT_PATH, 16 | "flow/utils/aimsun/small_template.ang") 17 | 18 | 19 | flow_params = dict( 20 | # name of the experiment 21 | exp_tag='aimsun_small_template', 22 | 23 | # name of the flow environment the experiment is running on 24 | env_name=TestEnv, 25 | 26 | # name of the network class the experiment is running on 27 | network=Network, 28 | 29 | # simulator that is used by the experiment 30 | simulator='aimsun', 31 | 32 | # Aimsun-related parameters 33 | sim=AimsunParams( 34 | sim_step=0.1, 35 | render=True, 36 | emission_path='data', 37 | replication_name="Replication 930", 38 | centroid_config_name="Centroid Configuration 910" 39 | ), 40 | 41 | # environment related parameters (see flow.core.params.EnvParams) 42 | env=EnvParams( 43 | horizon=3000, 44 | ), 45 | 46 | # network-related parameters (see flow.core.params.NetParams and the 47 | # network's documentation or ADDITIONAL_NET_PARAMS component) 48 | net=NetParams( 49 | inflows=InFlows(), 50 | template=template_path 51 | ), 52 | 53 | # vehicles to be placed in the network at the start of a rollout (see 54 | # flow.core.params.VehicleParams) 55 | veh=vehicles, 56 | ) 57 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | # VSCode project settings 92 | .vscode 93 | 94 | # Don't add xml/csv/png 95 | *.xml 96 | *.csv 97 | *.png 98 | .DS_Store 99 | 100 | # Custom for learning-traffic 101 | .idea/** 102 | Makefile 103 | data/ 104 | debug/ 105 | .vs/** 106 | 107 | # Custom for Aimsun 108 | flow.ang 109 | *.ang.lck 110 | *.sqlite 111 | *.ang.old 112 | *.sang 113 | 114 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. flow documentation master file, created by 2 | sphinx-quickstart on Sun Aug 27 17:07:23 2017. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to Flow 7 | ================ 8 | 9 | `Flow `_ is a computational framework for deep RL and control experiments for traffic microsimulation. Visit `our website `_ for more information. 10 | 11 | Flow is a work in progress - input is welcome. Available documentation is limited for now. 12 | `Tutorials `_ are available in iPython notebook format. 13 | 14 | *If you are looking for Akvo Flow, their documentation can be found at* http://flowsupport.akvo.org. 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | :caption: Contents: 19 | 20 | intro 21 | flow_setup 22 | flow_examples 23 | tutorials 24 | multiagent 25 | rendering 26 | visualizing 27 | regression 28 | examples 29 | modules 30 | 31 | 32 | .. Citing Flow 33 | .. ============ 34 | 35 | If you use Flow for academic research, you are highly encouraged to cite our paper: 36 | 37 | C. Wu, A. Kreidieh, K. Parvate, E. Vinitsky, A. Bayen, "Flow: Architecture and 38 | Benchmarking for Reinforcement Learning in Traffic Control," CoRR, 39 | vol. abs/1710.05465, 2017. [Online]. Available: https://arxiv.org/abs/1710.05465 40 | 41 | If you use the benchmarks, you are highly encouraged to cite our paper: 42 | 43 | Vinitsky, E., Kreidieh, A., Le Flem, L., Kheterpal, N., Jang, K., Wu, F., ... & 44 | Bayen, A. M. (2018, October). Benchmarks for reinforcement learning in 45 | mixed-autonomy traffic. In Conference on Robot Learning (pp. 399-409). 46 | 47 | Indices and tables 48 | ================== 49 | 50 | * :ref:`genindex` 51 | * :ref:`modindex` 52 | * :ref:`search` 53 | -------------------------------------------------------------------------------- /scripts/departure_time_issue.patch: -------------------------------------------------------------------------------- 1 | diff -bur sumo_orig_test_2/src/traci-server/TraCIServerAPI_Vehicle.cpp sumo_orig_patch_test/src/traci-server/TraCIServerAPI_Vehicle.cpp 2 | --- sumo_orig_test_2/src/traci-server/TraCIServerAPI_Vehicle.cpp 2017-10-12 22:22:35.000000000 -0700 3 | +++ sumo_orig_patch_test/src/traci-server/TraCIServerAPI_Vehicle.cpp 2017-10-12 19:15:46.000000000 -0700 4 | @@ -1103,7 +1103,8 @@ 5 | return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, error, outputStorage); 6 | } 7 | if (vehicleParams.departProcedure == DEPART_GIVEN && vehicleParams.depart < MSNet::getInstance()->getCurrentTimeStep()) { 8 | - return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.", outputStorage); 9 | + vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep(); 10 | + // return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past.", outputStorage); 11 | } 12 | 13 | if (!server.readTypeCheckingString(inputStorage, helper)) { 14 | diff -bur sumo_orig_test_2/tools/build/version.py sumo_orig_patch_test/tools/build/version.py 15 | --- sumo_orig_test_2/tools/build/version.py 2017-10-12 22:22:48.000000000 -0700 16 | +++ sumo_orig_patch_test/tools/build/version.py 2017-10-13 04:27:43.000000000 -0700 17 | @@ -124,7 +124,7 @@ 18 | # svnFile is newer. lets update the revision number 19 | try: 20 | svnInfo = subprocess.check_output(['svn', 'info', sumoSrc]) 21 | - svnRevision = int(re.search('Revision: (\d*)', svnInfo).group(1)) 22 | + svnRevision = int(re.search('Revision: (\d*)', repr(svnInfo)).group(1)) 23 | except: 24 | svnRevision = parseRevision(svnFile) 25 | create_version_file(versionFile, svnRevision, svnFile) 26 | -------------------------------------------------------------------------------- /flow/utils/leaderboard/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM continuumio/miniconda3:4.5.4 2 | MAINTAINER Fangyu Wu (fangyuwu@berkeley.edu) 3 | 4 | # System 5 | RUN apt-get update && \ 6 | apt-get -y upgrade && \ 7 | apt-get install -y \ 8 | vim \ 9 | apt-utils 10 | 11 | # Flow 12 | RUN cd ~ && \ 13 | git clone https://github.com/flow-project/flow.git && \ 14 | cd flow && \ 15 | python setup.py develop 16 | 17 | # SUMO dependencies 18 | RUN apt-get install -y \ 19 | cmake \ 20 | build-essential \ 21 | swig \ 22 | libgdal-dev \ 23 | libxerces-c-dev \ 24 | libproj-dev \ 25 | libfox-1.6-dev \ 26 | libxml2-dev \ 27 | libxslt1-dev \ 28 | openjdk-8-jdk 29 | 30 | # SUMO 31 | RUN cd ~ && \ 32 | git clone --recursive https://github.com/eclipse/sumo.git && \ 33 | cd sumo && \ 34 | git checkout 016c09d306 && \ 35 | mkdir build/cmake-build && \ 36 | cd build/cmake-build && \ 37 | cmake ../.. && \ 38 | make 39 | 40 | # Ray/RLlib dependencies 41 | RUN apt-get install -y \ 42 | pkg-config \ 43 | autoconf \ 44 | curl \ 45 | libtool \ 46 | unzip \ 47 | flex \ 48 | bison \ 49 | psmisc \ 50 | python && \ 51 | conda install -y \ 52 | libgcc \ 53 | cython 54 | 55 | # Ray/RLlib 56 | RUN cd ~ && \ 57 | git clone https://github.com/eugenevinitsky/ray.git && \ 58 | cd ray/python && \ 59 | git checkout 6e07ea2 && \ 60 | python setup.py develop 61 | 62 | # Startup process 63 | RUN echo 'export SUMO_HOME="$HOME/sumo"' >> ~/.bashrc && \ 64 | echo 'export PATH="$HOME/sumo/bin:$PATH"' >> ~/.bashrc && \ 65 | echo 'export PYTHONPATH="$HOME/sumo/tools:$PYTHONPATH"' >> ~/.bashrc && \ 66 | echo 'export PYTHONPATH="/data:$PYTHONPATH"' >> ~/.bashrc && \ 67 | echo '. ~/.bashrc' >> /startup.sh && \ 68 | echo 'cd ~/flow/flow/utils/leaderboard' >> /startup.sh && \ 69 | echo 'python run.py' >> /startup.sh && \ 70 | chmod +x /startup.sh && \ 71 | # Temporary solution to fix gym version 72 | pip install --upgrade gym 73 | 74 | # Default command 75 | CMD ["/startup.sh"] 76 | -------------------------------------------------------------------------------- /docs/Fail-safes.md: -------------------------------------------------------------------------------- 1 | ## Fail-safes 2 | - All car controllers come equipped with a fail-safe rule wherein cars are not allowed to move at a speed that would cause them to crash if the car in front of them suddenly started breaking with max acceleration. If they attempt to do so, they will be reset to move at $v_{safe}$ where $v_{safe}$ is the speed such that the cars will come to rest at the same point. 3 | - $v_{safe}$ is calculated like so: 4 | - Consider a car with speed $v_{i}$ at position $x_i$ following another car at position $x_{i+1}$ and velocity $v_{i+1}$. 5 | - **Because of the discretization, the front cars speed that you need to be concerned about is actually its speed one time-step later. So, rather than assume the front car has velocity $v_{i+1}$ assume it could have speed $v_{i+1} - max_{deaccel}*timestep$** 6 | - The following car has a delay $\tau$ where $\tau \geq 0$ 7 | - At $t = 0$, the front car starts braking with max acceleration $a$. It will come to rest at $q_1 = \frac{v_{i+1}}{a}$. 8 | - Because of the delay, car i will only start braking at $\tau$. 9 | - Consequently, it will come to rest at $q_2 = \tau + \frac{V_i}{a}$ 10 | - We want that $x_i(q_2) = x_{i+1}(q_2)$ 11 | - Doing some kinematics: $x_i(q_2) = x_i(0) + v_{safe}*\left(\tau + \frac{v_{safe}}{a}\right) - \frac{1}{2}\left(\frac{v_{safe}^2}{a} \right)$ 12 | - $x_{i+1}(q_2) = x_{i+1}(0) + \frac{v_{i+1}^2(0)}{a} - \frac{1}{2}\frac{v_{i+1}^2(0)}{a} = x_{i+1}(0) + \frac{v_{i+1}^2(0)}{2a}$ 13 | - We set the two to be equal and solve for $v_{safe}$. To simplify the notation a bit, we set $x_i(0) - x_{i+1}(0) - \frac{v_{i+1}^2(0)}{2a} = d$ 14 | - This yields $0 = d + v_{safe}*\left(\tau + \frac{v_{safe}}{a}\right) - \frac{1}{2}\left(\frac{v_{safe}^2}{a} \right).$ 15 | - This has relevant solution $v_{safe} = -a \tau + \sqrt{a}\sqrt{-2d + a\tau^2}$ 16 | - *Additional note: Even for RL cars, which can shift to arbitrary velocities, you can never let them jump velocities by an acceleration larger than max_accel or max_deaccel. If you don't, you can't guarantee safety.* -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/ring.py: -------------------------------------------------------------------------------- 1 | """Used as an example of ring experiment. 2 | 3 | This example consists of 22 IDM cars on a ring creating shockwaves. 4 | """ 5 | 6 | from flow.controllers import IDMController, ContinuousRouter 7 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams 8 | from flow.core.params import VehicleParams 9 | from flow.envs.ring.accel import AccelEnv, ADDITIONAL_ENV_PARAMS 10 | from flow.networks.ring import RingNetwork, ADDITIONAL_NET_PARAMS 11 | 12 | 13 | vehicles = VehicleParams() 14 | vehicles.add( 15 | veh_id="idm", 16 | acceleration_controller=(IDMController, {}), 17 | routing_controller=(ContinuousRouter, {}), 18 | num_vehicles=22) 19 | 20 | 21 | flow_params = dict( 22 | # name of the experiment 23 | exp_tag='ring', 24 | 25 | # name of the flow environment the experiment is running on 26 | env_name=AccelEnv, 27 | 28 | # name of the network class the experiment is running on 29 | network=RingNetwork, 30 | 31 | # simulator that is used by the experiment 32 | simulator='traci', 33 | 34 | # sumo-related parameters (see flow.core.params.SumoParams) 35 | sim=SumoParams( 36 | render=True, 37 | sim_step=0.1, 38 | ), 39 | 40 | # environment related parameters (see flow.core.params.EnvParams) 41 | env=EnvParams( 42 | horizon=1500, 43 | additional_params=ADDITIONAL_ENV_PARAMS, 44 | ), 45 | 46 | # network-related parameters (see flow.core.params.NetParams and the 47 | # network's documentation or ADDITIONAL_NET_PARAMS component) 48 | net=NetParams( 49 | additional_params=ADDITIONAL_NET_PARAMS.copy(), 50 | ), 51 | 52 | # vehicles to be placed in the network at the start of a rollout (see 53 | # flow.core.params.VehicleParams) 54 | veh=vehicles, 55 | 56 | # parameters specifying the positioning of vehicles upon initialization/ 57 | # reset (see flow.core.params.InitialConfig) 58 | initial=InitialConfig( 59 | bunching=20, 60 | ), 61 | ) 62 | -------------------------------------------------------------------------------- /docs/source/multiagent.rst: -------------------------------------------------------------------------------- 1 | Creating Multiagent Environments 2 | ================================ 3 | In addition to single agent control, Flow supports the use of 4 | multiple agents with individual controllers and distinct rewards. 5 | 6 | To do this, we use RLlib's multiagent support. 7 | The changes for multiagent environments are as follows: 8 | instead of receiving a list of actions and returning a single observation 9 | and a single reward, we now receive a dictionary of actions and 10 | return a dictionary of rewards and a dictionary of observations. 11 | 12 | The keys of the dictionary are IDs of the agent policies. 13 | 14 | **Note that you must also subclass MultiEnv.** 15 | 16 | A brief example of a multiagent environment: 17 | :: 18 | 19 | from flow.envs.multiagent.base import MultiEnv 20 | 21 | class MultiAgentAccelEnv(AccelEnv, MultiEnv): 22 | """Example multiagent environment""" 23 | 24 | def _apply_rl_actions(self, rl_actions): 25 | """ 26 | Apply individual agent actions. 27 | 28 | :param rl_actions: dictionary of format {agent_id : action vector}. 29 | """ 30 | rl_ids = [] 31 | rl_action_list = [] 32 | for rl_id, action in rl_actions.items(): 33 | rl_ids.append(rl_id) 34 | rl_action_list.append(action) 35 | self.k.vehicle.apply_acceleration(rl_ids, rl_action_list) 36 | 37 | def compute_reward(self, rl_actions, **kwargs): 38 | """In this example, all agents receive a reward of 10""" 39 | reward_dict = {} 40 | for rl_id, action in rl_actions.items(): 41 | reward_dict[rl_id] = 10 42 | return reward_dict 43 | 44 | def get_state(self, **kwargs): 45 | """Every agent observes its own speed""" 46 | obs_dict = {} 47 | for rl_id in self.k.vehicle.get_rl_ids(): 48 | obs_dict[rl_id] = self.k.vehicle.get_speed(rl_id) 49 | return obs_dict 50 | 51 | 52 | For further details look at our 53 | `multiagent examples `_. 54 | -------------------------------------------------------------------------------- /docs/source/flow.controllers.rst: -------------------------------------------------------------------------------- 1 | flow.controllers package 2 | ======================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | flow.controllers.base\_controller module 8 | ---------------------------------------- 9 | 10 | .. automodule:: flow.controllers.base_controller 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | flow.controllers.base\_lane\_changing\_controller module 16 | -------------------------------------------------------- 17 | 18 | .. automodule:: flow.controllers.base_lane_changing_controller 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | flow.controllers.base\_routing\_controller module 24 | ------------------------------------------------- 25 | 26 | .. automodule:: flow.controllers.base_routing_controller 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | flow.controllers.car\_following\_models module 32 | ---------------------------------------------- 33 | 34 | .. automodule:: flow.controllers.car_following_models 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | flow.controllers.lane\_change\_controllers module 40 | ------------------------------------------------- 41 | 42 | .. automodule:: flow.controllers.lane_change_controllers 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | flow.controllers.rlcontroller module 48 | ------------------------------------ 49 | 50 | .. automodule:: flow.controllers.rlcontroller 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | flow.controllers.routing\_controllers module 56 | -------------------------------------------- 57 | 58 | .. automodule:: flow.controllers.routing_controllers 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | 63 | flow.controllers.velocity\_controllers module 64 | --------------------------------------------- 65 | 66 | .. automodule:: flow.controllers.velocity_controllers 67 | :members: 68 | :undoc-members: 69 | :show-inheritance: 70 | 71 | 72 | Module contents 73 | --------------- 74 | 75 | .. automodule:: flow.controllers 76 | :members: 77 | :undoc-members: 78 | :show-inheritance: 79 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/figureeight012.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of figureeight without RL control. 2 | 3 | Baseline is human acceleration and intersection behavior. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import SumoCarFollowingParams 9 | from flow.core.params import VehicleParams 10 | from flow.controllers import IDMController 11 | from flow.controllers import ContinuousRouter 12 | from flow.benchmarks.figureeight0 import flow_params 13 | 14 | 15 | def figure_eight_baseline(num_runs, render=True): 16 | """Run script for all figure eight baselines. 17 | 18 | Parameters 19 | ---------- 20 | num_runs : int 21 | number of rollouts the performance of the environment is evaluated 22 | over 23 | render : bool, optional 24 | specifies whether to use the gui during execution 25 | 26 | Returns 27 | ------- 28 | Experiment 29 | class needed to run simulations 30 | """ 31 | sim_params = flow_params['sim'] 32 | env_params = flow_params['env'] 33 | 34 | # modify the rendering to match what is requested 35 | sim_params.render = render 36 | 37 | # set the evaluation flag to True 38 | env_params.evaluate = True 39 | 40 | # we want no autonomous vehicles in the simulation 41 | vehicles = VehicleParams() 42 | vehicles.add(veh_id='human', 43 | acceleration_controller=(IDMController, {'noise': 0.2}), 44 | routing_controller=(ContinuousRouter, {}), 45 | car_following_params=SumoCarFollowingParams( 46 | speed_mode='obey_safe_speed', 47 | ), 48 | num_vehicles=14) 49 | 50 | flow_params['env'].horizon = env_params.horizon 51 | exp = Experiment(flow_params) 52 | 53 | results = exp.run(num_runs) 54 | avg_speed = np.mean(results['returns']) 55 | 56 | return avg_speed 57 | 58 | 59 | if __name__ == '__main__': 60 | runs = 2 # number of simulations to average over 61 | res = figure_eight_baseline(num_runs=runs) 62 | 63 | print('---------') 64 | print('The average speed across {} runs is {}'.format(runs, res)) 65 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | cache: pip 4 | 5 | python: 6 | - "3.5" 7 | 8 | os: linux 9 | 10 | dist: xenial 11 | 12 | services: 13 | - xvfb 14 | 15 | sudo: required 16 | 17 | git: 18 | depth: 1 19 | 20 | before_install: 21 | # install and run pep8 and docstyle tests 22 | - pip install pydocstyle 23 | - pydocstyle --convention numpy 24 | - pip install flake8 25 | - flake8 --version 26 | - flake8 --show-source 27 | 28 | # Setup conda (needed for opencv, ray dependency) 29 | - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; 30 | - bash miniconda.sh -b -p $HOME/miniconda 31 | - export PATH="$HOME/miniconda/bin:$PATH" 32 | - export TEST_FLAG="True" 33 | - conda config --append channels https://repo.anaconda.com/pkgs/free 34 | - conda config --append channels https://repo.anaconda.com/pkgs/pro 35 | 36 | # Requirements for stable baselines 37 | - sudo apt-get update && sudo apt-get install cmake libopenmpi-dev python3-dev zlib1g-dev 38 | 39 | # Set up requirements for flow 40 | - conda env create -f environment.yml 41 | - source activate flow 42 | 43 | # [sumo] dependencies and binaries 44 | - pushd $HOME/build/flow-project 45 | - ./flow/scripts/setup_sumo_ubuntu1604.sh 46 | - popd 47 | - source ~/.bashrc 48 | 49 | # [aimsun] install the conda env and update the path to the env 50 | - pushd $HOME/build/flow-project 51 | - ./flow/scripts/setup_aimsun.sh 52 | - popd 53 | - source ~/.bashrc 54 | - export AIMSUN_SITEPACKAGES="/home/travis/miniconda/envs/aimsun_flow" 55 | - export AIMSUN_NEXT_PATH="/home/user/Aimsun_Next_XXX" 56 | 57 | # Install stable-baselines 58 | - pip install stable_baselines==2.7.0 59 | 60 | # Install h-baselines 61 | - pushd $HOME 62 | - git clone https://github.com/AboudyKreidieh/h-baselines.git 63 | - pushd h-baselines 64 | - pip install -e . 65 | - popd 66 | - popd 67 | 68 | - ls ../ 69 | 70 | install: 71 | - sudo apt update 72 | - sudo apt install -y freeglut3-dev libgl1-mesa-dev libglu1-mesa-dev 73 | - pip install -e . 74 | - pip install coveralls 75 | - pip install jupyter 76 | 77 | script: 78 | - nose2 --with-coverage 79 | 80 | after_success: 81 | - coveralls 82 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/figure_eight.py: -------------------------------------------------------------------------------- 1 | """Example of a figure 8 network with human-driven vehicles. 2 | 3 | Right-of-way dynamics near the intersection causes vehicles to queue up on 4 | either side of the intersection, leading to a significant reduction in the 5 | average speed of vehicles in the network. 6 | """ 7 | from flow.controllers import IDMController, StaticLaneChanger, ContinuousRouter 8 | from flow.core.params import SumoParams, EnvParams, NetParams 9 | from flow.core.params import VehicleParams, SumoCarFollowingParams 10 | from flow.envs.ring.accel import ADDITIONAL_ENV_PARAMS 11 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS 12 | from flow.envs import AccelEnv 13 | from flow.networks import FigureEightNetwork 14 | 15 | vehicles = VehicleParams() 16 | vehicles.add( 17 | veh_id="idm", 18 | acceleration_controller=(IDMController, {}), 19 | lane_change_controller=(StaticLaneChanger, {}), 20 | routing_controller=(ContinuousRouter, {}), 21 | car_following_params=SumoCarFollowingParams( 22 | speed_mode="obey_safe_speed", 23 | decel=1.5, 24 | ), 25 | initial_speed=0, 26 | num_vehicles=14) 27 | 28 | 29 | flow_params = dict( 30 | # name of the experiment 31 | exp_tag='figure8', 32 | 33 | # name of the flow environment the experiment is running on 34 | env_name=AccelEnv, 35 | 36 | # name of the network class the experiment is running on 37 | network=FigureEightNetwork, 38 | 39 | # simulator that is used by the experiment 40 | simulator='traci', 41 | 42 | # sumo-related parameters (see flow.core.params.SumoParams) 43 | sim=SumoParams( 44 | render=True, 45 | ), 46 | 47 | # environment related parameters (see flow.core.params.EnvParams) 48 | env=EnvParams( 49 | horizon=1500, 50 | additional_params=ADDITIONAL_ENV_PARAMS.copy(), 51 | ), 52 | 53 | # network-related parameters (see flow.core.params.NetParams and the 54 | # network's documentation or ADDITIONAL_NET_PARAMS component) 55 | net=NetParams( 56 | additional_params=ADDITIONAL_NET_PARAMS.copy(), 57 | ), 58 | 59 | # vehicles to be placed in the network at the start of a rollout (see 60 | # flow.core.params.VehicleParams) 61 | veh=vehicles, 62 | ) 63 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/grid1.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of grid1 without RL control. 2 | 3 | Baseline is an actuated traffic light provided by SUMO. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import TrafficLightParams 9 | from flow.benchmarks.grid1 import flow_params 10 | from flow.benchmarks.grid1 import N_ROWS 11 | from flow.benchmarks.grid1 import N_COLUMNS 12 | 13 | 14 | def grid1_baseline(num_runs, render=True): 15 | """Run script for the grid1 baseline. 16 | 17 | Parameters 18 | ---------- 19 | num_runs : int 20 | number of rollouts the performance of the environment is evaluated 21 | over 22 | render: bool, optional 23 | specifies whether to the gui during execution 24 | 25 | Returns 26 | ------- 27 | flow.core.experiment.Experiment 28 | class needed to run simulations 29 | """ 30 | sim_params = flow_params['sim'] 31 | env_params = flow_params['env'] 32 | 33 | # define the traffic light logic 34 | tl_logic = TrafficLightParams(baseline=False) 35 | phases = [{'duration': '31', 'minDur': '5', 'maxDur': '45', 36 | "state": "GrGr"}, 37 | {'duration': '2', 'minDur': '2', 'maxDur': '2', 38 | "state": "yryr"}, 39 | {'duration': '31', 'minDur': '5', 'maxDur': '45', 40 | "state": "rGrG"}, 41 | {'duration': '2', 'minDur': '2', 'maxDur': '2', 42 | "state": "ryry"}] 43 | for i in range(N_ROWS*N_COLUMNS): 44 | tl_logic.add('center'+str(i), tls_type='actuated', phases=phases, 45 | programID=1) 46 | 47 | # modify the rendering to match what is requested 48 | sim_params.render = render 49 | 50 | # set the evaluation flag to True 51 | env_params.evaluate = True 52 | 53 | flow_params['env'].horizon = env_params.horizon 54 | exp = Experiment(flow_params) 55 | 56 | results = exp.run(num_runs) 57 | total_delay = np.mean(results['returns']) 58 | 59 | return total_delay 60 | 61 | 62 | if __name__ == '__main__': 63 | runs = 1 # number of simulations to average over 64 | res = grid1_baseline(num_runs=runs, render=False) 65 | 66 | print('---------') 67 | print('The total delay across {} runs is {}'.format(runs, res)) 68 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/grid0.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of grid0 without RL control. 2 | 3 | Baseline is an actuated traffic light provided by SUMO. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import TrafficLightParams 9 | from flow.benchmarks.grid0 import flow_params 10 | from flow.benchmarks.grid0 import N_ROWS 11 | from flow.benchmarks.grid0 import N_COLUMNS 12 | 13 | 14 | def grid0_baseline(num_runs, render=True): 15 | """Run script for the grid0 baseline. 16 | 17 | Parameters 18 | ---------- 19 | num_runs : int 20 | number of rollouts the performance of the environment is evaluated 21 | over 22 | render : bool, optional 23 | specifies whether to use the gui during execution 24 | 25 | Returns 26 | ------- 27 | flow.core.experiment.Experiment 28 | class needed to run simulations 29 | """ 30 | sim_params = flow_params['sim'] 31 | env_params = flow_params['env'] 32 | 33 | # define the traffic light logic 34 | tl_logic = TrafficLightParams(baseline=False) 35 | 36 | phases = [{"duration": "31", "minDur": "8", "maxDur": "45", 37 | "state": "GrGr"}, 38 | {"duration": "6", "minDur": "3", "maxDur": "6", 39 | "state": "yryr"}, 40 | {"duration": "31", "minDur": "8", "maxDur": "45", 41 | "state": "rGrG"}, 42 | {"duration": "6", "minDur": "3", "maxDur": "6", 43 | "state": "ryry"}] 44 | 45 | for i in range(N_ROWS * N_COLUMNS): 46 | tl_logic.add('center'+str(i), tls_type='actuated', phases=phases, 47 | programID=1) 48 | 49 | # modify the rendering to match what is requested 50 | sim_params.render = render 51 | 52 | # set the evaluation flag to True 53 | env_params.evaluate = True 54 | 55 | flow_params['env'].horizon = env_params.horizon 56 | exp = Experiment(flow_params) 57 | 58 | results = exp.run(num_runs) 59 | total_delay = np.mean(results['returns']) 60 | 61 | return total_delay 62 | 63 | 64 | if __name__ == '__main__': 65 | runs = 1 # number of simulations to average over 66 | res = grid0_baseline(num_runs=runs) 67 | 68 | print('---------') 69 | print('The total delay across {} runs is {}'.format(runs, res)) 70 | -------------------------------------------------------------------------------- /docs/Docker_Tutorial.md: -------------------------------------------------------------------------------- 1 | 2 | # Docker Tutorial 3 | 4 | - Note: all the hard work is in making a good Dockerfile. You should be able to go into Dockerfile and just update version numbers from now forward. There are comments (denoted by `#` ) for the sections that involve SUMO, including the patch that happens before building. Don’t touch anything outside the SUMO section. Also, if you’re feeling ambitious, check what the rllab latest Dockerfile is and merge in any changes they’ve made. 5 | - TODO: Update link to sumo patch, must be correct before attempting build. I recommend using AWS S3. 6 | - Familiarize yourself with the docker tutorial at: https://docs.docker.com/get-started/ 7 | - Optional: ssh into lab machine 8 | - Optional: install Docker on lab machine account 9 | - Transfer `Dockerfile` , and `environment.yml` file from rllab into same directory (root) 10 | - Can use Dropbox public links (wget) or git or AWS 11 | - Note: environment.yml should be exactly the same as the one in rllab, except we have two more dependencies: 12 | - `libxml2=2.9.4` 13 | - `libxslt=1.1.29` 14 | - Takeaway: when updating `environment.yml` make sure to look at both the old version in flow_dev and the newer ones in rllab, and don’t lose data 15 | - In the same directory that contains the Dockerfile and environment file, run: 16 | - `docker build -t .` 17 | - Check it’s there: `docker images` 18 | - Create a dockerhub account 19 | - `docker login` 20 | - `docker tag /:latest` 21 | - `docker push /:latest` 22 | - Now update your config_personal to point to the right image! `/` 23 | - If you run out of space there are great tutorials online about removing floating containers and images 24 | 25 | Notes: 26 | 27 | - If building SUMO fails, it may be necessary to update the patch. 28 | - Build two files for /src/traci-server/TraCIServerAPI_Vehicle.cpp. In one, change the line 29 | from: 30 | return server.writeErrorStatusCmd(CMD_SET_VEHICLE_VARIABLE, "Departure time in the past."; 31 | to: 32 | vehicleParams.depart = MSNet::getInstance()->getCurrentTimeStep(); 33 | - Now go to the outer sumo directory and run diff -Naur /path/to/originalTraciServerAPI /path/to/newtraciServer > sumo-departure-time.patch 34 | - Upload this file to an AWS bucket, make its path private, and add the path to the dockerfile in the part that install SUMO. 35 | -------------------------------------------------------------------------------- /flow/core/kernel/traffic_light/aimsun.py: -------------------------------------------------------------------------------- 1 | """Script containing the base traffic light kernel class.""" 2 | from flow.core.kernel.traffic_light.base import KernelTrafficLight 3 | 4 | 5 | class AimsunKernelTrafficLight(KernelTrafficLight): 6 | """Aimsun traffic light kernel. 7 | 8 | Implements all methods discussed in the base traffic light kernel class. 9 | """ 10 | 11 | def __init__(self, master_kernel): 12 | """Instantiate the sumo traffic light kernel. 13 | 14 | Parameters 15 | ---------- 16 | master_kernel : flow.core.kernel.Kernel 17 | the higher level kernel (used to call methods from other 18 | sub-kernels) 19 | """ 20 | KernelTrafficLight.__init__(self, master_kernel) 21 | 22 | # names of nodes with traffic lights 23 | self.__ids = [] 24 | self.num_meters = 0 25 | 26 | def pass_api(self, kernel_api): 27 | """See parent class.""" 28 | self.kernel_api = kernel_api 29 | 30 | def update(self, reset): 31 | """See parent class.""" 32 | pass 33 | 34 | def get_ids(self): 35 | """See parent class.""" 36 | return self.kernel_api.get_traffic_light_ids() 37 | 38 | def set_state(self, meter_aimsun_id, state): 39 | """Set the state of the traffic lights on a specific meter. 40 | 41 | Parameters 42 | ---------- 43 | meter_aimsun_id : int 44 | aimsun id of the meter 45 | state : int 46 | desired state(s) for the traffic light 47 | 0: red 48 | 1: green 49 | 2: yellow 50 | link_index : int, optional 51 | index of the link whose traffic light state is meant to be changed. 52 | If no value is provided, the lights on all links are updated. 53 | """ 54 | self.kernel_api.set_traffic_light_state(meter_aimsun_id, None, state) 55 | 56 | def get_state(self, meter_aimsun_id): 57 | """Return the state of the traffic light(s) at the specified node. 58 | 59 | Parameters 60 | ---------- 61 | meter_aimsun_id: int 62 | aimsun id of the meter 63 | 64 | Returns 65 | ------- 66 | state : int 67 | desired state(s) for the traffic light 68 | 0: red 69 | 1: green 70 | 2: yellow 71 | """ 72 | return self.kernel_api.get_traffic_light_state(meter_aimsun_id) 73 | -------------------------------------------------------------------------------- /docs/source/flow.benchmarks.rst: -------------------------------------------------------------------------------- 1 | flow.benchmarks package 2 | ======================= 3 | 4 | Submodules 5 | ---------- 6 | 7 | flow.benchmarks.bottleneck0 module 8 | ---------------------------------- 9 | 10 | .. automodule:: flow.benchmarks.bottleneck0 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | flow.benchmarks.bottleneck1 module 16 | ---------------------------------- 17 | 18 | .. automodule:: flow.benchmarks.bottleneck1 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | flow.benchmarks.bottleneck2 module 24 | ---------------------------------- 25 | 26 | .. automodule:: flow.benchmarks.bottleneck2 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | 31 | flow.benchmarks.figureeight0 module 32 | ----------------------------------- 33 | 34 | .. automodule:: flow.benchmarks.figureeight0 35 | :members: 36 | :undoc-members: 37 | :show-inheritance: 38 | 39 | flow.benchmarks.figureeight1 module 40 | ----------------------------------- 41 | 42 | .. automodule:: flow.benchmarks.figureeight1 43 | :members: 44 | :undoc-members: 45 | :show-inheritance: 46 | 47 | flow.benchmarks.figureeight2 module 48 | ----------------------------------- 49 | 50 | .. automodule:: flow.benchmarks.figureeight2 51 | :members: 52 | :undoc-members: 53 | :show-inheritance: 54 | 55 | flow.benchmarks.grid0 module 56 | ---------------------------- 57 | 58 | .. automodule:: flow.benchmarks.grid0 59 | :members: 60 | :undoc-members: 61 | :show-inheritance: 62 | 63 | flow.benchmarks.grid1 module 64 | ---------------------------- 65 | 66 | .. automodule:: flow.benchmarks.grid1 67 | :members: 68 | :undoc-members: 69 | :show-inheritance: 70 | 71 | flow.benchmarks.merge0 module 72 | ----------------------------- 73 | 74 | .. automodule:: flow.benchmarks.merge0 75 | :members: 76 | :undoc-members: 77 | :show-inheritance: 78 | 79 | flow.benchmarks.merge1 module 80 | ----------------------------- 81 | 82 | .. automodule:: flow.benchmarks.merge1 83 | :members: 84 | :undoc-members: 85 | :show-inheritance: 86 | 87 | flow.benchmarks.merge2 module 88 | ----------------------------- 89 | 90 | .. automodule:: flow.benchmarks.merge2 91 | :members: 92 | :undoc-members: 93 | :show-inheritance: 94 | 95 | 96 | Module contents 97 | --------------- 98 | 99 | .. automodule:: flow.benchmarks 100 | :members: 101 | :undoc-members: 102 | :show-inheritance: 103 | -------------------------------------------------------------------------------- /flow/benchmarks/figureeight2.py: -------------------------------------------------------------------------------- 1 | """Benchmark for figureeight2. 2 | 3 | Trains a fraction of vehicles in a ring road structure to regulate the flow of 4 | vehicles through an intersection. In this example, every vehicle in the 5 | network is an autonomous vehicle. 6 | 7 | - **Action Dimension**: (14, ) 8 | - **Observation Dimension**: (28, ) 9 | - **Horizon**: 1500 steps 10 | """ 11 | from flow.envs import AccelEnv 12 | from flow.networks import FigureEightNetwork 13 | from copy import deepcopy 14 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams, \ 15 | SumoCarFollowingParams 16 | from flow.core.params import VehicleParams 17 | from flow.controllers import ContinuousRouter, RLController 18 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS 19 | 20 | # time horizon of a single rollout 21 | HORIZON = 1500 22 | 23 | # We place 16 autonomous vehicle and 0 human-driven vehicles in the network 24 | vehicles = VehicleParams() 25 | vehicles.add( 26 | veh_id="rl", 27 | acceleration_controller=(RLController, {}), 28 | routing_controller=(ContinuousRouter, {}), 29 | car_following_params=SumoCarFollowingParams( 30 | speed_mode="obey_safe_speed", 31 | ), 32 | num_vehicles=14) 33 | 34 | flow_params = dict( 35 | # name of the experiment 36 | exp_tag="figure_eight_2", 37 | 38 | # name of the flow environment the experiment is running on 39 | env_name=AccelEnv, 40 | 41 | # name of the network class the experiment is running on 42 | network=FigureEightNetwork, 43 | 44 | # simulator that is used by the experiment 45 | simulator='traci', 46 | 47 | # sumo-related parameters (see flow.core.params.SumoParams) 48 | sim=SumoParams( 49 | sim_step=0.1, 50 | render=False, 51 | ), 52 | 53 | # environment related parameters (see flow.core.params.EnvParams) 54 | env=EnvParams( 55 | horizon=HORIZON, 56 | additional_params={ 57 | "target_velocity": 20, 58 | "max_accel": 3, 59 | "max_decel": 3, 60 | "sort_vehicles": False 61 | }, 62 | ), 63 | 64 | # network-related parameters (see flow.core.params.NetParams and the 65 | # network's documentation or ADDITIONAL_NET_PARAMS component) 66 | net=NetParams( 67 | additional_params=deepcopy(ADDITIONAL_NET_PARAMS), 68 | ), 69 | 70 | # vehicles to be placed in the network at the start of a rollout (see 71 | # flow.core.params.VehicleParams) 72 | veh=vehicles, 73 | 74 | # parameters specifying the positioning of vehicles upon initialization/ 75 | # reset (see flow.core.params.InitialConfig) 76 | initial=InitialConfig(), 77 | ) 78 | -------------------------------------------------------------------------------- /flow/controllers/base_lane_changing_controller.py: -------------------------------------------------------------------------------- 1 | """Contains the base lane change controller class.""" 2 | 3 | from abc import ABCMeta, abstractmethod 4 | 5 | 6 | class BaseLaneChangeController(metaclass=ABCMeta): 7 | """Base class for lane-changing controllers. 8 | 9 | Instantiates a controller and forces the user to pass a 10 | lane_changing duration to the controller. 11 | 12 | Usage 13 | ----- 14 | >>> from flow.core.params import VehicleParams 15 | >>> from flow.controllers import SimLaneChangeController 16 | >>> vehicles = VehicleParams() 17 | >>> vehicles.add("human", 18 | >>> lane_change_controller=(SimLaneChangeController, {})) 19 | 20 | Note: You can replace SimLaneChangeController with any lane changing 21 | controller of your choice. 22 | 23 | Parameters 24 | ---------- 25 | veh_id : str 26 | ID of the vehicle this controller is used for 27 | lane_change_params : dict 28 | Dictionary of lane changes params that may optional contain 29 | "min_gap", which denotes the minimize safe gap (in meters) a car 30 | is willing to lane-change into. 31 | """ 32 | 33 | def __init__(self, veh_id, lane_change_params=None): 34 | """Instantiate the base class for lane-changing controllers.""" 35 | if lane_change_params is None: 36 | lane_change_params = {} 37 | 38 | self.veh_id = veh_id 39 | self.lane_change_params = lane_change_params 40 | 41 | @abstractmethod 42 | def get_lane_change_action(self, env): 43 | """Specify the lane change action to be performed. 44 | 45 | If discrete lane changes are being performed, the action is a direction 46 | 47 | * -1: lane change right 48 | * 0: no lane change 49 | * 1: lane change left 50 | 51 | Parameters 52 | ---------- 53 | env : flow.envs.Env 54 | state of the environment at the current time step 55 | 56 | Returns 57 | ------- 58 | float or int 59 | requested lane change action 60 | """ 61 | pass 62 | 63 | def get_action(self, env): 64 | """Return the action of the lane change controller. 65 | 66 | Modifies the lane change action to ensure safety, if requested. 67 | 68 | Parameters 69 | ---------- 70 | env : flow.envs.Env 71 | state of the environment at the current time step 72 | 73 | Returns 74 | ------- 75 | float or int 76 | lane change action 77 | """ 78 | lc_action = self.get_lane_change_action(env) 79 | # TODO(ak): add failsafe 80 | 81 | return lc_action 82 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/minicity.py: -------------------------------------------------------------------------------- 1 | """Example of modified minicity network with human-driven vehicles.""" 2 | from flow.controllers import IDMController 3 | from flow.controllers import RLController 4 | from flow.core.params import SumoParams, EnvParams, NetParams, InitialConfig 5 | from flow.core.params import SumoCarFollowingParams, SumoLaneChangeParams 6 | from flow.core.params import VehicleParams 7 | from flow.envs.ring.accel import AccelEnv, ADDITIONAL_ENV_PARAMS 8 | from flow.controllers.routing_controllers import MinicityRouter 9 | from flow.networks import MiniCityNetwork 10 | 11 | 12 | vehicles = VehicleParams() 13 | vehicles.add( 14 | veh_id="idm", 15 | acceleration_controller=(IDMController, {}), 16 | routing_controller=(MinicityRouter, {}), 17 | car_following_params=SumoCarFollowingParams( 18 | speed_mode=1, 19 | ), 20 | lane_change_params=SumoLaneChangeParams( 21 | lane_change_mode="no_lc_safe", 22 | ), 23 | initial_speed=0, 24 | num_vehicles=90) 25 | vehicles.add( 26 | veh_id="rl", 27 | acceleration_controller=(RLController, {}), 28 | routing_controller=(MinicityRouter, {}), 29 | car_following_params=SumoCarFollowingParams( 30 | speed_mode="obey_safe_speed", 31 | ), 32 | initial_speed=0, 33 | num_vehicles=10) 34 | 35 | 36 | flow_params = dict( 37 | # name of the experiment 38 | exp_tag='minicity', 39 | 40 | # name of the flow environment the experiment is running on 41 | env_name=AccelEnv, 42 | 43 | # name of the network class the experiment is running on 44 | network=MiniCityNetwork, 45 | 46 | # simulator that is used by the experiment 47 | simulator='traci', 48 | 49 | # sumo-related parameters (see flow.core.params.SumoParams) 50 | sim=SumoParams( 51 | sim_step=0.25, 52 | render='drgb', 53 | save_render=False, 54 | sight_radius=30, 55 | pxpm=3, 56 | show_radius=True, 57 | ), 58 | 59 | # environment related parameters (see flow.core.params.EnvParams) 60 | env=EnvParams( 61 | horizon=750, 62 | additional_params=ADDITIONAL_ENV_PARAMS 63 | ), 64 | 65 | # network-related parameters (see flow.core.params.NetParams and the 66 | # network's documentation or ADDITIONAL_NET_PARAMS component) 67 | net=NetParams(), 68 | 69 | # vehicles to be placed in the network at the start of a rollout (see 70 | # flow.core.params.VehicleParams) 71 | veh=vehicles, 72 | 73 | # parameters specifying the positioning of vehicles upon initialization/ 74 | # reset (see flow.core.params.InitialConfig) 75 | initial=InitialConfig( 76 | spacing="random", 77 | min_gap=5, 78 | ), 79 | ) 80 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/bottleneck0.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of bottleneck0 without RL control. 2 | 3 | Baseline is no AVs. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import InFlows 9 | from flow.core.params import SumoLaneChangeParams 10 | from flow.core.params import SumoCarFollowingParams 11 | from flow.core.params import VehicleParams 12 | from flow.controllers import ContinuousRouter 13 | from flow.benchmarks.bottleneck0 import flow_params 14 | from flow.benchmarks.bottleneck0 import SCALING 15 | 16 | 17 | def bottleneck0_baseline(num_runs, render=True): 18 | """Run script for the bottleneck0 baseline. 19 | 20 | Parameters 21 | ---------- 22 | num_runs : int 23 | number of rollouts the performance of the environment is evaluated 24 | over 25 | render : bool, optional 26 | specifies whether to use the gui during execution 27 | 28 | Returns 29 | ------- 30 | flow.core.experiment.Experiment 31 | class needed to run simulations 32 | """ 33 | sim_params = flow_params['sim'] 34 | env_params = flow_params['env'] 35 | net_params = flow_params['net'] 36 | 37 | # we want no autonomous vehicles in the simulation 38 | vehicles = VehicleParams() 39 | vehicles.add(veh_id='human', 40 | car_following_params=SumoCarFollowingParams( 41 | speed_mode=9, 42 | ), 43 | routing_controller=(ContinuousRouter, {}), 44 | lane_change_params=SumoLaneChangeParams( 45 | lane_change_mode=0, 46 | ), 47 | num_vehicles=1 * SCALING) 48 | 49 | # only include human vehicles in inflows 50 | flow_rate = 2300 * SCALING 51 | inflow = InFlows() 52 | inflow.add(veh_type='human', edge='1', 53 | vehs_per_hour=flow_rate, 54 | departLane='random', departSpeed=10) 55 | net_params.inflows = inflow 56 | 57 | # modify the rendering to match what is requested 58 | sim_params.render = render 59 | 60 | # set the evaluation flag to True 61 | env_params.evaluate = True 62 | 63 | flow_params['env'].horizon = env_params.horizon 64 | exp = Experiment(flow_params) 65 | 66 | results = exp.run(num_runs) 67 | return np.mean(results['returns']), np.std(results['returns']) 68 | 69 | 70 | if __name__ == '__main__': 71 | runs = 2 # number of simulations to average over 72 | mean, std = bottleneck0_baseline(num_runs=runs, render=True) 73 | 74 | print('---------') 75 | print('The average outflow, std. deviation over 500 seconds ' 76 | 'across {} runs is {}, {}'.format(runs, mean, std)) 77 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/bottleneck1.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of bottleneck1 without RL control. 2 | 3 | Baseline is no AVs. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import InFlows 9 | from flow.core.params import SumoLaneChangeParams 10 | from flow.core.params import SumoCarFollowingParams 11 | from flow.core.params import VehicleParams 12 | from flow.controllers import ContinuousRouter 13 | from flow.benchmarks.bottleneck1 import flow_params 14 | from flow.benchmarks.bottleneck1 import SCALING 15 | 16 | 17 | def bottleneck1_baseline(num_runs, render=True): 18 | """Run script for the bottleneck1 baseline. 19 | 20 | Parameters 21 | ---------- 22 | num_runs : int 23 | number of rollouts the performance of the environment is evaluated 24 | over 25 | render: str, optional 26 | specifies whether to use the gui during execution 27 | 28 | Returns 29 | ------- 30 | flow.core.experiment.Experiment 31 | class needed to run simulations 32 | """ 33 | sim_params = flow_params['sim'] 34 | env_params = flow_params['env'] 35 | net_params = flow_params['net'] 36 | 37 | # we want no autonomous vehicles in the simulation 38 | vehicles = VehicleParams() 39 | vehicles.add(veh_id='human', 40 | car_following_params=SumoCarFollowingParams( 41 | speed_mode=9, 42 | ), 43 | routing_controller=(ContinuousRouter, {}), 44 | lane_change_params=SumoLaneChangeParams( 45 | lane_change_mode=1621, 46 | ), 47 | num_vehicles=1 * SCALING) 48 | 49 | # only include human vehicles in inflows 50 | flow_rate = 2300 * SCALING 51 | inflow = InFlows() 52 | inflow.add(veh_type='human', edge='1', 53 | vehs_per_hour=flow_rate, 54 | departLane='random', departSpeed=10) 55 | net_params.inflows = inflow 56 | 57 | # modify the rendering to match what is requested 58 | sim_params.render = render 59 | 60 | # set the evaluation flag to True 61 | env_params.evaluate = True 62 | 63 | flow_params['env'].horizon = env_params.horizon 64 | exp = Experiment(flow_params) 65 | 66 | results = exp.run(num_runs) 67 | 68 | return np.mean(results['returns']), np.std(results['returns']) 69 | 70 | 71 | if __name__ == '__main__': 72 | runs = 2 # number of simulations to average over 73 | mean, std = bottleneck1_baseline(num_runs=runs, render=False) 74 | 75 | print('---------') 76 | print('The average outflow, std. deviation over 500 seconds ' 77 | 'across {} runs is {}, {}'.format(runs, mean, std)) 78 | -------------------------------------------------------------------------------- /flow/benchmarks/baselines/bottleneck2.py: -------------------------------------------------------------------------------- 1 | """Evaluates the baseline performance of bottleneck2 without RL control. 2 | 3 | Baseline is no AVs. 4 | """ 5 | 6 | import numpy as np 7 | from flow.core.experiment import Experiment 8 | from flow.core.params import InFlows 9 | from flow.core.params import SumoLaneChangeParams 10 | from flow.core.params import SumoCarFollowingParams 11 | from flow.core.params import VehicleParams 12 | from flow.controllers import ContinuousRouter 13 | from flow.benchmarks.bottleneck2 import flow_params 14 | from flow.benchmarks.bottleneck2 import SCALING 15 | 16 | 17 | def bottleneck2_baseline(num_runs, render=True): 18 | """Run script for the bottleneck2 baseline. 19 | 20 | Parameters 21 | ---------- 22 | num_runs : int 23 | number of rollouts the performance of the environment is evaluated 24 | over 25 | render : bool, optional 26 | specifies whether to use the gui during execution 27 | 28 | Returns 29 | ------- 30 | flow.core.experiment.Experiment 31 | class needed to run simulations 32 | """ 33 | sim_params = flow_params['sim'] 34 | env_params = flow_params['env'] 35 | net_params = flow_params['net'] 36 | 37 | # we want no autonomous vehicles in the simulation 38 | vehicles = VehicleParams() 39 | vehicles.add(veh_id='human', 40 | car_following_params=SumoCarFollowingParams( 41 | speed_mode=9, 42 | ), 43 | routing_controller=(ContinuousRouter, {}), 44 | lane_change_params=SumoLaneChangeParams( 45 | lane_change_mode=0, 46 | ), 47 | num_vehicles=1 * SCALING) 48 | 49 | # only include human vehicles in inflows 50 | flow_rate = 2300 * SCALING 51 | inflow = InFlows() 52 | inflow.add(veh_type='human', edge='1', 53 | vehs_per_hour=flow_rate, 54 | departLane='random', departSpeed=10) 55 | net_params.inflows = inflow 56 | 57 | # modify the rendering to match what is requested 58 | sim_params.render = render 59 | 60 | # set the evaluation flag to True 61 | env_params.evaluate = True 62 | 63 | flow_params['env'].horizon = env_params.horizon 64 | exp = Experiment(flow_params) 65 | 66 | results = exp.run(num_runs) 67 | 68 | return np.mean(results['returns']), np.std(results['returns']) 69 | 70 | 71 | if __name__ == '__main__': 72 | runs = 2 # number of simulations to average over 73 | mean, std = bottleneck2_baseline(num_runs=runs, render=False) 74 | 75 | print('---------') 76 | print('The average outflow, std. deviation over 500 seconds ' 77 | 'across {} runs is {}, {}'.format(runs, mean, std)) 78 | -------------------------------------------------------------------------------- /flow/core/kernel/traffic_light/traci.py: -------------------------------------------------------------------------------- 1 | """Script containing the TraCI traffic light kernel class.""" 2 | 3 | from flow.core.kernel.traffic_light import KernelTrafficLight 4 | import traci.constants as tc 5 | 6 | 7 | class TraCITrafficLight(KernelTrafficLight): 8 | """Sumo traffic light kernel. 9 | 10 | Implements all methods discussed in the base traffic light kernel class. 11 | """ 12 | 13 | def __init__(self, master_kernel): 14 | """Instantiate the sumo traffic light kernel. 15 | 16 | Parameters 17 | ---------- 18 | master_kernel : flow.core.kernel.Kernel 19 | the higher level kernel (used to call methods from other 20 | sub-kernels) 21 | """ 22 | KernelTrafficLight.__init__(self, master_kernel) 23 | 24 | self.__tls = dict() # contains current time step traffic light data 25 | self.__tls_properties = dict() # traffic light xml properties 26 | 27 | # names of nodes with traffic lights 28 | self.__ids = [] 29 | 30 | # number of traffic light nodes 31 | self.num_traffic_lights = 0 32 | 33 | def pass_api(self, kernel_api): 34 | """See parent class. 35 | 36 | Subscriptions and vehicle IDs are also added here. 37 | """ 38 | KernelTrafficLight.pass_api(self, kernel_api) 39 | 40 | # names of nodes with traffic lights 41 | self.__ids = kernel_api.trafficlight.getIDList() 42 | 43 | # number of traffic light nodes 44 | self.num_traffic_lights = len(self.__ids) 45 | 46 | # subscribe the traffic light signal data 47 | for node_id in self.__ids: 48 | self.kernel_api.trafficlight.subscribe( 49 | node_id, [tc.TL_RED_YELLOW_GREEN_STATE]) 50 | 51 | def update(self, reset): 52 | """See parent class.""" 53 | tls_obs = {} 54 | for tl_id in self.__ids: 55 | tls_obs[tl_id] = \ 56 | self.kernel_api.trafficlight.getSubscriptionResults(tl_id) 57 | self.__tls = tls_obs.copy() 58 | 59 | def get_ids(self): 60 | """See parent class.""" 61 | return self.__ids 62 | 63 | def set_state(self, node_id, state, link_index="all"): 64 | """See parent class.""" 65 | if link_index == "all": 66 | # if lights on all lanes are changed 67 | self.kernel_api.trafficlight.setRedYellowGreenState( 68 | tlsID=node_id, state=state) 69 | else: 70 | # if lights on a single lane is changed 71 | self.kernel_api.trafficlight.setLinkState( 72 | tlsID=node_id, tlsLinkIndex=link_index, state=state) 73 | 74 | def get_state(self, node_id): 75 | """See parent class.""" 76 | return self.__tls[node_id][tc.TL_RED_YELLOW_GREEN_STATE] 77 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/highway.py: -------------------------------------------------------------------------------- 1 | """Example of an open multi-lane network with human-driven vehicles.""" 2 | 3 | from flow.controllers import IDMController 4 | from flow.core.params import SumoParams, EnvParams, NetParams, InitialConfig, SumoLaneChangeParams 5 | from flow.core.params import VehicleParams, InFlows 6 | from flow.envs.ring.lane_change_accel import ADDITIONAL_ENV_PARAMS 7 | from flow.networks.highway import HighwayNetwork, ADDITIONAL_NET_PARAMS 8 | from flow.envs import LaneChangeAccelEnv 9 | 10 | vehicles = VehicleParams() 11 | vehicles.add( 12 | veh_id="human", 13 | acceleration_controller=(IDMController, {}), 14 | lane_change_params=SumoLaneChangeParams( 15 | model="SL2015", 16 | lc_sublane=2.0, 17 | ), 18 | num_vehicles=20) 19 | vehicles.add( 20 | veh_id="human2", 21 | acceleration_controller=(IDMController, {}), 22 | lane_change_params=SumoLaneChangeParams( 23 | model="SL2015", 24 | lc_sublane=2.0, 25 | ), 26 | num_vehicles=20) 27 | 28 | env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) 29 | 30 | inflow = InFlows() 31 | inflow.add( 32 | veh_type="human", 33 | edge="highway_0", 34 | probability=0.25, 35 | departLane="free", 36 | departSpeed=20) 37 | inflow.add( 38 | veh_type="human2", 39 | edge="highway_0", 40 | probability=0.25, 41 | departLane="free", 42 | departSpeed=20) 43 | 44 | 45 | flow_params = dict( 46 | # name of the experiment 47 | exp_tag='highway', 48 | 49 | # name of the flow environment the experiment is running on 50 | env_name=LaneChangeAccelEnv, 51 | 52 | # name of the network class the experiment is running on 53 | network=HighwayNetwork, 54 | 55 | # simulator that is used by the experiment 56 | simulator='traci', 57 | 58 | # sumo-related parameters (see flow.core.params.SumoParams) 59 | sim=SumoParams( 60 | render=True, 61 | lateral_resolution=1.0, 62 | ), 63 | 64 | # environment related parameters (see flow.core.params.EnvParams) 65 | env=EnvParams( 66 | horizon=1500, 67 | additional_params=ADDITIONAL_ENV_PARAMS.copy(), 68 | ), 69 | 70 | # network-related parameters (see flow.core.params.NetParams and the 71 | # network's documentation or ADDITIONAL_NET_PARAMS component) 72 | net=NetParams( 73 | inflows=inflow, 74 | additional_params=ADDITIONAL_NET_PARAMS.copy(), 75 | ), 76 | 77 | # vehicles to be placed in the network at the start of a rollout (see 78 | # flow.core.params.VehicleParams) 79 | veh=vehicles, 80 | 81 | # parameters specifying the positioning of vehicles upon initialization/ 82 | # reset (see flow.core.params.InitialConfig) 83 | initial=InitialConfig( 84 | spacing="uniform", 85 | shuffle=True, 86 | ), 87 | ) 88 | -------------------------------------------------------------------------------- /examples/exp_configs/rl/singleagent/singleagent_figure_eight.py: -------------------------------------------------------------------------------- 1 | """Figure eight example.""" 2 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams 3 | from flow.core.params import VehicleParams, SumoCarFollowingParams 4 | from flow.controllers import IDMController, ContinuousRouter, RLController 5 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS 6 | from flow.envs import AccelEnv 7 | from flow.networks import FigureEightNetwork 8 | 9 | # time horizon of a single rollout 10 | HORIZON = 1500 11 | # number of rollouts per training iteration 12 | N_ROLLOUTS = 20 13 | # number of parallel workers 14 | N_CPUS = 2 15 | 16 | # We place one autonomous vehicle and 13 human-driven vehicles in the network 17 | vehicles = VehicleParams() 18 | vehicles.add( 19 | veh_id='human', 20 | acceleration_controller=(IDMController, { 21 | 'noise': 0.2 22 | }), 23 | routing_controller=(ContinuousRouter, {}), 24 | car_following_params=SumoCarFollowingParams( 25 | speed_mode="obey_safe_speed", 26 | decel=1.5, 27 | ), 28 | num_vehicles=13) 29 | vehicles.add( 30 | veh_id='rl', 31 | acceleration_controller=(RLController, {}), 32 | routing_controller=(ContinuousRouter, {}), 33 | car_following_params=SumoCarFollowingParams( 34 | speed_mode="obey_safe_speed", 35 | decel=1.5, 36 | ), 37 | num_vehicles=1) 38 | 39 | flow_params = dict( 40 | # name of the experiment 41 | exp_tag='singleagent_figure_eight', 42 | 43 | # name of the flow environment the experiment is running on 44 | env_name=AccelEnv, 45 | 46 | # name of the network class the experiment is running on 47 | network=FigureEightNetwork, 48 | 49 | # simulator that is used by the experiment 50 | simulator='traci', 51 | 52 | # sumo-related parameters (see flow.core.params.SumoParams) 53 | sim=SumoParams( 54 | sim_step=0.1, 55 | render=False, 56 | ), 57 | 58 | # environment related parameters (see flow.core.params.EnvParams) 59 | env=EnvParams( 60 | horizon=HORIZON, 61 | additional_params={ 62 | 'target_velocity': 20, 63 | 'max_accel': 3, 64 | 'max_decel': 3, 65 | 'sort_vehicles': False 66 | }, 67 | ), 68 | 69 | # network-related parameters (see flow.core.params.NetParams and the 70 | # network's documentation or ADDITIONAL_NET_PARAMS component) 71 | net=NetParams( 72 | additional_params=ADDITIONAL_NET_PARAMS.copy(), 73 | ), 74 | 75 | # vehicles to be placed in the network at the start of a rollout (see 76 | # flow.core.params.VehicleParams) 77 | veh=vehicles, 78 | 79 | # parameters specifying the positioning of vehicles upon initialization/ 80 | # reset (see flow.core.params.InitialConfig) 81 | initial=InitialConfig(), 82 | ) 83 | -------------------------------------------------------------------------------- /examples/exp_configs/rl/singleagent/singleagent_ring.py: -------------------------------------------------------------------------------- 1 | """Ring road example. 2 | 3 | Trains a single autonomous vehicle to stabilize the flow of 21 human-driven 4 | vehicles in a variable length ring road. 5 | """ 6 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams 7 | from flow.core.params import VehicleParams, SumoCarFollowingParams 8 | from flow.controllers import RLController, IDMController, ContinuousRouter 9 | from flow.envs import WaveAttenuationPOEnv 10 | from flow.networks import RingNetwork 11 | 12 | # time horizon of a single rollout 13 | HORIZON = 3000 14 | # number of rollouts per training iteration 15 | N_ROLLOUTS = 20 16 | # number of parallel workers 17 | N_CPUS = 2 18 | 19 | # We place one autonomous vehicle and 22 human-driven vehicles in the network 20 | vehicles = VehicleParams() 21 | vehicles.add( 22 | veh_id="human", 23 | acceleration_controller=(IDMController, { 24 | "noise": 0.2 25 | }), 26 | car_following_params=SumoCarFollowingParams( 27 | min_gap=0 28 | ), 29 | routing_controller=(ContinuousRouter, {}), 30 | num_vehicles=21) 31 | vehicles.add( 32 | veh_id="rl", 33 | acceleration_controller=(RLController, {}), 34 | routing_controller=(ContinuousRouter, {}), 35 | num_vehicles=1) 36 | 37 | flow_params = dict( 38 | # name of the experiment 39 | exp_tag="stabilizing_the_ring", 40 | 41 | # name of the flow environment the experiment is running on 42 | env_name=WaveAttenuationPOEnv, 43 | 44 | # name of the network class the experiment is running on 45 | network=RingNetwork, 46 | 47 | # simulator that is used by the experiment 48 | simulator='traci', 49 | 50 | # sumo-related parameters (see flow.core.params.SumoParams) 51 | sim=SumoParams( 52 | sim_step=0.1, 53 | render=False, 54 | restart_instance=False 55 | ), 56 | 57 | # environment related parameters (see flow.core.params.EnvParams) 58 | env=EnvParams( 59 | horizon=HORIZON, 60 | warmup_steps=750, 61 | clip_actions=False, 62 | additional_params={ 63 | "max_accel": 1, 64 | "max_decel": 1, 65 | "ring_length": [220, 270], 66 | }, 67 | ), 68 | 69 | # network-related parameters (see flow.core.params.NetParams and the 70 | # network's documentation or ADDITIONAL_NET_PARAMS component) 71 | net=NetParams( 72 | additional_params={ 73 | "length": 260, 74 | "lanes": 1, 75 | "speed_limit": 30, 76 | "resolution": 40, 77 | }, ), 78 | 79 | # vehicles to be placed in the network at the start of a rollout (see 80 | # flow.core.params.VehicleParams) 81 | veh=vehicles, 82 | 83 | # parameters specifying the positioning of vehicles upon initialization/ 84 | # reset (see flow.core.params.InitialConfig) 85 | initial=InitialConfig(), 86 | ) 87 | -------------------------------------------------------------------------------- /docs/source/rendering.rst: -------------------------------------------------------------------------------- 1 | Flow Renderer 2 | ******************* 3 | 4 | Flow has a customized renderer built on pyglet. It provides a convenient 5 | interface for image-based learning. It supports rendering the simulation as a 6 | top-view snapshot and can extract local observations of RL vehicles or 7 | tracked human vehicles. 8 | 9 | An example of the minicity rendered by the pyglet renderer can found below. 10 | 11 | .. image:: ../img/minicity_pyglet_render_3pxpm.png 12 | :width: 500 13 | :align: center 14 | 15 | The green arrows are untracked human vehicles, while the blue arrows are RL 16 | vehicles and tracked human vehicles. Color saturation is proportional to 17 | speed. For example, the greener the human vehicles, the faster they are driving. 18 | The observation radius of RL and tracked human vehicles are marked by circles. 19 | 20 | An example of an extracted local observation is as follows. 21 | 22 | .. image:: ../img/local_obs_pyglet_render_3pxpm.png 23 | :width: 200 24 | :align: center 25 | 26 | To generate the rendering seen above, use 27 | 28 | :: 29 | 30 | exp = minicity_example(render='drgb', # Render in dynamic RGB colors 31 | save_render=False, # Disable saving 32 | sight_radius=30, # Radius of obs. 33 | pxpm=3, # Render at 3 pixel per meter 34 | show_radius=True) # Show obs. radius 35 | 36 | To render in grayscale without observation circles, which is usually desired for 37 | learning, use 38 | 39 | :: 40 | 41 | exp = minicity_example(render='gray', # Render in grayscale 42 | save_render=False, # Disable saving 43 | sight_radius=30, # Radius of obs. 44 | pxpm=3, # Render at 3 pixel per meter 45 | show_radius=False) # Hide obs. radius 46 | 47 | An example of a frame rendered in grayscale without circles is as follows. 48 | 49 | .. image:: ../img/minicity_pyglet_render_3pxpm_gray_noobs.png 50 | :width: 500 51 | :align: center 52 | 53 | An extracted location observation is presented below. 54 | 55 | .. image:: ../img/local_obs_pyglet_render_3pxpm_gray_noobs.png 56 | :width: 200 57 | :align: center 58 | 59 | To save the rendering, set ``save_render=True``. The rendered frames and local 60 | observations will be saved at ``~/flow_rendering``. 61 | 62 | Finally, to compile the rendered frames into a video, install ``ffmpeg`` and run 63 | 64 | :: 65 | 66 | ffmpeg -i "~/flow_rendering/path_to/frame_%06d.png" -pix_fmt yuv420p -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" replay.mp4 67 | 68 | For more information, check the 69 | `PygletRenderer `_ class. 70 | 71 | *The custom renderer is slower than SUMO's built-in GUI. We are working on 72 | performance optimization and will update a faster version in near future.* 73 | -------------------------------------------------------------------------------- /flow/core/kernel/simulation/base.py: -------------------------------------------------------------------------------- 1 | """Script containing the base simulation kernel class.""" 2 | 3 | 4 | class KernelSimulation(object): 5 | """Base simulation kernel. 6 | 7 | The simulation kernel is responsible for generating the simulation and 8 | passing to all other kernel the API that they can use to interact with the 9 | simulation. 10 | 11 | The simulation kernel is also responsible for advancing, resetting, and 12 | storing whatever simulation data is relevant. 13 | 14 | All methods in this class are abstract and must be overwritten by other 15 | child classes. 16 | """ 17 | 18 | def __init__(self, master_kernel): 19 | """Initialize the simulation kernel. 20 | 21 | Parameters 22 | ---------- 23 | master_kernel : flow.core.kernel.Kernel 24 | the higher level kernel (used to call methods from other 25 | sub-kernels) 26 | """ 27 | self.master_kernel = master_kernel 28 | self.kernel_api = None 29 | 30 | def pass_api(self, kernel_api): 31 | """Acquire the kernel api that was generated by the simulation kernel. 32 | 33 | Parameters 34 | ---------- 35 | kernel_api : any 36 | an API that may be used to interact with the simulator 37 | """ 38 | self.kernel_api = kernel_api 39 | 40 | def start_simulation(self, network, sim_params): 41 | """Start a simulation instance. 42 | 43 | network : any 44 | an object or variable that is meant to symbolize the network that 45 | is used during the simulation. For example, in the case of sumo 46 | simulations, this is (string) the path to the .sumo.cfg file. 47 | sim_params : flow.core.params.SimParams 48 | simulation-specific parameters 49 | """ 50 | raise NotImplementedError 51 | 52 | def simulation_step(self): 53 | """Advance the simulation by one step. 54 | 55 | This is done in most cases by calling a relevant simulator API method. 56 | """ 57 | raise NotImplementedError 58 | 59 | def update(self, reset): 60 | """Update the internal attributes of the simulation kernel. 61 | 62 | Any update operations are meant to support ease of simulation in 63 | current and future steps. 64 | 65 | Parameters 66 | ---------- 67 | reset : bool 68 | specifies whether the simulator was reset in the last simulation 69 | step 70 | """ 71 | raise NotImplementedError 72 | 73 | def check_collision(self): 74 | """Determine if a collision occurred in the last time step. 75 | 76 | Returns 77 | ------- 78 | bool 79 | True if collision occurred, False otherwise 80 | """ 81 | raise NotImplementedError 82 | 83 | def close(self): 84 | """Close the current simulation instance.""" 85 | raise NotImplementedError 86 | -------------------------------------------------------------------------------- /flow/benchmarks/figureeight0.py: -------------------------------------------------------------------------------- 1 | """Benchmark for figureeight0. 2 | 3 | Trains a fraction of vehicles in a ring road structure to regulate the flow of 4 | vehicles through an intersection. In this example, the last vehicle in the 5 | network is an autonomous vehicle. 6 | 7 | - **Action Dimension**: (1, ) 8 | - **Observation Dimension**: (28, ) 9 | - **Horizon**: 1500 steps 10 | """ 11 | from flow.envs import AccelEnv 12 | from flow.networks import FigureEightNetwork 13 | from copy import deepcopy 14 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams, \ 15 | SumoCarFollowingParams 16 | from flow.core.params import VehicleParams 17 | from flow.controllers import IDMController, ContinuousRouter, RLController 18 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS 19 | 20 | # time horizon of a single rollout 21 | HORIZON = 1500 22 | 23 | # We place 1 autonomous vehicle and 13 human-driven vehicles in the network 24 | vehicles = VehicleParams() 25 | vehicles.add( 26 | veh_id="human", 27 | acceleration_controller=(IDMController, { 28 | "noise": 0.2 29 | }), 30 | routing_controller=(ContinuousRouter, {}), 31 | car_following_params=SumoCarFollowingParams( 32 | speed_mode="obey_safe_speed", 33 | decel=1.5, 34 | ), 35 | num_vehicles=13) 36 | vehicles.add( 37 | veh_id="rl", 38 | acceleration_controller=(RLController, {}), 39 | routing_controller=(ContinuousRouter, {}), 40 | car_following_params=SumoCarFollowingParams( 41 | speed_mode="obey_safe_speed", 42 | ), 43 | num_vehicles=1) 44 | 45 | flow_params = dict( 46 | # name of the experiment 47 | exp_tag="figure_eight_0", 48 | 49 | # name of the flow environment the experiment is running on 50 | env_name=AccelEnv, 51 | 52 | # name of the network class the experiment is running on 53 | network=FigureEightNetwork, 54 | 55 | # simulator that is used by the experiment 56 | simulator='traci', 57 | 58 | # sumo-related parameters (see flow.core.params.SumoParams) 59 | sim=SumoParams( 60 | sim_step=0.1, 61 | render=False, 62 | ), 63 | 64 | # environment related parameters (see flow.core.params.EnvParams) 65 | env=EnvParams( 66 | horizon=HORIZON, 67 | additional_params={ 68 | "target_velocity": 20, 69 | "max_accel": 3, 70 | "max_decel": 3, 71 | "sort_vehicles": False 72 | }, 73 | ), 74 | 75 | # network-related parameters (see flow.core.params.NetParams and the 76 | # network's documentation or ADDITIONAL_NET_PARAMS component) 77 | net=NetParams( 78 | additional_params=deepcopy(ADDITIONAL_NET_PARAMS), 79 | ), 80 | 81 | # vehicles to be placed in the network at the start of a rollout (see 82 | # flow.core.params.VehicleParams) 83 | veh=vehicles, 84 | 85 | # parameters specifying the positioning of vehicles upon initialization/ 86 | # reset (see flow.core.params.InitialConfig) 87 | initial=InitialConfig(), 88 | ) 89 | -------------------------------------------------------------------------------- /flow/visualize/plot_ray_results.py: -------------------------------------------------------------------------------- 1 | """Plot results from ray-based simulations. 2 | 3 | This method accepts as input the progress file generated by ray 4 | (usually stored at ~/ray_results/.../progress.csv) 5 | as well as the column(s) to be plotted. 6 | 7 | If no column is specified, all existing columns will be printed. 8 | 9 | Example usage 10 | ----- 11 | :: 12 | python plot_ray_results.py .csv mean_reward max_reward 13 | """ 14 | 15 | import csv 16 | import argparse 17 | import matplotlib.pyplot as plt 18 | from collections import defaultdict 19 | 20 | 21 | EXAMPLE_USAGE = 'plot_ray_results.py ' + \ 22 | '~/ray_results/experiment-tag/experiment-name/seed-id/progress.csv ' + \ 23 | 'evaluation/return-average training/return-average' 24 | 25 | 26 | def plot_progress(filepath, columns): 27 | """Plot ray results from a csv file. 28 | 29 | Plot the values contained in the csv file at for each column 30 | in the list of string columns. 31 | """ 32 | data = defaultdict(list) 33 | 34 | with open(filepath) as f: 35 | # if columns list is empty, print a list of all columns and return 36 | if not columns: 37 | reader = csv.reader(f) 38 | print('Columns are: ' + ', '.join(next(reader))) 39 | return 40 | 41 | try: 42 | reader = csv.DictReader(f) 43 | for row in reader: 44 | for col in columns: 45 | data[col].append(float(row[col])) 46 | except KeyError: 47 | print('Error: {} was called with an unknown column name "{}".\n' 48 | 'Run "python {} {}" to get a list of all the existing ' 49 | 'columns'.format(__file__, col, __file__, filepath)) 50 | raise 51 | except ValueError: 52 | print('Error: {} was called with an invalid column name "{}".\n' 53 | 'This column contains values that are not convertible to ' 54 | 'floats.'.format(__file__, col)) 55 | raise 56 | 57 | plt.ion() 58 | for col_name, values in data.items(): 59 | plt.plot(values, label=col_name) 60 | plt.legend() 61 | plt.show() 62 | 63 | 64 | def create_parser(): 65 | """Parse visualization options user can specify in command line. 66 | 67 | Returns 68 | ------- 69 | argparse.Namespace 70 | the output parser object 71 | """ 72 | parser = argparse.ArgumentParser( 73 | formatter_class=argparse.RawDescriptionHelpFormatter, 74 | description='[Flow] Plots progress.csv file generated by ray.', 75 | epilog='Example usage:\n\t' + EXAMPLE_USAGE) 76 | 77 | parser.add_argument('file', type=str, help='Path to the csv file.') 78 | parser.add_argument( 79 | 'columns', type=str, nargs='*', help='Names of the columns to plot.') 80 | 81 | return parser 82 | 83 | 84 | if __name__ == '__main__': 85 | parser = create_parser() 86 | args = parser.parse_args() 87 | plot_progress(args.file, args.columns) 88 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/merge.py: -------------------------------------------------------------------------------- 1 | """Example of a merge network with human-driven vehicles. 2 | 3 | In the absence of autonomous vehicles, the network exhibits properties of 4 | convective instability, with perturbations propagating upstream from the merge 5 | point before exiting the network. 6 | """ 7 | 8 | from flow.core.params import SumoParams, EnvParams, \ 9 | NetParams, InitialConfig, InFlows, SumoCarFollowingParams 10 | from flow.core.params import VehicleParams 11 | from flow.controllers import IDMController 12 | from flow.envs.merge import MergePOEnv, ADDITIONAL_ENV_PARAMS 13 | from flow.networks import MergeNetwork 14 | 15 | # inflow rate at the highway 16 | FLOW_RATE = 2000 17 | 18 | vehicles = VehicleParams() 19 | vehicles.add( 20 | veh_id="human", 21 | acceleration_controller=(IDMController, { 22 | "noise": 0.2 23 | }), 24 | car_following_params=SumoCarFollowingParams( 25 | speed_mode="obey_safe_speed", 26 | ), 27 | num_vehicles=5) 28 | 29 | inflow = InFlows() 30 | inflow.add( 31 | veh_type="human", 32 | edge="inflow_highway", 33 | vehs_per_hour=FLOW_RATE, 34 | departLane="free", 35 | departSpeed=10) 36 | inflow.add( 37 | veh_type="human", 38 | edge="inflow_merge", 39 | vehs_per_hour=100, 40 | departLane="free", 41 | departSpeed=7.5) 42 | 43 | 44 | flow_params = dict( 45 | # name of the experiment 46 | exp_tag='merge-baseline', 47 | 48 | # name of the flow environment the experiment is running on 49 | env_name=MergePOEnv, 50 | 51 | # name of the network class the experiment is running on 52 | network=MergeNetwork, 53 | 54 | # simulator that is used by the experiment 55 | simulator='traci', 56 | 57 | # sumo-related parameters (see flow.core.params.SumoParams) 58 | sim=SumoParams( 59 | render=True, 60 | emission_path="./data/", 61 | sim_step=0.2, 62 | restart_instance=False, 63 | ), 64 | 65 | # environment related parameters (see flow.core.params.EnvParams) 66 | env=EnvParams( 67 | horizon=3600, 68 | additional_params=ADDITIONAL_ENV_PARAMS, 69 | sims_per_step=5, 70 | warmup_steps=0, 71 | ), 72 | 73 | # network-related parameters (see flow.core.params.NetParams and the 74 | # network's documentation or ADDITIONAL_NET_PARAMS component) 75 | net=NetParams( 76 | inflows=inflow, 77 | additional_params={ 78 | "merge_length": 100, 79 | "pre_merge_length": 500, 80 | "post_merge_length": 100, 81 | "merge_lanes": 1, 82 | "highway_lanes": 1, 83 | "speed_limit": 30, 84 | }, 85 | ), 86 | 87 | # vehicles to be placed in the network at the start of a rollout (see 88 | # flow.core.params.VehicleParams) 89 | veh=vehicles, 90 | 91 | # parameters specifying the positioning of vehicles upon initialization/ 92 | # reset (see flow.core.params.InitialConfig) 93 | initial=InitialConfig( 94 | spacing="uniform", 95 | perturbation=5.0, 96 | ), 97 | ) 98 | -------------------------------------------------------------------------------- /flow/utils/aimsun/constants.py: -------------------------------------------------------------------------------- 1 | """Constants used by the aimsun API for sending/receiving TCP messages.""" 2 | 3 | ############################################################################### 4 | # Simulation Commands # 5 | ############################################################################### 6 | 7 | #: simulation step 8 | SIMULATION_STEP = 0x00 9 | 10 | #: terminate the simulation 11 | SIMULATION_TERMINATE = 0x01 12 | 13 | 14 | ############################################################################### 15 | # Network Commands # 16 | ############################################################################### 17 | 18 | #: get the edge name in aimsun 19 | GET_EDGE_NAME = 0x02 20 | 21 | 22 | ############################################################################### 23 | # Vehicle Commands # 24 | ############################################################################### 25 | 26 | #: add a vehicle 27 | ADD_VEHICLE = 0x03 28 | 29 | #: remove a vehicle 30 | REMOVE_VEHICLE = 0x04 31 | 32 | #: set vehicle speed 33 | VEH_SET_SPEED = 0x05 34 | 35 | #: apply vehicle lane change 36 | VEH_SET_LANE = 0x06 37 | 38 | #: set vehicle route 39 | VEH_SET_ROUTE = 0x07 40 | 41 | #: set color 42 | VEH_SET_COLOR = 0x08 43 | 44 | #: get IDs of entering vehicles 45 | VEH_GET_ENTERED_IDS = 0x09 46 | 47 | #: get IDs of exiting vehicles 48 | VEH_GET_EXITED_IDS = 0x0A 49 | 50 | #: get vehicle type in Aimsun 51 | VEH_GET_TYPE_ID = 0x0B 52 | 53 | #: get vehicle static information 54 | VEH_GET_STATIC = 0x0C 55 | 56 | #: get vehicle tracking information 57 | VEH_GET_TRACKING = 0x0D 58 | 59 | #: get vehicle leader 60 | VEH_GET_LEADER = 0x0E 61 | 62 | #: get vehicle follower 63 | VEH_GET_FOLLOWER = 0x0F 64 | 65 | #: get vehicle next section 66 | VEH_GET_NEXT_SECTION = 0x10 67 | 68 | #: get vehicle route 69 | VEH_GET_ROUTE = 0x11 70 | 71 | #: get vehicle speed if no API command was submitted 72 | VEH_GET_DEFAULT_SPEED = 0x12 73 | 74 | #: get vehicle angle 75 | VEH_GET_ORIENTATION = 0x13 76 | 77 | # TODO: not 100% sure what this is... 78 | VEH_GET_TIMESTEP = 0x14 79 | 80 | # TODO: not 100% sure what this is... 81 | VEH_GET_TIMEDELTA = 0x15 82 | 83 | #: get vehicle type name in Aimsun 84 | VEH_GET_TYPE_NAME = 0x16 85 | 86 | #: get vehicle length 87 | VEH_GET_LENGTH = 0x17 88 | 89 | #: set vehicle as tracked in Aimsun 90 | VEH_SET_TRACKED = 0x18 91 | 92 | #: set vehicle as untracked in Aimsun 93 | VEH_SET_NO_TRACKED = 0x19 94 | 95 | 96 | ############################################################################### 97 | # Traffic Light Commands # 98 | ############################################################################### 99 | 100 | #: get traffic light IDs 101 | TL_GET_IDS = 0x1A 102 | 103 | #: set traffic light state 104 | TL_SET_STATE = 0x1B 105 | 106 | #: get traffic light state 107 | TL_GET_STATE = 0x1C 108 | -------------------------------------------------------------------------------- /flow/benchmarks/figureeight1.py: -------------------------------------------------------------------------------- 1 | """Benchmark for figureeight1. 2 | 3 | Trains a fraction of vehicles in a ring road structure to regulate the flow of 4 | vehicles through an intersection. In this example, every other vehicle in the 5 | network is an autonomous vehicle. 6 | 7 | - **Action Dimension**: (7, ) 8 | - **Observation Dimension**: (28, ) 9 | - **Horizon**: 1500 steps 10 | """ 11 | from flow.envs import AccelEnv 12 | from flow.networks import FigureEightNetwork 13 | from copy import deepcopy 14 | from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams, \ 15 | SumoCarFollowingParams 16 | from flow.core.params import VehicleParams 17 | from flow.controllers import IDMController, ContinuousRouter, RLController 18 | from flow.networks.figure_eight import ADDITIONAL_NET_PARAMS 19 | 20 | # time horizon of a single rollout 21 | HORIZON = 1500 22 | 23 | # We place 8 autonomous vehicle and 8 human-driven vehicles in the network 24 | vehicles = VehicleParams() 25 | for i in range(7): 26 | vehicles.add( 27 | veh_id="human{}".format(i), 28 | acceleration_controller=(IDMController, { 29 | "noise": 0.2 30 | }), 31 | routing_controller=(ContinuousRouter, {}), 32 | car_following_params=SumoCarFollowingParams( 33 | speed_mode="obey_safe_speed", 34 | decel=1.5, 35 | ), 36 | num_vehicles=1) 37 | vehicles.add( 38 | veh_id="rl{}".format(i), 39 | acceleration_controller=(RLController, {}), 40 | routing_controller=(ContinuousRouter, {}), 41 | car_following_params=SumoCarFollowingParams( 42 | speed_mode="obey_safe_speed", 43 | ), 44 | num_vehicles=1) 45 | 46 | flow_params = dict( 47 | # name of the experiment 48 | exp_tag="figure_eight_1", 49 | 50 | # name of the flow environment the experiment is running on 51 | env_name=AccelEnv, 52 | 53 | # name of the network class the experiment is running on 54 | network=FigureEightNetwork, 55 | 56 | # simulator that is used by the experiment 57 | simulator='traci', 58 | 59 | # sumo-related parameters (see flow.core.params.SumoParams) 60 | sim=SumoParams( 61 | sim_step=0.1, 62 | render=False, 63 | ), 64 | 65 | # environment related parameters (see flow.core.params.EnvParams) 66 | env=EnvParams( 67 | horizon=HORIZON, 68 | additional_params={ 69 | "target_velocity": 20, 70 | "max_accel": 3, 71 | "max_decel": 3, 72 | "sort_vehicles": False 73 | }, 74 | ), 75 | 76 | # network-related parameters (see flow.core.params.NetParams and the 77 | # network's documentation or ADDITIONAL_NET_PARAMS component) 78 | net=NetParams( 79 | additional_params=deepcopy(ADDITIONAL_NET_PARAMS), 80 | ), 81 | 82 | # vehicles to be placed in the network at the start of a rollout (see 83 | # flow.core.params.VehicleParams) 84 | veh=vehicles, 85 | 86 | # parameters specifying the positioning of vehicles upon initialization/ 87 | # reset (see flow.core.params.InitialConfig) 88 | initial=InitialConfig(), 89 | ) 90 | -------------------------------------------------------------------------------- /tests/slow_tests/test_baselines.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import os 3 | 4 | from flow.benchmarks.baselines.bottleneck0 import bottleneck0_baseline 5 | from flow.benchmarks.baselines.bottleneck1 import bottleneck1_baseline 6 | from flow.benchmarks.baselines.bottleneck2 import bottleneck2_baseline 7 | from flow.benchmarks.baselines.figureeight012 import figure_eight_baseline 8 | from flow.benchmarks.baselines.grid0 import grid0_baseline 9 | from flow.benchmarks.baselines.grid1 import grid1_baseline 10 | from flow.benchmarks.baselines.merge012 import merge_baseline 11 | 12 | os.environ["TEST_FLAG"] = "True" 13 | 14 | 15 | class TestBaselines(unittest.TestCase): 16 | """ 17 | Tests that the baselines in the benchmarks folder are running and 18 | returning expected values (i.e. values that match those in the CoRL paper 19 | reported on the website, or other). 20 | """ 21 | 22 | def test_bottleneck0(self): 23 | """ 24 | Tests flow/benchmark/baselines/bottleneck0.py 25 | """ 26 | # run the bottleneck to make sure it runs 27 | bottleneck0_baseline(num_runs=1, render=False) 28 | 29 | # TODO: check that the performance measure is within some range 30 | 31 | def test_bottleneck1(self): 32 | """ 33 | Tests flow/benchmark/baselines/bottleneck1.py 34 | """ 35 | # run the bottleneck to make sure it runs 36 | bottleneck1_baseline(num_runs=1, render=False) 37 | 38 | # TODO: check that the performance measure is within some range 39 | 40 | def test_bottleneck2(self): 41 | """ 42 | Tests flow/benchmark/baselines/bottleneck2.py 43 | """ 44 | # run the bottleneck to make sure it runs 45 | bottleneck2_baseline(num_runs=1, render=False) 46 | 47 | # TODO: check that the performance measure is within some range 48 | 49 | def test_figure_eight(self): 50 | """ 51 | Tests flow/benchmark/baselines/figureeight{0,1,2}.py 52 | """ 53 | # run the bottleneck to make sure it runs 54 | figure_eight_baseline(num_runs=1, render=False) 55 | 56 | # TODO: check that the performance measure is within some range 57 | 58 | def test_grid0(self): 59 | """ 60 | Tests flow/benchmark/baselines/grid0.py 61 | """ 62 | # run the bottleneck to make sure it runs 63 | grid0_baseline(num_runs=1, render=False) 64 | 65 | # TODO: check that the performance measure is within some range 66 | 67 | def test_grid1(self): 68 | """ 69 | Tests flow/benchmark/baselines/grid1.py 70 | """ 71 | # run the bottleneck to make sure it runs 72 | grid1_baseline(num_runs=1, render=False) 73 | 74 | # TODO: check that the performance measure is within some range 75 | 76 | def test_merge(self): 77 | """ 78 | Tests flow/benchmark/baselines/merge{0,1,2}.py 79 | """ 80 | # run the bottleneck to make sure it runs 81 | merge_baseline(num_runs=1, render=False) 82 | 83 | # TODO: check that the performance measure is within some range 84 | 85 | 86 | if __name__ == '__main__': 87 | unittest.main() 88 | -------------------------------------------------------------------------------- /examples/exp_scripts/bottleneck_density_sweep_capacity_diagram.py: -------------------------------------------------------------------------------- 1 | """Bottleneck runner script for generating flow-density plots. 2 | 3 | Run density experiment to generate capacity diagram for the 4 | bottleneck experiment 5 | """ 6 | 7 | import multiprocessing 8 | import numpy as np 9 | import os 10 | import ray 11 | 12 | from examples.sumo.bottlenecks import bottleneck_example 13 | 14 | 15 | @ray.remote 16 | def run_bottleneck(flow_rate, num_trials, num_steps, render=None): 17 | """Run a rollout of the bottleneck environment. 18 | 19 | Parameters 20 | ---------- 21 | flow_rate : float 22 | bottleneck inflow rate 23 | num_trials : int 24 | number of rollouts to perform 25 | num_steps : int 26 | number of simulation steps per rollout 27 | render : bool 28 | whether to render the environment 29 | 30 | Returns 31 | ------- 32 | float 33 | average outflow rate across rollouts 34 | float 35 | average speed across rollouts 36 | float 37 | average rollout density outflow 38 | list of float 39 | per rollout outflows 40 | float 41 | inflow rate 42 | """ 43 | print('Running experiment for inflow rate: ', flow_rate, render) 44 | exp = bottleneck_example(flow_rate, num_steps, restart_instance=True) 45 | info_dict = exp.run(num_trials, num_steps) 46 | 47 | return info_dict['average_outflow'], \ 48 | np.mean(info_dict['velocities']), \ 49 | np.mean(info_dict['average_rollout_density_outflow']), \ 50 | info_dict['per_rollout_outflows'], \ 51 | flow_rate 52 | 53 | 54 | if __name__ == '__main__': 55 | # import the experiment variable` 56 | densities = list(range(400, 3000, 100)) 57 | outflows = [] 58 | velocities = [] 59 | bottleneckdensities = [] 60 | 61 | per_step_densities = [] 62 | per_step_avg_velocities = [] 63 | per_step_outflows = [] 64 | 65 | rollout_inflows = [] 66 | rollout_outflows = [] 67 | 68 | num_cpus = multiprocessing.cpu_count() 69 | ray.init(num_cpus=max(num_cpus - 2, 1)) 70 | bottleneck_outputs = [run_bottleneck.remote(d, 10, 2000) 71 | for d in densities] 72 | for output in ray.get(bottleneck_outputs): 73 | outflow, velocity, bottleneckdensity, \ 74 | per_rollout_outflows, flow_rate = output 75 | for i, _ in enumerate(per_rollout_outflows): 76 | rollout_outflows.append(per_rollout_outflows[i]) 77 | rollout_inflows.append(flow_rate) 78 | outflows.append(outflow) 79 | velocities.append(velocity) 80 | bottleneckdensities.append(bottleneckdensity) 81 | 82 | path = os.path.dirname(os.path.abspath(__file__)) 83 | np.savetxt(path + '/../../data/rets.csv', 84 | np.matrix([densities, 85 | outflows, 86 | velocities, 87 | bottleneckdensities]).T, 88 | delimiter=',') 89 | np.savetxt(path + '/../../data/inflows_outflows.csv', 90 | np.matrix([rollout_inflows, 91 | rollout_outflows]).T, 92 | delimiter=',') 93 | -------------------------------------------------------------------------------- /examples/simulate.py: -------------------------------------------------------------------------------- 1 | """Runner script for non-RL simulations in flow. 2 | 3 | Usage 4 | python simulate.py EXP_CONFIG --no_render 5 | """ 6 | import argparse 7 | import sys 8 | import json 9 | import os 10 | from flow.core.experiment import Experiment 11 | 12 | from flow.core.params import AimsunParams 13 | from flow.utils.rllib import FlowParamsEncoder 14 | 15 | 16 | def parse_args(args): 17 | """Parse training options user can specify in command line. 18 | 19 | Returns 20 | ------- 21 | argparse.Namespace 22 | the output parser object 23 | """ 24 | parser = argparse.ArgumentParser( 25 | description="Parse argument used when running a Flow simulation.", 26 | epilog="python simulate.py EXP_CONFIG --num_runs INT --no_render") 27 | 28 | # required input parameters 29 | parser.add_argument( 30 | 'exp_config', type=str, 31 | help='Name of the experiment configuration file, as located in ' 32 | 'exp_configs/non_rl.') 33 | 34 | # optional input parameters 35 | parser.add_argument( 36 | '--num_runs', type=int, default=1, 37 | help='Number of simulations to run. Defaults to 1.') 38 | parser.add_argument( 39 | '--no_render', 40 | action='store_true', 41 | help='Specifies whether to run the simulation during runtime.') 42 | parser.add_argument( 43 | '--aimsun', 44 | action='store_true', 45 | help='Specifies whether to run the simulation using the simulator ' 46 | 'Aimsun. If not specified, the simulator used is SUMO.') 47 | parser.add_argument( 48 | '--gen_emission', 49 | action='store_true', 50 | help='Specifies whether to generate an emission file from the ' 51 | 'simulation.') 52 | 53 | return parser.parse_known_args(args)[0] 54 | 55 | 56 | if __name__ == "__main__": 57 | flags = parse_args(sys.argv[1:]) 58 | 59 | # Get the flow_params object. 60 | module = __import__("exp_configs.non_rl", fromlist=[flags.exp_config]) 61 | flow_params = getattr(module, flags.exp_config).flow_params 62 | 63 | # Get the custom callables for the runner. 64 | if hasattr(getattr(module, flags.exp_config), "custom_callables"): 65 | callables = getattr(module, flags.exp_config).custom_callables 66 | else: 67 | callables = None 68 | 69 | flow_params['sim'].render = not flags.no_render 70 | flow_params['simulator'] = 'aimsun' if flags.aimsun else 'traci' 71 | 72 | # If Aimsun is being called, replace SumoParams with AimsunParams. 73 | if flags.aimsun: 74 | sim_params = AimsunParams() 75 | sim_params.__dict__.update(flow_params['sim'].__dict__) 76 | flow_params['sim'] = sim_params 77 | 78 | # Specify an emission path if they are meant to be generated. 79 | if flags.gen_emission: 80 | flow_params['sim'].emission_path = "./data" 81 | 82 | # Create the flow_params object 83 | fp_ = flow_params['exp_tag'] 84 | dir_ = flow_params['sim'].emission_path 85 | with open(os.path.join(dir_, "{}.json".format(fp_)), 'w') as outfile: 86 | json.dump(flow_params, outfile, 87 | cls=FlowParamsEncoder, sort_keys=True, indent=4) 88 | 89 | # Create the experiment object. 90 | exp = Experiment(flow_params, callables) 91 | 92 | # Run for the specified number of rollouts. 93 | exp.run(flags.num_runs, convert_to_csv=flags.gen_emission) 94 | -------------------------------------------------------------------------------- /flow/utils/flow_warnings.py: -------------------------------------------------------------------------------- 1 | """Warnings that may be printed by Flow (e.g. deprecation warnings).""" 2 | 3 | import functools 4 | import inspect 5 | import warnings 6 | 7 | string_types = (type(b''), type(u'')) 8 | 9 | 10 | def deprecated_attribute(obj, dep_from, dep_to): 11 | """Print a deprecation warning. 12 | 13 | Parameters 14 | ---------- 15 | obj : class 16 | The class with the deprecated attribute 17 | dep_from : str 18 | old (deprecated) name of the attribute 19 | dep_to : str 20 | new name for the attribute 21 | """ 22 | warnings.simplefilter('always', PendingDeprecationWarning) 23 | warnings.warn( 24 | "The attribute {} in {} is deprecated, use {} instead.".format( 25 | dep_from, obj.__class__.__name__, dep_to), 26 | PendingDeprecationWarning 27 | ) 28 | 29 | 30 | def deprecated(base, new_path): 31 | """Print a deprecation warning. 32 | 33 | This is a decorator which can be used to mark functions as deprecated. It 34 | will result in a warning being emitted when the function is used. 35 | """ 36 | # if isinstance(base, string_types): 37 | 38 | # The @deprecated is used with a 'reason'. 39 | # 40 | # .. code-block:: python 41 | # 42 | # @deprecated("please, use another function") 43 | # def old_function(x, y): 44 | # pass 45 | 46 | def decorator(func1): 47 | 48 | if inspect.isclass(func1): 49 | fmt1 = "The class {base}.{name} is deprecated, use " \ 50 | "{new_path} instead." 51 | else: 52 | fmt1 = "The function {base}.{name} is deprecated, use " \ 53 | "{new_path} instead." 54 | 55 | @functools.wraps(func1) 56 | def new_func1(*args, **kwargs): 57 | warnings.simplefilter('always', PendingDeprecationWarning) 58 | warnings.warn( 59 | fmt1.format( 60 | base=base, 61 | name=func1.__name__, 62 | new_path=new_path 63 | ), 64 | category=PendingDeprecationWarning, 65 | stacklevel=2 66 | ) 67 | warnings.simplefilter('default', PendingDeprecationWarning) 68 | return func1(*args, **kwargs) 69 | 70 | return new_func1 71 | 72 | return decorator 73 | # 74 | # elif inspect.isclass(reason) or inspect.isfunction(reason): 75 | # 76 | # # The @deprecated is used without any 'reason'. 77 | # # 78 | # # .. code-block:: python 79 | # # 80 | # # @deprecated 81 | # # def old_function(x, y): 82 | # # pass 83 | # 84 | # func2 = reason 85 | # 86 | # if inspect.isclass(func2): 87 | # fmt2 = "Call to deprecated class {name}." 88 | # else: 89 | # fmt2 = "Call to deprecated function {name}." 90 | # 91 | # @functools.wraps(func2) 92 | # def new_func2(*args, **kwargs): 93 | # warnings.simplefilter('always', DeprecationWarning) 94 | # warnings.warn( 95 | # fmt2.format(name=func2.__name__), 96 | # category=DeprecationWarning, 97 | # stacklevel=2 98 | # ) 99 | # warnings.simplefilter('default', DeprecationWarning) 100 | # return func2(*args, **kwargs) 101 | # 102 | # return new_func2 103 | # 104 | # else: 105 | # raise TypeError(repr(type(reason))) 106 | -------------------------------------------------------------------------------- /tutorials/README.md: -------------------------------------------------------------------------------- 1 | # Flow Tutorials 2 | 3 | ## Setup 4 | 5 | 1. Make sure you have Python 3 installed (we recommend using the [Anaconda 6 | Python distribution](https://www.continuum.io/downloads)). 7 | 2. **Install Jupyter** with `pip install jupyter`. Verify that you can start 8 | a Jupyter notebook with the command `jupyter-notebook`. 9 | 3. **Install Flow** by executing the following [installation instructions]( 10 | https://flow.readthedocs.io/en/latest/flow_setup.html). 11 | 12 | ## Tutorials 13 | 14 | Each file ``tutorials/tutorial*.ipynb`` is a separate tutorial. They can be 15 | opened in a Jupyter notebook by running the following commands: 16 | 17 | ```shell 18 | source activate flow 19 | cd /tutorials 20 | jupyter-notebook 21 | ``` 22 | 23 | Instructions are written in each file. To do each tutorial, first run all of 24 | the cells in the Jupyter notebook. Then modify the ones that need to be 25 | modified in order to prevent any exceptions from being raised. Throughout these 26 | tutorials, you may find the 27 | [Flow documentation](https://flow.readthedocs.io/en/latest/) helpful. 28 | 29 | > **Common error:** if, when running a notebook, you run into an error of the form 30 | > `ImportError: No module named flow.something`, this probably means that the 31 | > `flow` Conda environment is not active in your notebook. Go into the 32 | > [Conda tab](https://stackoverflow.com/questions/38984238/how-to-set-a-default-environment-for-anaconda-jupyter) 33 | > and make sure that `flow` is selected. In case you don't have this Conda tab, 34 | > try running `conda install nb_conda` just after `source activate flow`, 35 | > then open the notebook again. If this doesn't work either, you can try other 36 | > solutions [here](https://stackoverflow.com/questions/39604271/conda-environments-not-showing-up-in-jupyter-notebook) 37 | > , or you can launch a Jupyter notebook using the `flow` environment directly 38 | > from the [Anaconda Navigator](https://docs.anaconda.com/anaconda/navigator/). 39 | > If you have the conda tab but you still get the error, open a new terminal 40 | > and execute the following commands: 41 | > ``` 42 | > cd / 43 | > source activate flow 44 | > python 45 | > ``` 46 | > (`cd /` is to make sure that `flow` is not in the folder you run `python` from). Then, in the Python interface that opens, run `import flow`. If you get an `ImportError`, this means you haven't installed Flow in your environment. Go back to the [installation instructions](https://flow.readthedocs.io/en/latest/flow_setup.html), especially the part where you do `pip install -e .` after having done `source activate flow`. 47 | 48 | The content of each tutorial is as follows: 49 | 50 | **Tutorial 0:** High-level introduction to Flow. 51 | 52 | **Tutorial 1:** Running SUMO simulations in Flow. 53 | 54 | **Tutorial 2:** Running Aimsun simulations in Flow. 55 | 56 | **Tutorial 3:** Running RLlib experiments for mixed-autonomy traffic. 57 | 58 | **Tutorial 4:** Saving and visualizing resuls from non-RL simulations and 59 | testing simulations in the presence of an RLlib agent. 60 | 61 | **Tutorial 5:** Creating custom networks. 62 | 63 | **Tutorial 6:** Importing networks from OpenStreetMap. 64 | 65 | **Tutorial 7:** Importing networks from simulator-specific template files. 66 | 67 | **Tutorial 8:** Creating custom environments. 68 | 69 | **Tutorial 9:** Creating custom controllers. 70 | 71 | **Tutorial 10:** Traffic lights. 72 | 73 | **Tutorial 11:** Running simulations with inflows of vehicles. 74 | 75 | **Tutorial 12:** Running the bottleneck environment. 76 | 77 | **Tutorial 13:** Running rllib experiments on Amazon EC2 instances 78 | -------------------------------------------------------------------------------- /docs/source/visualizing.rst: -------------------------------------------------------------------------------- 1 | Visualization 2 | ******************* 3 | 4 | Flow supports visualization of RLlib and SUMO computational experiments. 5 | When using one of the below visualizers, a window will appear similar to the 6 | one in the figure below. Click on the play button (highlighted in red) and the 7 | simulation will begin, with the autonomous vehicles exhibiting the behavior 8 | trained by the reinforcement learning algorithm. 9 | 10 | .. image:: ../img/visualizing.png 11 | :width: 400 12 | :align: center 13 | 14 | RLlib 15 | ===== 16 | Call the RLlib visualizer with 17 | :: 18 | 19 | python ./visualizer_rllib.py /ray_results/result_dir 1 20 | 21 | The first command-line argument corresponds to the directory containing 22 | experiment results (usually within RLlib's ``ray_results``). The second is 23 | the checkpoint number, corresponding to the iteration number you wish to 24 | visualize. 25 | 26 | Parameter storage 27 | ----------------- 28 | RLlib doesn't automatically store all parameters needed for restoring the 29 | state of a Flow experiment upon visualization. As such, Flow experiments in RLlib 30 | include code to store relevant parameters. Include the following code snippet in 31 | RLlib experiments you will need to visualize 32 | :: 33 | 34 | # Logging out flow_params to ray's experiment result folder 35 | from flow.utils.rllib import FlowParamsEncoder 36 | flow_json = json.dumps( 37 | flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) 38 | config['env_config']['flow_params'] = flow_json 39 | config['env_config']['run'] = alg_run 40 | 41 | This saves the relevant flow parameters to recreate Flow and perform 42 | a rollout. 43 | 44 | Another thing to keep in mind is that Flow parameters in RLlib experiments 45 | should be defined **outside** of the ``make_create_env`` function. This allows 46 | that environment creator function to use other experiment parameters later, 47 | upon visualization. 48 | 49 | 50 | 51 | Using Sumo-Web3d to visualize 52 | ============================= 53 | There are two options to create slightly fancy visualizations that look like 54 | 55 | .. image:: ../img/sumo_web3dvis.png 56 | :width: 400 57 | :align: center 58 | 59 | First, go to `Sumo-Web3d `_ and 60 | follow the installation instructions. 61 | 62 | Then, if you don't need any RL, from the sumo-web3d folder run 63 | 64 | :: 65 | 66 | python sumo_web3d/sumo_web3d.py "path to sumo.cfg" 67 | 68 | If you want to visualize the result of an RL experiment use the rllib 69 | visualization instructions given above with the additional flag 70 | `--sumo_web3d` 71 | 72 | :: 73 | 74 | python ./visualizer_rllib.py /result_dir/itr_XXX.pkl --sumo-web3d 75 | 76 | Then, either from the terminal logs pick out the printed port that has 77 | num-clients = 2 or you can run 78 | 79 | :: 80 | 81 | ps aux | grep sumo 82 | 83 | It will print out the ports running SUMO; you can then pick out the port number 84 | with 2 clients. For example, it may look something like 85 | 86 | :: 87 | 88 | eugenevinitsky 54189 0.0 0.1 4360720 11208 ?? Ss 89 | 5:33PM 0:00.04 sumo -c 90 | --remote-port 61057 --num-clients 2 --step-length 0.1 91 | --no-step-log --emission-output --time-to-teleport -1 92 | 93 | Here you would pick out 61057 and then run 94 | 95 | :: 96 | 97 | python sumo_web3d/sumo_web3d.py --sumo-port "port-num" -c "path to sumo.cfg" 98 | 99 | where "port_num" is the port indicated above, 61057. 100 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/bottleneck.py: -------------------------------------------------------------------------------- 1 | """File demonstrating formation of congestion in bottleneck.""" 2 | 3 | from flow.core.params import SumoParams, EnvParams, NetParams, InitialConfig 4 | from flow.core.params import InFlows, SumoLaneChangeParams, SumoCarFollowingParams 5 | from flow.core.params import VehicleParams 6 | from flow.core.params import TrafficLightParams 7 | from flow.controllers import SimLaneChangeController, ContinuousRouter 8 | from flow.envs import BottleneckEnv 9 | from flow.networks import BottleneckNetwork 10 | 11 | SCALING = 1 12 | DISABLE_TB = True 13 | 14 | # If set to False, ALINEA will control the ramp meter 15 | DISABLE_RAMP_METER = True 16 | INFLOW = 2300 17 | HORIZON = 1000 18 | 19 | vehicles = VehicleParams() 20 | vehicles.add( 21 | veh_id="human", 22 | lane_change_controller=(SimLaneChangeController, {}), 23 | routing_controller=(ContinuousRouter, {}), 24 | car_following_params=SumoCarFollowingParams( 25 | speed_mode=25, 26 | ), 27 | lane_change_params=SumoLaneChangeParams( 28 | lane_change_mode=1621, 29 | ), 30 | num_vehicles=1) 31 | 32 | inflow = InFlows() 33 | inflow.add( 34 | veh_type="human", 35 | edge="1", 36 | vehsPerHour=INFLOW, 37 | departLane="random", 38 | departSpeed=10) 39 | 40 | traffic_lights = TrafficLightParams() 41 | if not DISABLE_TB: 42 | traffic_lights.add(node_id="2") 43 | if not DISABLE_RAMP_METER: 44 | traffic_lights.add(node_id="3") 45 | 46 | 47 | flow_params = dict( 48 | # name of the experiment 49 | exp_tag='bay_bridge_toll', 50 | 51 | # name of the flow environment the experiment is running on 52 | env_name=BottleneckEnv, 53 | 54 | # name of the network class the experiment is running on 55 | network=BottleneckNetwork, 56 | 57 | # simulator that is used by the experiment 58 | simulator='traci', 59 | 60 | # sumo-related parameters (see flow.core.params.SumoParams) 61 | sim=SumoParams( 62 | sim_step=0.5, 63 | render=False, 64 | overtake_right=False, 65 | restart_instance=False 66 | ), 67 | 68 | # environment related parameters (see flow.core.params.EnvParams) 69 | env=EnvParams( 70 | horizon=HORIZON, 71 | additional_params={ 72 | "target_velocity": 40, 73 | "max_accel": 1, 74 | "max_decel": 1, 75 | "lane_change_duration": 5, 76 | "add_rl_if_exit": False, 77 | "disable_tb": DISABLE_TB, 78 | "disable_ramp_metering": DISABLE_RAMP_METER 79 | } 80 | ), 81 | 82 | # network-related parameters (see flow.core.params.NetParams and the 83 | # network's documentation or ADDITIONAL_NET_PARAMS component) 84 | net=NetParams( 85 | inflows=inflow, 86 | additional_params={ 87 | "scaling": SCALING, 88 | "speed_limit": 23 89 | } 90 | ), 91 | 92 | # vehicles to be placed in the network at the start of a rollout (see 93 | # flow.core.params.VehicleParams) 94 | veh=vehicles, 95 | 96 | # parameters specifying the positioning of vehicles upon initialization/ 97 | # reset (see flow.core.params.InitialConfig) 98 | initial=InitialConfig( 99 | spacing="random", 100 | min_gap=5, 101 | lanes_distribution=float("inf"), 102 | edges_distribution=["2", "3", "4", "5"] 103 | ), 104 | 105 | # traffic lights to be introduced to specific nodes (see 106 | # flow.core.params.TrafficLightParams) 107 | tls=traffic_lights, 108 | ) 109 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at flow.berkeley@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /tests/stress_tests/stress_test_rl.py: -------------------------------------------------------------------------------- 1 | """Repeatedly runs one step of an env to test for possible race conditions.""" 2 | 3 | import argparse 4 | import json 5 | import time 6 | import ray 7 | from ray.tune import run_experiments 8 | from ray.tune.registry import register_env 9 | 10 | from flow.utils.registry import make_create_env 11 | from flow.utils.rllib import FlowParamsEncoder 12 | 13 | # use this to specify the environment to run 14 | from benchmarks.bottleneck0 import flow_params 15 | 16 | # number of rollouts per training iteration 17 | N_ROLLOUTS = 50 18 | # number of parallel workers 19 | N_CPUS = 50 20 | 21 | EXAMPLE_USAGE = """ 22 | example usage: 23 | python ./stress_test_rl.py PPO 24 | 25 | Here the arguments are: 26 | PPO - the name of the RL algorithm you want to use for the stress test 27 | """ 28 | 29 | parser = argparse.ArgumentParser( 30 | formatter_class=argparse.RawDescriptionHelpFormatter, 31 | description="Parses algorithm to run", 32 | epilog=EXAMPLE_USAGE) 33 | 34 | # required input parameters 35 | parser.add_argument("alg", type=str, help="RL algorithm") 36 | 37 | if __name__ == "__main__": 38 | args = parser.parse_args() 39 | alg = args.alg.upper() 40 | 41 | start = time.time() 42 | print("stress test starting") 43 | ray.init() 44 | flow_params["env"].horizon = 1 45 | horizon = flow_params["env"].horizon 46 | 47 | create_env, env_name = make_create_env(params=flow_params, version=0) 48 | 49 | try: 50 | from ray.rllib.agents.agent import get_agent_class 51 | except ImportError: 52 | from ray.rllib.agents.registry import get_agent_class 53 | if alg == 'ARS': 54 | agent_cls = get_agent_class(alg) 55 | config = agent_cls._default_config.copy() 56 | config["num_workers"] = N_CPUS 57 | config["num_deltas"] = N_CPUS 58 | config["deltas_used"] = N_CPUS 59 | elif alg == 'PPO': 60 | agent_cls = get_agent_class(alg) 61 | config = agent_cls._default_config.copy() 62 | config["num_workers"] = N_CPUS 63 | config["timesteps_per_batch"] = horizon * N_ROLLOUTS 64 | config["vf_loss_coeff"] = 1.0 65 | config["kl_target"] = 0.02 66 | config["use_gae"] = True 67 | config["horizon"] = 1 68 | config["clip_param"] = 0.2 69 | config["num_sgd_iter"] = 1 70 | config["min_steps_per_task"] = 1 71 | config["sgd_batchsize"] = horizon * N_ROLLOUTS 72 | elif alg == 'ES': 73 | agent_cls = get_agent_class(alg) 74 | config["num_workers"] = N_CPUS 75 | config["episodes_per_batch"] = N_CPUS 76 | config["timesteps_per_batch"] = N_CPUS 77 | 78 | # save the flow params for replay 79 | flow_json = json.dumps( 80 | flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) 81 | config['env_config']['flow_params'] = flow_json 82 | config['env_config']['run'] = alg 83 | 84 | # Register as rllib env 85 | register_env(env_name, create_env) 86 | 87 | trials = run_experiments({ 88 | "highway_stabilize": { 89 | "run": alg, # Pulled from command line args 90 | "env": env_name, 91 | "config": { 92 | **config 93 | }, 94 | "max_failures": 999, 95 | "stop": { 96 | "training_iteration": 50000 97 | }, 98 | "repeat": 1, 99 | "trial_resources": { 100 | "cpu": 1, 101 | "gpu": 0, 102 | "extra_cpu": N_CPUS - 1, 103 | }, 104 | }, 105 | }) 106 | 107 | end = time.time() 108 | 109 | print("Stress test took " + str(end - start)) 110 | -------------------------------------------------------------------------------- /flow/core/kernel/traffic_light/base.py: -------------------------------------------------------------------------------- 1 | """Script containing the base traffic light kernel class.""" 2 | 3 | 4 | class KernelTrafficLight(object): 5 | """Base traffic light kernel. 6 | 7 | This kernel sub-class is used to interact with the simulator with regards 8 | to all traffic light -dependent components. Specifically, this class 9 | contains methods for: 10 | 11 | * Interacting with the simulator: This consisting specifying the states of 12 | certain traffic lights at a given time step. This can be done by calling 13 | the following method: 14 | 15 | >>> from flow.envs.base import Env 16 | >>> env = Env(...) 17 | >>> node_id = 'test_intersection' # name of the node 18 | >>> env.k.traffic_light.set_state(node_id, 'r') 19 | 20 | * State acquisition: This methods contains several methods for acquiring 21 | state information from specific traffic lights. For example, if you would 22 | like to get the state ("r", "g", etc.) of a node with a traffic light, 23 | that can be done by calling: 24 | 25 | >>> tl_state = env.k.traffic_light.get_state(node_id) 26 | 27 | All methods in this class are abstract, and must be filled in by the child 28 | vehicle kernel of separate simulators. 29 | """ 30 | 31 | def __init__(self, master_kernel): 32 | """Instantiate the base traffic light kernel. 33 | 34 | Parameters 35 | ---------- 36 | master_kernel : flow.core.kernel.Kernel 37 | the higher level kernel (used to call methods from other 38 | sub-kernels) 39 | """ 40 | self.master_kernel = master_kernel 41 | self.kernel_api = None 42 | 43 | def pass_api(self, kernel_api): 44 | """Acquire the kernel api that was generated by the simulation kernel. 45 | 46 | Parameters 47 | ---------- 48 | kernel_api : any 49 | an API that may be used to interact with the simulator 50 | """ 51 | self.kernel_api = kernel_api 52 | 53 | def update(self, reset): 54 | """Update the states and phases of the traffic lights. 55 | 56 | This ensures that the traffic light variables match current traffic 57 | light data. 58 | 59 | Parameters 60 | ---------- 61 | reset : bool 62 | specifies whether the simulator was reset in the last simulation 63 | step 64 | """ 65 | raise NotImplementedError 66 | 67 | def get_ids(self): 68 | """Return the names of all nodes with traffic lights.""" 69 | raise NotImplementedError 70 | 71 | def set_state(self, node_id, state, link_index="all"): 72 | """Set the state of the traffic lights on a specific node. 73 | 74 | Parameters 75 | ---------- 76 | node_id : str 77 | name of the node with the controlled traffic lights 78 | state : str 79 | desired state(s) for the traffic light 80 | link_index : int, optional 81 | index of the link whose traffic light state is meant to be changed. 82 | If no value is provided, the lights on all links are updated. 83 | """ 84 | raise NotImplementedError 85 | 86 | def get_state(self, node_id): 87 | """Return the state of the traffic light(s) at the specified node. 88 | 89 | Parameters 90 | ---------- 91 | node_id: str 92 | name of the node 93 | 94 | Returns 95 | ------- 96 | state : str 97 | Index = lane index 98 | Element = state of the traffic light at that node/lane 99 | """ 100 | raise NotImplementedError 101 | -------------------------------------------------------------------------------- /scripts/benchmark_autoscale.yaml: -------------------------------------------------------------------------------- 1 | # benchmark_cluster.yaml script — running the benchmark experiments 2 | 3 | # An unique identifier for the head node and workers of this cluster. 4 | #cluster_name: test # 5 | 6 | # The minimum number of workers nodes to launch in addition to the head 7 | # node. This number should be >= 0. 8 | min_workers: 0 # 9 | 10 | # The maximum number of workers nodes to launch in addition to the head 11 | # node. This takes precedence over min_workers. 12 | max_workers: 0 13 | 14 | # The autoscaler will scale up the cluster to this target fraction of resource 15 | # usage. For example, if a cluster of 10 nodes is 100% busy and 16 | # target_utilization is 0.8, it would resize the cluster to 13. This fraction 17 | # can be decreased to increase the aggressiveness of upscaling. 18 | target_utilization_fraction: 0.8 19 | 20 | # If a node is idle for this many minutes, it will be removed. 21 | idle_timeout_minutes: 5 22 | 23 | # Cloud-provider specific configuration. 24 | provider: 25 | type: aws 26 | region: us-west-1 27 | availability_zone: us-west-1a 28 | 29 | # How Ray will authenticate with newly launched nodes. 30 | auth: 31 | ssh_user: ubuntu 32 | # By default Ray creates a new private keypair, but you can also use your own. 33 | # If you do so, make sure to also set "KeyName" in the head and worker node 34 | # configurations below. 35 | # ssh_private_key: /path/to/your/key.pem 36 | 37 | # Provider-specific config for the head node, e.g. instance type. By default 38 | # Ray will auto-configure unspecified fields such as SubnetId and KeyName. 39 | # For more documentation on available fields, see: 40 | # http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.ServiceResource.create_instances 41 | head_node: 42 | InstanceType: c4.4xlarge 43 | ImageId: ami-09544298704576518 # Flow AMI (Ubuntu) 44 | InstanceMarketOptions: 45 | MarketType: spot 46 | #Additional options can be found in the boto docs, e.g. 47 | SpotOptions: 48 | MaxPrice: "1.0" 49 | 50 | # Additional options in the boto docs. 51 | 52 | # Provider-specific config for worker nodes, e.g. instance type. By default 53 | # Ray will auto-configure unspecified fields such as SubnetId and KeyName. 54 | # For more documentation on available fields, see: 55 | # http://boto3.readthedocs.io/en/latest/reference/services/ec2.html#EC2.ServiceResource.create_instances 56 | worker_nodes: 57 | InstanceType: c4.4xlarge 58 | ImageId: ami-09544298704576518 # Flow AMI (Ubuntu) 59 | 60 | #Run workers on spot by default. Comment this out to use on-demand. 61 | InstanceMarketOptions: 62 | MarketType: spot 63 | # Additional options can be found in the boto docs, e.g. 64 | SpotOptions: 65 | MaxPrice: "1.0" 66 | 67 | # Additional options in the boto docs. 68 | 69 | setup_commands: 70 | - cd flow && git fetch && git checkout origin/master 71 | 72 | # Custom commands that will be run on the head node after common setup. 73 | head_setup_commands: 74 | - pip install boto3==1.4.8 # 1.4.8 adds InstanceMarketOptions 75 | 76 | # Custom commands that will be run on worker nodes after common setup. 77 | worker_setup_commands: [] 78 | 79 | # Command to start ray on the head node. You don't need to change this. 80 | head_start_ray_commands: 81 | - ray stop 82 | - >- 83 | ulimit -n 65536; 84 | ray start 85 | --head 86 | --redis-port=6379 87 | --object-manager-port=8076 88 | --autoscaling-config=~/ray_bootstrap_config.yaml 89 | # Command to start ray on worker nodes. You don't need to change this. 90 | worker_start_ray_commands: 91 | - ray stop 92 | - >- 93 | ulimit -n 65536; 94 | ray start 95 | --redis-address=$RAY_HEAD_IP:6379 96 | --object-manager-port=8076 97 | -------------------------------------------------------------------------------- /examples/exp_configs/non_rl/highway_single.py: -------------------------------------------------------------------------------- 1 | """Example of an open network with human-driven vehicles.""" 2 | from flow.controllers import IDMController 3 | from flow.core.params import EnvParams 4 | from flow.core.params import NetParams 5 | from flow.core.params import InitialConfig 6 | from flow.core.params import InFlows 7 | from flow.core.params import VehicleParams 8 | from flow.core.params import SumoParams 9 | from flow.core.params import SumoLaneChangeParams 10 | from flow.core.params import SumoCarFollowingParams 11 | from flow.networks import HighwayNetwork 12 | from flow.envs import TestEnv 13 | from flow.networks.highway import ADDITIONAL_NET_PARAMS 14 | 15 | # the speed of vehicles entering the network 16 | TRAFFIC_SPEED = 24.1 17 | # the maximum speed at the downstream boundary edge 18 | END_SPEED = 6.0 19 | # the inflow rate of vehicles 20 | TRAFFIC_FLOW = 2215 21 | # the simulation time horizon (in steps) 22 | HORIZON = 1500 23 | # whether to include noise in the car-following models 24 | INCLUDE_NOISE = True 25 | 26 | additional_net_params = ADDITIONAL_NET_PARAMS.copy() 27 | additional_net_params.update({ 28 | # length of the highway 29 | "length": 2500, 30 | # number of lanes 31 | "lanes": 1, 32 | # speed limit for all edges 33 | "speed_limit": 30, 34 | # number of edges to divide the highway into 35 | "num_edges": 2, 36 | # whether to include a ghost edge. This edge is provided a different speed 37 | # limit. 38 | "use_ghost_edge": True, 39 | # speed limit for the ghost edge 40 | "ghost_speed_limit": END_SPEED, 41 | # length of the downstream ghost edge with the reduced speed limit 42 | "boundary_cell_length": 300, 43 | }) 44 | 45 | vehicles = VehicleParams() 46 | vehicles.add( 47 | "human", 48 | acceleration_controller=(IDMController, { 49 | 'a': 1.3, 50 | 'b': 2.0, 51 | 'noise': 0.3 if INCLUDE_NOISE else 0.0 52 | }), 53 | car_following_params=SumoCarFollowingParams( 54 | min_gap=0.5 55 | ), 56 | lane_change_params=SumoLaneChangeParams( 57 | model="SL2015", 58 | lc_sublane=2.0, 59 | ), 60 | ) 61 | 62 | inflows = InFlows() 63 | inflows.add( 64 | veh_type="human", 65 | edge="highway_0", 66 | vehs_per_hour=TRAFFIC_FLOW, 67 | depart_lane="free", 68 | depart_speed=TRAFFIC_SPEED, 69 | name="idm_highway_inflow") 70 | 71 | flow_params = dict( 72 | # name of the experiment 73 | exp_tag='highway-single', 74 | 75 | # name of the flow environment the experiment is running on 76 | env_name=TestEnv, 77 | 78 | # name of the network class the experiment is running on 79 | network=HighwayNetwork, 80 | 81 | # simulator that is used by the experiment 82 | simulator='traci', 83 | 84 | # environment related parameters (see flow.core.params.EnvParams) 85 | env=EnvParams( 86 | horizon=HORIZON, 87 | warmup_steps=500, 88 | sims_per_step=3, 89 | ), 90 | 91 | # sumo-related parameters (see flow.core.params.SumoParams) 92 | sim=SumoParams( 93 | sim_step=0.4, 94 | render=False, 95 | use_ballistic=True, 96 | restart_instance=False 97 | ), 98 | 99 | # network-related parameters (see flow.core.params.NetParams and the 100 | # network's documentation or ADDITIONAL_NET_PARAMS component) 101 | net=NetParams( 102 | inflows=inflows, 103 | additional_params=additional_net_params 104 | ), 105 | 106 | # vehicles to be placed in the network at the start of a rollout (see 107 | # flow.core.params.VehicleParams) 108 | veh=vehicles, 109 | 110 | # parameters specifying the positioning of vehicles upon initialization/ 111 | # reset (see flow.core.params.InitialConfig) 112 | initial=InitialConfig(), 113 | ) 114 | --------------------------------------------------------------------------------