From c6de1e5c964c94ceb9dacf8f380e2e866bd1b15c Mon Sep 17 00:00:00 2001 From: AboudyKreidieh Date: Thu, 9 Aug 2018 23:59:29 -0700 Subject: [PATCH] benchmark baselines --- flow/benchmarks/baselines/bottleneck0.py | 177 ++++++++-------- flow/benchmarks/baselines/bottleneck1.py | 179 ++++++++-------- flow/benchmarks/baselines/bottleneck2.py | 177 ++++++++-------- flow/benchmarks/baselines/figureeight012.py | 82 ++++++++ .../baselines/figureeight{0,1,2}.py | 72 ------- flow/benchmarks/baselines/grid0.py | 199 +++++++++--------- flow/benchmarks/baselines/grid1.py | 199 +++++++++--------- flow/benchmarks/baselines/merge012.py | 108 ++++++++++ flow/benchmarks/baselines/merge{0,1,2}.py | 98 --------- tests/slow_tests/test_benchmarks.py | 102 +++++++++ 10 files changed, 785 insertions(+), 608 deletions(-) create mode 100644 flow/benchmarks/baselines/figureeight012.py delete mode 100644 flow/benchmarks/baselines/figureeight{0,1,2}.py create mode 100644 flow/benchmarks/baselines/merge012.py delete mode 100644 flow/benchmarks/baselines/merge{0,1,2}.py create mode 100644 tests/slow_tests/test_benchmarks.py diff --git a/flow/benchmarks/baselines/bottleneck0.py b/flow/benchmarks/baselines/bottleneck0.py index b415fe7f..7fde82a7 100644 --- a/flow/benchmarks/baselines/bottleneck0.py +++ b/flow/benchmarks/baselines/bottleneck0.py @@ -32,86 +32,97 @@ DISABLE_RAMP_METER = True AV_FRAC = 0.10 -vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode=9, - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, - num_vehicles=1 * SCALING) - -controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), - ("4", 2, True), ("5", 1, False)] -num_observed_segments = [("1", 1), ("2", 3), ("3", 3), - ("4", 3), ("5", 1)] -additional_env_params = { - "target_velocity": 40, - "disable_tb": True, - "disable_ramp_metering": True, - "controlled_segments": controlled_segments, - "symmetric": False, - "observed_segments": num_observed_segments, - "reset_inflow": False, - "lane_change_duration": 5, - "max_accel": 3, - "max_decel": 3, - "inflow_range": [1000, 2000] -} - -# flow rate -flow_rate = 1900 * SCALING - -# percentage of flow coming out of each lane -inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate, - departLane="random", departSpeed=10) - -traffic_lights = TrafficLights() -if not DISABLE_TB: - traffic_lights.add(node_id="2") -if not DISABLE_RAMP_METER: - traffic_lights.add(node_id="3") - -additional_net_params = {"scaling": SCALING} -net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) - -sumo_params = SumoParams( - sim_step=0.5, - sumo_binary="sumo-gui", - print_warnings=False, - restart_instance=False, -) - -env_params = EnvParams( - evaluate=True, # Set to True to evaluate traffic metrics - warmup_steps=40, - sims_per_step=1, - horizon=HORIZON, - additional_params=additional_env_params, -) - -initial_config = InitialConfig( - spacing="uniform", - min_gap=5, - lanes_distribution=float("inf"), - edges_distribution=["2", "3", "4", "5"], -) - -scenario = BottleneckScenario(name="bay_bridge_toll", - generator_class=BottleneckGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) - -env = DesiredVelocityEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -avg_outflow = np.mean([outflow[-1] for outflow in results["per_step_returns"]]) -print('The average outflow over 500 seconds ' - 'across {} runs is {}'.format(num_runs, avg_outflow)) + +def bottleneck0_baseline(num_runs, sumo_binary="sumo-gui"): + vehicles = Vehicles() + vehicles.add(veh_id="human", + speed_mode=9, + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, + num_vehicles=1 * SCALING) + + controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), + ("4", 2, True), ("5", 1, False)] + num_observed_segments = [("1", 1), ("2", 3), ("3", 3), + ("4", 3), ("5", 1)] + additional_env_params = { + "target_velocity": 40, + "disable_tb": True, + "disable_ramp_metering": True, + "controlled_segments": controlled_segments, + "symmetric": False, + "observed_segments": num_observed_segments, + "reset_inflow": False, + "lane_change_duration": 5, + "max_accel": 3, + "max_decel": 3, + "inflow_range": [1000, 2000] + } + + # flow rate + flow_rate = 1900 * SCALING + + # percentage of flow coming out of each lane + inflow = InFlows() + inflow.add(veh_type="human", edge="1", + vehs_per_hour=flow_rate, + departLane="random", departSpeed=10) + + traffic_lights = TrafficLights() + if not DISABLE_TB: + traffic_lights.add(node_id="2") + if not DISABLE_RAMP_METER: + traffic_lights.add(node_id="3") + + additional_net_params = {"scaling": SCALING} + net_params = NetParams(in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) + + sumo_params = SumoParams( + sim_step=0.5, + sumo_binary=sumo_binary, + print_warnings=False, + restart_instance=False, + ) + + env_params = EnvParams( + evaluate=True, # Set to True to evaluate traffic metrics + warmup_steps=40, + sims_per_step=1, + horizon=HORIZON, + additional_params=additional_env_params, + ) + + initial_config = InitialConfig( + spacing="uniform", + min_gap=5, + lanes_distribution=float("inf"), + edges_distribution=["2", "3", "4", "5"], + ) + + scenario = BottleneckScenario(name="bay_bridge_toll", + generator_class=BottleneckGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) + + env = DesiredVelocityEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + avg_outflow = np.mean([outflow[-1] + for outflow in results["per_step_returns"]]) + + return avg_outflow + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = bottleneck0_baseline(num_runs=runs) + + print('---------') + print('The average outflow over 500 seconds ' + 'across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/bottleneck1.py b/flow/benchmarks/baselines/bottleneck1.py index 0f13eb01..153cfbbe 100644 --- a/flow/benchmarks/baselines/bottleneck1.py +++ b/flow/benchmarks/baselines/bottleneck1.py @@ -1,5 +1,5 @@ """ -This script is used to quickly evaluate a baseline for bottleneck0. +This script is used to quickly evaluate a baseline for bottleneck1. Baseline is no AVs. Bottleneck in which the actions are specifying a desired velocity in a segment @@ -33,86 +33,97 @@ DISABLE_RAMP_METER = True AV_FRAC = 0.25 -vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode=9, - routing_controller=(ContinuousRouter, {}), - lane_change_mode=1621, - num_vehicles=1 * SCALING) - -controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), - ("4", 2, True), ("5", 1, False)] -num_observed_segments = [("1", 1), ("2", 3), ("3", 3), - ("4", 3), ("5", 1)] -additional_env_params = { - "target_velocity": 40, - "disable_tb": True, - "disable_ramp_metering": True, - "controlled_segments": controlled_segments, - "symmetric": False, - "observed_segments": num_observed_segments, - "reset_inflow": False, - "lane_change_duration": 5, - "max_accel": 3, - "max_decel": 3, - "inflow_range": [1000, 2000] -} - -# flow rate -flow_rate = 1900 * SCALING - -# percentage of flow coming out of each lane -inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate, - departLane="random", departSpeed=10) - -traffic_lights = TrafficLights() -if not DISABLE_TB: - traffic_lights.add(node_id="2") -if not DISABLE_RAMP_METER: - traffic_lights.add(node_id="3") - -additional_net_params = {"scaling": SCALING} -net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) - -sumo_params = SumoParams( - sim_step=0.5, - sumo_binary="sumo-gui", - print_warnings=False, - restart_instance=False, -) - -env_params = EnvParams( - evaluate=True, # Set to True to evaluate traffic metrics - warmup_steps=40, - sims_per_step=1, - horizon=HORIZON, - additional_params=additional_env_params, -) - -initial_config = InitialConfig( - spacing="uniform", - min_gap=5, - lanes_distribution=float("inf"), - edges_distribution=["2", "3", "4", "5"], -) - -scenario = BottleneckScenario(name="bay_bridge_toll", - generator_class=BottleneckGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) - -env = DesiredVelocityEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -avg_outflow = np.mean([outflow[-1] for outflow in results["per_step_returns"]]) -print('The average outflow over 500 seconds ' - 'across {} runs is {}'.format(num_runs, avg_outflow)) + +def bottleneck1_baseline(num_runs, sumo_binary="sumo-gui"): + vehicles = Vehicles() + vehicles.add(veh_id="human", + speed_mode=9, + routing_controller=(ContinuousRouter, {}), + lane_change_mode=1621, + num_vehicles=1 * SCALING) + + controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), + ("4", 2, True), ("5", 1, False)] + num_observed_segments = [("1", 1), ("2", 3), ("3", 3), + ("4", 3), ("5", 1)] + additional_env_params = { + "target_velocity": 40, + "disable_tb": True, + "disable_ramp_metering": True, + "controlled_segments": controlled_segments, + "symmetric": False, + "observed_segments": num_observed_segments, + "reset_inflow": False, + "lane_change_duration": 5, + "max_accel": 3, + "max_decel": 3, + "inflow_range": [1000, 2000] + } + + # flow rate + flow_rate = 1900 * SCALING + + # percentage of flow coming out of each lane + inflow = InFlows() + inflow.add(veh_type="human", edge="1", + vehs_per_hour=flow_rate, + departLane="random", departSpeed=10) + + traffic_lights = TrafficLights() + if not DISABLE_TB: + traffic_lights.add(node_id="2") + if not DISABLE_RAMP_METER: + traffic_lights.add(node_id="3") + + additional_net_params = {"scaling": SCALING} + net_params = NetParams(in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) + + sumo_params = SumoParams( + sim_step=0.5, + sumo_binary=sumo_binary, + print_warnings=False, + restart_instance=False, + ) + + env_params = EnvParams( + evaluate=True, # Set to True to evaluate traffic metrics + warmup_steps=40, + sims_per_step=1, + horizon=HORIZON, + additional_params=additional_env_params, + ) + + initial_config = InitialConfig( + spacing="uniform", + min_gap=5, + lanes_distribution=float("inf"), + edges_distribution=["2", "3", "4", "5"], + ) + + scenario = BottleneckScenario(name="bay_bridge_toll", + generator_class=BottleneckGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) + + env = DesiredVelocityEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + avg_outflow = np.mean([outflow[-1] + for outflow in results["per_step_returns"]]) + + return avg_outflow + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = bottleneck1_baseline(num_runs=runs) + + print('---------') + print('The average outflow over 500 seconds ' + 'across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/bottleneck2.py b/flow/benchmarks/baselines/bottleneck2.py index 52bdb172..0ff7e059 100644 --- a/flow/benchmarks/baselines/bottleneck2.py +++ b/flow/benchmarks/baselines/bottleneck2.py @@ -32,86 +32,97 @@ DISABLE_RAMP_METER = True AV_FRAC = .10 -vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode=9, - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, - num_vehicles=1 * SCALING) - -controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), - ("4", 2, True), ("5", 1, False)] -num_observed_segments = [("1", 1), ("2", 3), ("3", 3), - ("4", 3), ("5", 1)] -additional_env_params = { - "target_velocity": 40, - "disable_tb": True, - "disable_ramp_metering": True, - "controlled_segments": controlled_segments, - "symmetric": False, - "observed_segments": num_observed_segments, - "reset_inflow": False, - "lane_change_duration": 5, - "max_accel": 3, - "max_decel": 3, - "inflow_range": [1000, 2000] -} - -# flow rate -flow_rate = 1900 * SCALING - -# percentage of flow coming out of each lane -inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate, - departLane="random", departSpeed=10) - -traffic_lights = TrafficLights() -if not DISABLE_TB: - traffic_lights.add(node_id="2") -if not DISABLE_RAMP_METER: - traffic_lights.add(node_id="3") - -additional_net_params = {"scaling": SCALING} -net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) - -sumo_params = SumoParams( - sim_step=0.5, - sumo_binary="sumo-gui", - print_warnings=False, - restart_instance=False, -) - -env_params = EnvParams( - evaluate=True, # Set to True to evaluate traffic metrics - warmup_steps=40, - sims_per_step=1, - horizon=HORIZON, - additional_params=additional_env_params, -) - -initial_config = InitialConfig( - spacing="uniform", - min_gap=5, - lanes_distribution=float("inf"), - edges_distribution=["2", "3", "4", "5"], -) - -scenario = BottleneckScenario(name="bay_bridge_toll", - generator_class=BottleneckGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) - -env = DesiredVelocityEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -avg_outflow = np.mean([outflow[-1] for outflow in results["per_step_returns"]]) -print('The average outflow over 500 seconds ' - 'across {} runs is {}'.format(num_runs, avg_outflow)) + +def bottleneck2_baseline(num_runs, sumo_binary="sumo-gui"): + vehicles = Vehicles() + vehicles.add(veh_id="human", + speed_mode=9, + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, + num_vehicles=1 * SCALING) + + controlled_segments = [("1", 1, False), ("2", 2, True), ("3", 2, True), + ("4", 2, True), ("5", 1, False)] + num_observed_segments = [("1", 1), ("2", 3), ("3", 3), + ("4", 3), ("5", 1)] + additional_env_params = { + "target_velocity": 40, + "disable_tb": True, + "disable_ramp_metering": True, + "controlled_segments": controlled_segments, + "symmetric": False, + "observed_segments": num_observed_segments, + "reset_inflow": False, + "lane_change_duration": 5, + "max_accel": 3, + "max_decel": 3, + "inflow_range": [1000, 2000] + } + + # flow rate + flow_rate = 1900 * SCALING + + # percentage of flow coming out of each lane + inflow = InFlows() + inflow.add(veh_type="human", edge="1", + vehs_per_hour=flow_rate, + departLane="random", departSpeed=10) + + traffic_lights = TrafficLights() + if not DISABLE_TB: + traffic_lights.add(node_id="2") + if not DISABLE_RAMP_METER: + traffic_lights.add(node_id="3") + + additional_net_params = {"scaling": SCALING} + net_params = NetParams(in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) + + sumo_params = SumoParams( + sim_step=0.5, + sumo_binary=sumo_binary, + print_warnings=False, + restart_instance=False, + ) + + env_params = EnvParams( + evaluate=True, # Set to True to evaluate traffic metrics + warmup_steps=40, + sims_per_step=1, + horizon=HORIZON, + additional_params=additional_env_params, + ) + + initial_config = InitialConfig( + spacing="uniform", + min_gap=5, + lanes_distribution=float("inf"), + edges_distribution=["2", "3", "4", "5"], + ) + + scenario = BottleneckScenario(name="bay_bridge_toll", + generator_class=BottleneckGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) + + env = DesiredVelocityEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + avg_outflow = np.mean([outflow[-1] + for outflow in results["per_step_returns"]]) + + return avg_outflow + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = bottleneck2_baseline(num_runs=runs) + + print('---------') + print('The average outflow over 500 seconds ' + 'across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/figureeight012.py b/flow/benchmarks/baselines/figureeight012.py new file mode 100644 index 00000000..4529b40e --- /dev/null +++ b/flow/benchmarks/baselines/figureeight012.py @@ -0,0 +1,82 @@ +""" +Script to evaluate the baseline performance of figureeight without RL control +Baseline is human intersection behavior + +Trains a fraction of vehicles in a ring road structure to regulate the flow of +vehicles through an intersection. In this example, the last vehicle in the +network is an autonomous vehicle. + +Action Dimension: (1, ) + +Observation Dimension: (28, ) + +Horizon: 1500 steps +""" + +from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams +from flow.core.vehicles import Vehicles +from flow.controllers import IDMController, ContinuousRouter +from flow.scenarios.figure8.figure8_scenario import Figure8Scenario +from flow.scenarios.figure8.gen import Figure8Generator +from flow.scenarios.figure8.figure8_scenario import ADDITIONAL_NET_PARAMS +from flow.envs.loop.loop_accel import AccelEnv +from flow.core.experiment import SumoExperiment +import numpy as np + +# time horizon of a single rollout +HORIZON = 1500 + + +def figure_eight_baseline(num_runs, sumo_binary="sumo-gui"): + # We place 1 autonomous vehicle and 13 human-driven vehicles in the network + vehicles = Vehicles() + vehicles.add(veh_id="human", + acceleration_controller=(IDMController, {"noise": 0.2}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=14) + + sumo_params = SumoParams( + sim_step=0.1, + sumo_binary=sumo_binary, + ) + + env_params = EnvParams( + horizon=HORIZON, + evaluate=True, # Set to True to evaluate traffic metrics + additional_params={ + "target_velocity": 20, + "max_accel": 3, + "max_decel": 3, + }, + ) + + initial_config = InitialConfig() + + net_params = NetParams( + no_internal_links=False, + additional_params=ADDITIONAL_NET_PARAMS, + ) + + scenario = Figure8Scenario(name="figure_eight", + generator_class=Figure8Generator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) + + env = AccelEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + avg_speed = np.mean(results["mean_returns"]) + + return avg_speed + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = figure_eight_baseline(num_runs=runs) + + print('---------') + print('The average speed across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/figureeight{0,1,2}.py b/flow/benchmarks/baselines/figureeight{0,1,2}.py deleted file mode 100644 index a36b7b0b..00000000 --- a/flow/benchmarks/baselines/figureeight{0,1,2}.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Script to evaluate the baseline performance of figureeight without RL control -Baseline is human intersection behavior - -Trains a fraction of vehicles in a ring road structure to regulate the flow of -vehicles through an intersection. In this example, the last vehicle in the -network is an autonomous vehicle. - -Action Dimension: (1, ) - -Observation Dimension: (28, ) - -Horizon: 1500 steps -""" - -from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams -from flow.core.vehicles import Vehicles -from flow.controllers import IDMController, ContinuousRouter -from flow.scenarios.figure8.figure8_scenario import Figure8Scenario -from flow.scenarios.figure8.gen import Figure8Generator -from flow.scenarios.figure8.figure8_scenario import ADDITIONAL_NET_PARAMS -from flow.envs.loop.loop_accel import AccelEnv -from flow.core.experiment import SumoExperiment -import numpy as np - -# time horizon of a single rollout -HORIZON = 1500 - -# We place 1 autonomous vehicle and 13 human-driven vehicles in the network -vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=14) - -sumo_params = SumoParams( - sim_step=0.1, - sumo_binary="sumo-gui", -) - -env_params = EnvParams( - horizon=HORIZON, - evaluate=True, # Set to True to evaluate traffic metrics - additional_params={ - "target_velocity": 20, - "max_accel": 3, - "max_decel": 3, - }, -) - -initial_config = InitialConfig() - -net_params = NetParams( - no_internal_links=False, - additional_params=ADDITIONAL_NET_PARAMS, -) - -scenario = Figure8Scenario(name="figure_eight", - generator_class=Figure8Generator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) - -env = AccelEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -avg_speed = np.mean(results["mean_returns"]) -print('The average speed across {} runs is {}'.format(num_runs, avg_speed)) diff --git a/flow/benchmarks/baselines/grid0.py b/flow/benchmarks/baselines/grid0.py index d2cfe36d..6b2ec23e 100644 --- a/flow/benchmarks/baselines/grid0.py +++ b/flow/benchmarks/baselines/grid0.py @@ -41,98 +41,109 @@ # number of vehicles originating in the left, right, top, and bottom edges N_LEFT, N_RIGHT, N_TOP, N_BOTTOM = 1, 1, 1, 1 -# we place a sufficient number of vehicles to ensure they confirm with the -# total number specified above. We also use a "right_of_way" speed mode to -# support traffic light compliance -vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(SumoCarFollowingController, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, - max_speed=V_ENTER, - ), - routing_controller=(GridRouter, {}), - num_vehicles=(N_LEFT+N_RIGHT)*N_COLUMNS + (N_BOTTOM+N_TOP)*N_ROWS, - speed_mode="right_of_way") - -# inflows of vehicles are place on all outer edges (listed here) -outer_edges = [] -outer_edges += ["left{}_{}".format(N_ROWS, i) for i in range(N_COLUMNS)] -outer_edges += ["right0_{}".format(i) for i in range(N_ROWS)] -outer_edges += ["bot{}_0".format(i) for i in range(N_ROWS)] -outer_edges += ["top{}_{}".format(i, N_COLUMNS) for i in range(N_ROWS)] - -# equal inflows for each edge (as dictate by the EDGE_INFLOW constant) -inflow = InFlows() -for edge in outer_edges: - inflow.add(veh_type="human", edge=edge, vehs_per_hour=EDGE_INFLOW, - departLane="free", departSpeed="max") - -# define the traffic light logic -tl_logic = TrafficLights(baseline=False) -phases = [{"duration": "31", "minDur": "8", "maxDur": "45", - "state": "GGGrrrGGGrrr"}, - {"duration": "6", "minDur": "3", "maxDur": "6", - "state": "yyyrrryyyrrr"}, - {"duration": "31", "minDur": "8", "maxDur": "45", - "state": "rrrGGGrrrGGG"}, - {"duration": "6", "minDur": "3", "maxDur": "6", - "state": "rrryyyrrryyy"}] -for i in range(N_ROWS*N_COLUMNS): - tl_logic.add("center"+str(i), tls_type="actuated", phases=phases, - programID=1) - -net_params = NetParams( - in_flows=inflow, - no_internal_links=False, - additional_params={ - "speed_limit": V_ENTER + 5, - "grid_array": { - "short_length": SHORT_LENGTH, - "inner_length": INNER_LENGTH, - "long_length": LONG_LENGTH, - "row_num": N_ROWS, - "col_num": N_COLUMNS, - "cars_left": N_LEFT, - "cars_right": N_RIGHT, - "cars_top": N_TOP, - "cars_bot": N_BOTTOM, + +def grid0_baseline(num_runs, sumo_binary="sumo-gui"): + # we place a sufficient number of vehicles to ensure they confirm with the + # total number specified above. We also use a "right_of_way" speed mode to + # support traffic light compliance + vehicles = Vehicles() + vehicles.add(veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, + max_speed=V_ENTER, + ), + routing_controller=(GridRouter, {}), + num_vehicles=(N_LEFT+N_RIGHT)*N_COLUMNS + + (N_BOTTOM+N_TOP)*N_ROWS, + speed_mode="right_of_way") + + # inflows of vehicles are place on all outer edges (listed here) + outer_edges = [] + outer_edges += ["left{}_{}".format(N_ROWS, i) for i in range(N_COLUMNS)] + outer_edges += ["right0_{}".format(i) for i in range(N_ROWS)] + outer_edges += ["bot{}_0".format(i) for i in range(N_ROWS)] + outer_edges += ["top{}_{}".format(i, N_COLUMNS) for i in range(N_ROWS)] + + # equal inflows for each edge (as dictate by the EDGE_INFLOW constant) + inflow = InFlows() + for edge in outer_edges: + inflow.add(veh_type="human", edge=edge, vehs_per_hour=EDGE_INFLOW, + departLane="free", departSpeed="max") + + # define the traffic light logic + tl_logic = TrafficLights(baseline=False) + phases = [{"duration": "31", "minDur": "8", "maxDur": "45", + "state": "GGGrrrGGGrrr"}, + {"duration": "6", "minDur": "3", "maxDur": "6", + "state": "yyyrrryyyrrr"}, + {"duration": "31", "minDur": "8", "maxDur": "45", + "state": "rrrGGGrrrGGG"}, + {"duration": "6", "minDur": "3", "maxDur": "6", + "state": "rrryyyrrryyy"}] + for i in range(N_ROWS*N_COLUMNS): + tl_logic.add("center"+str(i), tls_type="actuated", phases=phases, + programID=1) + + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params={ + "speed_limit": V_ENTER + 5, + "grid_array": { + "short_length": SHORT_LENGTH, + "inner_length": INNER_LENGTH, + "long_length": LONG_LENGTH, + "row_num": N_ROWS, + "col_num": N_COLUMNS, + "cars_left": N_LEFT, + "cars_right": N_RIGHT, + "cars_top": N_TOP, + "cars_bot": N_BOTTOM, + }, + "horizontal_lanes": 1, + "vertical_lanes": 1, + }, + ) + + sumo_params = SumoParams( + restart_instance=False, + sim_step=1, + sumo_binary=sumo_binary, + ) + + env_params = EnvParams( + evaluate=True, # Set to True to evaluate traffic metrics + horizon=HORIZON, + additional_params={ + "switch_time": 2.0, + "num_observed": 2, + "tl_type": "actuated", }, - "horizontal_lanes": 1, - "vertical_lanes": 1, - }, - ) - -sumo_params = SumoParams( - restart_instance=False, - sim_step=1, - sumo_binary="sumo-gui", - ) - -env_params = EnvParams( - evaluate=True, # Set to True to evaluate traffic metrics - horizon=HORIZON, - additional_params={ - "switch_time": 2.0, - "num_observed": 2, - "tl_type": "actuated", - }, - ) - -initial_config = InitialConfig(shuffle=True) - -scenario = SimpleGridScenario(name="grid", - generator_class=SimpleGridGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=tl_logic) - -env = PO_TrafficLightGridEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -total_delay = np.mean(results["returns"]) -print('The total delay across {} runs is {}'.format(num_runs, total_delay)) + ) + + initial_config = InitialConfig(shuffle=True) + + scenario = SimpleGridScenario(name="grid", + generator_class=SimpleGridGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=tl_logic) + + env = PO_TrafficLightGridEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + total_delay = np.mean(results["returns"]) + + return total_delay + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = grid0_baseline(num_runs=runs) + + print('---------') + print('The total delay across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/grid1.py b/flow/benchmarks/baselines/grid1.py index da72337b..5f72c2aa 100644 --- a/flow/benchmarks/baselines/grid1.py +++ b/flow/benchmarks/baselines/grid1.py @@ -41,98 +41,109 @@ # number of vehicles originating in the left, right, top, and bottom edges N_LEFT, N_RIGHT, N_TOP, N_BOTTOM = 1, 1, 1, 1 -# we place a sufficient number of vehicles to ensure they confirm with the -# total number specified above. We also use a "right_of_way" speed mode to -# support traffic light compliance -vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(SumoCarFollowingController, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, - max_speed=V_ENTER, - ), - routing_controller=(GridRouter, {}), - num_vehicles=(N_LEFT+N_RIGHT)*N_COLUMNS + (N_BOTTOM+N_TOP)*N_ROWS, - speed_mode="right_of_way") - -# inflows of vehicles are place on all outer edges (listed here) -outer_edges = [] -outer_edges += ["left{}_{}".format(N_ROWS, i) for i in range(N_COLUMNS)] -outer_edges += ["right0_{}".format(i) for i in range(N_ROWS)] -outer_edges += ["bot{}_0".format(i) for i in range(N_ROWS)] -outer_edges += ["top{}_{}".format(i, N_COLUMNS) for i in range(N_ROWS)] - -# equal inflows for each edge (as dictate by the EDGE_INFLOW constant) -inflow = InFlows() -for edge in outer_edges: - inflow.add(veh_type="human", edge=edge, vehs_per_hour=EDGE_INFLOW, - departLane="free", departSpeed="max") - -# define the traffic light logic -tl_logic = TrafficLights(baseline=False) -phases = [{"duration": "31", "minDur": "8", "maxDur": "45", - "state": "GGGrrrGGGrrr"}, - {"duration": "6", "minDur": "3", "maxDur": "6", - "state": "yyyrrryyyrrr"}, - {"duration": "31", "minDur": "8", "maxDur": "45", - "state": "rrrGGGrrrGGG"}, - {"duration": "6", "minDur": "3", "maxDur": "6", - "state": "rrryyyrrryyy"}] -for i in range(N_ROWS*N_COLUMNS): - tl_logic.add("center"+str(i), tls_type="actuated", phases=phases, - programID=1) - -net_params = NetParams( - in_flows=inflow, - no_internal_links=False, - additional_params={ - "speed_limit": V_ENTER + 5, - "grid_array": { - "short_length": SHORT_LENGTH, - "inner_length": INNER_LENGTH, - "long_length": LONG_LENGTH, - "row_num": N_ROWS, - "col_num": N_COLUMNS, - "cars_left": N_LEFT, - "cars_right": N_RIGHT, - "cars_top": N_TOP, - "cars_bot": N_BOTTOM, + +def grid1_baseline(num_runs, sumo_binary="sumo-gui"): + # we place a sufficient number of vehicles to ensure they confirm with the + # total number specified above. We also use a "right_of_way" speed mode to + # support traffic light compliance + vehicles = Vehicles() + vehicles.add(veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, + max_speed=V_ENTER, + ), + routing_controller=(GridRouter, {}), + num_vehicles=(N_LEFT+N_RIGHT)*N_COLUMNS + + (N_BOTTOM+N_TOP)*N_ROWS, + speed_mode="right_of_way") + + # inflows of vehicles are place on all outer edges (listed here) + outer_edges = [] + outer_edges += ["left{}_{}".format(N_ROWS, i) for i in range(N_COLUMNS)] + outer_edges += ["right0_{}".format(i) for i in range(N_ROWS)] + outer_edges += ["bot{}_0".format(i) for i in range(N_ROWS)] + outer_edges += ["top{}_{}".format(i, N_COLUMNS) for i in range(N_ROWS)] + + # equal inflows for each edge (as dictate by the EDGE_INFLOW constant) + inflow = InFlows() + for edge in outer_edges: + inflow.add(veh_type="human", edge=edge, vehs_per_hour=EDGE_INFLOW, + departLane="free", departSpeed="max") + + # define the traffic light logic + tl_logic = TrafficLights(baseline=False) + phases = [{"duration": "31", "minDur": "8", "maxDur": "45", + "state": "GGGrrrGGGrrr"}, + {"duration": "6", "minDur": "3", "maxDur": "6", + "state": "yyyrrryyyrrr"}, + {"duration": "31", "minDur": "8", "maxDur": "45", + "state": "rrrGGGrrrGGG"}, + {"duration": "6", "minDur": "3", "maxDur": "6", + "state": "rrryyyrrryyy"}] + for i in range(N_ROWS*N_COLUMNS): + tl_logic.add("center"+str(i), tls_type="actuated", phases=phases, + programID=1) + + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params={ + "speed_limit": V_ENTER + 5, + "grid_array": { + "short_length": SHORT_LENGTH, + "inner_length": INNER_LENGTH, + "long_length": LONG_LENGTH, + "row_num": N_ROWS, + "col_num": N_COLUMNS, + "cars_left": N_LEFT, + "cars_right": N_RIGHT, + "cars_top": N_TOP, + "cars_bot": N_BOTTOM, + }, + "horizontal_lanes": 1, + "vertical_lanes": 1, + }, + ) + + sumo_params = SumoParams( + restart_instance=False, + sim_step=1, + sumo_binary=sumo_binary, + ) + + env_params = EnvParams( + evaluate=True, # Set to True to evaluate traffic metrics + horizon=HORIZON, + additional_params={ + "switch_time": 2.0, + "num_observed": 2, + "tl_type": "actuated", }, - "horizontal_lanes": 1, - "vertical_lanes": 1, - }, - ) - -sumo_params = SumoParams( - restart_instance=False, - sim_step=1, - sumo_binary="sumo-gui", - ) - -env_params = EnvParams( - evaluate=True, # Set to True to evaluate traffic metrics - horizon=HORIZON, - additional_params={ - "switch_time": 2.0, - "num_observed": 2, - "tl_type": "actuated", - }, - ) - -initial_config = InitialConfig(shuffle=True) - -scenario = SimpleGridScenario(name="grid", - generator_class=SimpleGridGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=tl_logic) - -env = PO_TrafficLightGridEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 2 -results = exp.run(num_runs, HORIZON) -total_delay = np.mean(results["returns"]) -print('The total delay across {} runs is {}'.format(num_runs, total_delay)) + ) + + initial_config = InitialConfig(shuffle=True) + + scenario = SimpleGridScenario(name="grid", + generator_class=SimpleGridGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=tl_logic) + + env = PO_TrafficLightGridEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + total_delay = np.mean(results["returns"]) + + return total_delay + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = grid1_baseline(num_runs=runs) + + print('---------') + print('The total delay across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/merge012.py b/flow/benchmarks/baselines/merge012.py new file mode 100644 index 00000000..953c2beb --- /dev/null +++ b/flow/benchmarks/baselines/merge012.py @@ -0,0 +1,108 @@ +""" +Script to evaluate the baseline performance of the merge scenario without AVs + +Trains a small percentage of autonomous vehicles to dissipate shockwaves caused +by merges in an open network. The autonomous penetration rate in this example +is 10%. + +Action Dimension: (5, ) + +Observation Dimension: (25, ) + +Horizon: 750 steps +""" + +from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams, \ + InFlows +from flow.scenarios.merge.scenario import ADDITIONAL_NET_PARAMS +from flow.core.vehicles import Vehicles +from flow.core.experiment import SumoExperiment +from flow.controllers import SumoCarFollowingController +from flow.scenarios.merge.scenario import MergeScenario +from flow.scenarios.merge.gen import MergeGenerator +from flow.envs.merge import WaveAttenuationMergePOEnv +import numpy as np + +# time horizon of a single rollout +HORIZON = int(750*(0.5/0.2)) +# inflow rate at the highway +FLOW_RATE = 2000 +# percent of autonomous vehicles +RL_PENETRATION = 0.1 +# num_rl term (see ADDITIONAL_ENV_PARAMs) +NUM_RL = 5 + + +def merge_baseline(num_runs, sumo_binary="sumo-gui"): + # We consider a highway network with an upstream merging lane producing + # shockwaves + additional_net_params = ADDITIONAL_NET_PARAMS.copy() + additional_net_params["merge_lanes"] = 1 + additional_net_params["highway_lanes"] = 1 + additional_net_params["pre_merge_length"] = 500 + + # RL vehicles constitute 5% of the total number of vehicles + vehicles = Vehicles() + vehicles.add(veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + speed_mode="no_collide", + num_vehicles=5) + + # Vehicles are introduced from both sides of merge, with RL vehicles + # entering from the highway portion as well + inflow = InFlows() + inflow.add(veh_type="human", edge="inflow_highway", + vehs_per_hour=FLOW_RATE, + departLane="free", departSpeed=10) + inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, + departLane="free", departSpeed=7.5) + + sumo_params = SumoParams( + restart_instance=False, + sim_step=0.2, # time step decreased to prevent occasional crashes + sumo_binary=sumo_binary, + ) + + env_params = EnvParams( + horizon=HORIZON, + sims_per_step=5, # value raised to ensure sec/step match experiment + warmup_steps=0, + evaluate=True, # Set to True to evaluate traffic metric performance + additional_params={ + "max_accel": 1.5, + "max_decel": 1.5, + "target_velocity": 20, + "num_rl": NUM_RL, + }, + ) + + initial_config = InitialConfig() + + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params, + ) + + scenario = MergeScenario(name="merge", + generator_class=MergeGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) + + env = WaveAttenuationMergePOEnv(env_params, sumo_params, scenario) + + exp = SumoExperiment(env, scenario) + + results = exp.run(num_runs, HORIZON) + avg_speed = np.mean(results["mean_returns"]) + + return avg_speed + + +if __name__ == "__main__": + runs = 2 # number of simulations to average over + res = merge_baseline(num_runs=runs) + + print('---------') + print('The average speed across {} runs is {}'.format(runs, res)) diff --git a/flow/benchmarks/baselines/merge{0,1,2}.py b/flow/benchmarks/baselines/merge{0,1,2}.py deleted file mode 100644 index 02123da4..00000000 --- a/flow/benchmarks/baselines/merge{0,1,2}.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -Script to evaluate the baseline performance of the merge scenario without AVs - -Trains a small percentage of autonomous vehicles to dissipate shockwaves caused -by merges in an open network. The autonomous penetration rate in this example -is 10%. - -Action Dimension: (5, ) - -Observation Dimension: (25, ) - -Horizon: 750 steps -""" - -from flow.core.params import SumoParams, EnvParams, InitialConfig, NetParams, \ - InFlows -from flow.scenarios.merge.scenario import ADDITIONAL_NET_PARAMS -from flow.core.vehicles import Vehicles -from flow.core.experiment import SumoExperiment -from flow.controllers import SumoCarFollowingController -from flow.scenarios.merge.scenario import MergeScenario -from flow.scenarios.merge.gen import MergeGenerator -from flow.envs.merge import WaveAttenuationMergePOEnv -import numpy as np - -# time horizon of a single rollout -HORIZON = int(750*(0.5/0.2)) -# inflow rate at the highway -FLOW_RATE = 2000 -# percent of autonomous vehicles -RL_PENETRATION = 0.1 -# num_rl term (see ADDITIONAL_ENV_PARAMs) -NUM_RL = 5 - -# We consider a highway network with an upstream merging lane producing -# shockwaves -additional_net_params = ADDITIONAL_NET_PARAMS.copy() -additional_net_params["merge_lanes"] = 1 -additional_net_params["highway_lanes"] = 1 -additional_net_params["pre_merge_length"] = 500 - -# RL vehicles constitute 5% of the total number of vehicles -vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(SumoCarFollowingController, {}), - speed_mode="no_collide", - num_vehicles=5) - -# Vehicles are introduced from both sides of merge, with RL vehicles entering -# from the highway portion as well -inflow = InFlows() -inflow.add(veh_type="human", edge="inflow_highway", - vehs_per_hour=FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) - -sumo_params = SumoParams( - restart_instance=False, - sim_step=0.2, # time step decreased to prevent occasional crashes - sumo_binary="sumo", -) - -env_params = EnvParams( - horizon=HORIZON, - sims_per_step=5, # value raised to ensure sec/step match experiment - warmup_steps=0, - evaluate=True, # Set to True to evaluate traffic metric performance - additional_params={ - "max_accel": 1.5, - "max_decel": 1.5, - "target_velocity": 20, - "num_rl": NUM_RL, - }, -) - -initial_config = InitialConfig() - -net_params = NetParams( - in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params, -) - -scenario = MergeScenario(name="merge", - generator_class=MergeGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) - -env = WaveAttenuationMergePOEnv(env_params, sumo_params, scenario) - -exp = SumoExperiment(env, scenario) - -num_runs = 5 -results = exp.run(num_runs, HORIZON) -avg_speed = np.mean(results["mean_returns"]) -print('The average speed across {} runs is {}'.format(num_runs, avg_speed)) diff --git a/tests/slow_tests/test_benchmarks.py b/tests/slow_tests/test_benchmarks.py new file mode 100644 index 00000000..39785f07 --- /dev/null +++ b/tests/slow_tests/test_benchmarks.py @@ -0,0 +1,102 @@ +import unittest +import os + +from flow.benchmarks.baselines.bottleneck0 import bottleneck0_baseline +from flow.benchmarks.baselines.bottleneck1 import bottleneck1_baseline +from flow.benchmarks.baselines.bottleneck2 import bottleneck2_baseline +from flow.benchmarks.baselines.figureeight012 import figure_eight_baseline +from flow.benchmarks.baselines.grid0 import grid0_baseline +from flow.benchmarks.baselines.grid1 import grid1_baseline +from flow.benchmarks.baselines.merge012 import merge_baseline + +os.environ["TEST_FLAG"] = "True" + + +class TestBaselines(unittest.TestCase): + + """ + Tests that the baselines in the benchmarks folder are running and + returning expected values (i.e. values that match those in the CoRL paper + reported on the website, or other). + """ + + def test_bottleneck0(self): + """ + Tests flow/benchmark/baselines/bottleneck0.py + """ + # run the bottleneck to make sure it runs + res = bottleneck0_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 400) + self.assertLessEqual(res, 1400) + + def test_bottleneck1(self): + """ + Tests flow/benchmark/baselines/bottleneck1.py + """ + # run the bottleneck to make sure it runs + res = bottleneck1_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 400) + self.assertLessEqual(res, 1400) + + def test_bottleneck2(self): + """ + Tests flow/benchmark/baselines/bottleneck2.py + """ + # run the bottleneck to make sure it runs + res = bottleneck2_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 1300) + self.assertLessEqual(res, 1700) + + def test_figure_eight(self): + """ + Tests flow/benchmark/baselines/figureeight{0,1,2}.py + """ + # run the bottleneck to make sure it runs + res = figure_eight_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 4.0) + self.assertLessEqual(res, 4.4) + + def test_grid0(self): + """ + Tests flow/benchmark/baselines/grid0.py + """ + # run the bottleneck to make sure it runs + res = grid0_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 34000) + self.assertLessEqual(res, 36000) + + def test_grid1(self): + """ + Tests flow/benchmark/baselines/grid1.py + """ + # run the bottleneck to make sure it runs + res = grid1_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 71000) + self.assertLessEqual(res, 73000) + + def test_merge(self): + """ + Tests flow/benchmark/baselines/merge{0,1,2}.py + """ + # run the bottleneck to make sure it runs + res = merge_baseline(num_runs=1, sumo_binary="sumo") + + # check that the resulting performance measure is within some range + self.assertGreaterEqual(res, 7.5) + self.assertLessEqual(res, 9.5) + + +if __name__ == '__main__': + unittest.main()