diff --git a/examples/rllab/cooperative_merge.py b/examples/rllab/cooperative_merge.py index ec185b30a..c8ce40f8a 100644 --- a/examples/rllab/cooperative_merge.py +++ b/examples/rllab/cooperative_merge.py @@ -30,41 +30,39 @@ def run_task(*_): # so place the merging vehicles after the vehicles in the ring vehicles = Vehicles() # Inner ring vehicles - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=6, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.0, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=6, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.0, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) # A single learning agent in the inner ring - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.01, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.01, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) # Outer ring vehicles - vehicles.add(veh_id="merge-human", - acceleration_controller=(IDMController, {"noise": 0.2}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=10, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.0, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) + vehicles.add( + veh_id="merge-human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=10, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.0, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) env_params = EnvParams( horizon=HORIZON, @@ -75,8 +73,7 @@ def run_task(*_): "n_preceding": 2, "n_following": 2, "n_merging_in": 2, - } - ) + }) additional_net_params = ADDITIONAL_NET_PARAMS.copy() additional_net_params["ring_radius"] = 50 @@ -84,36 +81,27 @@ def run_task(*_): additional_net_params["outer_lanes"] = 1 additional_net_params["lane_length"] = 75 net_params = NetParams( - no_internal_links=False, - additional_params=additional_net_params - ) + no_internal_links=False, additional_params=additional_net_params) initial_config = InitialConfig( - x0=50, - spacing="uniform", - additional_params={"merge_bunching": 0} - ) + x0=50, spacing="uniform", additional_params={"merge_bunching": 0}) scenario = TwoLoopsOneMergingScenario( name=exp_tag, generator_class=TwoLoopOneMergingGenerator, vehicles=vehicles, net_params=net_params, - initial_config=initial_config - ) + initial_config=initial_config) env_name = "TwoLoopsMergePOEnv" - pass_params = (env_name, sumo_params, vehicles, env_params, - net_params, initial_config, scenario) + pass_params = (env_name, sumo_params, vehicles, env_params, net_params, + initial_config, scenario) env = GymEnv(env_name, record_video=False, register_params=pass_params) horizon = env.horizon env = normalize(env) - policy = GaussianMLPPolicy( - env_spec=env.spec, - hidden_sizes=(100, 50, 25) - ) + policy = GaussianMLPPolicy(env_spec=env.spec, hidden_sizes=(100, 50, 25)) baseline = LinearFeatureBaseline(env_spec=env.spec) diff --git a/examples/rllab/figure_eight.py b/examples/rllab/figure_eight.py index 10c04cbcc..2defcdf74 100644 --- a/examples/rllab/figure_eight.py +++ b/examples/rllab/figure_eight.py @@ -18,36 +18,50 @@ def run_task(*_): - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo-gui") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo-gui") vehicles = Vehicles() - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {"noise": 0.2}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=13) - - additional_env_params = {"target_velocity": 20, - "max_accel": 3, "max_decel": 3} - env_params = EnvParams(horizon=HORIZON, - additional_params=additional_env_params) - - additional_net_params = {"radius_ring": 30, "lanes": 1, "speed_limit": 30, - "resolution": 40} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=13) + + additional_env_params = { + "target_velocity": 20, + "max_accel": 3, + "max_decel": 3 + } + env_params = EnvParams( + horizon=HORIZON, additional_params=additional_env_params) + + additional_net_params = { + "radius_ring": 30, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) initial_config = InitialConfig(spacing="uniform") print("XXX name", exp_tag) - scenario = Figure8Scenario(exp_tag, Figure8Generator, vehicles, net_params, - initial_config=initial_config) + scenario = Figure8Scenario( + exp_tag, + Figure8Generator, + vehicles, + net_params, + initial_config=initial_config) env_name = "AccelEnv" pass_params = (env_name, sumo_params, vehicles, env_params, net_params, @@ -57,10 +71,7 @@ def run_task(*_): horizon = env.horizon env = normalize(env) - policy = GaussianMLPPolicy( - env_spec=env.spec, - hidden_sizes=(16, 16) - ) + policy = GaussianMLPPolicy(env_spec=env.spec, hidden_sizes=(16, 16)) baseline = LinearFeatureBaseline(env_spec=env.spec) diff --git a/examples/rllab/green_wave.py b/examples/rllab/green_wave.py index 43128ba64..e7cadd008 100644 --- a/examples/rllab/green_wave.py +++ b/examples/rllab/green_wave.py @@ -33,20 +33,23 @@ def gen_edges(row_num, col_num): def get_flow_params(v_enter, vehs_per_hour, col_num, row_num, additional_net_params): - initial_config = InitialConfig(spacing="uniform", - lanes_distribution=float("inf"), - shuffle=True) + initial_config = InitialConfig( + spacing="uniform", lanes_distribution=float("inf"), shuffle=True) inflow = InFlows() outer_edges = gen_edges(col_num, row_num) for i in range(len(outer_edges)): - inflow.add(veh_type="idm", edge=outer_edges[i], - vehs_per_hour=vehs_per_hour, - departLane="free", departSpeed=v_enter) - - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) + inflow.add( + veh_type="idm", + edge=outer_edges[i], + vehs_per_hour=vehs_per_hour, + departLane="free", + departSpeed=v_enter) + + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) return initial_config, net_params @@ -54,8 +57,8 @@ def get_flow_params(v_enter, vehs_per_hour, col_num, row_num, def get_non_flow_params(enter_speed, additional_net_params): additional_init_params = {"enter_speed": enter_speed} initial_config = InitialConfig(additional_params=additional_init_params) - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) return initial_config, net_params @@ -74,43 +77,56 @@ def run_task(*_): tot_cars = (num_cars_left + num_cars_right) * m \ + (num_cars_bot + num_cars_top) * n - grid_array = {"short_length": short_length, "inner_length": inner_length, - "long_length": long_length, "row_num": n, "col_num": m, - "cars_left": num_cars_left, "cars_right": num_cars_right, - "cars_top": num_cars_top, "cars_bot": num_cars_bot} + grid_array = { + "short_length": short_length, + "inner_length": inner_length, + "long_length": long_length, + "row_num": n, + "col_num": m, + "cars_left": num_cars_left, + "cars_right": num_cars_right, + "cars_top": num_cars_top, + "cars_bot": num_cars_bot + } - sumo_params = SumoParams(sim_step=1, - sumo_binary="sumo-gui") + sumo_params = SumoParams(sim_step=1, sumo_binary="sumo-gui") vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(SumoCarFollowingController, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, - tau=1.1, - max_speed=v_enter), - routing_controller=(GridRouter, {}), - num_vehicles=tot_cars, - speed_mode="all_checks") + vehicles.add( + veh_id="idm", + acceleration_controller=(SumoCarFollowingController, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, tau=1.1, max_speed=v_enter), + routing_controller=(GridRouter, {}), + num_vehicles=tot_cars, + speed_mode="all_checks") tl_logic = TrafficLights(baseline=False) - additional_env_params = {"target_velocity": 50, "num_steps": 500, - "switch_time": 3.0} + additional_env_params = { + "target_velocity": 50, + "num_steps": 500, + "switch_time": 3.0 + } env_params = EnvParams(additional_params=additional_env_params) - additional_net_params = {"speed_limit": 35, "grid_array": grid_array, - "horizontal_lanes": 1, "vertical_lanes": 1} + additional_net_params = { + "speed_limit": 35, + "grid_array": grid_array, + "horizontal_lanes": 1, + "vertical_lanes": 1 + } initial_config, net_params = get_flow_params(10, 300, n, m, additional_net_params) - scenario = SimpleGridScenario(name="grid-intersection", - generator_class=SimpleGridGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=tl_logic) + scenario = SimpleGridScenario( + name="grid-intersection", + generator_class=SimpleGridGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=tl_logic) env_name = "PO_TrafficLightGridEnv" pass_params = (env_name, sumo_params, vehicles, env_params, net_params, @@ -120,10 +136,7 @@ def run_task(*_): horizon = env.horizon env = normalize(env) - policy = GaussianMLPPolicy( - env_spec=env.spec, - hidden_sizes=(32, 32) - ) + policy = GaussianMLPPolicy(env_spec=env.spec, hidden_sizes=(32, 32)) baseline = LinearFeatureBaseline(env_spec=env.spec) diff --git a/examples/rllab/stabilizing_highway.py b/examples/rllab/stabilizing_highway.py index d25c3fa96..374f48288 100644 --- a/examples/rllab/stabilizing_highway.py +++ b/examples/rllab/stabilizing_highway.py @@ -39,56 +39,76 @@ def run_task(_): - sumo_params = SumoParams(sumo_binary="sumo-gui", - sim_step=0.2, - restart_instance=True) + sumo_params = SumoParams( + sumo_binary="sumo-gui", sim_step=0.2, restart_instance=True) # RL vehicles constitute 5% of the total number of vehicles vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - speed_mode="no_collide", - num_vehicles=5) - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + speed_mode="no_collide", + num_vehicles=5) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) # 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=(1-RL_PENETRATION) * FLOW_RATE, - departLane="free", departSpeed=10) - inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=RL_PENETRATION * FLOW_RATE, - departLane="free", departSpeed=10) - inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) - - additional_env_params = {"target_velocity": 25, "num_rl": NUM_RL, - "max_accel": 1.5, "max_decel": 1.5} - env_params = EnvParams(horizon=HORIZON, - sims_per_step=5, - warmup_steps=0, - additional_params=additional_env_params) + inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=(1 - RL_PENETRATION) * FLOW_RATE, + departLane="free", + departSpeed=10) + inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=RL_PENETRATION * FLOW_RATE, + departLane="free", + departSpeed=10) + inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) + + additional_env_params = { + "target_velocity": 25, + "num_rl": NUM_RL, + "max_accel": 1.5, + "max_decel": 1.5 + } + env_params = EnvParams( + horizon=HORIZON, + sims_per_step=5, + warmup_steps=0, + additional_params=additional_env_params) 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 - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) - initial_config = InitialConfig(spacing="uniform", - lanes_distribution=float("inf")) + initial_config = InitialConfig( + spacing="uniform", lanes_distribution=float("inf")) - scenario = MergeScenario(name="merge-rl", - generator_class=MergeGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = MergeScenario( + name="merge-rl", + generator_class=MergeGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env_name = "WaveAttenuationMergePOEnv" pass_params = (env_name, sumo_params, vehicles, env_params, net_params, @@ -108,7 +128,7 @@ def run_task(_): env=env, policy=policy, baseline=baseline, - batch_size=HORIZON*N_ROLLOUTS, + batch_size=HORIZON * N_ROLLOUTS, max_path_length=HORIZON, n_itr=1000, # whole_paths=True, diff --git a/examples/rllab/stabilizing_the_ring.py b/examples/rllab/stabilizing_the_ring.py index 8ada31b65..390e3145f 100644 --- a/examples/rllab/stabilizing_the_ring.py +++ b/examples/rllab/stabilizing_the_ring.py @@ -22,31 +22,45 @@ def run_task(*_): sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo", seed=0) vehicles = Vehicles() - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=1) - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=21) - - additional_env_params = {"target_velocity": 8, - "ring_length": [220, 270], - "max_accel": 1, "max_decel": 1} - env_params = EnvParams(horizon=HORIZON, - additional_params=additional_env_params, - warmup_steps=750) - - additional_net_params = {"length": 260, "lanes": 1, "speed_limit": 30, - "resolution": 40} + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=21) + + additional_env_params = { + "target_velocity": 8, + "ring_length": [220, 270], + "max_accel": 1, + "max_decel": 1 + } + env_params = EnvParams( + horizon=HORIZON, + additional_params=additional_env_params, + warmup_steps=750) + + additional_net_params = { + "length": 260, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) initial_config = InitialConfig(spacing="uniform", bunching=50) print("XXX name", exp_tag) - scenario = LoopScenario(exp_tag, CircleGenerator, vehicles, net_params, - initial_config=initial_config) + scenario = LoopScenario( + exp_tag, + CircleGenerator, + vehicles, + net_params, + initial_config=initial_config) env_name = "WaveAttenuationPOEnv" pass_params = (env_name, sumo_params, vehicles, env_params, net_params, @@ -58,7 +72,7 @@ def run_task(*_): policy = GaussianGRUPolicy( env_spec=env.spec, - hidden_sizes=(5,), + hidden_sizes=(5, ), ) baseline = LinearFeatureBaseline(env_spec=env.spec) diff --git a/examples/rllab/velocity_bottleneck.py b/examples/rllab/velocity_bottleneck.py index c064e0ae1..2fece113f 100644 --- a/examples/rllab/velocity_bottleneck.py +++ b/examples/rllab/velocity_bottleneck.py @@ -28,60 +28,71 @@ PARALLEL_ROLLOUTS = 32 i = 0 -sumo_params = SumoParams(sim_step=0.5, sumo_binary="sumo", - restart_instance=True) +sumo_params = SumoParams( + sim_step=0.5, sumo_binary="sumo", restart_instance=True) vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode=9, - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, # 1621,#0b100000101, - num_vehicles=1 * SCALING) -vehicles.add(veh_id="followerstopper", - acceleration_controller=(RLController, - {"fail_safe": "instantaneous"}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * SCALING) +vehicles.add( + veh_id="human", + speed_mode=9, + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, # 1621,#0b100000101, + num_vehicles=1 * SCALING) +vehicles.add( + veh_id="followerstopper", + acceleration_controller=(RLController, { + "fail_safe": "instantaneous" + }), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + lane_change_mode=0, + num_vehicles=1 * SCALING) horizon = 1000 # edge name, how many segments to observe/control, whether the segment is # controlled 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] - } -env_params = EnvParams(additional_params=additional_env_params, - warmup_steps=40, - sims_per_step=2, horizon=horizon) +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] +} +env_params = EnvParams( + additional_params=additional_env_params, + warmup_steps=40, + sims_per_step=2, + horizon=horizon) flow_rate = 1500 * SCALING print('flow rate is ', flow_rate) env_name = "DesiredVelocityEnv" inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * (1 - AV_FRAC), - departLane="random", departSpeed=10) -inflow.add(veh_type="followerstopper", edge="1", - vehs_per_hour=flow_rate * (AV_FRAC), - departLane="random", departSpeed=10) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * (1 - AV_FRAC), + departLane="random", + departSpeed=10) +inflow.add( + veh_type="followerstopper", + edge="1", + vehs_per_hour=flow_rate * (AV_FRAC), + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -90,33 +101,34 @@ 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) - -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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_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) def run_task(*_): - pass_params = (env_name, sumo_params, vehicles, env_params, - net_params, initial_config, scenario) + pass_params = (env_name, sumo_params, vehicles, env_params, net_params, + initial_config, scenario) env = GymEnv(env_name, record_video=False, register_params=pass_params) horizon = env.horizon env = normalize(env) - policy = GaussianGRUPolicy( - env_spec=env.spec, - hidden_sizes=(64,) - ) + policy = GaussianGRUPolicy(env_spec=env.spec, hidden_sizes=(64, )) baseline = LinearFeatureBaseline(env_spec=env.spec) @@ -149,5 +161,4 @@ def run_task(*_): mode="local", exp_prefix=exp_tag, # plot=True, - sync_s3_pkl=True - ) + sync_s3_pkl=True) diff --git a/examples/rllib/cooperative_merge.py b/examples/rllib/cooperative_merge.py index e48aedc3c..8b0634cab 100644 --- a/examples/rllib/cooperative_merge.py +++ b/examples/rllib/cooperative_merge.py @@ -34,39 +34,37 @@ # so place the merging vehicles after the vehicles in the ring vehicles = Vehicles() # Inner ring vehicles -vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=6, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.0, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) +vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=6, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.0, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) # A single learning agent in the inner ring -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.01, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.01, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) # Outer ring vehicles -vehicles.add(veh_id="merge-human", - acceleration_controller=(IDMController, {"noise": 0.2}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=10, - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.0, - tau=0.5 - ), - sumo_lc_params=SumoLaneChangeParams()) +vehicles.add( + veh_id="merge-human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=10, + sumo_car_following_params=SumoCarFollowingParams(minGap=0.0, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) flow_params = dict( # name of the experiment @@ -129,7 +127,6 @@ ), ) - if __name__ == "__main__": ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=False) @@ -146,8 +143,8 @@ config["horizon"] = HORIZON # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(params=flow_params, version=0) diff --git a/examples/rllib/figure_eight.py b/examples/rllib/figure_eight.py index b4febd380..5230becee 100644 --- a/examples/rllib/figure_eight.py +++ b/examples/rllib/figure_eight.py @@ -25,16 +25,20 @@ # We place one 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=13) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) +vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=13) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) flow_params = dict( # name of the experiment @@ -81,7 +85,6 @@ initial=InitialConfig(), ) - if __name__ == "__main__": ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=False) @@ -99,8 +102,8 @@ config["observation_filter"] = "NoFilter" # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(params=flow_params, version=0) diff --git a/examples/rllib/green_wave.py b/examples/rllib/green_wave.py index ceef48a2b..0090dfe19 100644 --- a/examples/rllib/green_wave.py +++ b/examples/rllib/green_wave.py @@ -39,19 +39,23 @@ def gen_edges(row_num, col_num): def get_flow_params(col_num, row_num, additional_net_params): - initial_config = InitialConfig(spacing="uniform", - lanes_distribution=float("inf"), - shuffle=True) + initial_config = InitialConfig( + spacing="uniform", lanes_distribution=float("inf"), shuffle=True) inflow = InFlows() outer_edges = gen_edges(col_num, row_num) for i in range(len(outer_edges)): - inflow.add(veh_type="idm", edge=outer_edges[i], probability=0.25, - departLane="free", departSpeed=20) - - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) + inflow.add( + veh_type="idm", + edge=outer_edges[i], + probability=0.25, + departLane="free", + departSpeed=20) + + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) return initial_config, net_params @@ -59,8 +63,8 @@ def get_flow_params(col_num, row_num, additional_net_params): def get_non_flow_params(enter_speed, additional_net_params): additional_init_params = {"enter_speed": enter_speed} initial_config = InitialConfig(additional_params=additional_init_params) - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) return initial_config, net_params @@ -80,32 +84,43 @@ def get_non_flow_params(enter_speed, additional_net_params): tot_cars = (num_cars_left + num_cars_right) * m \ + (num_cars_bot + num_cars_top) * n -grid_array = {"short_length": short_length, "inner_length": inner_length, - "long_length": long_length, "row_num": n, "col_num": m, - "cars_left": num_cars_left, "cars_right": num_cars_right, - "cars_top": num_cars_top, "cars_bot": num_cars_bot, - "rl_veh": rl_veh} +grid_array = { + "short_length": short_length, + "inner_length": inner_length, + "long_length": long_length, + "row_num": n, + "col_num": m, + "cars_left": num_cars_left, + "cars_right": num_cars_right, + "cars_top": num_cars_top, + "cars_bot": num_cars_bot, + "rl_veh": rl_veh +} additional_env_params = {"target_velocity": 50, "switch_time": 3.0} -additional_net_params = {"speed_limit": 35, "grid_array": grid_array, - "horizontal_lanes": 1, "vertical_lanes": 1} +additional_net_params = { + "speed_limit": 35, + "grid_array": grid_array, + "horizontal_lanes": 1, + "vertical_lanes": 1 +} vehicles = Vehicles() -vehicles.add(veh_id="idm", - acceleration_controller=(SumoCarFollowingController, {}), - sumo_car_following_params=SumoCarFollowingParams( - minGap=2.5, - max_speed=v_enter, - ), - routing_controller=(GridRouter, {}), - num_vehicles=tot_cars, - speed_mode="all_checks") +vehicles.add( + veh_id="idm", + acceleration_controller=(SumoCarFollowingController, {}), + sumo_car_following_params=SumoCarFollowingParams( + minGap=2.5, + max_speed=v_enter, + ), + routing_controller=(GridRouter, {}), + num_vehicles=tot_cars, + speed_mode="all_checks") initial_config, net_params = \ get_non_flow_params(v_enter, additional_net_params) - flow_params = dict( # name of the experiment exp_tag="green_wave", @@ -144,7 +159,6 @@ def get_non_flow_params(enter_speed, additional_net_params): initial=initial_config, ) - if __name__ == "__main__": ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=True) @@ -163,8 +177,8 @@ def get_non_flow_params(enter_speed, additional_net_params): config["horizon"] = HORIZON # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(params=flow_params, version=0) diff --git a/examples/rllib/merge_two_level_policy.py b/examples/rllib/merge_two_level_policy.py index 99c62d43a..fd476e387 100644 --- a/examples/rllib/merge_two_level_policy.py +++ b/examples/rllib/merge_two_level_policy.py @@ -15,7 +15,6 @@ def choose_policy(inputs): return tf.cast(inputs[:, 7] > 0.482496, tf.int32) """ - if __name__ == "__main__": config = ppo.DEFAULT_CONFIG.copy() horizon = HORIZON @@ -37,9 +36,11 @@ def choose_policy(inputs): # Two-level policy parameters config["model"].update({"fcnet_hiddens": [32, 32]}) - options = {"num_subpolicies": 2, - "fn_choose_subpolicy": fn_choose_subpolicy, - "hierarchical_fcnet_hiddens": [[32, 32]] * 2} + options = { + "num_subpolicies": 2, + "fn_choose_subpolicy": fn_choose_subpolicy, + "hierarchical_fcnet_hiddens": [[32, 32]] * 2 + } config["model"].update({"custom_options": options}) flow_env_name = "TwoLoopsMergePOEnv" @@ -48,11 +49,13 @@ def choose_policy(inputs): flow_params["flowenv"] = flow_env_name flow_params["exp_tag"] = exp_tag flow_params["module"] = os.path.basename(__file__)[:-3] - config['model']['custom_options'].update({'flowenv': flow_env_name, - 'exp_tag': exp_tag, - 'module': this_file}) - create_env, env_name = make_create_env(flow_env_name, flow_params, - version=0, exp_tag=exp_tag) + config['model']['custom_options'].update({ + 'flowenv': flow_env_name, + 'exp_tag': exp_tag, + 'module': this_file + }) + create_env, env_name = make_create_env( + flow_env_name, flow_params, version=0, exp_tag=exp_tag) # Register as rllib env register_rllib_env(env_name, create_env) diff --git a/examples/rllib/ring_two_level_policy.py b/examples/rllib/ring_two_level_policy.py index f8e642fe5..cc8cde4e4 100644 --- a/examples/rllib/ring_two_level_policy.py +++ b/examples/rllib/ring_two_level_policy.py @@ -18,7 +18,6 @@ def choose_policy(inputs): return tf.cast(inputs[:, 0] > 1e6, tf.int32) """ - if __name__ == "__main__": config = ppo.DEFAULT_CONFIG.copy() horizon = 100 @@ -30,12 +29,13 @@ def choose_policy(inputs): config["gamma"] = 0.999 config["horizon"] = horizon - config["model"].update( - {"fcnet_hiddens": [5, 5]}) + config["model"].update({"fcnet_hiddens": [5, 5]}) - options = {"num_subpolicies": 2, - "fn_choose_subpolicy": fn_choose_subpolicy, - "hierarchical_fcnet_hiddens": [[32, 32]] * 2} + options = { + "num_subpolicies": 2, + "fn_choose_subpolicy": fn_choose_subpolicy, + "hierarchical_fcnet_hiddens": [[32, 32]] * 2 + } config["model"].update({"custom_options": options}) # config["model"].update( diff --git a/examples/rllib/stabilizing_highway.py b/examples/rllib/stabilizing_highway.py index 608e78e21..a84ab10ba 100644 --- a/examples/rllib/stabilizing_highway.py +++ b/examples/rllib/stabilizing_highway.py @@ -46,26 +46,40 @@ # RL vehicles constitute 5% of the total number of vehicles vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - speed_mode="no_collide", - num_vehicles=5) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) +vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + speed_mode="no_collide", + num_vehicles=5) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) # 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=(1 - RL_PENETRATION) * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=RL_PENETRATION * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) +inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=(1 - RL_PENETRATION) * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=RL_PENETRATION * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) flow_params = dict( # name of the experiment @@ -116,7 +130,6 @@ initial=InitialConfig(), ) - if __name__ == "__main__": ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=True) @@ -133,8 +146,8 @@ config["horizon"] = HORIZON # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(params=flow_params, version=0) diff --git a/examples/rllib/stabilizing_the_ring.py b/examples/rllib/stabilizing_the_ring.py index 9eab3f5e1..3fa691d92 100644 --- a/examples/rllib/stabilizing_the_ring.py +++ b/examples/rllib/stabilizing_the_ring.py @@ -25,14 +25,18 @@ # We place one autonomous vehicle and 22 human-driven vehicles in the network vehicles = Vehicles() -vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=21) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=1) +vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + num_vehicles=21) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=1) flow_params = dict( # name of the experiment @@ -72,8 +76,7 @@ "lanes": 1, "speed_limit": 30, "resolution": 40, - }, - ), + }, ), # vehicles to be placed in the network at the start of a rollout (see # flow.core.vehicles.Vehicles) @@ -84,7 +87,6 @@ initial=InitialConfig(), ) - if __name__ == "__main__": ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=True) @@ -101,8 +103,8 @@ config["horizon"] = HORIZON # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(params=flow_params, version=0) diff --git a/examples/rllib/velocity_bottleneck.py b/examples/rllib/velocity_bottleneck.py index 0e7d265f9..f504d2bd7 100644 --- a/examples/rllib/velocity_bottleneck.py +++ b/examples/rllib/velocity_bottleneck.py @@ -32,24 +32,25 @@ AV_FRAC = 0.10 vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode="all_checks", - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, - num_vehicles=1 * SCALING) -vehicles.add(veh_id="followerstopper", - acceleration_controller=(RLController, {}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * SCALING) +vehicles.add( + veh_id="human", + speed_mode="all_checks", + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, + num_vehicles=1 * SCALING) +vehicles.add( + veh_id="followerstopper", + acceleration_controller=(RLController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + 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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -69,12 +70,18 @@ # percentage of flow coming out of each lane inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * (1 - AV_FRAC), - departLane="random", departSpeed=10) -inflow.add(veh_type="followerstopper", edge="1", - vehs_per_hour=flow_rate * AV_FRAC, - departLane="random", departSpeed=10) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * (1 - AV_FRAC), + departLane="random", + departSpeed=10) +inflow.add( + veh_type="followerstopper", + edge="1", + vehs_per_hour=flow_rate * AV_FRAC, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -83,9 +90,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) flow_params = dict( # name of the experiment @@ -142,7 +150,6 @@ tls=traffic_lights, ) - if __name__ == '__main__': ray.init(num_cpus=PARALLEL_ROLLOUTS, redirect_output=True) @@ -158,8 +165,8 @@ config["horizon"] = HORIZON # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json create_env, env_name = make_create_env(flow_params, version=0) diff --git a/examples/sumo/bay_bridge.py b/examples/sumo/bay_bridge.py index 7aba3185f..e2cb4072a 100644 --- a/examples/sumo/bay_bridge.py +++ b/examples/sumo/bay_bridge.py @@ -12,8 +12,8 @@ from flow.scenarios.bay_bridge.scenario import BayBridgeScenario from flow.controllers import SumoCarFollowingController, BayBridgeRouter -NETFILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), - "bay_bridge.net.xml") +NETFILE = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "bay_bridge.net.xml") def bay_bridge_example(sumo_binary=None, @@ -38,30 +38,30 @@ def bay_bridge_example(sumo_binary=None, A non-rl experiment demonstrating the performance of human-driven vehicles simulated by sumo on the Bay Bridge. """ - sumo_params = SumoParams(sim_step=0.6, - overtake_right=True) + sumo_params = SumoParams(sim_step=0.6, overtake_right=True) if sumo_binary is not None: sumo_params.sumo_binary = sumo_binary sumo_car_following_params = SumoCarFollowingParams(speedDev=0.2) sumo_lc_params = SumoLaneChangeParams( - lcAssertive=20, - lcPushy=0.8, - lcSpeedGain=4.0, - model="LC2013", - # lcKeepRight=0.8 + lcAssertive=20, + lcPushy=0.8, + lcSpeedGain=4.0, + model="LC2013", + # lcKeepRight=0.8 ) vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(SumoCarFollowingController, {}), - routing_controller=(BayBridgeRouter, {}), - speed_mode="all_checks", - lane_change_mode="no_lat_collide", - sumo_car_following_params=sumo_car_following_params, - sumo_lc_params=sumo_lc_params, - num_vehicles=1400) + vehicles.add( + veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + routing_controller=(BayBridgeRouter, {}), + speed_mode="all_checks", + lane_change_mode="no_lat_collide", + sumo_car_following_params=sumo_car_following_params, + sumo_lc_params=sumo_lc_params, + num_vehicles=1400) additional_env_params = {} env_params = EnvParams(additional_params=additional_env_params) @@ -72,42 +72,93 @@ def bay_bridge_example(sumo_binary=None, if use_inflows: # south - inflow.add(veh_type="human", edge="183343422", vehsPerHour=528, - departLane="0", departSpeed=20) - inflow.add(veh_type="human", edge="183343422", vehsPerHour=864, - departLane="1", departSpeed=20) - inflow.add(veh_type="human", edge="183343422", vehsPerHour=600, - departLane="2", departSpeed=20) - - inflow.add(veh_type="human", edge="393649534", probability=0.1, - departLane="0", departSpeed=20) # no data for this + inflow.add( + veh_type="human", + edge="183343422", + vehsPerHour=528, + departLane="0", + departSpeed=20) + inflow.add( + veh_type="human", + edge="183343422", + vehsPerHour=864, + departLane="1", + departSpeed=20) + inflow.add( + veh_type="human", + edge="183343422", + vehsPerHour=600, + departLane="2", + departSpeed=20) + + inflow.add( + veh_type="human", + edge="393649534", + probability=0.1, + departLane="0", + departSpeed=20) # no data for this # west - inflow.add(veh_type="human", edge="11189946", vehsPerHour=1752, - departLane="0", departSpeed=20) - inflow.add(veh_type="human", edge="11189946", vehsPerHour=2136, - departLane="1", departSpeed=20) - inflow.add(veh_type="human", edge="11189946", vehsPerHour=576, - departLane="2", departSpeed=20) + inflow.add( + veh_type="human", + edge="11189946", + vehsPerHour=1752, + departLane="0", + departSpeed=20) + inflow.add( + veh_type="human", + edge="11189946", + vehsPerHour=2136, + departLane="1", + departSpeed=20) + inflow.add( + veh_type="human", + edge="11189946", + vehsPerHour=576, + departLane="2", + departSpeed=20) # north - inflow.add(veh_type="human", edge="28413687#0", vehsPerHour=2880, - departLane="0", departSpeed=20) - inflow.add(veh_type="human", edge="28413687#0", vehsPerHour=2328, - departLane="1", departSpeed=20) - inflow.add(veh_type="human", edge="28413687#0", vehsPerHour=3060, - departLane="2", departSpeed=20) - inflow.add(veh_type="human", edge="11198593", probability=0.1, - departLane="0", departSpeed=20) # no data for this - inflow.add(veh_type="human", edge="11197889", probability=0.1, - departLane="0", departSpeed=20) # no data for this + inflow.add( + veh_type="human", + edge="28413687#0", + vehsPerHour=2880, + departLane="0", + departSpeed=20) + inflow.add( + veh_type="human", + edge="28413687#0", + vehsPerHour=2328, + departLane="1", + departSpeed=20) + inflow.add( + veh_type="human", + edge="28413687#0", + vehsPerHour=3060, + departLane="2", + departSpeed=20) + inflow.add( + veh_type="human", + edge="11198593", + probability=0.1, + departLane="0", + departSpeed=20) # no data for this + inflow.add( + veh_type="human", + edge="11197889", + probability=0.1, + departLane="0", + departSpeed=20) # no data for this # midway through bridge - inflow.add(veh_type="human", edge="35536683", probability=0.1, - departLane="0", departSpeed=20) # no data for this - - net_params = NetParams(in_flows=inflow, - no_internal_links=False) + inflow.add( + veh_type="human", + edge="35536683", + probability=0.1, + departLane="0", + departSpeed=20) # no data for this + + net_params = NetParams(in_flows=inflow, no_internal_links=False) net_params.netfile = NETFILE # download the netfile from AWS @@ -120,19 +171,20 @@ def bay_bridge_example(sumo_binary=None, my_file = urllib.request.urlopen(my_url) data_to_write = my_file.read() - with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), - NETFILE), "wb+") as f: + with open( + os.path.join(os.path.dirname(os.path.abspath(__file__)), NETFILE), + "wb+") as f: f.write(data_to_write) - initial_config = InitialConfig(spacing="uniform", - min_gap=15) + initial_config = InitialConfig(spacing="uniform", min_gap=15) - scenario = BayBridgeScenario(name="bay_bridge", - generator_class=BayBridgeGenerator, - vehicles=vehicles, - traffic_lights=traffic_lights, - net_params=net_params, - initial_config=initial_config) + scenario = BayBridgeScenario( + name="bay_bridge", + generator_class=BayBridgeGenerator, + vehicles=vehicles, + traffic_lights=traffic_lights, + net_params=net_params, + initial_config=initial_config) env = BayBridgeEnv(env_params, sumo_params, scenario) @@ -141,9 +193,8 @@ def bay_bridge_example(sumo_binary=None, if __name__ == "__main__": # import the experiment variable - exp = bay_bridge_example(sumo_binary="sumo-gui", - use_inflows=False, - use_traffic_lights=False) + exp = bay_bridge_example( + sumo_binary="sumo-gui", use_inflows=False, use_traffic_lights=False) # run for a set number of rollouts / time steps exp.run(1, 1500) diff --git a/examples/sumo/bay_bridge_toll.py b/examples/sumo/bay_bridge_toll.py index c632834b1..d1fb652ac 100644 --- a/examples/sumo/bay_bridge_toll.py +++ b/examples/sumo/bay_bridge_toll.py @@ -11,12 +11,11 @@ from flow.scenarios.bay_bridge_toll.scenario import BayBridgeTollScenario from flow.controllers import SumoCarFollowingController, BayBridgeRouter -NETFILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), - "bottleneck.net.xml") +NETFILE = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "bottleneck.net.xml") -def bay_bridge_bottleneck_example(sumo_binary=None, - use_traffic_lights=False): +def bay_bridge_bottleneck_example(sumo_binary=None, use_traffic_lights=False): """ Performs a non-RL simulation of the bottleneck portion of the Oakland-San Francisco Bay Bridge. This consists of the toll booth and sections of the @@ -33,44 +32,59 @@ def bay_bridge_bottleneck_example(sumo_binary=None, ---- Unlike the bay_bridge_example, inflows are always activated here. """ - sumo_params = SumoParams(sim_step=0.4, - overtake_right=True) + sumo_params = SumoParams(sim_step=0.4, overtake_right=True) if sumo_binary is not None: sumo_params.sumo_binary = sumo_binary sumo_car_following_params = SumoCarFollowingParams(speedDev=0.2) sumo_lc_params = SumoLaneChangeParams( - model="LC2013", lcCooperative=0.2, lcSpeedGain=15) + model="LC2013", lcCooperative=0.2, lcSpeedGain=15) vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(SumoCarFollowingController, {}), - routing_controller=(BayBridgeRouter, {}), - speed_mode="all_checks", - lane_change_mode="no_lat_collide", - sumo_car_following_params=sumo_car_following_params, - sumo_lc_params=sumo_lc_params, - num_vehicles=50) + vehicles.add( + veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + routing_controller=(BayBridgeRouter, {}), + speed_mode="all_checks", + lane_change_mode="no_lat_collide", + sumo_car_following_params=sumo_car_following_params, + sumo_lc_params=sumo_lc_params, + num_vehicles=50) additional_env_params = {} env_params = EnvParams(additional_params=additional_env_params) inflow = InFlows() - inflow.add(veh_type="human", edge="393649534", probability=0.2, - departLane="random", departSpeed=10) - inflow.add(veh_type="human", edge="4757680", probability=0.2, - departLane="random", departSpeed=10) - inflow.add(veh_type="human", edge="32661316", probability=0.2, - departLane="random", departSpeed=10) - inflow.add(veh_type="human", edge="90077193#0", vehs_per_hour=2000, - departLane="random", departSpeed=10) - - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - netfile=NETFILE) + inflow.add( + veh_type="human", + edge="393649534", + probability=0.2, + departLane="random", + departSpeed=10) + inflow.add( + veh_type="human", + edge="4757680", + probability=0.2, + departLane="random", + departSpeed=10) + inflow.add( + veh_type="human", + edge="32661316", + probability=0.2, + departLane="random", + departSpeed=10) + inflow.add( + veh_type="human", + edge="90077193#0", + vehs_per_hour=2000, + departLane="random", + departSpeed=10) + + net_params = NetParams( + in_flows=inflow, no_internal_links=False, netfile=NETFILE) # download the netfile from AWS if use_traffic_lights: @@ -82,18 +96,21 @@ def bay_bridge_bottleneck_example(sumo_binary=None, my_file = urllib.request.urlopen(my_url) data_to_write = my_file.read() - with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), - NETFILE), "wb+") as f: + with open( + os.path.join(os.path.dirname(os.path.abspath(__file__)), NETFILE), + "wb+") as f: f.write(data_to_write) - initial_config = InitialConfig(spacing="uniform", # "random", - min_gap=15) + initial_config = InitialConfig( + spacing="uniform", # "random", + min_gap=15) - scenario = BayBridgeTollScenario(name="bay_bridge_toll", - generator_class=BayBridgeTollGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = BayBridgeTollScenario( + name="bay_bridge_toll", + generator_class=BayBridgeTollGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = BayBridgeEnv(env_params, sumo_params, scenario) @@ -102,8 +119,8 @@ def bay_bridge_bottleneck_example(sumo_binary=None, if __name__ == "__main__": # import the experiment variable - exp = bay_bridge_bottleneck_example(sumo_binary="sumo-gui", - use_traffic_lights=False) + exp = bay_bridge_bottleneck_example( + sumo_binary="sumo-gui", use_traffic_lights=False) # run for a set number of rollouts / time steps exp.run(1, 1500) diff --git a/examples/sumo/bottleneck.py b/examples/sumo/bottleneck.py index d9291013e..5e0cd738d 100644 --- a/examples/sumo/bottleneck.py +++ b/examples/sumo/bottleneck.py @@ -23,31 +23,41 @@ def bottleneck_example(flow_rate, horizon, sumo_binary=None): if sumo_binary is None: sumo_binary = "sumo" - sumo_params = SumoParams(sim_step=0.5, sumo_binary=sumo_binary, - overtake_right=False, restart_instance=True) + sumo_params = SumoParams( + sim_step=0.5, + sumo_binary=sumo_binary, + overtake_right=False, + restart_instance=True) vehicles = Vehicles() - vehicles.add(veh_id="human", - speed_mode=25, - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - lane_change_mode=1621, - num_vehicles=1) - - additional_env_params = {"target_velocity": 40, - "max_accel": 1, - "max_decel": 1, - "lane_change_duration": 5, - "add_rl_if_exit": False, - "disable_tb": DISABLE_TB, - "disable_ramp_metering": DISABLE_RAMP_METER} - env_params = EnvParams(horizon=horizon, - additional_params=additional_env_params) + vehicles.add( + veh_id="human", + speed_mode=25, + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + lane_change_mode=1621, + num_vehicles=1) + + additional_env_params = { + "target_velocity": 40, + "max_accel": 1, + "max_decel": 1, + "lane_change_duration": 5, + "add_rl_if_exit": False, + "disable_tb": DISABLE_TB, + "disable_ramp_metering": DISABLE_RAMP_METER + } + env_params = EnvParams( + horizon=horizon, additional_params=additional_env_params) inflow = InFlows() - inflow.add(veh_type="human", edge="1", vehsPerHour=flow_rate, - departLane="random", departSpeed=10) + inflow.add( + veh_type="human", + edge="1", + vehsPerHour=flow_rate, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -56,20 +66,24 @@ def bottleneck_example(flow_rate, horizon, sumo_binary=None): 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) - - initial_config = InitialConfig(spacing="random", 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) + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) + + initial_config = InitialConfig( + spacing="random", + 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 = BottleneckEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/figure_eight.py b/examples/sumo/figure_eight.py index b62d44445..e4350b17a 100755 --- a/examples/sumo/figure_eight.py +++ b/examples/sumo/figure_eight.py @@ -21,24 +21,26 @@ def figure_eight_example(sumo_binary=None): sumo_params.sumo_binary = sumo_binary vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - lane_change_controller=(StaticLaneChanger, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - initial_speed=0, - num_vehicles=14) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + lane_change_controller=(StaticLaneChanger, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + initial_speed=0, + num_vehicles=14) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) additional_net_params = ADDITIONAL_NET_PARAMS.copy() - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) - - scenario = Figure8Scenario(name="figure8", - generator_class=Figure8Generator, - vehicles=vehicles, - net_params=net_params) + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) + + scenario = Figure8Scenario( + name="figure8", + generator_class=Figure8Generator, + vehicles=vehicles, + net_params=net_params) env = AccelEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/grid.py b/examples/sumo/grid.py index ff051fd2d..0b9644466 100644 --- a/examples/sumo/grid.py +++ b/examples/sumo/grid.py @@ -24,50 +24,75 @@ def grid_example(sumo_binary=None): tot_cars = (num_cars_left + num_cars_right) * m \ + (num_cars_top + num_cars_bot) * n - grid_array = {"short_length": short_length, "inner_length": inner_length, - "long_length": long_length, "row_num": n, "col_num": m, - "cars_left": num_cars_left, "cars_right": num_cars_right, - "cars_top": num_cars_top, "cars_bot": num_cars_bot} - - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo-gui") + grid_array = { + "short_length": short_length, + "inner_length": inner_length, + "long_length": long_length, + "row_num": n, + "col_num": m, + "cars_left": num_cars_left, + "cars_right": num_cars_right, + "cars_top": num_cars_top, + "cars_bot": num_cars_bot + } + + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo-gui") if sumo_binary is not None: sumo_params.sumo_binary = sumo_binary vehicles = Vehicles() - vehicles.add(veh_id="human", - routing_controller=(GridRouter, {}), - num_vehicles=tot_cars) + vehicles.add( + veh_id="human", + routing_controller=(GridRouter, {}), + num_vehicles=tot_cars) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) 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"}] + 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" + }] tl_logic.add("center0", phases=phases, programID=1) tl_logic.add("center1", phases=phases, programID=1) tl_logic.add("center2", tls_type="actuated", phases=phases, programID=1) - additional_net_params = {"grid_array": grid_array, "speed_limit": 35, - "horizontal_lanes": 1, "vertical_lanes": 1} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + additional_net_params = { + "grid_array": grid_array, + "speed_limit": 35, + "horizontal_lanes": 1, + "vertical_lanes": 1 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) initial_config = InitialConfig() - scenario = SimpleGridScenario(name="grid-intersection", - generator_class=SimpleGridGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=tl_logic) + scenario = SimpleGridScenario( + name="grid-intersection", + generator_class=SimpleGridGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=tl_logic) env = AccelEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/highway.py b/examples/sumo/highway.py index 25b482327..b83f03f25 100644 --- a/examples/sumo/highway.py +++ b/examples/sumo/highway.py @@ -20,33 +20,43 @@ def highway_example(sumo_binary=None): sumo_params.sumo_binary = sumo_binary vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {}), - num_vehicles=20) - vehicles.add(veh_id="human2", - acceleration_controller=(IDMController, {}), - num_vehicles=20) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, {}), + num_vehicles=20) + vehicles.add( + veh_id="human2", + acceleration_controller=(IDMController, {}), + num_vehicles=20) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) inflow = InFlows() - inflow.add(veh_type="human", edge="highway", probability=0.25, - departLane="free", departSpeed=20) - inflow.add(veh_type="human2", edge="highway", probability=0.25, - departLane="free", departSpeed=20) + inflow.add( + veh_type="human", + edge="highway", + probability=0.25, + departLane="free", + departSpeed=20) + inflow.add( + veh_type="human2", + edge="highway", + probability=0.25, + departLane="free", + departSpeed=20) additional_net_params = ADDITIONAL_NET_PARAMS.copy() - net_params = NetParams(in_flows=inflow, - additional_params=additional_net_params) + net_params = NetParams( + in_flows=inflow, additional_params=additional_net_params) - initial_config = InitialConfig(spacing="uniform", - shuffle=True) + initial_config = InitialConfig(spacing="uniform", shuffle=True) - scenario = HighwayScenario(name="highway", - generator_class=HighwayGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = HighwayScenario( + name="highway", + generator_class=HighwayGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = AccelEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/loop_merge.py b/examples/sumo/loop_merge.py index 4053c9580..a400ed881 100755 --- a/examples/sumo/loop_merge.py +++ b/examples/sumo/loop_merge.py @@ -15,9 +15,8 @@ def loop_merge_example(sumo_binary=None): - sumo_params = SumoParams(sim_step=0.1, - emission_path="./data/", - sumo_binary="sumo-gui") + sumo_params = SumoParams( + sim_step=0.1, emission_path="./data/", sumo_binary="sumo-gui") if sumo_binary is not None: sumo_params.sumo_binary = sumo_binary @@ -25,24 +24,24 @@ def loop_merge_example(sumo_binary=None): # note that the vehicles are added sequentially by the generator, # so place the merging vehicles after the vehicles in the ring vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=7, - speed_mode="no_collide", - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.0, tau=0.5), - sumo_lc_params=SumoLaneChangeParams()) - vehicles.add(veh_id="merge-idm", - acceleration_controller=(IDMController, {}), - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=10, - speed_mode="no_collide", - sumo_car_following_params=SumoCarFollowingParams( - minGap=0.01, tau=0.5), - sumo_lc_params=SumoLaneChangeParams()) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=7, + speed_mode="no_collide", + sumo_car_following_params=SumoCarFollowingParams(minGap=0.0, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) + vehicles.add( + veh_id="merge-idm", + acceleration_controller=(IDMController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=10, + speed_mode="no_collide", + sumo_car_following_params=SumoCarFollowingParams(minGap=0.01, tau=0.5), + sumo_lc_params=SumoLaneChangeParams()) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) @@ -52,23 +51,17 @@ def loop_merge_example(sumo_binary=None): additional_net_params["outer_lanes"] = 1 additional_net_params["lane_length"] = 75 net_params = NetParams( - no_internal_links=False, - additional_params=additional_net_params - ) + no_internal_links=False, additional_params=additional_net_params) initial_config = InitialConfig( - x0=50, - spacing="uniform", - additional_params={"merge_bunching": 0} - ) + x0=50, spacing="uniform", additional_params={"merge_bunching": 0}) scenario = TwoLoopsOneMergingScenario( name="two-loop-one-merging", generator_class=TwoLoopOneMergingGenerator, vehicles=vehicles, net_params=net_params, - initial_config=initial_config - ) + initial_config=initial_config) env = AccelEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/merge.py b/examples/sumo/merge.py index b1d8d0979..0763dc7b2 100644 --- a/examples/sumo/merge.py +++ b/examples/sumo/merge.py @@ -20,48 +20,60 @@ def merge_example(sumo_binary=None): - sumo_params = SumoParams(sumo_binary="sumo-gui", - emission_path="./data/", - sim_step=0.2, - restart_instance=True) + sumo_params = SumoParams( + sumo_binary="sumo-gui", + emission_path="./data/", + sim_step=0.2, + restart_instance=True) if sumo_binary is not None: sumo_params.sumo_binary = sumo_binary vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - speed_mode="no_collide", - num_vehicles=5) - - env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS, - sims_per_step=5, - warmup_steps=0) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + speed_mode="no_collide", + num_vehicles=5) + + env_params = EnvParams( + additional_params=ADDITIONAL_ENV_PARAMS, + sims_per_step=5, + warmup_steps=0) 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) + 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) 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 - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) - - initial_config = InitialConfig(spacing="uniform", - perturbation=5.0) - - scenario = MergeScenario(name="merge-baseline", - generator_class=MergeGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) + + initial_config = InitialConfig(spacing="uniform", perturbation=5.0) + + scenario = MergeScenario( + name="merge-baseline", + generator_class=MergeGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = WaveAttenuationMergePOEnv(env_params, sumo_params, scenario) diff --git a/examples/sumo/sugiyama.py b/examples/sumo/sugiyama.py index aa6920082..e92b75027 100755 --- a/examples/sumo/sugiyama.py +++ b/examples/sumo/sugiyama.py @@ -21,10 +21,11 @@ def sugiyama_example(sumo_binary=None): sumo_params.sumo_binary = sumo_binary vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=22) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=22) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) @@ -33,11 +34,12 @@ def sugiyama_example(sumo_binary=None): initial_config = InitialConfig(bunching=20) - scenario = LoopScenario(name="sugiyama", - generator_class=CircleGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = LoopScenario( + name="sugiyama", + generator_class=CircleGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = AccelEnv(env_params, sumo_params, scenario) diff --git a/flow/benchmarks/baselines/bottleneck0.py b/flow/benchmarks/baselines/bottleneck0.py index b415fe7f2..425b7b536 100644 --- a/flow/benchmarks/baselines/bottleneck0.py +++ b/flow/benchmarks/baselines/bottleneck0.py @@ -33,16 +33,16 @@ 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) +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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -62,9 +62,12 @@ # 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) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -73,9 +76,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) sumo_params = SumoParams( sim_step=0.5, @@ -99,12 +103,13 @@ 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) +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) diff --git a/flow/benchmarks/baselines/bottleneck1.py b/flow/benchmarks/baselines/bottleneck1.py index 0f13eb011..8cb259674 100644 --- a/flow/benchmarks/baselines/bottleneck1.py +++ b/flow/benchmarks/baselines/bottleneck1.py @@ -34,16 +34,16 @@ 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) +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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -63,9 +63,12 @@ # 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) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -74,9 +77,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) sumo_params = SumoParams( sim_step=0.5, @@ -100,12 +104,13 @@ 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) +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) diff --git a/flow/benchmarks/baselines/bottleneck2.py b/flow/benchmarks/baselines/bottleneck2.py index 52bdb172f..532c89668 100644 --- a/flow/benchmarks/baselines/bottleneck2.py +++ b/flow/benchmarks/baselines/bottleneck2.py @@ -33,16 +33,16 @@ AV_FRAC = .10 vehicles = Vehicles() -vehicles.add(veh_id="human", - speed_mode=9, - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, - num_vehicles=1 * SCALING) +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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -62,9 +62,12 @@ # 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) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -73,9 +76,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) sumo_params = SumoParams( sim_step=0.5, @@ -99,12 +103,13 @@ 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) +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) diff --git a/flow/benchmarks/baselines/figureeight{0,1,2}.py b/flow/benchmarks/baselines/figureeight{0,1,2}.py index a36b7b0b2..40a8969ca 100644 --- a/flow/benchmarks/baselines/figureeight{0,1,2}.py +++ b/flow/benchmarks/baselines/figureeight{0,1,2}.py @@ -28,11 +28,14 @@ # 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) +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, @@ -56,11 +59,12 @@ additional_params=ADDITIONAL_NET_PARAMS, ) -scenario = Figure8Scenario(name="figure_eight", - generator_class=Figure8Generator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) +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) diff --git a/flow/benchmarks/baselines/grid0.py b/flow/benchmarks/baselines/grid0.py index d2cfe36de..5e5e595f5 100644 --- a/flow/benchmarks/baselines/grid0.py +++ b/flow/benchmarks/baselines/grid0.py @@ -45,15 +45,16 @@ # 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") +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 = [] @@ -65,68 +66,86 @@ # 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") + 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) +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, + 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-gui", - ) + 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", - }, - ) + 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) +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) diff --git a/flow/benchmarks/baselines/grid1.py b/flow/benchmarks/baselines/grid1.py index da72337b9..438c2d56e 100644 --- a/flow/benchmarks/baselines/grid1.py +++ b/flow/benchmarks/baselines/grid1.py @@ -45,15 +45,16 @@ # 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") +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 = [] @@ -65,68 +66,86 @@ # 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") + 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) +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, + 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-gui", - ) + 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", - }, - ) + 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) +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) diff --git a/flow/benchmarks/baselines/merge{0,1,2}.py b/flow/benchmarks/baselines/merge{0,1,2}.py index 02123da47..368ec4de8 100644 --- a/flow/benchmarks/baselines/merge{0,1,2}.py +++ b/flow/benchmarks/baselines/merge{0,1,2}.py @@ -24,7 +24,7 @@ import numpy as np # time horizon of a single rollout -HORIZON = int(750*(0.5/0.2)) +HORIZON = int(750 * (0.5 / 0.2)) # inflow rate at the highway FLOW_RATE = 2000 # percent of autonomous vehicles @@ -41,19 +41,27 @@ # 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.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) +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, @@ -82,11 +90,12 @@ additional_params=additional_net_params, ) -scenario = MergeScenario(name="merge", - generator_class=MergeGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) +scenario = MergeScenario( + name="merge", + generator_class=MergeGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = WaveAttenuationMergePOEnv(env_params, sumo_params, scenario) diff --git a/flow/benchmarks/bottleneck0.py b/flow/benchmarks/bottleneck0.py index 17a93b780..3afa5a7b0 100644 --- a/flow/benchmarks/bottleneck0.py +++ b/flow/benchmarks/bottleneck0.py @@ -25,22 +25,23 @@ 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) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * SCALING) +vehicles.add( + veh_id="human", + speed_mode=9, + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, + num_vehicles=1 * SCALING) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + 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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -60,12 +61,18 @@ # percentage of flow coming out of each lane inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * (1 - AV_FRAC), - departLane="random", departSpeed=10) -inflow.add(veh_type="rl", edge="1", - vehs_per_hour=flow_rate * AV_FRAC, - departLane="random", departSpeed=10) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * (1 - AV_FRAC), + departLane="random", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="1", + vehs_per_hour=flow_rate * AV_FRAC, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -74,9 +81,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/bottleneck1.py b/flow/benchmarks/bottleneck1.py index a4d16ae15..5a7e57c6c 100644 --- a/flow/benchmarks/bottleneck1.py +++ b/flow/benchmarks/bottleneck1.py @@ -26,22 +26,23 @@ 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) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * SCALING) +vehicles.add( + veh_id="human", + speed_mode=9, + routing_controller=(ContinuousRouter, {}), + lane_change_mode=1621, + num_vehicles=1 * SCALING) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + 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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -61,12 +62,18 @@ # percentage of flow coming out of each lane inflow = InFlows() -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * (1 - AV_FRAC), - departLane="random", departSpeed=10) -inflow.add(veh_type="rl", edge="1", - vehs_per_hour=flow_rate * AV_FRAC, - departLane="random", departSpeed=10) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * (1 - AV_FRAC), + departLane="random", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="1", + vehs_per_hour=flow_rate * AV_FRAC, + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -75,9 +82,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/bottleneck2.py b/flow/benchmarks/bottleneck2.py index 0e40e34ca..faa2e54d7 100644 --- a/flow/benchmarks/bottleneck2.py +++ b/flow/benchmarks/bottleneck2.py @@ -26,22 +26,23 @@ AV_FRAC = .10 vehicles = Vehicles() -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * SCALING) -vehicles.add(veh_id="human", - speed_mode=9, - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, - num_vehicles=1 * SCALING) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + lane_change_mode=0, + num_vehicles=1 * SCALING) +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)] +num_observed_segments = [("1", 1), ("2", 3), ("3", 3), ("4", 3), ("5", 1)] additional_env_params = { "target_velocity": 40, "disable_tb": True, @@ -61,12 +62,18 @@ # percentage of flow coming out of each lane inflow = InFlows() -inflow.add(veh_type="rl", edge="1", - vehs_per_hour=flow_rate * AV_FRAC, - departLane="random", departSpeed=10) -inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * (1 - AV_FRAC), - departLane="random", departSpeed=10) +inflow.add( + veh_type="rl", + edge="1", + vehs_per_hour=flow_rate * AV_FRAC, + departLane="random", + departSpeed=10) +inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * (1 - AV_FRAC), + departLane="random", + departSpeed=10) traffic_lights = TrafficLights() if not DISABLE_TB: @@ -75,9 +82,10 @@ 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) +net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/figureeight0.py b/flow/benchmarks/figureeight0.py index 018e16c6c..a583c7efa 100644 --- a/flow/benchmarks/figureeight0.py +++ b/flow/benchmarks/figureeight0.py @@ -20,16 +20,20 @@ # 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=13) -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) +vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=13) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/figureeight1.py b/flow/benchmarks/figureeight1.py index f5dc305f6..4d735b865 100644 --- a/flow/benchmarks/figureeight1.py +++ b/flow/benchmarks/figureeight1.py @@ -21,16 +21,20 @@ # We place 8 autonomous vehicle and 8 human-driven vehicles in the network vehicles = Vehicles() for i in range(7): - vehicles.add(veh_id="human{}".format(i), - acceleration_controller=(IDMController, {"noise": 0.2}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) - vehicles.add(veh_id="rl{}".format(i), - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) + vehicles.add( + veh_id="human{}".format(i), + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) + vehicles.add( + veh_id="rl{}".format(i), + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/figureeight2.py b/flow/benchmarks/figureeight2.py index 4d4f5be2d..5067771cb 100644 --- a/flow/benchmarks/figureeight2.py +++ b/flow/benchmarks/figureeight2.py @@ -20,11 +20,12 @@ # We place 16 autonomous vehicle and 0 human-driven vehicles in the network vehicles = Vehicles() -vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=14) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=14) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/grid0.py b/flow/benchmarks/grid0.py index af59fa7c9..3bdf25cdd 100644 --- a/flow/benchmarks/grid0.py +++ b/flow/benchmarks/grid0.py @@ -36,15 +36,16 @@ # 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") +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 = [] @@ -56,8 +57,12 @@ # 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") + inflow.add( + veh_type="human", + edge=edge, + vehs_per_hour=EDGE_INFLOW, + departLane="free", + departSpeed="max") flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/grid1.py b/flow/benchmarks/grid1.py index 99780f595..1e11bd471 100644 --- a/flow/benchmarks/grid1.py +++ b/flow/benchmarks/grid1.py @@ -36,15 +36,16 @@ # 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") +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 = [] @@ -56,8 +57,12 @@ # 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") + inflow.add( + veh_type="human", + edge=edge, + vehs_per_hour=EDGE_INFLOW, + departLane="free", + departSpeed="max") flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/merge0.py b/flow/benchmarks/merge0.py index aac35dfea..7beba2faf 100644 --- a/flow/benchmarks/merge0.py +++ b/flow/benchmarks/merge0.py @@ -34,26 +34,38 @@ # 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.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) +vehicles.add( + veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + speed_mode="no_collide", + num_vehicles=5) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) # 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=(1 - RL_PENETRATION) * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=RL_PENETRATION * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) +inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=(1 - RL_PENETRATION) * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=RL_PENETRATION * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/merge1.py b/flow/benchmarks/merge1.py index a7bc73f17..9336efc02 100644 --- a/flow/benchmarks/merge1.py +++ b/flow/benchmarks/merge1.py @@ -34,26 +34,38 @@ # 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.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) +vehicles.add( + veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + speed_mode="no_collide", + num_vehicles=5) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) # 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=(1 - RL_PENETRATION) * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=RL_PENETRATION * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) +inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=(1 - RL_PENETRATION) * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=RL_PENETRATION * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/merge2.py b/flow/benchmarks/merge2.py index 2130468d7..dfcc8cee4 100644 --- a/flow/benchmarks/merge2.py +++ b/flow/benchmarks/merge2.py @@ -34,26 +34,38 @@ # 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.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) +vehicles.add( + veh_id="human", + acceleration_controller=(SumoCarFollowingController, {}), + speed_mode="no_collide", + num_vehicles=5) +vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) # 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=(1 - RL_PENETRATION) * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=RL_PENETRATION * FLOW_RATE, - departLane="free", departSpeed=10) -inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) +inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=(1 - RL_PENETRATION) * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=RL_PENETRATION * FLOW_RATE, + departLane="free", + departSpeed=10) +inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) flow_params = dict( # name of the experiment diff --git a/flow/benchmarks/rllab/trpo_runner.py b/flow/benchmarks/rllab/trpo_runner.py index cf209e032..e5c413296 100644 --- a/flow/benchmarks/rllab/trpo_runner.py +++ b/flow/benchmarks/rllab/trpo_runner.py @@ -48,8 +48,7 @@ def run_task(*_): vehicles=vehicles, net_params=net_params, initial_config=initial_config, - traffic_lights=traffic_lights - ) + traffic_lights=traffic_lights) pass_params = (env_name, sumo_params, vehicles, env_params, net_params, initial_config, scenario) @@ -57,10 +56,7 @@ def run_task(*_): env = GymEnv(env_name, record_video=False, register_params=pass_params) env = normalize(env) - policy = GaussianMLPPolicy( - env_spec=env.spec, - hidden_sizes=(100, 50, 25) - ) + policy = GaussianMLPPolicy(env_spec=env.spec, hidden_sizes=(100, 50, 25)) baseline = LinearFeatureBaseline(env_spec=env.spec) horizon = flow_params["env"].horizon diff --git a/flow/benchmarks/rllib/ars_runner.py b/flow/benchmarks/rllib/ars_runner.py index f73216870..9d5eafef8 100644 --- a/flow/benchmarks/rllib/ars_runner.py +++ b/flow/benchmarks/rllib/ars_runner.py @@ -23,7 +23,6 @@ # number of parallel workers PARALLEL_ROLLOUTS = 25 - if __name__ == "__main__": # get the env name and a creator for the environment create_env, env_name = make_create_env(params=flow_params, version=0) @@ -42,8 +41,8 @@ config['eval_rollouts'] = PARALLEL_ROLLOUTS # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json # Register as rllib env @@ -58,7 +57,9 @@ }, "checkpoint_freq": 5, "max_failures": 999, - "stop": {"training_iteration": 500}, + "stop": { + "training_iteration": 500 + }, "repeat": 3, "trial_resources": { "cpu": 1, diff --git a/flow/benchmarks/rllib/ppo_runner.py b/flow/benchmarks/rllib/ppo_runner.py index fabeb265d..13104853d 100644 --- a/flow/benchmarks/rllib/ppo_runner.py +++ b/flow/benchmarks/rllib/ppo_runner.py @@ -23,7 +23,6 @@ # number of parallel workers PARALLEL_ROLLOUTS = 3 - if __name__ == "__main__": # get the env name and a creator for the environment create_env, env_name = make_create_env(params=flow_params, version=0) @@ -42,8 +41,8 @@ config["clip_param"] = 0.2 # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json # Register as rllib env @@ -58,7 +57,9 @@ }, "checkpoint_freq": 5, "max_failures": 999, - "stop": {"training_iteration": 5}, + "stop": { + "training_iteration": 5 + }, "repeat": 1, "trial_resources": { "cpu": 1, diff --git a/flow/controllers/__init__.py b/flow/controllers/__init__.py index 9765c89c1..60b0c11f8 100755 --- a/flow/controllers/__init__.py +++ b/flow/controllers/__init__.py @@ -20,9 +20,11 @@ from flow.controllers.routing_controllers import ContinuousRouter, \ GridRouter, BayBridgeRouter -__all__ = ["RLController", "BaseController", "BaseLaneChangeController", - "BaseRouter", "CFMController", "BCMController", "OVMController", - "LinearOVM", "IDMController", "SumoCarFollowingController", - "FollowerStopper", "PISaturation", "HandTunedVelocityController", - "StaticLaneChanger", "SumoLaneChangeController", "ContinuousRouter", - "GridRouter", "BayBridgeRouter"] +__all__ = [ + "RLController", "BaseController", "BaseLaneChangeController", "BaseRouter", + "CFMController", "BCMController", "OVMController", "LinearOVM", + "IDMController", "SumoCarFollowingController", "FollowerStopper", + "PISaturation", "HandTunedVelocityController", "StaticLaneChanger", + "SumoLaneChangeController", "ContinuousRouter", "GridRouter", + "BayBridgeRouter" +] diff --git a/flow/controllers/base_controller.py b/flow/controllers/base_controller.py index 305218085..75c3190c3 100755 --- a/flow/controllers/base_controller.py +++ b/flow/controllers/base_controller.py @@ -179,9 +179,9 @@ def get_safe_velocity_action(self, env, action): if this_vel + action * sim_step > safe_velocity: if safe_velocity > 0: - return (safe_velocity - this_vel)/sim_step + return (safe_velocity - this_vel) / sim_step else: - return -this_vel/sim_step + return -this_vel / sim_step else: return action diff --git a/flow/controllers/base_lane_changing_controller.py b/flow/controllers/base_lane_changing_controller.py index de7c953d3..71eee5169 100755 --- a/flow/controllers/base_lane_changing_controller.py +++ b/flow/controllers/base_lane_changing_controller.py @@ -1,5 +1,4 @@ class BaseLaneChangeController: - def __init__(self, veh_id, lane_change_params={}): """Base class for lane-changing controllers. diff --git a/flow/controllers/base_routing_controller.py b/flow/controllers/base_routing_controller.py index 9015a4e53..36169d3b4 100755 --- a/flow/controllers/base_routing_controller.py +++ b/flow/controllers/base_routing_controller.py @@ -1,4 +1,3 @@ - class BaseRouter: def __init__(self, veh_id, router_params): """Base class for routing controllers. diff --git a/flow/controllers/car_following_models.py b/flow/controllers/car_following_models.py index 5bd679329..3f5fe788b 100755 --- a/flow/controllers/car_following_models.py +++ b/flow/controllers/car_following_models.py @@ -15,7 +15,6 @@ class CFMController(BaseController): - def __init__(self, veh_id, sumo_cf_params, @@ -53,9 +52,13 @@ def __init__(self, type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe, - noise=noise) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe, + noise=noise) self.veh_id = veh_id self.k_d = k_d @@ -79,7 +82,6 @@ def get_accel(self, env): class BCMController(BaseController): - def __init__(self, veh_id, sumo_cf_params, @@ -118,9 +120,13 @@ def __init__(self, type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe, - noise=noise) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe, + noise=noise) self.veh_id = veh_id self.k_d = k_d @@ -156,7 +162,6 @@ def get_accel(self, env): class OVMController(BaseController): - def __init__(self, veh_id, sumo_cf_params, @@ -196,9 +201,13 @@ def __init__(self, type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe, - noise=noise) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe, + noise=noise) self.veh_id = veh_id self.v_max = v_max self.alpha = alpha @@ -229,7 +238,6 @@ def get_accel(self, env): class LinearOVM(BaseController): - def __init__(self, veh_id, sumo_cf_params, @@ -261,9 +269,13 @@ def __init__(self, type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe, - noise=noise) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe, + noise=noise) self.veh_id = veh_id # 4.8*1.85 for case I, 3.8*1.85 for case II, per Nakayama self.v_max = v_max @@ -279,7 +291,7 @@ def get_accel(self, env): alpha = 1.689 # the average value from Nakayama paper if h < self.h_st: v_h = 0 - elif self.h_st <= h <= self.h_st + self.v_max/alpha: + elif self.h_st <= h <= self.h_st + self.v_max / alpha: v_h = alpha * (h - self.h_st) else: v_h = self.v_max @@ -288,7 +300,6 @@ def get_accel(self, env): class IDMController(BaseController): - def __init__(self, veh_id, v0=30, @@ -328,9 +339,13 @@ def __init__(self, type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe, - noise=noise) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe, + noise=noise) self.v0 = v0 self.T = T self.a = a @@ -356,14 +371,13 @@ def get_accel(self, env): else: lead_vel = env.vehicles.get_speed(lead_id) s_star = self.s0 + max( - 0, - v * self.T + v*(v-lead_vel) / (2*np.sqrt(self.a*self.b))) + 0, v * self.T + v * (v - lead_vel) / + (2 * np.sqrt(self.a * self.b))) - return self.a * (1 - (v/self.v0)**self.delta - (s_star/h)**2) + return self.a * (1 - (v / self.v0)**self.delta - (s_star / h)**2) class SumoCarFollowingController(BaseController): - def __init__(self, veh_id, sumo_cf_params): """Instantiates a car-following controller whose actions are purely defined by sumo. diff --git a/flow/controllers/rlcontroller.py b/flow/controllers/rlcontroller.py index 14a4a412a..81fd816f9 100755 --- a/flow/controllers/rlcontroller.py +++ b/flow/controllers/rlcontroller.py @@ -2,7 +2,6 @@ class RLController(BaseController): - def __init__(self, veh_id, sumo_cf_params, time_delay=0, fail_safe=None): """Instantiates an RL Controller. @@ -23,5 +22,9 @@ def __init__(self, veh_id, sumo_cf_params, time_delay=0, fail_safe=None): type of flow-imposed failsafe the vehicle should posses, defaults to no failsafe (None) """ - BaseController.__init__(self, veh_id, sumo_cf_params, - delay=time_delay, fail_safe=fail_safe) + BaseController.__init__( + self, + veh_id, + sumo_cf_params, + delay=time_delay, + fail_safe=fail_safe) diff --git a/flow/controllers/velocity_controllers.py b/flow/controllers/velocity_controllers.py index e09236587..16b806621 100644 --- a/flow/controllers/velocity_controllers.py +++ b/flow/controllers/velocity_controllers.py @@ -16,8 +16,8 @@ def __init__(self, veh_id, sumo_cf_params, v_des=15, danger_edges=None): v_des: float, optional desired speed of the vehicles (m/s) """ - BaseController.__init__(self, veh_id, sumo_cf_params, delay=1.0, - fail_safe='safe_velocity') + BaseController.__init__( + self, veh_id, sumo_cf_params, delay=1.0, fail_safe='safe_velocity') # desired speed of the vehicle self.v_des = v_des @@ -62,9 +62,9 @@ def get_accel(self, env): dx = env.vehicles.get_headway(self.veh_id) dv_minus = min(lead_vel - this_vel, 0) - dx_1 = self.dx_1_0 + 1 / (2 * self.d_1) * dv_minus ** 2 - dx_2 = self.dx_2_0 + 1 / (2 * self.d_2) * dv_minus ** 2 - dx_3 = self.dx_3_0 + 1 / (2 * self.d_3) * dv_minus ** 2 + dx_1 = self.dx_1_0 + 1 / (2 * self.d_1) * dv_minus**2 + dx_2 = self.dx_2_0 + 1 / (2 * self.d_2) * dv_minus**2 + dx_3 = self.dx_3_0 + 1 / (2 * self.d_3) * dv_minus**2 # compute the desired velocity if dx <= dx_1: @@ -159,10 +159,9 @@ def get_accel(self, env): class HandTunedVelocityController(FollowerStopper): - def __init__(self, veh_id, v_regions, sumo_cf_params, danger_edges=None): - super().__init__(veh_id, sumo_cf_params, v_regions[0], - danger_edges=danger_edges) + super().__init__( + veh_id, sumo_cf_params, v_regions[0], danger_edges=danger_edges) self.v_regions = v_regions def get_accel(self, env): @@ -182,7 +181,11 @@ def get_accel(self, env): class FeedbackController(FollowerStopper): - def __init__(self, veh_id, sumo_cf_params, Kp, desired_bottleneck_density, + def __init__(self, + veh_id, + sumo_cf_params, + Kp, + desired_bottleneck_density, danger_edges=None): super().__init__(veh_id, sumo_cf_params, danger_edges=danger_edges) self.Kp = Kp @@ -191,9 +194,10 @@ def __init__(self, veh_id, sumo_cf_params, Kp, desired_bottleneck_density, def get_accel(self, env): current_lane = env.vehicles.get_lane(veh_id=self.veh_id) future_lanes = env.scenario.get_bottleneck_lanes(current_lane) - future_edge_lanes = ["3_"+str(current_lane), - "4_"+str(future_lanes[0]), - "5_"+str(future_lanes[1])] + future_edge_lanes = [ + "3_" + str(current_lane), "4_" + str(future_lanes[0]), + "5_" + str(future_lanes[1]) + ] current_density = env.get_bottleneck_density(future_edge_lanes) edge = env.vehicles.get_edge(self.veh_id) @@ -203,8 +207,10 @@ def get_accel(self, env): self.v_des = None else: self.v_des = max( - min(self.v_des + self.Kp * (self.desired_density - - current_density), 23), 0) + min( + self.v_des + + self.Kp * (self.desired_density - current_density), + 23), 0) # print(current_density, self.v_des) return super().get_accel(env) diff --git a/flow/core/experiment.py b/flow/core/experiment.py index 2f606f9b4..f3c730b5c 100755 --- a/flow/core/experiment.py +++ b/flow/core/experiment.py @@ -6,7 +6,6 @@ class SumoExperiment: - def __init__(self, env, scenario): """ This class acts as a runner for a scenario and environment. @@ -24,8 +23,8 @@ def __init__(self, env, scenario): self.vehicles = scenario.vehicles self.cfg = scenario.cfg - logging.info(" Starting experiment" + str(self.name) + " at " - + str(datetime.datetime.utcnow())) + logging.info(" Starting experiment" + str(self.name) + " at " + + str(datetime.datetime.utcnow())) logging.info("initializing environment.") @@ -51,6 +50,7 @@ def run(self, num_runs, num_steps, rl_actions=None, convert_to_csv=False): """ info_dict = {} if rl_actions is None: + def rl_actions(*_): return None @@ -87,10 +87,10 @@ def rl_actions(*_): info_dict["mean_returns"] = mean_rets info_dict["per_step_returns"] = ret_lists - print("Average, std return: {}, {}".format(np.mean(rets), - np.std(rets))) - print("Average, std speed: {}, {}".format(np.mean(mean_vels), - np.std(std_vels))) + print("Average, std return: {}, {}".format( + np.mean(rets), np.std(rets))) + print("Average, std speed: {}, {}".format( + np.mean(mean_vels), np.std(std_vels))) self.env.terminate() if convert_to_csv: diff --git a/flow/core/generator.py b/flow/core/generator.py index f3cdf0c90..f3fa219a9 100755 --- a/flow/core/generator.py +++ b/flow/core/generator.py @@ -24,7 +24,6 @@ class Generator(Serializable): - def __init__(self, net_params, base): """Base class for generating transportation networks. @@ -189,9 +188,12 @@ def generate_net(self, net_params, traffic_lights): printxml(x, self.net_path + self.cfgfn) subprocess.call( - ["netconvert -c " + self.net_path + self.cfgfn + " --output-file=" - + self.cfg_path + self.netfn + ' --no-internal-links="%s"' - % no_internal_links], shell=True) + [ + "netconvert -c " + self.net_path + self.cfgfn + + " --output-file=" + self.cfg_path + self.netfn + + ' --no-internal-links="%s"' % no_internal_links + ], + shell=True) # collect data from the generated network configuration file error = None @@ -256,8 +258,11 @@ def generate_cfg(self, net_params, traffic_lights): nodes = self.specify_tll(net_params) tll = [] for node in nodes: - tll.append({"id": node['id'], "type": tl_type, - "programID": program_id}) + tll.append({ + "id": node['id'], + "type": tl_type, + "programID": program_id + }) for elem in tll: e = E("tlLogic", **elem) @@ -277,8 +282,11 @@ def generate_cfg(self, net_params, traffic_lights): if node["type"] == "static" and not node.get("phases"): continue - elem = {"id": str(node["id"]), "type": str(node["type"]), - "programID": str(node["programID"])} + elem = { + "id": str(node["id"]), + "type": str(node["type"]), + "programID": str(node["programID"]) + } if node.get("offset"): elem["offset"] = str(node.get("offset")) @@ -288,8 +296,11 @@ def generate_cfg(self, net_params, traffic_lights): for phase in node.get("phases"): e.append(E("phase", **phase)) else: - e.append(E("param", - **{"key": key, "value": str(value)})) + e.append( + E("param", **{ + "key": key, + "value": str(value) + })) add.append(e) @@ -297,8 +308,12 @@ def generate_cfg(self, net_params, traffic_lights): gui = E("viewsettings") gui.append(E("scheme", name="real world")) - gui.append(E("background", backgroundColor="100,100,100", - showGrid="0", gridXSize="100.00", gridYSize="100.00")) + gui.append( + E("background", + backgroundColor="100,100,100", + showGrid="0", + gridXSize="100.00", + gridYSize="100.00")) printxml(gui, self.cfg_path + self.guifn) cfg = makexml("configuration", @@ -306,8 +321,13 @@ def generate_cfg(self, net_params, traffic_lights): logging.debug(self.netfn) - cfg.append(self._inputs(self.name, net=self.netfn, add=self.addfn, - rou=self.roufn, gui=self.guifn)) + cfg.append( + self._inputs( + self.name, + net=self.netfn, + add=self.addfn, + rou=self.roufn, + gui=self.guifn)) t = E("time") t.append(E("begin", value=repr(start_time))) if end_time: @@ -338,8 +358,10 @@ def make_routes(self, scenario, initial_config): # add the types of vehicles to the xml file for params in vehicles.types: - type_params_str = {key: str(params["type_params"][key]) - for key in params["type_params"]} + type_params_str = { + key: str(params["type_params"][key]) + for key in params["type_params"] + } routes.append(E("vType", id=params["veh_id"], **type_params_str)) self.vehicle_ids = vehicles.get_ids() @@ -355,10 +377,16 @@ def make_routes(self, scenario, initial_config): edge, pos = positions[i] lane = lanes[i] type_depart_speed = vehicles.get_initial_speed(veh_id) - routes.append(self._vehicle( - veh_type, "route" + edge, depart="0", id=veh_id, - color="1,1,1", departSpeed=str(type_depart_speed), - departPos=str(pos), departLane=str(lane))) + routes.append( + self._vehicle( + veh_type, + "route" + edge, + depart="0", + id=veh_id, + color="1,1,1", + departSpeed=str(type_depart_speed), + departPos=str(pos), + departLane=str(lane))) # add the in-flows from various edges to the xml file if self.net_params.in_flows is not None: @@ -502,8 +530,13 @@ def _vehicle(self, type, route, departPos, number=0, id=None, **kwargs): raise ValueError("Supply either ID or Number") if not id: id = type + "_" + str(number) - return E("vehicle", type=type, id=id, route=route, departPos=departPos, - **kwargs) + return E( + "vehicle", + type=type, + id=id, + route=route, + departPos=departPos, + **kwargs) def _inputs(self, name, net=None, rou=None, add=None, gui=None): inp = E("input") @@ -550,8 +583,8 @@ def _import_edges_from_net(self): """ # import the .net.xml file containing all edge/type data parser = etree.XMLParser(recover=True) - tree = ElementTree.parse(os.path.join(self.cfg_path, self.netfn), - parser=parser) + tree = ElementTree.parse( + os.path.join(self.cfg_path, self.netfn), parser=parser) root = tree.getroot() @@ -607,8 +640,8 @@ def _import_edges_from_net(self): net_data[edge_id]["length"] = float(lane.attrib["length"]) if net_data[edge_id]["speed"] is None \ and "speed" in lane.attrib: - net_data[edge_id]["speed"] = float(lane. - attrib["speed"]) + net_data[edge_id]["speed"] = float( + lane.attrib["speed"]) # if no speed value is present anywhere, set it to some default if net_data[edge_id]["speed"] is None: diff --git a/flow/core/params.py b/flow/core/params.py index df1a4f7ec..9500da760 100755 --- a/flow/core/params.py +++ b/flow/core/params.py @@ -3,7 +3,6 @@ class SumoParams: - def __init__(self, port=None, sim_step=0.1, @@ -80,7 +79,6 @@ def __init__(self, class EnvParams: - def __init__(self, vehicle_arrangement_shuffle=False, starting_position_shuffle=False, @@ -143,7 +141,6 @@ def get_additional_param(self, key): class NetParams: - def __init__(self, no_internal_links=True, in_flows=None, @@ -190,7 +187,6 @@ def __init__(self, class InitialConfig: - def __init__(self, shuffle=False, spacing="uniform", @@ -262,19 +258,19 @@ def get_additional_params(self, key): class SumoCarFollowingParams: - - def __init__(self, - accel=1.0, - decel=1.5, - sigma=0.5, - tau=1.0, # past 1 at sim_step=0.1 you no longer see waves - min_gap=2.5, - max_speed=30, - speed_factor=1.0, - speed_dev=0.1, - impatience=0.5, - car_follow_model="IDM", - **kwargs): + def __init__( + self, + accel=1.0, + decel=1.5, + sigma=0.5, + tau=1.0, # past 1 at sim_step=0.1 you no longer see waves + min_gap=2.5, + max_speed=30, + speed_factor=1.0, + speed_dev=0.1, + impatience=0.5, + car_follow_model="IDM", + **kwargs): """Parameters for sumo-controlled acceleration behavior Attributes @@ -349,7 +345,6 @@ def __init__(self, class SumoLaneChangeParams: - def __init__(self, model="LC2013", lc_strategic=1.0, @@ -434,8 +429,8 @@ def __init__(self, # check for deprecations (lcSpeedGainRight) if "lcSpeedGainRight" in kwargs: - deprecation_warning( - self, "lcSpeedGainRight", "lc_speed_gain_right") + deprecation_warning(self, "lcSpeedGainRight", + "lc_speed_gain_right") lc_speed_gain_right = kwargs["lcSpeedGainRight"] # check for deprecations (lcSublane) @@ -465,8 +460,8 @@ def __init__(self, # check for deprecations (lcTimeToImpatience) if "lcTimeToImpatience" in kwargs: - deprecation_warning( - self, "lcTimeToImpatience", "lc_time_to_impatience") + deprecation_warning(self, "lcTimeToImpatience", + "lc_time_to_impatience") lc_time_to_impatience = kwargs["lcTimeToImpatience"] # check for deprecations (lcAccelLat) @@ -509,7 +504,6 @@ def __init__(self, class InFlows: - def __init__(self): """ Used to add inflows to a network. Inflows can be specified for any edge @@ -567,8 +561,12 @@ def add(self, # delete since all parameters in kwargs are used again later del kwargs["vehsPerHour"] - new_inflow = {"name": "flow_%d" % self.num_flows, "vtype": veh_type, - "route": "route" + edge, "end": end} + new_inflow = { + "name": "flow_%d" % self.num_flows, + "vtype": veh_type, + "route": "route" + edge, + "end": end + } new_inflow.update(kwargs) diff --git a/flow/core/rewards.py b/flow/core/rewards.py index cc8538b0e..4fe333725 100755 --- a/flow/core/rewards.py +++ b/flow/core/rewards.py @@ -119,13 +119,14 @@ def min_delay(env): vel = np.array(env.vehicles.get_speed(env.vehicles.get_ids())) vel = vel[vel >= -1e-6] - v_top = max(env.scenario.speed_limit(edge) - for edge in env.scenario.get_edge_list()) + v_top = max( + env.scenario.speed_limit(edge) + for edge in env.scenario.get_edge_list()) time_step = env.sim_step max_cost = time_step * sum(vel.shape) cost = time_step * sum((v_top - vel) / v_top) - return max((max_cost - cost)/max_cost, 0) + return max((max_cost - cost) / max_cost, 0) def min_delay_unscaled(env): @@ -141,12 +142,13 @@ def min_delay_unscaled(env): vel = np.array(env.vehicles.get_speed(env.vehicles.get_ids())) vel = vel[vel >= -1e-6] - v_top = max(env.scenario.speed_limit(edge) - for edge in env.scenario.get_edge_list()) + v_top = max( + env.scenario.speed_limit(edge) + for edge in env.scenario.get_edge_list()) time_step = env.sim_step cost = time_step * sum((v_top - vel) / v_top) - return cost/len(env.vehicles.get_ids()) + return cost / len(env.vehicles.get_ids()) def penalize_tl_changes(actions, gain=1): @@ -160,7 +162,10 @@ def penalize_tl_changes(actions, gain=1): return -action_penalty -def penalize_headway_variance(vehicles, vids, normalization=1, penalty_gain=1, +def penalize_headway_variance(vehicles, + vids, + normalization=1, + penalty_gain=1, penalty_exponent=1): """A reward function used to train rl vehicles to encourage large headways among a pre-specified list of vehicles vids. @@ -179,14 +184,17 @@ def penalize_headway_variance(vehicles, vids, normalization=1, penalty_gain=1, penalty_exponent: float, optional used to allow exponential punishing of smaller headways """ - headways = penalty_gain * np.power(np.array( - [vehicles.get_headway(veh_id) / normalization for veh_id in vids]), - penalty_exponent) + headways = penalty_gain * np.power( + np.array( + [vehicles.get_headway(veh_id) / normalization + for veh_id in vids]), penalty_exponent) return -np.var(headways) -def punish_small_rl_headways(env, headway_threshold, - penalty_gain=1, penalty_exponent=1): +def punish_small_rl_headways(env, + headway_threshold, + penalty_gain=1, + penalty_exponent=1): """A reward function used to train rl vehicles to avoid small headways. A penalty is issued whenever rl vehicles are below a pre-defined desired @@ -260,10 +268,12 @@ def punish_queues_in_lane(env, edge, lane, penalty_gain=1, penalty_exponent=1): to the queues in the lane in question """ # IDs of all vehicles in passed-in lane - lane_ids = [veh_id for veh_id in env.vehicles.get_ids_by_edge(edge) - if env.vehicles.get_lane(veh_id) == lane] + lane_ids = [ + veh_id for veh_id in env.vehicles.get_ids_by_edge(edge) + if env.vehicles.get_lane(veh_id) == lane + ] - return -1 * (len(lane_ids) ** penalty_exponent) * penalty_gain + return -1 * (len(lane_ids)**penalty_exponent) * penalty_gain def reward_rl_opening_headways(env, reward_gain=0.1, reward_exponent=1): @@ -295,7 +305,7 @@ def reward_rl_opening_headways(env, reward_gain=0.1, reward_exponent=1): print('rl id:', rl_id) print('follower id:', follower_id) continue - total_reward += follower_headway ** reward_exponent + total_reward += follower_headway**reward_exponent # print(total_reward) if total_reward < 0: print('negative total reward of:', total_reward) diff --git a/flow/core/traffic_lights.py b/flow/core/traffic_lights.py index 77a39dfa7..b5212fd3b 100644 --- a/flow/core/traffic_lights.py +++ b/flow/core/traffic_lights.py @@ -8,7 +8,6 @@ class TrafficLights: - def __init__(self, baseline=False): """Base traffic light. @@ -200,18 +199,33 @@ def actuated_default(self): max_gap = 3.0 detector_gap = 0.8 show_detectors = True - 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"}] - - return {"tl_type": str(tl_type), - "program_id": str(program_id), - "max_gap": str(max_gap), - "detector_gap": str(detector_gap), - "show_detectors": show_detectors, - "phases": phases} + 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" + }] + + return { + "tl_type": str(tl_type), + "program_id": str(program_id), + "max_gap": str(max_gap), + "detector_gap": str(detector_gap), + "show_detectors": show_detectors, + "phases": phases + } diff --git a/flow/core/util.py b/flow/core/util.py index e49db3fad..325b0f3cb 100755 --- a/flow/core/util.py +++ b/flow/core/util.py @@ -25,7 +25,6 @@ class NameEncoder(json.JSONEncoder): - """ Custom encoder used to generate ``flow_params.json`` Extends ``json.JSONEncoder``. @@ -88,16 +87,17 @@ def unstring_flow_params(flow_params): better_params = flow_params.copy() veh_params = flow_params['veh'] - better_veh_params = [eval_veh_params(veh_param) for - veh_param in veh_params] + better_veh_params = [ + eval_veh_params(veh_param) for veh_param in veh_params + ] better_net_params = eval_net_params(flow_params) better_params['veh'] = better_veh_params better_params['net'] = better_net_params if 'additional_params' in flow_params['env']: if 'scenario_type' in flow_params['env']['additional_params']: - evaluated_scenario = eval(flow_params['env']['additional_params'] - ['scenario_type']) + evaluated_scenario = eval( + flow_params['env']['additional_params']['scenario_type']) better_params['env']['additional_params']['scenario_type'] = \ evaluated_scenario @@ -183,8 +183,8 @@ def eval_veh_params(orig_params): new_params['routing_controller'] = new_route_controller if 'sumo_car_following_params' in new_params: cf_params = SumoCarFollowingParams() - cf_params.controller_params = (orig_params['sumo_car_following_params'] - ['controller_params']) + cf_params.controller_params = ( + orig_params['sumo_car_following_params']['controller_params']) new_params['sumo_car_following_params'] = cf_params if 'sumo_lc_params' in new_params: @@ -218,9 +218,11 @@ def get_rllib_params(path): gamma = jsondata['gamma'] horizon = jsondata['horizon'] hidden_layers = jsondata['model']['fcnet_hiddens'] - rllib_params = {'gamma': gamma, - 'horizon': horizon, - 'hidden_layers': hidden_layers} + rllib_params = { + 'gamma': gamma, + 'horizon': horizon, + 'hidden_layers': hidden_layers + } return rllib_params @@ -262,8 +264,14 @@ def get_flow_params(config): return flow_params, make_create_env -def register_env(env_name, sumo_params, type_params, env_params, net_params, - initial_config, scenario, env_version_num=0): +def register_env(env_name, + sumo_params, + type_params, + env_params, + net_params, + initial_config, + scenario, + env_version_num=0): num_steps = env_params.horizon register( id=env_name + '-v' + str(env_version_num), @@ -273,8 +281,7 @@ def register_env(env_name, sumo_params, type_params, env_params, net_params, "env_params": env_params, "sumo_params": sumo_params, "scenario": scenario - } - ) + }) def makexml(name, nsl): @@ -286,8 +293,8 @@ def makexml(name, nsl): def printxml(t, fn): - etree.ElementTree(t).write(fn, pretty_print=True, encoding='UTF-8', - xml_declaration=True) + etree.ElementTree(t).write( + fn, pretty_print=True, encoding='UTF-8', xml_declaration=True) def ensure_dir(path): diff --git a/flow/core/vehicles.py b/flow/core/vehicles.py index 27e227f91..ac22e5e2c 100755 --- a/flow/core/vehicles.py +++ b/flow/core/vehicles.py @@ -11,13 +11,16 @@ from flow.core.params import SumoCarFollowingParams, SumoLaneChangeParams -SPEED_MODES = {"aggressive": 0, "no_collide": 1, "right_of_way": 25, - "all_checks": 31} +SPEED_MODES = { + "aggressive": 0, + "no_collide": 1, + "right_of_way": 25, + "all_checks": 31 +} LC_MODES = {"aggressive": 0, "no_lat_collide": 512, "strategic": 1621} class Vehicles: - def __init__(self): """Base vehicle class. @@ -182,16 +185,27 @@ def add(self, "sumo_lc_params": sumo_lc_params} self.initial.append({ - "veh_id": veh_id, - "acceleration_controller": acceleration_controller, - "lane_change_controller": lane_change_controller, - "routing_controller": routing_controller, - "initial_speed": initial_speed, - "num_vehicles": num_vehicles, - "speed_mode": speed_mode, - "lane_change_mode": lane_change_mode, - "sumo_car_following_params": sumo_car_following_params, - "sumo_lc_params": sumo_lc_params}) + "veh_id": + veh_id, + "acceleration_controller": + acceleration_controller, + "lane_change_controller": + lane_change_controller, + "routing_controller": + routing_controller, + "initial_speed": + initial_speed, + "num_vehicles": + num_vehicles, + "speed_mode": + speed_mode, + "lane_change_mode": + lane_change_mode, + "sumo_car_following_params": + sumo_car_following_params, + "sumo_lc_params": + sumo_lc_params + }) # this is used to return the actual headways from the vehicles class self.minGap[veh_id] = type_params["minGap"] @@ -334,8 +348,7 @@ def update(self, vehicle_obs, sim_obs, env): # updated the list of departed and arrived vehicles self._num_departed.append( len(sim_obs[tc.VAR_DEPARTED_VEHICLES_IDS])) - self._num_arrived.append( - len(sim_obs[tc.VAR_ARRIVED_VEHICLES_IDS])) + self._num_arrived.append(len(sim_obs[tc.VAR_ARRIVED_VEHICLES_IDS])) # update the "headway", "leader", and "follower" variables for veh_id in self.__ids: @@ -423,14 +436,14 @@ def _add_departed(self, veh_id, veh_type, env): self.__controlled_lc_ids.append(veh_id) # subscribe the new vehicle - env.traci_connection.vehicle.subscribe( - veh_id, [tc.VAR_LANE_INDEX, tc.VAR_LANEPOSITION, - tc.VAR_ROAD_ID, tc.VAR_SPEED, tc.VAR_EDGES]) + env.traci_connection.vehicle.subscribe(veh_id, [ + tc.VAR_LANE_INDEX, tc.VAR_LANEPOSITION, tc.VAR_ROAD_ID, + tc.VAR_SPEED, tc.VAR_EDGES + ]) env.traci_connection.vehicle.subscribeLeader(veh_id, 2000) # some constant vehicle parameters to the vehicles class - self.set_length( - veh_id, env.traci_connection.vehicle.getLength(veh_id)) + self.set_length(veh_id, env.traci_connection.vehicle.getLength(veh_id)) # set the absolute position of the vehicle self.set_absolute_position(veh_id, 0) @@ -611,8 +624,9 @@ def get_lane_change_mode(self, veh_id, error=-1001): """ if isinstance(veh_id, (list, np.ndarray)): - return [self.get_lane_change_mode(vehID, error) - for vehID in veh_id] + return [ + self.get_lane_change_mode(vehID, error) for vehID in veh_id + ] return self.__vehicles.get(veh_id, {}).get("lane_change_mode", error) def get_speed_mode(self, veh_id, error=-1001): @@ -669,8 +683,9 @@ def get_absolute_position(self, veh_id, error=-1001): """ if isinstance(veh_id, (list, np.ndarray)): - return [self.get_absolute_position(vehID, error) - for vehID in veh_id] + return [ + self.get_absolute_position(vehID, error) for vehID in veh_id + ] return self.__vehicles.get(veh_id, {}).get("absolute_position", error) def get_position(self, veh_id, error=-1001): @@ -788,8 +803,10 @@ def get_lane_changing_controller(self, veh_id, error=None): """ if isinstance(veh_id, (list, np.ndarray)): - return [self.get_lane_changing_controller(vehID, error) - for vehID in veh_id] + return [ + self.get_lane_changing_controller(vehID, error) + for vehID in veh_id + ] return self.__vehicles.get(veh_id, {}).get("lane_changer", error) def get_routing_controller(self, veh_id, error=None): @@ -808,8 +825,9 @@ def get_routing_controller(self, veh_id, error=None): """ if isinstance(veh_id, (list, np.ndarray)): - return [self.get_routing_controller(vehID, error) - for vehID in veh_id] + return [ + self.get_routing_controller(vehID, error) for vehID in veh_id + ] return self.__vehicles.get(veh_id, {}).get("router", error) def get_route(self, veh_id, error=list()): @@ -993,8 +1011,9 @@ def get_state(self, veh_id, state_name, error=None): specified vehicles at the current time step. """ if isinstance(veh_id, list): - return [self.get_state(vehID, state_name, error) - for vehID in veh_id] + return [ + self.get_state(vehID, state_name, error) for vehID in veh_id + ] return self.__vehicles.get(veh_id, {}).get(state_name, error) def _multi_lane_headways(self, env): @@ -1003,12 +1022,12 @@ def _multi_lane_headways(self, env): edge_list = env.scenario.get_edge_list() junction_list = env.scenario.get_junction_list() tot_list = edge_list + junction_list - num_edges = (len(env.scenario.get_edge_list()) + - len(env.scenario.get_junction_list())) + num_edges = (len(env.scenario.get_edge_list()) + len( + env.scenario.get_junction_list())) # maximum number of lanes in the network - max_lanes = max([env.scenario.num_lanes(edge_id) - for edge_id in tot_list]) + max_lanes = max( + [env.scenario.num_lanes(edge_id) for edge_id in tot_list]) # Key = edge id # Element = list, with the ith element containing tuples with the name diff --git a/flow/envs/__init__.py b/flow/envs/__init__.py index 96de0f63e..39d39a9b7 100755 --- a/flow/envs/__init__.py +++ b/flow/envs/__init__.py @@ -13,9 +13,10 @@ from flow.envs.merge import WaveAttenuationMergePOEnv from flow.envs.test import TestEnv -__all__ = ["Env", "AccelEnv", "LaneChangeAccelEnv", "LaneChangeAccelPOEnv", - "GreenWaveTestEnv", "GreenWaveTestEnv", "WaveAttenuationMergePOEnv", - "TwoLoopsMergePOEnv", "BottleneckEnv", "BottleNeckAccelEnv", - "WaveAttenuationEnv", "WaveAttenuationPOEnv", "TrafficLightGridEnv", - "PO_TrafficLightGridEnv", "DesiredVelocityEnv", "TestEnv", - "BayBridgeEnv"] +__all__ = [ + "Env", "AccelEnv", "LaneChangeAccelEnv", "LaneChangeAccelPOEnv", + "GreenWaveTestEnv", "GreenWaveTestEnv", "WaveAttenuationMergePOEnv", + "TwoLoopsMergePOEnv", "BottleneckEnv", "BottleNeckAccelEnv", + "WaveAttenuationEnv", "WaveAttenuationPOEnv", "TrafficLightGridEnv", + "PO_TrafficLightGridEnv", "DesiredVelocityEnv", "TestEnv", "BayBridgeEnv" +] diff --git a/flow/envs/base_env.py b/flow/envs/base_env.py index c3acce71e..445f2b1e7 100755 --- a/flow/envs/base_env.py +++ b/flow/envs/base_env.py @@ -35,7 +35,6 @@ class Env(gym.Env, Serializable): - def __init__(self, env_params, sumo_params, scenario): """Base environment class. @@ -180,10 +179,12 @@ def start_sumo(self): port = sumolib.miscutils.getFreeSocketPort() # command used to start sumo - sumo_call = [self.sumo_params.sumo_binary, - "-c", self.scenario.cfg, - "--remote-port", str(port), - "--step-length", str(self.sim_step)] + sumo_call = [ + self.sumo_params.sumo_binary, "-c", self.scenario.cfg, + "--remote-port", + str(port), "--step-length", + str(self.sim_step) + ] # add step logs (if requested) if self.sumo_params.no_step_log: @@ -232,8 +233,8 @@ def start_sumo(self): logging.debug(" Step length: " + str(self.sim_step)) # Opening the I/O thread to SUMO - self.sumo_proc = subprocess.Popen(sumo_call, - preexec_fn=os.setsid) + self.sumo_proc = subprocess.Popen( + sumo_call, preexec_fn=os.setsid) # wait a small period of time for the subprocess to activate # before trying to connect with traci @@ -283,16 +284,18 @@ def setup_initial_state(self): # subscribe the requested states for traci-related speedups for veh_id in self.vehicles.get_ids(): - self.traci_connection.vehicle.subscribe( - veh_id, [tc.VAR_LANE_INDEX, tc.VAR_LANEPOSITION, - tc.VAR_ROAD_ID, tc.VAR_SPEED, tc.VAR_EDGES]) + self.traci_connection.vehicle.subscribe(veh_id, [ + tc.VAR_LANE_INDEX, tc.VAR_LANEPOSITION, tc.VAR_ROAD_ID, + tc.VAR_SPEED, tc.VAR_EDGES + ]) self.traci_connection.vehicle.subscribeLeader(veh_id, 2000) # subscribe some simulation parameters needed to check for entering, # exiting, and colliding vehicles - self.traci_connection.simulation.subscribe( - [tc.VAR_DEPARTED_VEHICLES_IDS, tc.VAR_ARRIVED_VEHICLES_IDS, - tc.VAR_TELEPORT_STARTING_VEHICLES_IDS]) + self.traci_connection.simulation.subscribe([ + tc.VAR_DEPARTED_VEHICLES_IDS, tc.VAR_ARRIVED_VEHICLES_IDS, + tc.VAR_TELEPORT_STARTING_VEHICLES_IDS + ]) # subscribe the traffic light for node_id in self.traffic_lights.get_ids(): @@ -331,9 +334,11 @@ def setup_initial_state(self): # collect subscription information from sumo vehicle_obs = self.traci_connection.vehicle.getSubscriptionResults() tls_obs = self.traci_connection.trafficlight.getSubscriptionResults() - id_lists = {tc.VAR_DEPARTED_VEHICLES_IDS: [], - tc.VAR_TELEPORT_STARTING_VEHICLES_IDS: [], - tc.VAR_ARRIVED_VEHICLES_IDS: []} + id_lists = { + tc.VAR_DEPARTED_VEHICLES_IDS: [], + tc.VAR_TELEPORT_STARTING_VEHICLES_IDS: [], + tc.VAR_ARRIVED_VEHICLES_IDS: [] + } # store new observations in the vehicles and traffic lights class self.vehicles.update(vehicle_obs, id_lists, self) @@ -394,8 +399,8 @@ def step(self, rl_actions): veh_id) target_lane = lc_contr.get_action(self) direction.append(target_lane) - self.apply_lane_change(self.vehicles.get_controlled_lc_ids(), - direction=direction) + self.apply_lane_change( + self.vehicles.get_controlled_lc_ids(), direction=direction) # perform (optionally) routing actions for all vehicle in the # network, including rl and sumo-controlled vehicles @@ -551,17 +556,23 @@ def reset(self): try: self.traci_connection.vehicle.addFull( - veh_id, route_id, typeID=str(type_id), + veh_id, + route_id, + typeID=str(type_id), departLane=str(lane_index), - departPos=str(lane_pos), departSpeed=str(speed)) + departPos=str(lane_pos), + departSpeed=str(speed)) except (FatalTraCIError, TraCIException): # if a vehicle was not removed in the first attempt, remove it # now and then reintroduce it self.traci_connection.vehicle.remove(veh_id) self.traci_connection.vehicle.addFull( - veh_id, route_id, typeID=str(type_id), + veh_id, + route_id, + typeID=str(type_id), departLane=str(lane_index), - departPos=str(lane_pos), departSpeed=str(speed)) + departPos=str(lane_pos), + departSpeed=str(speed)) self.traci_connection.simulationStep() @@ -624,9 +635,10 @@ def apply_rl_actions(self, rl_actions=None): # clip according to the action space requirements if isinstance(self.action_space, Box): - rl_actions = np.clip(rl_actions, - a_min=self.action_space.low, - a_max=self.action_space.high) + rl_actions = np.clip( + rl_actions, + a_min=self.action_space.low, + a_max=self.action_space.high) self._apply_rl_actions(rl_actions) @@ -650,7 +662,7 @@ def apply_acceleration(self, veh_ids, acc): for i, vid in enumerate(veh_ids): if acc[i] is not None: this_vel = self.vehicles.get_speed(vid) - next_vel = max([this_vel + acc[i]*self.sim_step, 0]) + next_vel = max([this_vel + acc[i] * self.sim_step, 0]) self.traci_connection.vehicle.slowDown(vid, next_vel, 1) def apply_lane_change(self, veh_ids, direction): @@ -685,8 +697,9 @@ def apply_lane_change(self, veh_ids, direction): # change out of range this_lane = self.vehicles.get_lane(veh_id) this_edge = self.vehicles.get_edge(veh_id) - target_lane = min(max(this_lane + direction[i], 0), - self.scenario.num_lanes(this_edge) - 1) + target_lane = min( + max(this_lane + direction[i], 0), + self.scenario.num_lanes(this_edge) - 1) # perform the requested lane action action in TraCI if target_lane != this_lane: @@ -731,8 +744,8 @@ def get_x_by_id(self, veh_id): if self.vehicles.get_edge(veh_id) == '': # occurs when a vehicle crashes is teleported for some other reason return 0. - return self.scenario.get_x(self.vehicles.get_edge(veh_id), - self.vehicles.get_position(veh_id)) + return self.scenario.get_x( + self.vehicles.get_edge(veh_id), self.vehicles.get_position(veh_id)) def sort_by_position(self): """Sorts the vehicle ids of vehicles in the network by position. @@ -750,8 +763,9 @@ def sort_by_position(self): of None should be returned """ if self.env_params.sort_vehicles: - sorted_ids = sorted(self.vehicles.get_ids(), - key=self.vehicles.get_absolute_position) + sorted_ids = sorted( + self.vehicles.get_ids(), + key=self.vehicles.get_absolute_position) return sorted_ids, None else: return self.vehicles.get_ids(), None @@ -772,8 +786,8 @@ def update_vehicle_colors(self): for veh_id in self.vehicles.get_rl_ids(): try: # color rl vehicles red - self.traci_connection.vehicle.setColor(vehID=veh_id, - color=(255, 0, 0, 255)) + self.traci_connection.vehicle.setColor( + vehID=veh_id, color=(255, 0, 0, 255)) except (FatalTraCIError, TraCIException): pass @@ -785,8 +799,8 @@ def update_vehicle_colors(self): else: # color unobserved human-driven vehicles white color = (255, 255, 255, 255) - self.traci_connection.vehicle.setColor(vehID=veh_id, - color=color) + self.traci_connection.vehicle.setColor( + vehID=veh_id, color=color) except (FatalTraCIError, TraCIException): pass diff --git a/flow/envs/bay_bridge/base.py b/flow/envs/bay_bridge/base.py index a87de7098..8cb188d8f 100644 --- a/flow/envs/bay_bridge/base.py +++ b/flow/envs/bay_bridge/base.py @@ -3,18 +3,19 @@ from flow.envs import Env -EDGE_LIST = ['11198593', '236348360#1', '157598960', '11415208', '236348361', - '11198599', '35536683', '11198595.0', '11198595.656.0', "gneE5", - '340686911#3', '23874736', '119057701', '517934789', '236348364', - '124952171', "gneE0", "11198599", "124952182.0", '236348360#0', - '497579295', '340686911#2.0', '340686911#1', '394443191', - '322962944', "32661309#1.0", "90077193#1.777", "90077193#1.0", - "90077193#1.812", "gneE1", "183343422", "393649534", "32661316", - "4757680", "124952179", "11189946", "119058993", "28413679", - "11197898", "123741311", "123741303", "90077193#0", "28413687#0", - "28413687#1", "11197889", "123741382#0", "123741382#1", "gneE3", - "340686911#0.54.0", "340686911#0.54.54.0", - "340686911#0.54.54.127.0", "340686911#2.35"] +EDGE_LIST = [ + '11198593', '236348360#1', '157598960', '11415208', '236348361', + '11198599', '35536683', '11198595.0', '11198595.656.0', "gneE5", + '340686911#3', '23874736', '119057701', '517934789', '236348364', + '124952171', "gneE0", "11198599", "124952182.0", '236348360#0', + '497579295', '340686911#2.0', '340686911#1', '394443191', '322962944', + "32661309#1.0", "90077193#1.777", "90077193#1.0", "90077193#1.812", + "gneE1", "183343422", "393649534", "32661316", "4757680", "124952179", + "11189946", "119058993", "28413679", "11197898", "123741311", "123741303", + "90077193#0", "28413687#0", "28413687#1", "11197889", "123741382#0", + "123741382#1", "gneE3", "340686911#0.54.0", "340686911#0.54.54.0", + "340686911#0.54.54.127.0", "340686911#2.35" +] MAX_LANES = 24 NUM_EDGES = len(EDGE_LIST) @@ -85,8 +86,8 @@ def additional_command(self): self.edge_dict = defaultdict(list) # update the dict with all the edges in edge_list so we can look # forward for edges - self.edge_dict.update((k, [[] for _ in range(MAX_LANES)]) - for k in EDGE_LIST) + self.edge_dict.update( + (k, [[] for _ in range(MAX_LANES)]) for k in EDGE_LIST) for veh_id in self.vehicles.get_ids(): edge = self.vehicles.get_edge(veh_id) if edge not in self.edge_dict: @@ -134,7 +135,8 @@ def ramp_meter_lane_change_control(self): color = self.traci_connection.vehicle.getColor(veh_id) self.cars_before_ramp[veh_id] = { "lane_change_mode": lane_change_mode, - "color": color} + "color": color + } self.traci_connection.vehicle.setLaneChangeMode( veh_id, 512) self.traci_connection.vehicle.setColor( @@ -152,13 +154,18 @@ def apply_toll_bridge_control(self): self.traci_connection.vehicle.setLaneChangeMode( veh_id, lane_change_mode) if lane not in FAST_TRACK_ON: - self.toll_wait_time[lane] = max(0, np.random.normal( - loc=MEAN_SECONDS_WAIT_AT_TOLL / self.sim_step, - scale=1 / self.sim_step)) + self.toll_wait_time[lane] = max( + 0, + np.random.normal( + loc=MEAN_SECONDS_WAIT_AT_TOLL / self.sim_step, + scale=1 / self.sim_step)) else: - self.toll_wait_time[lane] = max(0, np.random.normal( - loc=MEAN_SECONDS_WAIT_AT_FAST_TRACK / self.sim_step, - scale=1 / self.sim_step)) + self.toll_wait_time[lane] = max( + 0, + np.random.normal( + loc=MEAN_SECONDS_WAIT_AT_FAST_TRACK / + self.sim_step, + scale=1 / self.sim_step)) cars_that_have_left.append(veh_id) @@ -178,7 +185,9 @@ def apply_toll_bridge_control(self): lc_mode = self.vehicles.get_lane_change_mode(veh_id) color = self.traci_connection.vehicle.getColor(veh_id) self.cars_waiting_for_toll[veh_id] = { - "lane_change_mode": lc_mode, "color": color} + "lane_change_mode": lc_mode, + "color": color + } self.traci_connection.vehicle.setLaneChangeMode( veh_id, 512) self.traci_connection.vehicle.setColor( diff --git a/flow/envs/bottleneck_env.py b/flow/envs/bottleneck_env.py index e6541e8f1..bf8befdef 100644 --- a/flow/envs/bottleneck_env.py +++ b/flow/envs/bottleneck_env.py @@ -55,7 +55,6 @@ "target_velocity": 30, # if an RL vehicle exits, place it back at the front "add_rl_if_exit": True, - } # Keys for VSL style experiments @@ -64,11 +63,13 @@ "controlled_segments": [("1", 1, True), ("2", 1, True), ("3", 1, True), ("4", 1, True), ("5", 1, True)], # whether lanes in a segment have the same action or not - "symmetric": False, + "symmetric": + False, # which edges are observed "observed_segments": [("1", 1), ("2", 1), ("3", 1), ("4", 1), ("5", 1)], # whether the inflow should be reset on each rollout - "reset_inflow": False, + "reset_inflow": + False, # the range of inflows to reset on "inflow_range": [1000, 2000] } @@ -82,7 +83,6 @@ class BottleneckEnv(Env): - def __init__(self, env_params, sumo_params, scenario): """Environment used as a simplified representation of the toll booth portion of the bay bridge. Contains ramp meters, and a toll both. @@ -95,12 +95,11 @@ def __init__(self, env_params, sumo_params, scenario): """ for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) for p in ADDITIONAL_NET_PARAMS.keys(): if p not in scenario.net_params.additional_params: - raise KeyError('Net parameter "{}" not supplied'. - format(p)) + raise KeyError('Net parameter "{}" not supplied'.format(p)) self.num_rl = deepcopy(scenario.vehicles.num_rl_vehicles) super().__init__(env_params, sumo_params, scenario) @@ -113,8 +112,8 @@ def __init__(self, env_params, sumo_params, scenario): self.toll_wait_time = np.abs( np.random.normal(MEAN_NUM_SECONDS_WAIT_AT_TOLL / self.sim_step, 4 / self.sim_step, NUM_TOLL_LANES * self.scaling)) - self.fast_track_lanes = range(int(np.ceil(1.5 * self.scaling)), - int(np.ceil(2.6 * self.scaling))) + self.fast_track_lanes = range( + int(np.ceil(1.5 * self.scaling)), int(np.ceil(2.6 * self.scaling))) self.tl_state = "" self.disable_tb = env_params.get_additional_param("disable_tb") @@ -151,15 +150,16 @@ def additional_command(self): self.edge_dict = defaultdict(list) # update the dict with all the edges in edge_list # so we can look forward for edges - self.edge_dict.update( - (k, [[] for _ in range(MAX_LANES * self.scaling)]) - for k in EDGE_LIST) + self.edge_dict.update((k, [[] + for _ in range(MAX_LANES * self.scaling)]) + for k in EDGE_LIST) for veh_id in self.vehicles.get_ids(): try: edge = self.vehicles.get_edge(veh_id) if edge not in self.edge_dict: - self.edge_dict.update( - {edge: [[] for _ in range(MAX_LANES * self.scaling)]}) + self.edge_dict.update({ + edge: [[] for _ in range(MAX_LANES * self.scaling)] + }) lane = self.vehicles.get_lane(veh_id) # integer pos = self.vehicles.get_position(veh_id) self.edge_dict[edge][lane].append((veh_id, pos)) @@ -229,10 +229,10 @@ def alinea(self): self.feedback_timer = 0 # now implement the integral controller update # find all the vehicles in an edge - q_update = self.feedback_coeff * (self.n_crit - - np.average(self.smoothed_num)) - self.q = np.clip(self.q + q_update, - a_min=self.q_min, a_max=self.q_max) + q_update = self.feedback_coeff * ( + self.n_crit - np.average(self.smoothed_num)) + self.q = np.clip( + self.q + q_update, a_min=self.q_min, a_max=self.q_max) # convert q to cycle time self.cycle_time = 7200 / self.q @@ -257,14 +257,16 @@ def apply_toll_bridge_control(self): veh_id, lane_change_mode) if lane not in self.fast_track_lanes: self.toll_wait_time[lane] = max( - 0, np.random.normal(MEAN_NUM_SECONDS_WAIT_AT_TOLL / - self.sim_step, - 1 / self.sim_step)) + 0, + np.random.normal( + MEAN_NUM_SECONDS_WAIT_AT_TOLL / self.sim_step, + 1 / self.sim_step)) else: self.toll_wait_time[lane] = max( - 0, np.random.normal(MEAN_NUM_SECONDS_WAIT_AT_FAST_TRACK - / self.sim_step, - 1 / self.sim_step)) + 0, + np.random.normal( + MEAN_NUM_SECONDS_WAIT_AT_FAST_TRACK / + self.sim_step, 1 / self.sim_step)) cars_that_have_left.append(veh_id) @@ -287,8 +289,8 @@ def apply_toll_bridge_control(self): self.cars_waiting_for_toll[veh_id] = \ {"lane_change_mode": lane_change_mode, "color": color} - self.traci_connection.vehicle.setLaneChangeMode(veh_id, - 512) + self.traci_connection.vehicle.setLaneChangeMode( + veh_id, 512) self.traci_connection.vehicle.setColor( veh_id, (255, 0, 255, 0)) else: @@ -307,8 +309,10 @@ def apply_toll_bridge_control(self): tlsID=TB_TL_ID, state=newTLState) def distance_to_bottleneck(self, veh_id): - pre_bottleneck_edges = {str(i): self.scenario.edge_length(str(i)) - for i in [1, 2, 3]} + pre_bottleneck_edges = { + str(i): self.scenario.edge_length(str(i)) + for i in [1, 2, 3] + } edge_pos = self.vehicles.get_position(veh_id) edge = self.vehicles.get_edge(veh_id) if edge in pre_bottleneck_edges: @@ -326,9 +330,11 @@ def get_bottleneck_density(self, lanes=None): BOTTLE_NECK_LEN = 280 bottleneck_ids = self.vehicles.get_ids_by_edge(['3', '4']) if lanes: - veh_ids = [veh_id for veh_id in bottleneck_ids - if str(self.vehicles.get_edge(veh_id)) + "_" + - str(self.vehicles.get_lane(veh_id)) in lanes] + veh_ids = [ + veh_id for veh_id in bottleneck_ids + if str(self.vehicles.get_edge(veh_id)) + "_" + + str(self.vehicles.get_lane(veh_id)) in lanes + ] else: veh_ids = self.vehicles.get_ids_by_edge(['3', '4']) return len(veh_ids) / BOTTLE_NECK_LEN @@ -341,13 +347,19 @@ def get_avg_bottleneck_velocity(self): # Dummy action and observation spaces @property def action_space(self): - return Box(low=-float("inf"), high=float("inf"), shape=(1,), - dtype=np.float32) + return Box( + low=-float("inf"), + high=float("inf"), + shape=(1, ), + dtype=np.float32) @property def observation_space(self): - return Box(low=-float("inf"), high=float("inf"), shape=(1,), - dtype=np.float32) + return Box( + low=-float("inf"), + high=float("inf"), + shape=(1, ), + dtype=np.float32) def compute_reward(self, state, rl_actions, **kwargs): """ Outflow rate over last ten seconds normalized to max of 1 """ @@ -391,8 +403,8 @@ class BottleNeckAccelEnv(BottleneckEnv): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_RL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) super().__init__(env_params, sumo_params, scenario) self.add_rl_if_exit = env_params.get_additional_param("add_rl_if_exit") @@ -404,7 +416,7 @@ def observation_space(self): num_obs = 2 * num_edges + 4 * MAX_LANES * self.scaling \ * num_rl_veh + 4 * num_rl_veh - return Box(low=0, high=1, shape=(num_obs,), dtype=np.float32) + return Box(low=0, high=1, shape=(num_obs, ), dtype=np.float32) def get_state(self): headway_scale = 1000 @@ -418,9 +430,8 @@ def get_state(self): # check if we have skipped a vehicle, if not, pad rl_id_num = self.rl_id_list.index(veh_id) if rl_id_num != id_counter: - rl_obs = np.concatenate((rl_obs, - np.zeros(4 * (rl_id_num - - id_counter)))) + rl_obs = np.concatenate( + (rl_obs, np.zeros(4 * (rl_id_num - id_counter)))) id_counter = rl_id_num + 1 else: id_counter += 1 @@ -435,13 +446,11 @@ def get_state(self): edge_num = -1 else: edge_num = int(edge_num) / 6 - rl_obs = np.concatenate((rl_obs, - [self.get_x_by_id(veh_id) / 1000, - (self.vehicles.get_speed(veh_id) / - self.max_speed), - (self.vehicles.get_lane(veh_id) / - MAX_LANES), - edge_num])) + rl_obs = np.concatenate((rl_obs, [ + self.get_x_by_id(veh_id) / 1000, + (self.vehicles.get_speed(veh_id) / self.max_speed), + (self.vehicles.get_lane(veh_id) / MAX_LANES), edge_num + ])) # if all the missing vehicles are at the end, pad diff = self.num_rl - int(rl_obs.shape[0] / 4) if diff > 0: @@ -455,41 +464,41 @@ def get_state(self): # check if we have skipped a vehicle, if not, pad rl_id_num = self.rl_id_list.index(veh_id) if rl_id_num != id_counter: - pad_mat = np.zeros(4 * MAX_LANES * self.scaling * - (rl_id_num - id_counter)) + pad_mat = np.zeros( + 4 * MAX_LANES * self.scaling * (rl_id_num - id_counter)) relative_obs = np.concatenate((relative_obs, pad_mat)) id_counter = rl_id_num + 1 else: id_counter += 1 num_lanes = MAX_LANES * self.scaling - headway = np.asarray([1000 for _ in - range(num_lanes)]) / headway_scale - tailway = np.asarray([1000 for _ in - range(num_lanes)]) / headway_scale - vel_in_front = np.asarray([0 for _ in - range(num_lanes)]) / self.max_speed - vel_behind = np.asarray([0 for _ in - range(num_lanes)]) / self.max_speed + headway = np.asarray([1000 + for _ in range(num_lanes)]) / headway_scale + tailway = np.asarray([1000 + for _ in range(num_lanes)]) / headway_scale + vel_in_front = np.asarray([0 for _ in range(num_lanes) + ]) / self.max_speed + vel_behind = np.asarray([0 for _ in range(num_lanes) + ]) / self.max_speed lane_leaders = self.vehicles.get_lane_leaders(veh_id) lane_followers = self.vehicles.get_lane_followers(veh_id) lane_headways = self.vehicles.get_lane_headways(veh_id) lane_tailways = self.vehicles.get_lane_tailways(veh_id) - headway[0:len(lane_headways)] = (np.asarray(lane_headways) / - headway_scale) - tailway[0:len(lane_tailways)] = (np.asarray(lane_tailways) / - headway_scale) + headway[0:len(lane_headways)] = ( + np.asarray(lane_headways) / headway_scale) + tailway[0:len(lane_tailways)] = ( + np.asarray(lane_tailways) / headway_scale) for i, lane_leader in enumerate(lane_leaders): if lane_leader != '': - vel_in_front[i] = (self.vehicles.get_speed(lane_leader) / - self.max_speed) + vel_in_front[i] = ( + self.vehicles.get_speed(lane_leader) / self.max_speed) for i, lane_follower in enumerate(lane_followers): if lane_followers != '': - vel_behind[i] = (self.vehicles.get_speed(lane_follower) - / self.max_speed) + vel_behind[i] = (self.vehicles.get_speed(lane_follower) / + self.max_speed) - relative_obs = np.concatenate((relative_obs, headway, - tailway, vel_in_front, vel_behind)) + relative_obs = np.concatenate((relative_obs, headway, tailway, + vel_in_front, vel_behind)) # if all the missing vehicles are at the end, pad diff = self.num_rl - int(relative_obs.shape[0] / (4 * MAX_LANES)) @@ -502,8 +511,8 @@ def get_state(self): for edge in self.scenario.get_edge_list(): veh_ids = self.vehicles.get_ids_by_edge(edge) if len(veh_ids) > 0: - avg_speed = (sum(self.vehicles.get_speed(veh_ids)) - / len(veh_ids)) / self.max_speed + avg_speed = (sum(self.vehicles.get_speed(veh_ids)) / + len(veh_ids)) / self.max_speed density = len(veh_ids) / self.scenario.edge_length(edge) edge_obs += [avg_speed, density] else: @@ -514,14 +523,13 @@ def get_state(self): def compute_reward(self, state, rl_actions, **kwargs): num_rl = self.vehicles.num_rl_vehicles lane_change_acts = np.abs(np.round(rl_actions[1::2])[:num_rl]) - return (rewards.desired_velocity(self) + - rewards.rl_forward_progress(self, gain=0.1) - - rewards.boolean_action_penalty(lane_change_acts, gain=1.0)) + return (rewards.desired_velocity(self) + rewards.rl_forward_progress( + self, gain=0.1) - rewards.boolean_action_penalty( + lane_change_acts, gain=1.0)) def sort_by_position(self): if self.env_params.sort_vehicles: - sorted_ids = sorted(self.vehicles.get_ids(), - key=self.get_x_by_id) + sorted_ids = sorted(self.vehicles.get_ids(), key=self.get_x_by_id) return sorted_ids, None else: return self.vehicles.get_ids(), None @@ -541,8 +549,10 @@ def _apply_rl_actions(self, actions): direction = np.round(actions[1::2])[:num_rl] # re-arrange actions according to mapping in observation space - sorted_rl_ids = [veh_id for veh_id in self.sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in self.sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] # represents vehicles that are allowed to change lanes non_lane_changing_veh = \ @@ -562,8 +572,8 @@ def additional_command(self): num_rl = self.vehicles.num_rl_vehicles if num_rl != len(self.rl_id_list) and self.add_rl_if_exit: # find the vehicles that have exited - diff_list = list(set(self.rl_id_list).difference( - self.vehicles.get_rl_ids())) + diff_list = list( + set(self.rl_id_list).difference(self.vehicles.get_rl_ids())) for rl_id in diff_list: # distribute rl cars evenly over lanes lane_num = self.rl_id_list.index(rl_id) % \ @@ -571,9 +581,12 @@ def additional_command(self): # reintroduce it at the start of the network try: self.traci_connection.vehicle.addFull( - rl_id, 'route1', typeID=str('rl'), + rl_id, + 'route1', + typeID=str('rl'), departLane=str(lane_num), - departPos="0", departSpeed="max") + departPos="0", + departSpeed="max") except Exception: pass @@ -601,15 +614,15 @@ def __init__(self, env_params, sumo_params, scenario): super().__init__(env_params, sumo_params, scenario) for p in ADDITIONAL_VSL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) # default (edge, segment, controlled) status add_env_params = self.env_params.additional_params default = [("1", 1, True), ("2", 1, True), ("3", 1, True), ("4", 1, True), ("5", 1, True)] - super(DesiredVelocityEnv, self).__init__(env_params, - sumo_params, scenario) + super(DesiredVelocityEnv, self).__init__(env_params, sumo_params, + scenario) self.segments = add_env_params.get("controlled_segments", default) # number of segments for each edge @@ -618,19 +631,21 @@ def __init__(self, env_params, sumo_params, scenario): # whether an edge is controlled self.is_controlled = [segment[2] for segment in self.segments] - self.num_controlled_segments = [segment[1] for segment in - self.segments if segment[2]] + self.num_controlled_segments = [ + segment[1] for segment in self.segments if segment[2] + ] # sum of segments - self.total_segments = int(np.sum([segment[1] for - segment in self.segments])) + self.total_segments = int( + np.sum([segment[1] for segment in self.segments])) # sum of controlled segments segment_list = [segment[1] for segment in self.segments if segment[2]] self.total_controlled_segments = int(np.sum(segment_list)) # list of controlled edges for comparison - self.controlled_edges = [segment[0] for segment in self.segments - if segment[2]] + self.controlled_edges = [ + segment[0] for segment in self.segments if segment[2] + ] additional_params = env_params.additional_params @@ -668,12 +683,14 @@ def __init__(self, env_params, sumo_params, scenario): self.action_index = [0] for i, (edge, segment, controlled) in enumerate(self.segments[:-1]): if self.symmetric: - self.action_index += [self.action_index[i] + - segment * controlled] + self.action_index += [ + self.action_index[i] + segment * controlled + ] else: num_lanes = self.scenario.num_lanes(edge) - self.action_index += [self.action_index[i] + - segment * controlled * num_lanes] + self.action_index += [ + self.action_index[i] + segment * controlled * num_lanes + ] self.action_index = {} action_list = [0] @@ -686,8 +703,10 @@ def __init__(self, env_params, sumo_params, scenario): else: num_lanes = self.scenario.num_lanes(edge) self.action_index[edge] = [action_list[index]] - action_list += [action_list[index] - + num_segments * controlled * num_lanes] + action_list += [ + action_list[index] + + num_segments * controlled * num_lanes + ] index += 1 @property @@ -698,8 +717,7 @@ def observation_space(self): for segment in self.obs_segments: num_obs += 4 * segment[1] * self.scenario.num_lanes(segment[0]) num_obs += 1 - return Box(low=0.0, high=1.0, shape=(num_obs,), - dtype=np.float32) + return Box(low=0.0, high=1.0, shape=(num_obs, ), dtype=np.float32) @property def action_space(self): @@ -711,9 +729,8 @@ def action_space(self): if segment[2]: # if controlled num_lanes = self.scenario.num_lanes(segment[0]) action_size += num_lanes * segment[1] - return Box(low=-1.5, high=1.0, - shape=(int(action_size),), - dtype=np.float32) + return Box( + low=-1.5, high=1.0, shape=(int(action_size), ), dtype=np.float32) def get_state(self): # action space is number of vehicles in each segment in each lane, @@ -762,16 +779,17 @@ def get_state(self): # compute the mean speed if the speed isn't zero num_rl = len(num_rl_vehicles_list) num_veh = len(num_vehicles_list) - mean_speed = np.nan_to_num([vehicle_speeds_list[i] / unnorm_veh_list[i] - if int(unnorm_veh_list[i]) else 0 - for i in range(num_veh)]) + mean_speed = np.nan_to_num([ + vehicle_speeds_list[i] / unnorm_veh_list[i] + if int(unnorm_veh_list[i]) else 0 for i in range(num_veh) + ]) mean_speed_norm = mean_speed / 50 - mean_rl_speed = np.nan_to_num([rl_speeds_list[i] / unnorm_rl_list[i] - if int(unnorm_rl_list[i]) else 0 - for i in range(num_rl) - ]) / 50 - outflow = np.asarray(self.vehicles.get_outflow_rate(20 * self.sim_step) - / 2000.0) + mean_rl_speed = np.nan_to_num([ + rl_speeds_list[i] / unnorm_rl_list[i] + if int(unnorm_rl_list[i]) else 0 for i in range(num_rl) + ]) / 50 + outflow = np.asarray( + self.vehicles.get_outflow_rate(20 * self.sim_step) / 2000.0) return np.concatenate((num_vehicles_list, num_rl_vehicles_list, mean_speed_norm, mean_rl_speed, [outflow])) @@ -794,13 +812,12 @@ def _apply_rl_actions(self, rl_actions): num_lanes = self.scenario.num_lanes(edge) # find what segment we fall into bucket = np.searchsorted(self.slices[edge], pos) - 1 - action = rl_actions[int(lane) + bucket * num_lanes - + self.action_index[edge]] + action = rl_actions[int(lane) + bucket * num_lanes + + self.action_index[edge]] else: # find what segment we fall into bucket = np.searchsorted(self.slices[edge], pos) - 1 - action = rl_actions[bucket + - self.action_index[edge]] + action = rl_actions[bucket + self.action_index[edge]] traci_veh = self.traci_connection.vehicle max_speed_curr = traci_veh.getMaxSpeed(rl_id) @@ -825,41 +842,46 @@ def reset(self): add_params = self.env_params.additional_params if add_params.get("reset_inflow"): inflow_range = add_params.get("inflow_range") - flow_rate = np.random.uniform(min(inflow_range), - max(inflow_range)) * self.scaling + flow_rate = np.random.uniform( + min(inflow_range), max(inflow_range)) * self.scaling for _ in range(100): try: inflow = InFlows() - inflow.add(veh_type="followerstopper", edge="1", - vehs_per_hour=flow_rate * .1, - departLane="random", departSpeed=10) - inflow.add(veh_type="human", edge="1", - vehs_per_hour=flow_rate * .9, - departLane="random", departSpeed=10) + inflow.add( + veh_type="followerstopper", + edge="1", + vehs_per_hour=flow_rate * .1, + departLane="random", + departSpeed=10) + inflow.add( + veh_type="human", + edge="1", + vehs_per_hour=flow_rate * .9, + departLane="random", + departSpeed=10) additional_net_params = {"scaling": self.scaling} net_params = NetParams( in_flows=inflow, no_internal_links=False, - additional_params=additional_net_params - ) + additional_params=additional_net_params) vehicles = Vehicles() - vehicles.add(veh_id="human", - speed_mode=9, - lane_change_controller=( - SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - lane_change_mode=0, # 1621,#0b100000101, - num_vehicles=1 * self.scaling) - vehicles.add(veh_id="followerstopper", - acceleration_controller=(RLController, {}), - lane_change_controller=( - SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode=9, - lane_change_mode=0, - num_vehicles=1 * self.scaling) + vehicles.add( + veh_id="human", + speed_mode=9, + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + lane_change_mode=0, # 1621,#0b100000101, + num_vehicles=1 * self.scaling) + vehicles.add( + veh_id="followerstopper", + acceleration_controller=(RLController, {}), + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode=9, + lane_change_mode=0, + num_vehicles=1 * self.scaling) self.vehicles = vehicles # delete the cfg and net files @@ -867,18 +889,18 @@ def reset(self): net_name = net_path + self.scenario.generator.name cfg_path = self.scenario.generator.cfg_path cfg_name = cfg_path + self.scenario.generator.name - for f in glob.glob(net_name+'*'): + for f in glob.glob(net_name + '*'): os.remove(f) - for f in glob.glob(cfg_name+'*'): + for f in glob.glob(cfg_name + '*'): os.remove(f) self.scenario = self.scenario.__class__( name=self.scenario.orig_name, generator_class=self.scenario.generator_class, - vehicles=vehicles, net_params=net_params, + vehicles=vehicles, + net_params=net_params, initial_config=self.scenario.initial_config, - traffic_lights=self.scenario.traffic_lights - ) + traffic_lights=self.scenario.traffic_lights) observation = super().reset() # reset the timer to zero diff --git a/flow/envs/green_wave_env.py b/flow/envs/green_wave_env.py index 20e3b6dd2..5cdcf3eef 100644 --- a/flow/envs/green_wave_env.py +++ b/flow/envs/green_wave_env.py @@ -55,6 +55,7 @@ class TrafficLightGridEnv(Env): reach the end of the network in order to ensure a constant number of vehicles. """ + def __init__(self, env_params, sumo_params, scenario): self.grid_array = scenario.net_params.additional_params["grid_array"] self.rows = self.grid_array["row_num"] @@ -70,7 +71,8 @@ def __init__(self, env_params, sumo_params, scenario): self.obs_var_labels = { 'edges': np.zeros((self.steps, self.vehicles.num_vehicles)), 'velocities': np.zeros((self.steps, self.vehicles.num_vehicles)), - 'positions': np.zeros((self.steps, self.vehicles.num_vehicles))} + 'positions': np.zeros((self.steps, self.vehicles.num_vehicles)) + } self.node_mapping = scenario.get_node_mapping() # keeps track of the last time the light was allowed to change. @@ -105,39 +107,60 @@ def action_space(self): if self.discrete: return Discrete(2 ** self.num_traffic_lights) else: - return Box(low=0, high=1, shape=(self.num_traffic_lights,), - dtype=np.float32) + return Box( + low=0, + high=1, + shape=(self.num_traffic_lights,), + dtype=np.float32) @property def observation_space(self): - speed = Box(low=0, high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - dist_to_intersec = Box(low=0., high=np.inf, - shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - edge_num = Box(low=0., high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - traffic_lights = Box(low=0., high=1, - shape=(3 * self.rows * self.cols,), - dtype=np.float32) + speed = Box( + low=0, + high=1, + shape=(self.vehicles.num_vehicles,), + dtype=np.float32) + dist_to_intersec = Box( + low=0., + high=np.inf, + shape=(self.vehicles.num_vehicles,), + dtype=np.float32) + edge_num = Box( + low=0., + high=1, + shape=(self.vehicles.num_vehicles,), + dtype=np.float32) + traffic_lights = Box( + low=0., + high=1, + shape=(3 * self.rows * self.cols,), + dtype=np.float32) return Tuple((speed, dist_to_intersec, edge_num, traffic_lights)) def get_state(self): # compute the normalizers - max_dist = max(self.scenario.short_length, - self.scenario.long_length, + max_dist = max(self.scenario.short_length, self.scenario.long_length, self.scenario.inner_length) # get the state arrays - speeds = [self.vehicles.get_speed(veh_id) / self.scenario.max_speed - for veh_id in self.vehicles.get_ids()] - dist_to_intersec = [self.get_distance_to_intersection(veh_id)/max_dist - for veh_id in self.vehicles.get_ids()] - edges = [self._convert_edge(self.vehicles.get_edge(veh_id)) / ( - self.scenario.num_edges - 1) for veh_id in self.vehicles.get_ids()] - - state = [speeds, dist_to_intersec, edges, - self.last_change.flatten().tolist()] + speeds = [ + self.vehicles.get_speed(veh_id) / self.scenario.max_speed + for veh_id in self.vehicles.get_ids() + ] + dist_to_intersec = [ + self.get_distance_to_intersection(veh_id) / max_dist + for veh_id in self.vehicles.get_ids() + ] + edges = [ + self._convert_edge(self.vehicles.get_edge(veh_id)) / + (self.scenario.num_edges - 1) + for veh_id in self.vehicles.get_ids() + ] + + state = [ + speeds, dist_to_intersec, edges, + self.last_change.flatten().tolist() + ] return np.array(state) def _apply_rl_actions(self, rl_actions): @@ -160,22 +183,26 @@ def _apply_rl_actions(self, rl_actions): if self.last_change[i, 1] == 0: self.traffic_lights.set_state( node_id='center{}'.format(i), - state="GGGrrrGGGrrr", env=self) + state="GGGrrrGGGrrr", + env=self) else: self.traffic_lights.set_state( node_id='center{}'.format(i), - state='rrrGGGrrrGGG', env=self) + state='rrrGGGrrrGGG', + env=self) self.last_change[i, 2] = 1 else: if action: if self.last_change[i, 1] == 0: self.traffic_lights.set_state( node_id='center{}'.format(i), - state='yyyrrryyyrrr', env=self) + state='yyyrrryyyrrr', + env=self) else: self.traffic_lights.set_state( node_id='center{}'.format(i), - state='rrryyyrrryyy', env=self) + state='rrryyyrrryyy', + env=self) self.last_change[i, 0] = 0.0 self.last_change[i, 1] = not self.last_change[i, 1] self.last_change[i, 2] = 0 @@ -287,8 +314,8 @@ def _split_edge(self, edge): if edge: if edge[0] == ":": # center center_index = int(edge.split("center")[1][0]) - base = ((self.cols+1) * self.rows * 2) \ - + ((self.rows+1) * self.cols * 2) + base = ((self.cols + 1) * self.rows * 2) \ + + ((self.rows + 1) * self.cols * 2) return base + center_index + 1 else: pattern = re.compile(r"[a-zA-Z]+") @@ -347,9 +374,12 @@ def _reroute_if_final_edge(self, veh_id): type_id = self.vehicles.get_state(veh_id, "type") lane_index = self.vehicles.get_lane(veh_id) self.traci_connection.vehicle.addFull( - veh_id, route_id, typeID=str(type_id), + veh_id, + route_id, + typeID=str(type_id), departLane=str(lane_index), - departPos="0", departSpeed="max") + departPos="0", + departSpeed="max") speed_mode = self.vehicles.type_parameters[type_id]["speed_mode"] self.traci_connection.vehicle.setSpeedMode(veh_id, speed_mode) @@ -362,18 +392,23 @@ def k_closest_to_intersection(self, edges, k): if k < 0: raise IndexError("k must be greater than 0") dists = [] + + def sort_lambda(veh_id): + return self.get_distance_to_intersection(veh_id) + if isinstance(edges, list): for edge in edges: vehicles = self.vehicles.get_ids_by_edge(edge) - dist = sorted(vehicles, - key=lambda veh_id: - self.get_distance_to_intersection(veh_id)) + dist = sorted( + vehicles, + key=sort_lambda + ) dists += dist[:k] else: vehicles = self.vehicles.get_ids_by_edge(edges) - dist = sorted(vehicles, - key=lambda veh_id: - self.get_distance_to_intersection(veh_id)) + dist = sorted( + vehicles, + key=lambda veh_id: self.get_distance_to_intersection(veh_id)) dists += dist[:k] return dists @@ -436,12 +471,13 @@ def observation_space(self): Partial observed state space. Velocities, distance to intersections, edge number (for nearby vehicles) traffic light state """ - tl_box = Box(low=0., - high=1, - shape=(12 * self.num_observed * self.num_traffic_lights - + 2 * len(self.scenario.get_edge_list()) - + 3 * self.num_traffic_lights,), - dtype=np.float32) + tl_box = Box( + low=0., + high=1, + shape=(12 * self.num_observed * self.num_traffic_lights + + 2 * len(self.scenario.get_edge_list()) + + 3 * self.num_traffic_lights,), + dtype=np.float32) return tl_box def get_state(self): @@ -453,8 +489,9 @@ def get_state(self): speeds = [] dist_to_intersec = [] edge_number = [] - max_speed = max(self.scenario.speed_limit(edge) - for edge in self.scenario.get_edge_list()) + max_speed = max( + self.scenario.speed_limit(edge) + for edge in self.scenario.get_edge_list()) max_dist = max(self.scenario.short_length, self.scenario.long_length, self.scenario.inner_length) all_observed_ids = [] @@ -467,12 +504,15 @@ def get_state(self): # check which edges we have so we can always pad in the right # positions - speeds += [self.vehicles.get_speed(veh_id) / max_speed - for veh_id in observed_ids] + speeds += [ + self.vehicles.get_speed(veh_id) / max_speed + for veh_id in observed_ids + ] dist_to_intersec += [ (self.scenario.edge_length(self.vehicles.get_edge(veh_id)) - self.vehicles.get_position(veh_id)) / max_dist - for veh_id in observed_ids] + for veh_id in observed_ids + ] edge_number += \ [self._convert_edge(self.vehicles.get_edge(veh_id)) / (self.scenario.num_edges - 1) @@ -491,15 +531,20 @@ def get_state(self): ids = self.vehicles.get_ids_by_edge(edge) if len(ids) > 0: density += [5 * len(ids) / self.scenario.edge_length(edge)] - velocity_avg += [np.mean([self.vehicles.get_speed(veh_id) - for veh_id in ids]) / max_speed] + velocity_avg += [ + np.mean( + [self.vehicles.get_speed(veh_id) + for veh_id in ids]) / max_speed + ] else: density += [0] velocity_avg += [0] self.observed_ids = all_observed_ids - return np.array(np.concatenate([speeds, dist_to_intersec, edge_number, - density, velocity_avg, - self.last_change.flatten().tolist()])) + return np.array( + np.concatenate([ + speeds, dist_to_intersec, edge_number, density, velocity_avg, + self.last_change.flatten().tolist() + ])) def compute_reward(self, state, rl_actions, **kwargs): if self.env_params.evaluate: @@ -517,6 +562,7 @@ class GreenWaveTestEnv(TrafficLightGridEnv): Class that overrides RL methods of green wave so we can test construction without needing to specify RL methods """ + def _apply_rl_actions(self, rl_actions): pass diff --git a/flow/envs/loop/lane_changing.py b/flow/envs/loop/lane_changing.py index 59ff6d7f4..f6f07efa1 100755 --- a/flow/envs/loop/lane_changing.py +++ b/flow/envs/loop/lane_changing.py @@ -59,8 +59,8 @@ class LaneChangeAccelEnv(Env): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) super().__init__(env_params, sumo_params, scenario) @@ -76,12 +76,21 @@ def action_space(self): @property def observation_space(self): - speed = Box(low=0, high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - lane = Box(low=0, high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - pos = Box(low=0., high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) + speed = Box( + low=0, + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) + lane = Box( + low=0, + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) + pos = Box( + low=0., + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) return Tuple((speed, pos, lane)) def compute_reward(self, state, rl_actions, **kwargs): @@ -101,21 +110,25 @@ def get_state(self): # normalizers max_speed = self.scenario.max_speed length = self.scenario.length - max_lanes = max(self.scenario.num_lanes(edge) - for edge in self.scenario.get_edge_list()) + max_lanes = max( + self.scenario.num_lanes(edge) + for edge in self.scenario.get_edge_list()) - return np.array([[self.vehicles.get_speed(veh_id) / max_speed, - self.get_x_by_id(veh_id) / length, - self.vehicles.get_lane(veh_id) / max_lanes] - for veh_id in self.sorted_ids]) + return np.array([[ + self.vehicles.get_speed(veh_id) / max_speed, + self.get_x_by_id(veh_id) / length, + self.vehicles.get_lane(veh_id) / max_lanes + ] for veh_id in self.sorted_ids]) def _apply_rl_actions(self, actions): acceleration = actions[::2] direction = actions[1::2] # re-arrange actions according to mapping in observation space - sorted_rl_ids = [veh_id for veh_id in self.sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in self.sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] # represents vehicles that are allowed to change lanes non_lane_changing_veh = \ @@ -166,8 +179,8 @@ class LaneChangeAccelPOEnv(LaneChangeAccelEnv): def __init__(self, env_params, sumo_params, scenario): # maximum number of lanes on any edge in the network - self.num_lanes = max(scenario.num_lanes(edge) - for edge in scenario.get_edge_list()) + self.num_lanes = max( + scenario.num_lanes(edge) for edge in scenario.get_edge_list()) # lists of visible vehicles, used for visualization purposes self.visible = [] @@ -176,14 +189,18 @@ def __init__(self, env_params, sumo_params, scenario): @property def observation_space(self): - return Box(low=0, high=1, - shape=(4 * self.vehicles.num_rl_vehicles * self.num_lanes - + self.vehicles.num_rl_vehicles,), - dtype=np.float32) + return Box( + low=0, + high=1, + shape=(4 * self.vehicles.num_rl_vehicles * self.num_lanes + + self.vehicles.num_rl_vehicles, ), + dtype=np.float32) def get_state(self): - obs = [0 for _ in range(4 * self.vehicles.num_rl_vehicles - * self.num_lanes)] + obs = [ + 0 + for _ in range(4 * self.vehicles.num_rl_vehicles * self.num_lanes) + ] self.visible = [] for i, rl_id in enumerate(self.vehicles.get_rl_ids()): diff --git a/flow/envs/loop/loop_accel.py b/flow/envs/loop/loop_accel.py index 70495cf71..bfd3cf12b 100755 --- a/flow/envs/loop/loop_accel.py +++ b/flow/envs/loop/loop_accel.py @@ -47,30 +47,39 @@ class AccelEnv(Env): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) super().__init__(env_params, sumo_params, scenario) @property def action_space(self): - return Box(low=-abs(self.env_params.additional_params["max_decel"]), - high=self.env_params.additional_params["max_accel"], - shape=(self.vehicles.num_rl_vehicles,), - dtype=np.float32) + return Box( + low=-abs(self.env_params.additional_params["max_decel"]), + high=self.env_params.additional_params["max_accel"], + shape=(self.vehicles.num_rl_vehicles, ), + dtype=np.float32) @property def observation_space(self): self.obs_var_labels = ["Velocity", "Absolute_pos"] - speed = Box(low=0, high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - pos = Box(low=0., high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) + speed = Box( + low=0, + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) + pos = Box( + low=0., + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) return Tuple((speed, pos)) def _apply_rl_actions(self, rl_actions): - sorted_rl_ids = [veh_id for veh_id in self.sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in self.sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] self.apply_acceleration(sorted_rl_ids, rl_actions) def compute_reward(self, state, rl_actions, **kwargs): @@ -83,9 +92,10 @@ def get_state(self, **kwargs): # speed normalizer max_speed = self.scenario.max_speed - return np.array([[self.vehicles.get_speed(veh_id) / max_speed, - self.get_x_by_id(veh_id) / self.scenario.length] - for veh_id in self.sorted_ids]) + return np.array([[ + self.vehicles.get_speed(veh_id) / max_speed, + self.get_x_by_id(veh_id) / self.scenario.length + ] for veh_id in self.sorted_ids]) def additional_command(self): # specify observed vehicles diff --git a/flow/envs/loop/loop_merges.py b/flow/envs/loop/loop_merges.py index 5a98196ae..658be2622 100755 --- a/flow/envs/loop/loop_merges.py +++ b/flow/envs/loop/loop_merges.py @@ -65,8 +65,8 @@ class TwoLoopsMergePOEnv(Env): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) self.n_preceding = env_params.additional_params["n_preceding"] self.n_following = env_params.additional_params["n_following"] @@ -81,25 +81,35 @@ def __init__(self, env_params, sumo_params, scenario): @property def observation_space(self): - speed = Box(low=0, high=np.inf, shape=(self.n_obs_vehicles,), - dtype=np.float32) - absolute_pos = Box(low=0., high=np.inf, shape=(self.n_obs_vehicles,), - dtype=np.float32) - queue_length = Box(low=0, high=np.inf, shape=(1,), dtype=np.float32) - vel_stats = Box(low=-np.inf, high=np.inf, shape=(2,), dtype=np.float32) + speed = Box( + low=0, + high=np.inf, + shape=(self.n_obs_vehicles, ), + dtype=np.float32) + absolute_pos = Box( + low=0., + high=np.inf, + shape=(self.n_obs_vehicles, ), + dtype=np.float32) + queue_length = Box(low=0, high=np.inf, shape=(1, ), dtype=np.float32) + vel_stats = Box( + low=-np.inf, high=np.inf, shape=(2, ), dtype=np.float32) return Tuple((speed, absolute_pos, queue_length, vel_stats)) @property def action_space(self): - return Box(low=-np.abs(self.env_params.additional_params["max_decel"]), - high=self.env_params.additional_params["max_accel"], - shape=(self.vehicles.num_rl_vehicles,), - dtype=np.float32) + return Box( + low=-np.abs(self.env_params.additional_params["max_decel"]), + high=self.env_params.additional_params["max_accel"], + shape=(self.vehicles.num_rl_vehicles, ), + dtype=np.float32) def _apply_rl_actions(self, rl_actions): - sorted_rl_ids = [veh_id for veh_id in self.sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in self.sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] self.apply_acceleration(sorted_rl_ids, rl_actions) def compute_reward(self, state, rl_actions, **kwargs): @@ -107,9 +117,9 @@ def compute_reward(self, state, rl_actions, **kwargs): # Use a similar weighting of of the headway reward as the velocity # reward - max_cost = np.array([self.env_params.additional_params[ - "target_velocity"]] * - self.vehicles.num_vehicles) + max_cost = np.array( + [self.env_params.additional_params["target_velocity"] + ] * self.vehicles.num_vehicles) max_cost = np.linalg.norm(max_cost) normalization = self.scenario.length / self.vehicles.num_vehicles headway_reward = 0.2 * max_cost * rewards.penalize_headway_variance( @@ -191,8 +201,8 @@ def get_state(self, **kwargs): vel_stats[1] = np.mean(vel_all[num_inner:]) vel_stats = np.nan_to_num(vel_stats) - return np.array([normalized_vel, normalized_pos, queue_length, - vel_stats]).T + return np.array( + [normalized_vel, normalized_pos, queue_length, vel_stats]).T def sort_by_position(self): """ @@ -206,11 +216,15 @@ def sort_by_position(self): sorted_indx = np.argsort(pos) sorted_ids = np.array(self.vehicles.get_ids())[sorted_indx] - sorted_human_ids = [veh_id for veh_id in sorted_ids - if veh_id not in self.vehicles.get_rl_ids()] + sorted_human_ids = [ + veh_id for veh_id in sorted_ids + if veh_id not in self.vehicles.get_rl_ids() + ] - sorted_rl_ids = [veh_id for veh_id in sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] sorted_separated_ids = sorted_human_ids + sorted_rl_ids diff --git a/flow/envs/loop/wave_attenuation.py b/flow/envs/loop/wave_attenuation.py index 98a354b82..5f44fa685 100644 --- a/flow/envs/loop/wave_attenuation.py +++ b/flow/envs/loop/wave_attenuation.py @@ -50,30 +50,39 @@ class WaveAttenuationEnv(Env): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) super().__init__(env_params, sumo_params, scenario) @property def action_space(self): - return Box(low=-np.abs(self.env_params.additional_params["max_decel"]), - high=self.env_params.additional_params["max_accel"], - shape=(self.vehicles.num_rl_vehicles,), - dtype=np.float32) + return Box( + low=-np.abs(self.env_params.additional_params["max_decel"]), + high=self.env_params.additional_params["max_accel"], + shape=(self.vehicles.num_rl_vehicles, ), + dtype=np.float32) @property def observation_space(self): self.obs_var_labels = ["Velocity", "Absolute_pos"] - speed = Box(low=0, high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) - pos = Box(low=0., high=1, shape=(self.vehicles.num_vehicles,), - dtype=np.float32) + speed = Box( + low=0, + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) + pos = Box( + low=0., + high=1, + shape=(self.vehicles.num_vehicles, ), + dtype=np.float32) return Tuple((speed, pos)) def _apply_rl_actions(self, rl_actions): - sorted_rl_ids = [veh_id for veh_id in self.sorted_ids - if veh_id in self.vehicles.get_rl_ids()] + sorted_rl_ids = [ + veh_id for veh_id in self.sorted_ids + if veh_id in self.vehicles.get_rl_ids() + ] self.apply_acceleration(sorted_rl_ids, rl_actions) def compute_reward(self, state, rl_actions, **kwargs): @@ -81,8 +90,10 @@ def compute_reward(self, state, rl_actions, **kwargs): if rl_actions is None: return 0 - vel = np.array([self.vehicles.get_speed(veh_id) - for veh_id in self.vehicles.get_ids()]) + vel = np.array([ + self.vehicles.get_speed(veh_id) + for veh_id in self.vehicles.get_ids() + ]) if any(vel < -100) or kwargs["fail"]: return 0. @@ -102,10 +113,10 @@ def compute_reward(self, state, rl_actions, **kwargs): return float(reward) def get_state(self, **kwargs): - return np.array( - [[self.vehicles.get_speed(veh_id) / self.scenario.max_speed, - self.get_x_by_id(veh_id) / self.scenario.length] - for veh_id in self.sorted_ids]) + return np.array([[ + self.vehicles.get_speed(veh_id) / self.scenario.max_speed, + self.get_x_by_id(veh_id) / self.scenario.length + ] for veh_id in self.sorted_ids]) def additional_command(self): # specify observed vehicles @@ -119,10 +130,16 @@ def reset(self): # update the scenario initial_config = InitialConfig(bunching=50, min_gap=0) additional_net_params = { - "length": random.randint( + "length": + random.randint( self.env_params.additional_params["ring_length"][0], self.env_params.additional_params["ring_length"][1]), - "lanes": 1, "speed_limit": 30, "resolution": 40 + "lanes": + 1, + "speed_limit": + 30, + "resolution": + 40 } net_params = NetParams(additional_params=additional_net_params) @@ -134,15 +151,15 @@ def reset(self): def v_eq_max_function(v): num_veh = self.vehicles.num_vehicles - 1 # maximum gap in the presence of one rl vehicle - s_eq_max = (self.scenario.length - - self.vehicles.num_vehicles * 5) / num_veh + s_eq_max = (self.scenario.length - + self.vehicles.num_vehicles * 5) / num_veh v0 = 30 s0 = 2 T = 1 gamma = 4 - error = s_eq_max - (s0 + v*T) * (1 - (v/v0)**gamma) ** -0.5 + error = s_eq_max - (s0 + v * T) * (1 - (v / v0)**gamma)**-0.5 return error @@ -155,8 +172,9 @@ def v_eq_max_function(v): print('-----------------------') # restart the sumo instance - self.restart_sumo(sumo_params=self.sumo_params, - sumo_binary=self.sumo_params.sumo_binary) + self.restart_sumo( + sumo_params=self.sumo_params, + sumo_binary=self.sumo_params.sumo_binary) # perform the generic reset function observation = super().reset() @@ -198,7 +216,7 @@ class WaveAttenuationPOEnv(WaveAttenuationEnv): @property def observation_space(self): - return Box(low=0, high=1, shape=(3,), dtype=np.float32) + return Box(low=0, high=1, shape=(3, ), dtype=np.float32) def get_state(self, **kwargs): rl_id = self.vehicles.get_rl_ids()[0] @@ -210,8 +228,8 @@ def get_state(self, **kwargs): observation = np.array([ self.vehicles.get_speed(rl_id) / max_speed, - (self.vehicles.get_speed(lead_id) - self.vehicles.get_speed( - rl_id)) / max_speed, + (self.vehicles.get_speed(lead_id) - self.vehicles.get_speed(rl_id)) + / max_speed, self.vehicles.get_headway(rl_id) / max_length ]) diff --git a/flow/envs/merge.py b/flow/envs/merge.py index e5c3bf231..6d572bff5 100644 --- a/flow/envs/merge.py +++ b/flow/envs/merge.py @@ -64,8 +64,8 @@ class WaveAttenuationMergePOEnv(Env): def __init__(self, env_params, sumo_params, scenario): for p in ADDITIONAL_ENV_PARAMS.keys(): if p not in env_params.additional_params: - raise KeyError('Environment parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Environment parameter "{}" not supplied'.format(p)) # maximum number of controlled vehicles self.num_rl = env_params.additional_params["num_rl"] @@ -81,14 +81,15 @@ def __init__(self, env_params, sumo_params, scenario): @property def action_space(self): - return Box(low=-abs(self.env_params.additional_params["max_decel"]), - high=self.env_params.additional_params["max_accel"], - shape=(self.num_rl,), - dtype=np.float32) + return Box( + low=-abs(self.env_params.additional_params["max_decel"]), + high=self.env_params.additional_params["max_accel"], + shape=(self.num_rl, ), + dtype=np.float32) @property def observation_space(self): - return Box(low=0, high=1, shape=(5 * self.num_rl,), dtype=np.float32) + return Box(low=0, high=1, shape=(5 * self.num_rl, ), dtype=np.float32) def _apply_rl_actions(self, rl_actions): for i, rl_id in enumerate(self.rl_veh): @@ -156,14 +157,15 @@ def compute_reward(self, state, rl_actions, **kwargs): lead_id = self.vehicles.get_leader(rl_id) if lead_id not in ["", None] \ and self.vehicles.get_speed(rl_id) > 0: - t_headway = max(self.vehicles.get_headway(rl_id) - / self.vehicles.get_speed(rl_id), 0) + t_headway = max( + self.vehicles.get_headway(rl_id) / + self.vehicles.get_speed(rl_id), 0) cost2 += min((t_headway - t_min) / t_min, 0) # weights for cost1, cost2, and cost3, respectively eta1, eta2 = 1.00, 0.10 - return max(eta1*cost1 + eta2*cost2, 0) + return max(eta1 * cost1 + eta2 * cost2, 0) def sort_by_position(self): # vehicles are sorted by their get_x_by_id value diff --git a/flow/scenarios/__init__.py b/flow/scenarios/__init__.py index 6e82e01d6..2a5a463b4 100644 --- a/flow/scenarios/__init__.py +++ b/flow/scenarios/__init__.py @@ -29,13 +29,16 @@ __all__ = ["Scenario"] # custom generators -__all__ += ["BayBridgeGenerator", "BayBridgeTollGenerator", - "BottleneckGenerator", "Figure8Generator", "SimpleGridGenerator", - "HighwayGenerator", "CircleGenerator", "MergeGenerator", - "NetFileGenerator", "TwoLoopOneMergingGenerator"] +__all__ += [ + "BayBridgeGenerator", "BayBridgeTollGenerator", "BottleneckGenerator", + "Figure8Generator", "SimpleGridGenerator", "HighwayGenerator", + "CircleGenerator", "MergeGenerator", "NetFileGenerator", + "TwoLoopOneMergingGenerator" +] # custom scenarios -__all__ += ["BayBridgeScenario", "BayBridgeTollScenario", "BottleneckScenario", - "Figure8Scenario", "SimpleGridScenario", "HighwayScenario", - "LoopScenario", "MergeScenario", "NetFileScenario", - "TwoLoopsOneMergingScenario"] +__all__ += [ + "BayBridgeScenario", "BayBridgeTollScenario", "BottleneckScenario", + "Figure8Scenario", "SimpleGridScenario", "HighwayScenario", "LoopScenario", + "MergeScenario", "NetFileScenario", "TwoLoopsOneMergingScenario" +] diff --git a/flow/scenarios/base_scenario.py b/flow/scenarios/base_scenario.py index 5aeab2065..59906f5e1 100755 --- a/flow/scenarios/base_scenario.py +++ b/flow/scenarios/base_scenario.py @@ -17,8 +17,11 @@ class Scenario(Serializable): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Base scenario class. @@ -72,14 +75,15 @@ def __init__(self, name, generator_class, vehicles, net_params, self.net_params, self.traffic_lights) # list of edges and internal links (junctions) - self._edge_list = [edge_id for edge_id in self._edges.keys() - if edge_id[0] != ":"] - self._junction_list = list(set(self._edges.keys()) - - set(self._edge_list)) + self._edge_list = [ + edge_id for edge_id in self._edges.keys() if edge_id[0] != ":" + ] + self._junction_list = list( + set(self._edges.keys()) - set(self._edge_list)) # maximum achievable speed on any edge in the network - self.max_speed = max(self.speed_limit(edge) - for edge in self.get_edge_list()) + self.max_speed = max( + self.speed_limit(edge) for edge in self.get_edge_list()) # parameters to be specified under each unique subclass's # __init__() function @@ -114,8 +118,9 @@ def __init__(self, name, generator_class, vehicles, net_params, # which cars are meant to be distributed # (may be overridden by subclass __init__()) if not hasattr(self, "length"): - self.length = sum([self.edge_length(edge_id) - for edge_id in self.get_edge_list()]) + self.length = sum([ + self.edge_length(edge_id) for edge_id in self.get_edge_list() + ]) # generate starting position for vehicles in the network if self.initial_config.positions is None: @@ -318,8 +323,8 @@ def gen_even_start_pos(self, initial_config, num_vehicles, **kwargs): # find the location of the internal edge in total_edgestarts, # which has the edges ordered by position edges = [tup[0] for tup in self.total_edgestarts] - indx_edge = next(i for i, edge in enumerate(edges) - if edge == pos[0]) + indx_edge = next( + i for i, edge in enumerate(edges) if edge == pos[0]) # take the next edge in the list, and place the car at the # beginning of this edge @@ -391,7 +396,7 @@ def gen_random_start_pos(self, initial_config, num_vehicles, **kwargs): """ (x0, min_gap, bunching, lanes_distr, available_length, available_edges, initial_config) = self._get_start_pos_util( - initial_config, num_vehicles, **kwargs) + initial_config, num_vehicles, **kwargs) # extra space a vehicle needs to cover from the start of an edge to be # fully in the edge and not risk having a gap with a vehicle behind it @@ -421,7 +426,7 @@ def gen_random_start_pos(self, initial_config, num_vehicles, **kwargs): for i in range(num_vehicles): edge_i = available_edges[edge_indx] pos_i = (init_absolute_pos[i] - decrement) % ( - self.edge_length(edge_i) - efs) + self.edge_length(edge_i) - efs) lane_i = int(((init_absolute_pos[i] - decrement) - pos_i) / (self.edge_length(edge_i) - efs)) @@ -434,7 +439,7 @@ def gen_random_start_pos(self, initial_config, num_vehicles, **kwargs): edge_i = available_edges[edge_indx] pos_i = (init_absolute_pos[i] - decrement) % ( - self.edge_length(edge_i) - efs) + self.edge_length(edge_i) - efs) lane_i = int(((init_absolute_pos[i] - decrement) - pos_i) / (self.edge_length(edge_i) - efs)) @@ -525,11 +530,13 @@ def _get_start_pos_util(self, initial_config, num_vehicles, **kwargs): # compute the lanes distribution (adjust of edge cases) if initial_config.edges_distribution == "all": - max_lane = max([self.num_lanes(edge_id) - for edge_id in self.get_edge_list()]) + max_lane = max( + [self.num_lanes(edge_id) for edge_id in self.get_edge_list()]) else: - max_lane = max([self.num_lanes(edge_id) - for edge_id in initial_config.edges_distribution]) + max_lane = max([ + self.num_lanes(edge_id) + for edge_id in initial_config.edges_distribution + ]) if initial_config.lanes_distribution > max_lane: lanes_distribution = max_lane diff --git a/flow/scenarios/bay_bridge/gen.py b/flow/scenarios/bay_bridge/gen.py index 1f331745b..0ac695e6b 100644 --- a/flow/scenarios/bay_bridge/gen.py +++ b/flow/scenarios/bay_bridge/gen.py @@ -5,6 +5,7 @@ class BayBridgeGenerator(NetFileGenerator): """ Bay Bridge generator. """ + def specify_routes(self, net_params): """ Routes for vehicles moving through the bay bridge from Oakland to San @@ -20,8 +21,8 @@ def specify_routes(self, net_params): "340686911#1": ["340686911#1", "340686911#2.0.0"], "340686911#2.0.0": ["340686911#2.0.0", "340686911#2.0.13"], "340686911#2.0.13": ["340686911#2.0.13", "340686911#2.35"], - "340686911#0.54.54.127.74": ["340686911#0.54.54.127.74", - "340686911#1"], + "340686911#0.54.54.127.74": + ["340686911#0.54.54.127.74", "340686911#1"], "340686911#3": ["340686911#3", "236348361"], "236348361": ["236348361", "236348360#0"], "236348360#0": ["236348360#0", "236348360#1"], @@ -66,12 +67,11 @@ def specify_routes(self, net_params): "90077193#1.812": ["90077193#1.812", "gneE3"], "gneE3": ["gneE3", "340686911#0.54.0"], "340686911#0.54.0": ["340686911#0.54.0", "340686911#0.54.54.0"], - "340686911#0.54.54.0": ["340686911#0.54.54.0", - "340686911#0.54.54.127.0"], - "340686911#0.54.54.127.0": ["340686911#0.54.54.127.0", - "340686911#0.54.54.127.74"], + "340686911#0.54.54.0": + ["340686911#0.54.54.0", "340686911#0.54.54.127.0"], + "340686911#0.54.54.127.0": + ["340686911#0.54.54.127.0", "340686911#0.54.54.127.74"], "340686911#2.35": ["340686911#2.35", "340686911#3"] - } return rts diff --git a/flow/scenarios/bay_bridge/scenario.py b/flow/scenarios/bay_bridge/scenario.py index ed1b86b77..65b1bd012 100644 --- a/flow/scenarios/bay_bridge/scenario.py +++ b/flow/scenarios/bay_bridge/scenario.py @@ -5,6 +5,7 @@ class BayBridgeScenario(NetFileScenario): """ A scenario used to simulate the bottleneck portion of the Bay Bridge. """ + def generate_starting_positions(self, **kwargs): """ See parent class. @@ -13,19 +14,51 @@ def generate_starting_positions(self, **kwargs): Oakland to San Francisco. """ self.initial_config.edges_distribution = [ - '236348360#1', '157598960', - '11415208', '236348361', '11198599', - '11198595.0', '11198595.656.0', - '340686911#3', '23874736', '119057701', '517934789', - '236348364', '124952171', "gneE0", "11198599", "124952182.0", - '236348360#0', '497579295', '340686911#2.0.0', - '340686911#1', '394443191', '322962944', "32661309#1.0", - "90077193#1.777", "90077193#1.0", "90077193#1.812", "gneE1", - "32661316", "4757680", "124952179", - "119058993", "28413679", "11197898", "123741311", - "123741303", "90077193#0", "28413687#1", "11197889", - "123741382#0", "123741382#1", "gneE3", "340686911#0.54.0", - "340686911#0.54.54.0", "340686911#0.54.54.127.0", "340686911#2.35", + '236348360#1', + '157598960', + '11415208', + '236348361', + '11198599', + '11198595.0', + '11198595.656.0', + '340686911#3', + '23874736', + '119057701', + '517934789', + '236348364', + '124952171', + "gneE0", + "11198599", + "124952182.0", + '236348360#0', + '497579295', + '340686911#2.0.0', + '340686911#1', + '394443191', + '322962944', + "32661309#1.0", + "90077193#1.777", + "90077193#1.0", + "90077193#1.812", + "gneE1", + "32661316", + "4757680", + "124952179", + "119058993", + "28413679", + "11197898", + "123741311", + "123741303", + "90077193#0", + "28413687#1", + "11197889", + "123741382#0", + "123741382#1", + "gneE3", + "340686911#0.54.0", + "340686911#0.54.54.0", + "340686911#0.54.54.127.0", + "340686911#2.35", ] return super().generate_starting_positions(**kwargs) diff --git a/flow/scenarios/bay_bridge_toll/gen.py b/flow/scenarios/bay_bridge_toll/gen.py index c66a407f7..18928cbb4 100644 --- a/flow/scenarios/bay_bridge_toll/gen.py +++ b/flow/scenarios/bay_bridge_toll/gen.py @@ -5,6 +5,7 @@ class BayBridgeTollGenerator(NetFileGenerator): """ Bay Bridge bottleneck generator. """ + def specify_routes(self, net_params): """ Routes for vehicles moving through the bay bridge from Oakland to San @@ -19,8 +20,8 @@ def specify_routes(self, net_params): "124952171": ["124952171", "11198599"], "340686911#1": ["340686911#1", "340686911#2.0.0"], "340686911#2.0.0": ["340686911#2.0.0", "340686911#2.0.13"], - "340686911#0.54.54.127.74": ["340686911#0.54.54.127.74", - "340686911#1"], + "340686911#0.54.54.127.74": + ["340686911#0.54.54.127.74", "340686911#1"], "340686911#2.0.13": ["340686911#2.0.13", "340686911#2.35"], "340686911#2.35": ["340686911#2.35"], "393649534": ["393649534", "124952179"], @@ -40,10 +41,10 @@ def specify_routes(self, net_params): "90077193#1.812": ["90077193#1.812", "gneE3"], "gneE3": ["gneE3", "340686911#0.54.0"], "340686911#0.54.0": ["340686911#0.54.0", "340686911#0.54.54.0"], - "340686911#0.54.54.0": ["340686911#0.54.54.0", - "340686911#0.54.54.127.0"], - "340686911#0.54.54.127.0": ["340686911#0.54.54.127.0", - "340686911#0.54.54.127.74"], + "340686911#0.54.54.0": + ["340686911#0.54.54.0", "340686911#0.54.54.127.0"], + "340686911#0.54.54.127.0": + ["340686911#0.54.54.127.0", "340686911#0.54.54.127.74"], } return rts diff --git a/flow/scenarios/bay_bridge_toll/scenario.py b/flow/scenarios/bay_bridge_toll/scenario.py index 8bc732d0d..24d785cc9 100644 --- a/flow/scenarios/bay_bridge_toll/scenario.py +++ b/flow/scenarios/bay_bridge_toll/scenario.py @@ -5,6 +5,7 @@ class BayBridgeTollScenario(NetFileScenario): """ A scenario used to simulate the Bay Bridge. """ + def generate_starting_positions(self, **kwargs): """ See parent class. @@ -13,15 +14,27 @@ def generate_starting_positions(self, **kwargs): Oakland to San Francisco. """ self.initial_config.edges_distribution = [ - '157598960', '11198599', - '11198595.0', '11198595.656.0', - '124952171', "gneE0", "11198599", "124952182.0", + '157598960', + '11198599', + '11198595.0', + '11198595.656.0', + '124952171', + "gneE0", + "11198599", + "124952182.0", '340686911#2.0.0', - '340686911#1', "32661309#1.0", - "90077193#1.777", "90077193#1.0", "90077193#1.812", "gneE1", + '340686911#1', + "32661309#1.0", + "90077193#1.777", + "90077193#1.0", + "90077193#1.812", + "gneE1", "124952179", - "gneE3", "340686911#0.54.0", - "340686911#0.54.54.0", "340686911#0.54.54.127.0", "340686911#2.35", + "gneE3", + "340686911#0.54.0", + "340686911#0.54.54.0", + "340686911#0.54.54.127.0", + "340686911#2.35", ] return super().generate_starting_positions(**kwargs) diff --git a/flow/scenarios/bottleneck/gen.py b/flow/scenarios/bottleneck/gen.py index 819c20da6..b08f0f23b 100644 --- a/flow/scenarios/bottleneck/gen.py +++ b/flow/scenarios/bottleneck/gen.py @@ -7,18 +7,47 @@ class BottleneckGenerator(Generator): Generator class for simulating the Bay Bridge toll. No parameters needed from net_params (the network is not parametrized) """ + def specify_nodes(self, net_params): """ See parent class """ - nodes = [{"id": "1", "x": "0", "y": "0"}, # pre-toll - {"id": "2", "x": "100", "y": "0"}, # toll - {"id": "3", "x": "410", "y": "0"}, # light - {"id": "4", "x": "550", "y": "0", "type": "zipper", - "radius": "20"}, # merge1 - {"id": "5", "x": "830", "y": "0", "type": "zipper", - "radius": "20"}, # merge2 - {"id": "6", "x": "985", "y": "0"}] # post-merge2 + nodes = [ + { + "id": "1", + "x": "0", + "y": "0" + }, # pre-toll + { + "id": "2", + "x": "100", + "y": "0" + }, # toll + { + "id": "3", + "x": "410", + "y": "0" + }, # light + { + "id": "4", + "x": "550", + "y": "0", + "type": "zipper", + "radius": "20" + }, # merge1 + { + "id": "5", + "x": "830", + "y": "0", + "type": "zipper", + "radius": "20" + }, # merge2 + { + "id": "6", + "x": "985", + "y": "0" + } + ] # post-merge2 return nodes def specify_edges(self, net_params): @@ -26,23 +55,55 @@ def specify_edges(self, net_params): See parent class """ scaling = net_params.additional_params.get("scaling", 1) - assert(isinstance(scaling, int)), "Scaling must be an int" + assert (isinstance(scaling, int)), "Scaling must be an int" - edges = [{"id": "1", "from": "1", "to": "2", "length": "100", # - "spreadType": "center", "numLanes": str(4*scaling), - "speed": "23"}, - {"id": "2", "from": "2", "to": "3", "length": "310", # DONE - "spreadType": "center", "numLanes": str(4*scaling), - "speed": "23"}, - {"id": "3", "from": "3", "to": "4", "length": "140", # DONE - "spreadType": "center", "numLanes": str(4*scaling), - "speed": "23"}, - {"id": "4", "from": "4", "to": "5", "length": "280", # DONE - "spreadType": "center", "numLanes": str(2*scaling), - "speed": "23"}, - {"id": "5", "from": "5", "to": "6", "length": "155", - "spreadType": "center", "numLanes": str(scaling), - "speed": "23"}] + edges = [ + { + "id": "1", + "from": "1", + "to": "2", + "length": "100", # + "spreadType": "center", + "numLanes": str(4 * scaling), + "speed": "23" + }, + { + "id": "2", + "from": "2", + "to": "3", + "length": "310", # DONE + "spreadType": "center", + "numLanes": str(4 * scaling), + "speed": "23" + }, + { + "id": "3", + "from": "3", + "to": "4", + "length": "140", # DONE + "spreadType": "center", + "numLanes": str(4 * scaling), + "speed": "23" + }, + { + "id": "4", + "from": "4", + "to": "5", + "length": "280", # DONE + "spreadType": "center", + "numLanes": str(2 * scaling), + "speed": "23" + }, + { + "id": "5", + "from": "5", + "to": "6", + "length": "155", + "spreadType": "center", + "numLanes": str(scaling), + "speed": "23" + } + ] return edges @@ -52,22 +113,32 @@ def specify_connections(self, net_params): """ scaling = net_params.additional_params.get("scaling", 1) conn = [] - for i in range(4*scaling): - conn += [{"from": "3", "to": "4", "fromLane": str(i), - "toLane": str(int(np.floor(i/2)))}] - for i in range(2*scaling): - conn += [{"from": "4", "to": "5", "fromLane": str(i), - "toLane": str(int(np.floor(i/2)))}] + for i in range(4 * scaling): + conn += [{ + "from": "3", + "to": "4", + "fromLane": str(i), + "toLane": str(int(np.floor(i / 2))) + }] + for i in range(2 * scaling): + conn += [{ + "from": "4", + "to": "5", + "fromLane": str(i), + "toLane": str(int(np.floor(i / 2))) + }] return conn def specify_routes(self, net_params): """ See parent class """ - rts = {"1": ["1", "2", "3", "4", "5"], - "2": ["2", "3", "4", "5"], - "3": ["3", "4", "5"], - "4": ["4", "5"], - "5": ["5"]} + rts = { + "1": ["1", "2", "3", "4", "5"], + "2": ["2", "3", "4", "5"], + "3": ["3", "4", "5"], + "4": ["4", "5"], + "5": ["5"] + } return rts diff --git a/flow/scenarios/bottleneck/scenario.py b/flow/scenarios/bottleneck/scenario.py index bc265ae00..ec4bea56a 100644 --- a/flow/scenarios/bottleneck/scenario.py +++ b/flow/scenarios/bottleneck/scenario.py @@ -9,8 +9,11 @@ class BottleneckScenario(Scenario): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Scenario class for Bay Bridge toll simulations. @@ -34,11 +37,7 @@ def specify_edge_starts(self): """ See parent class """ - return [("1", 0), - ("2", 100), - ("3", 405), - ("4", 425), - ("5", 580)] + return [("1", 0), ("2", 100), ("3", 405), ("4", 425), ("5", 580)] def get_bottleneck_lanes(self, lane): - return [int(lane/2), int(lane/4)] + return [int(lane / 2), int(lane / 4)] diff --git a/flow/scenarios/figure8/figure8_scenario.py b/flow/scenarios/figure8/figure8_scenario.py index 2ad651a84..4be692be1 100755 --- a/flow/scenarios/figure8/figure8_scenario.py +++ b/flow/scenarios/figure8/figure8_scenario.py @@ -4,7 +4,6 @@ from flow.core.traffic_lights import TrafficLights from flow.scenarios.base_scenario import Scenario - ADDITIONAL_NET_PARAMS = { # radius of the circular components "radius_ring": 30, @@ -18,7 +17,11 @@ class Figure8Scenario(Scenario): - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a figure 8 scenario. @@ -39,9 +42,9 @@ def __init__(self, name, generator_class, vehicles, net_params, if p not in net_params.additional_params: raise KeyError('Network parameter "{}" not supplied'.format(p)) - self.ring_edgelen = net_params.additional_params[ - "radius_ring"] * np.pi / 2. - self.intersection_len = 2 * net_params.additional_params["radius_ring"] + ring_radius = net_params.additional_params["radius_ring"] + self.ring_edgelen = ring_radius * np.pi / 2. + self.intersection_len = 2 * ring_radius self.junction_len = 2.9 + 3.3 * net_params.additional_params["lanes"] self.inner_space_len = 0.28 diff --git a/flow/scenarios/figure8/gen.py b/flow/scenarios/figure8/gen.py index 0231c1227..9cc5901cf 100755 --- a/flow/scenarios/figure8/gen.py +++ b/flow/scenarios/figure8/gen.py @@ -26,24 +26,52 @@ def specify_nodes(self, net_params): """ r = net_params.additional_params["radius_ring"] - nodes = [{"id": "center_intersection", "x": repr(0), "y": repr(0), - "type": "priority"}, - {"id": "top_upper_ring", "x": repr(r), "y": repr(2 * r), - "type": "priority"}, - {"id": "bottom_upper_ring_in", "x": repr(r), "y": repr(0), - "type": "priority"}, - {"id": "left_upper_ring", "x": repr(0), "y": repr(r), - "type": "priority"}, - {"id": "right_upper_ring", "x": repr(2 * r), "y": repr(r), - "type": "priority"}, - {"id": "top_lower_ring", "x": repr(-r), "y": repr(0), - "type": "priority"}, - {"id": "bottom_lower_ring", "x": repr(-r), "y": repr(-2 * r), - "type": "priority"}, - {"id": "left_lower_ring", "x": repr(-2 * r), "y": repr(-r), - "type": "priority"}, - {"id": "right_lower_ring_in", "x": repr(0), "y": repr(-r), - "type": "priority"}] + nodes = [{ + "id": "center_intersection", + "x": repr(0), + "y": repr(0), + "type": "priority" + }, { + "id": "top_upper_ring", + "x": repr(r), + "y": repr(2 * r), + "type": "priority" + }, { + "id": "bottom_upper_ring_in", + "x": repr(r), + "y": repr(0), + "type": "priority" + }, { + "id": "left_upper_ring", + "x": repr(0), + "y": repr(r), + "type": "priority" + }, { + "id": "right_upper_ring", + "x": repr(2 * r), + "y": repr(r), + "type": "priority" + }, { + "id": "top_lower_ring", + "x": repr(-r), + "y": repr(0), + "type": "priority" + }, { + "id": "bottom_lower_ring", + "x": repr(-r), + "y": repr(-2 * r), + "type": "priority" + }, { + "id": "left_lower_ring", + "x": repr(-2 * r), + "y": repr(-r), + "type": "priority" + }, { + "id": "right_lower_ring_in", + "x": repr(0), + "y": repr(-r), + "type": "priority" + }] return nodes @@ -57,88 +85,134 @@ def specify_edges(self, net_params): intersection_edgelen = 2 * r # intersection edges - edges = [{"id": "right_lower_ring_in", - "type": "edgeType", - "priority": "78", - "from": "right_lower_ring_in", - "to": "center_intersection", - "length": repr(intersection_edgelen / 2)}, - - {"id": "right_lower_ring_out", - "type": "edgeType", - "priority": "78", - "from": "center_intersection", - "to": "left_upper_ring", - "length": repr(intersection_edgelen / 2)}, - - {"id": "bottom_upper_ring_in", - "type": "edgeType", - "priority": "46", - "from": "bottom_upper_ring_in", - "to": "center_intersection", - "length": repr(intersection_edgelen / 2)}, - - {"id": "bottom_upper_ring_out", - "type": "edgeType", - "priority": "46", - "from": "center_intersection", - "to": "top_lower_ring", - "length": repr(intersection_edgelen / 2)}] + edges = [{ + "id": "right_lower_ring_in", + "type": "edgeType", + "priority": "78", + "from": "right_lower_ring_in", + "to": "center_intersection", + "length": repr(intersection_edgelen / 2) + }, { + "id": "right_lower_ring_out", + "type": "edgeType", + "priority": "78", + "from": "center_intersection", + "to": "left_upper_ring", + "length": repr(intersection_edgelen / 2) + }, { + "id": "bottom_upper_ring_in", + "type": "edgeType", + "priority": "46", + "from": "bottom_upper_ring_in", + "to": "center_intersection", + "length": repr(intersection_edgelen / 2) + }, { + "id": "bottom_upper_ring_out", + "type": "edgeType", + "priority": "46", + "from": "center_intersection", + "to": "top_lower_ring", + "length": repr(intersection_edgelen / 2) + }] # ring edges - edges += [{"id": "left_upper_ring", - "type": "edgeType", - "from": "left_upper_ring", - "to": "top_upper_ring", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (r * (1 - cos(t)), r * (1 + sin(t))) - for t in linspace(0, pi / 2, resolution)])}, - - {"id": "top_upper_ring", - "type": "edgeType", - "from": "top_upper_ring", - "to": "right_upper_ring", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (r * (1 + sin(t)), r * (1 + cos(t))) - for t in linspace(0, pi / 2, resolution)])}, - - {"id": "right_upper_ring", - "type": "edgeType", - "from": "right_upper_ring", - "to": "bottom_upper_ring_in", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (r * (1 + cos(t)), r * (1 - sin(t))) - for t in linspace(0, pi / 2, resolution)])}, - - {"id": "top_lower_ring", - "type": "edgeType", - "from": "top_lower_ring", - "to": "left_lower_ring", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (- r + r * cos(t), -r + r * sin(t)) - for t in linspace(pi / 2, pi, resolution)])}, - - {"id": "left_lower_ring", - "type": "edgeType", - "from": "left_lower_ring", - "to": "bottom_lower_ring", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (- r + r * cos(t), - r + r * sin(t)) - for t in linspace(pi, 3 * pi / 2, resolution)])}, - - {"id": "bottom_lower_ring", - "type": "edgeType", - "from": "bottom_lower_ring", - "to": "right_lower_ring_in", - "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (- r + r * cos(t), - r + r * sin(t)) - for t in linspace(-pi / 2, 0, resolution)])}] + edges += [{ + "id": + "left_upper_ring", + "type": + "edgeType", + "from": + "left_upper_ring", + "to": + "top_upper_ring", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * (1 - cos(t)), r * (1 + sin(t))) + for t in linspace(0, pi / 2, resolution) + ]) + }, { + "id": + "top_upper_ring", + "type": + "edgeType", + "from": + "top_upper_ring", + "to": + "right_upper_ring", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * (1 + sin(t)), r * (1 + cos(t))) + for t in linspace(0, pi / 2, resolution) + ]) + }, { + "id": + "right_upper_ring", + "type": + "edgeType", + "from": + "right_upper_ring", + "to": + "bottom_upper_ring_in", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * (1 + cos(t)), r * (1 - sin(t))) + for t in linspace(0, pi / 2, resolution) + ]) + }, { + "id": + "top_lower_ring", + "type": + "edgeType", + "from": + "top_lower_ring", + "to": + "left_lower_ring", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (-r + r * cos(t), -r + r * sin(t)) + for t in linspace(pi / 2, pi, resolution) + ]) + }, { + "id": + "left_lower_ring", + "type": + "edgeType", + "from": + "left_lower_ring", + "to": + "bottom_lower_ring", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (-r + r * cos(t), -r + r * sin(t)) + for t in linspace(pi, 3 * pi / 2, resolution) + ]) + }, { + "id": + "bottom_lower_ring", + "type": + "edgeType", + "from": + "bottom_lower_ring", + "to": + "right_lower_ring_in", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (-r + r * cos(t), -r + r * sin(t)) + for t in linspace(-pi / 2, 0, resolution) + ]) + }] return edges @@ -148,8 +222,11 @@ def specify_types(self, net_params): """ lanes = net_params.additional_params["lanes"] speed_limit = net_params.additional_params["speed_limit"] - types = [{"id": "edgeType", "numLanes": repr(lanes), - "speed": repr(speed_limit)}] + types = [{ + "id": "edgeType", + "numLanes": repr(lanes), + "speed": repr(speed_limit) + }] return types @@ -157,83 +234,67 @@ def specify_routes(self, net_params): """ See parent class """ - rts = {"bottom_lower_ring": ["bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring", - "top_upper_ring", "right_upper_ring", - "bottom_upper_ring_in", - "bottom_upper_ring_out", "top_lower_ring", - "left_lower_ring"], - - "right_lower_ring_in": ["right_lower_ring_in", - "right_lower_ring_out", - "left_upper_ring", - "top_upper_ring", "right_upper_ring", - "bottom_upper_ring_in", - "bottom_upper_ring_out", - "top_lower_ring", "left_lower_ring", - "bottom_lower_ring"], - - "right_lower_ring_out": ["right_lower_ring_out", - "left_upper_ring", "top_upper_ring", - "right_upper_ring", - "bottom_upper_ring_in", - "bottom_upper_ring_out", - "top_lower_ring", - "left_lower_ring", "bottom_lower_ring", - "right_lower_ring_in"], - - "left_upper_ring": ["left_upper_ring", "top_upper_ring", - "right_upper_ring", "bottom_upper_ring_in", - "bottom_upper_ring_out", "top_lower_ring", - "left_lower_ring", "bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out"], - - "top_upper_ring": ["top_upper_ring", "right_upper_ring", - "bottom_upper_ring_in", - "bottom_upper_ring_out", "top_lower_ring", - "left_lower_ring", "bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring"], - - "right_upper_ring": ["right_upper_ring", "bottom_upper_ring_in", - "bottom_upper_ring_out", - "top_lower_ring", "left_lower_ring", - "bottom_lower_ring", "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring", - "top_upper_ring"], - - "bottom_upper_ring_in": ["bottom_upper_ring_in", - "bottom_upper_ring_out", - "top_lower_ring", - "left_lower_ring", "bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out", - "left_upper_ring", "top_upper_ring", - "right_upper_ring"], - - "bottom_upper_ring_out": ["bottom_upper_ring_out", - "top_lower_ring", "left_lower_ring", - "bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out", - "left_upper_ring", "top_upper_ring", - "right_upper_ring", - "bottom_upper_ring_in"], - - "top_lower_ring": ["top_lower_ring", "left_lower_ring", - "bottom_lower_ring", "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring", - "top_upper_ring", - "right_upper_ring", "bottom_upper_ring_in", - "bottom_upper_ring_out"], - - "left_lower_ring": ["left_lower_ring", "bottom_lower_ring", - "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring", - "top_upper_ring", "right_upper_ring", - "bottom_upper_ring_in", - "bottom_upper_ring_out", "top_lower_ring"]} + rts = { + "bottom_lower_ring": [ + "bottom_lower_ring", "right_lower_ring_in", + "right_lower_ring_out", "left_upper_ring", "top_upper_ring", + "right_upper_ring", "bottom_upper_ring_in", + "bottom_upper_ring_out", "top_lower_ring", "left_lower_ring" + ], + "right_lower_ring_in": [ + "right_lower_ring_in", "right_lower_ring_out", + "left_upper_ring", "top_upper_ring", "right_upper_ring", + "bottom_upper_ring_in", "bottom_upper_ring_out", + "top_lower_ring", "left_lower_ring", "bottom_lower_ring" + ], + "right_lower_ring_out": [ + "right_lower_ring_out", "left_upper_ring", "top_upper_ring", + "right_upper_ring", "bottom_upper_ring_in", + "bottom_upper_ring_out", "top_lower_ring", "left_lower_ring", + "bottom_lower_ring", "right_lower_ring_in" + ], + "left_upper_ring": [ + "left_upper_ring", "top_upper_ring", "right_upper_ring", + "bottom_upper_ring_in", "bottom_upper_ring_out", + "top_lower_ring", "left_lower_ring", "bottom_lower_ring", + "right_lower_ring_in", "right_lower_ring_out" + ], + "top_upper_ring": [ + "top_upper_ring", "right_upper_ring", "bottom_upper_ring_in", + "bottom_upper_ring_out", "top_lower_ring", "left_lower_ring", + "bottom_lower_ring", "right_lower_ring_in", + "right_lower_ring_out", "left_upper_ring" + ], + "right_upper_ring": [ + "right_upper_ring", "bottom_upper_ring_in", + "bottom_upper_ring_out", "top_lower_ring", "left_lower_ring", + "bottom_lower_ring", "right_lower_ring_in", + "right_lower_ring_out", "left_upper_ring", "top_upper_ring" + ], + "bottom_upper_ring_in": [ + "bottom_upper_ring_in", "bottom_upper_ring_out", + "top_lower_ring", "left_lower_ring", "bottom_lower_ring", + "right_lower_ring_in", "right_lower_ring_out", + "left_upper_ring", "top_upper_ring", "right_upper_ring" + ], + "bottom_upper_ring_out": [ + "bottom_upper_ring_out", "top_lower_ring", "left_lower_ring", + "bottom_lower_ring", "right_lower_ring_in", + "right_lower_ring_out", "left_upper_ring", "top_upper_ring", + "right_upper_ring", "bottom_upper_ring_in" + ], + "top_lower_ring": [ + "top_lower_ring", "left_lower_ring", "bottom_lower_ring", + "right_lower_ring_in", "right_lower_ring_out", + "left_upper_ring", "top_upper_ring", "right_upper_ring", + "bottom_upper_ring_in", "bottom_upper_ring_out" + ], + "left_lower_ring": [ + "left_lower_ring", "bottom_lower_ring", "right_lower_ring_in", + "right_lower_ring_out", "left_upper_ring", "top_upper_ring", + "right_upper_ring", "bottom_upper_ring_in", + "bottom_upper_ring_out", "top_lower_ring" + ] + } return rts diff --git a/flow/scenarios/grid/gen.py b/flow/scenarios/grid/gen.py index 8207fdd9b..06aab89a1 100644 --- a/flow/scenarios/grid/gen.py +++ b/flow/scenarios/grid/gen.py @@ -66,15 +66,22 @@ def specify_types(self, net_params): vertical_lanes = add_params["vertical_lanes"] if isinstance(add_params["speed_limit"], int) or \ isinstance(add_params["speed_limit"], float): - speed_limit = {"horizontal": add_params["speed_limit"], - "vertical": add_params["speed_limit"]} + speed_limit = { + "horizontal": add_params["speed_limit"], + "vertical": add_params["speed_limit"] + } else: speed_limit = add_params["speed_limit"] - types = [{"id": "horizontal", "numLanes": repr(horizontal_lanes), - "speed": repr(speed_limit["horizontal"])}, - {"id": "vertical", "numLanes": repr(vertical_lanes), - "speed": repr(speed_limit["vertical"])}] + types = [{ + "id": "horizontal", + "numLanes": repr(horizontal_lanes), + "speed": repr(speed_limit["horizontal"]) + }, { + "id": "vertical", + "numLanes": repr(vertical_lanes), + "speed": repr(speed_limit["vertical"]) + }] return types @@ -109,10 +116,12 @@ def _build_inner_nodes(self): index = i * col_num + j x_center = j * inner_length y_center = i * inner_length - nodes.append({"id": "center" + str(index), - "x": repr(x_center), - "y": repr(y_center), - "type": node_type}) + nodes.append({ + "id": "center" + str(index), + "x": repr(x_center), + "y": repr(y_center), + "type": node_type + }) return nodes def _build_outer_nodes(self): @@ -137,66 +146,54 @@ def _build_outer_nodes(self): nodes = [] for i in range(col_num): # build the bottom nodes - nodes += [ - { - "id": "bot_col_short" + str(i), - "x": repr(i * inner_length), - "y": repr(-short_length), - "type": "priority" - }, - { - "id": "bot_col_long" + str(i), - "x": repr(i * inner_length), - "y": repr(-long_length), - "type": "priority" - } - ] + nodes += [{ + "id": "bot_col_short" + str(i), + "x": repr(i * inner_length), + "y": repr(-short_length), + "type": "priority" + }, { + "id": "bot_col_long" + str(i), + "x": repr(i * inner_length), + "y": repr(-long_length), + "type": "priority" + }] # build the top nodes - nodes += [ - { - "id": "top_col_short" + str(i), - "x": repr(i * inner_length), - "y": repr((row_num - 1) * inner_length + short_length), - "type": "priority" - }, - { - "id": "top_col_long" + str(i), - "x": repr(i * inner_length), - "y": repr((row_num - 1) * inner_length + long_length), - "type": "priority" - } - ] + nodes += [{ + "id": "top_col_short" + str(i), + "x": repr(i * inner_length), + "y": repr((row_num - 1) * inner_length + short_length), + "type": "priority" + }, { + "id": "top_col_long" + str(i), + "x": repr(i * inner_length), + "y": repr((row_num - 1) * inner_length + long_length), + "type": "priority" + }] for i in range(row_num): # build the left nodes - nodes += [ - { - "id": "left_row_short" + str(i), - "x": repr(-short_length), - "y": repr(i * inner_length), - "type": "priority" - }, - { - "id": "left_row_long" + str(i), - "x": repr(-long_length), - "y": repr(i * inner_length), - "type": "priority" - } - ] + nodes += [{ + "id": "left_row_short" + str(i), + "x": repr(-short_length), + "y": repr(i * inner_length), + "type": "priority" + }, { + "id": "left_row_long" + str(i), + "x": repr(-long_length), + "y": repr(i * inner_length), + "type": "priority" + }] # build the right nodes - nodes += [ - { - "id": "right_row_short" + str(i), - "x": repr((col_num - 1) * inner_length + short_length), - "y": repr(i * inner_length), - "type": "priority" - }, - { - "id": "right_row_long" + str(i), - "x": repr((col_num - 1) * inner_length + long_length), - "y": repr(i * inner_length), - "type": "priority" - } - ] + nodes += [{ + "id": "right_row_short" + str(i), + "x": repr((col_num - 1) * inner_length + short_length), + "y": repr(i * inner_length), + "type": "priority" + }, { + "id": "right_row_long" + str(i), + "x": repr((col_num - 1) * inner_length + long_length), + "y": repr(i * inner_length), + "type": "priority" + }] return nodes def _build_inner_edges(self): @@ -220,30 +217,27 @@ def _build_inner_edges(self): for i in range(row_num): for j in range(col_num - 1): node_index = i * col_num + j - index = "{}_{}".format(i, j+1) - self.node_mapping["center{}".format(node_index+1)].append( - "bot" + index) - self.node_mapping["center{}".format(node_index)].append( - "top" + index) - - edges += [ - { - "id": "top" + index, - "type": "horizontal", - "priority": "78", - "from": "center" + str(node_index + 1), - "to": "center" + str(node_index), - "length": repr(inner_length) - }, - { - "id": "bot" + index, - "type": "horizontal", - "priority": "78", - "from": "center" + str(node_index), - "to": "center" + str(node_index + 1), - "length": repr(inner_length) - } - ] + index = "{}_{}".format(i, j + 1) + self.node_mapping["center{}".format(node_index + + 1)].append("bot" + index) + self.node_mapping["center{}".format(node_index)].append("top" + + index) + + edges += [{ + "id": "top" + index, + "type": "horizontal", + "priority": "78", + "from": "center" + str(node_index + 1), + "to": "center" + str(node_index), + "length": repr(inner_length) + }, { + "id": "bot" + index, + "type": "horizontal", + "priority": "78", + "from": "center" + str(node_index), + "to": "center" + str(node_index + 1), + "length": repr(inner_length) + }] # Build the vertical edges for i in range(row_num - 1): @@ -256,24 +250,21 @@ def _build_inner_edges(self): self.node_mapping["center{}".format(node_index_bot)].append( "left" + index) - edges += [ - { - "id": "right" + index, - "type": "vertical", - "priority": "78", - "from": "center" + str(node_index_bot), - "to": "center" + str(node_index_top), - "length": repr(inner_length) - }, - { - "id": "left" + index, - "type": "vertical", - "priority": "78", - "from": "center" + str(node_index_top), - "to": "center" + str(node_index_bot), - "length": repr(inner_length) - } - ] + edges += [{ + "id": "right" + index, + "type": "vertical", + "priority": "78", + "from": "center" + str(node_index_bot), + "to": "center" + str(node_index_top), + "length": repr(inner_length) + }, { + "id": "left" + index, + "type": "vertical", + "priority": "78", + "from": "center" + str(node_index_top), + "to": "center" + str(node_index_bot), + "length": repr(inner_length) + }] return edges @@ -299,93 +290,83 @@ def _build_outer_edges(self): index = '0_' + str(i) # bottom edges self.node_mapping["center" + str(i)].append("right" + index) - edges += [ - { - "id": "right" + index, - "type": "vertical", - "priority": "78", - "from": "bot_col_short" + str(i), - "to": "center" + str(i), - "length": repr(short_length) - }, - { - "id": "left" + index, - "type": "vertical", - "priority": "78", - "from": "center" + str(i), - "to": "bot_col_long" + str(i), - "length": repr(long_length) - } - ] + edges += [{ + "id": "right" + index, + "type": "vertical", + "priority": "78", + "from": "bot_col_short" + str(i), + "to": "center" + str(i), + "length": repr(short_length) + }, { + "id": "left" + index, + "type": "vertical", + "priority": "78", + "from": "center" + str(i), + "to": "bot_col_long" + str(i), + "length": repr(long_length) + }] # top edges index = str(row_num) + '_' + str(i) center_start = (row_num - 1) * col_num - self.node_mapping["center" + str(center_start + i)].append( - "left" + index) - edges += [ - { - "id": "left" + index, - "type": "vertical", - "priority": "78", - "from": "top_col_short" + str(i), - "to": "center" + str(center_start + i), - "length": repr(short_length) - }, - { - "id": "right" + index, - "type": "vertical", - "priority": "78", - "from": "center" + str(center_start + i), - "to": "top_col_long" + str(i), - "length": repr(long_length) - } - ] + self.node_mapping["center" + str(center_start + i)].append("left" + + index) + edges += [{ + "id": "left" + index, + "type": "vertical", + "priority": "78", + "from": "top_col_short" + str(i), + "to": "center" + str(center_start + i), + "length": repr(short_length) + }, { + "id": "right" + index, + "type": "vertical", + "priority": "78", + "from": "center" + str(center_start + i), + "to": "top_col_long" + str(i), + "length": repr(long_length) + }] # build the left and then the right edges for j in range(row_num): index = str(j) + '_0' # left edges - self.node_mapping["center" + str(j*col_num)].append("bot" + index) - edges += [ - { - "id": "bot" + index, - "type": "horizontal", - "priority": "78", - "from": "left_row_short" + str(j), - "to": "center" + str(j * col_num), - "length": repr(short_length) - }, - { - "id": "top" + index, - "type": "horizontal", - "priority": "78", - "from": "center" + str(j * col_num), - "to": "left_row_long" + str(j), - "length": repr(long_length) - } - ] + self.node_mapping["center" + str(j * col_num)].append("bot" + + index) + edges += [{ + "id": "bot" + index, + "type": "horizontal", + "priority": "78", + "from": "left_row_short" + str(j), + "to": "center" + str(j * col_num), + "length": repr(short_length) + }, { + "id": "top" + index, + "type": "horizontal", + "priority": "78", + "from": "center" + str(j * col_num), + "to": "left_row_long" + str(j), + "length": repr(long_length) + }] # right edges index = str(j) + '_' + str(col_num) center_index = (j * col_num) + col_num - 1 - self.node_mapping["center"+str(center_index)].append("top"+index) - edges += [ - { - "id": "top" + index, - "type": "horizontal", - "priority": "78", - "from": "right_row_short" + str(j), - "to": "center" + str(center_index), - "length": repr(short_length) - }, - { - "id": "bot" + index, - "type": "horizontal", - "priority": "78", - "from": "center" + str(center_index), - "to": "right_row_long" + str(j), - "length": repr(long_length) - } - ] + self.node_mapping["center" + str(center_index)].append("top" + + index) + edges += [{ + "id": "top" + index, + "type": "horizontal", + "priority": "78", + "from": "right_row_short" + str(j), + "to": "center" + str(center_index), + "length": repr(short_length) + }, { + "id": "bot" + index, + "type": "horizontal", + "priority": "78", + "from": "center" + str(center_index), + "to": "right_row_long" + str(j), + "length": repr(long_length) + }] return edges diff --git a/flow/scenarios/grid/grid_scenario.py b/flow/scenarios/grid/grid_scenario.py index 02e6104e7..79820c8ea 100644 --- a/flow/scenarios/grid/grid_scenario.py +++ b/flow/scenarios/grid/grid_scenario.py @@ -30,12 +30,19 @@ "vertical_lanes": 1, # speed limit for all edges, may be represented as a float value, or a # dictionary with separate values for vertical and horizontal lanes - "speed_limit": {"vertical": 35, "horizontal": 35}, + "speed_limit": { + "vertical": 35, + "horizontal": 35 + }, } class SimpleGridScenario(Scenario): - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes an nxm grid scenario. @@ -75,8 +82,8 @@ def __init__(self, name, generator_class, vehicles, net_params, for p in ADDITIONAL_NET_PARAMS["grid_array"].keys(): if p not in net_params.additional_params["grid_array"]: - raise KeyError('Grid array parameter "{}" not supplied'. - format(p)) + raise KeyError( + 'Grid array parameter "{}" not supplied'.format(p)) # this is a (mx1)x(nx1)x2 array # the third dimension is vertical length, horizontal length @@ -106,10 +113,10 @@ def specify_edge_starts(self): for i in range(self.col_num + 1): for j in range(self.row_num + 1): index = str(j) + '_' + str(i) - edgestarts += [("left" + index, 0+i*50 + j*5000), - ("right" + index, 10+i*50 + j*5000), - ("top" + index, 15+i*50 + j*5000), - ("bot" + index, 20+i*50 + j*5000)] + edgestarts += [("left" + index, 0 + i * 50 + j * 5000), + ("right" + index, 10 + i * 50 + j * 5000), + ("top" + index, 15 + i * 50 + j * 5000), + ("bot" + index, 20 + i * 50 + j * 5000)] return edgestarts @@ -123,7 +130,7 @@ def specify_intersection_edge_starts(self): def gen_even_start_pos(self, initial_config, num_vehicles, **kwargs): row_num = self.grid_array["row_num"] col_num = self.grid_array["col_num"] - per_edge = int(num_vehicles/(2 * (row_num+col_num))) + per_edge = int(num_vehicles / (2 * (row_num + col_num))) start_positions = [] d_inc = 10 for i in range(self.col_num): diff --git a/flow/scenarios/highway/gen.py b/flow/scenarios/highway/gen.py index 6901f2a6c..c5b4f009e 100644 --- a/flow/scenarios/highway/gen.py +++ b/flow/scenarios/highway/gen.py @@ -17,8 +17,15 @@ def specify_nodes(self, net_params): """ length = net_params.additional_params["length"] - nodes = [{"id": "begin", "x": repr(0), "y": repr(0)}, - {"id": "end", "x": repr(length), "y": repr(0)}] + nodes = [{ + "id": "begin", + "x": repr(0), + "y": repr(0) + }, { + "id": "end", + "x": repr(length), + "y": repr(0) + }] return nodes @@ -28,13 +35,13 @@ def specify_edges(self, net_params): """ length = net_params.additional_params["length"] - edges = [ - {"id": "highway", - "type": "highwayType", - "from": "begin", - "to": "end", - "length": repr(length)} - ] + edges = [{ + "id": "highway", + "type": "highwayType", + "from": "begin", + "to": "end", + "length": repr(length) + }] return edges @@ -45,9 +52,11 @@ def specify_types(self, net_params): lanes = net_params.additional_params["lanes"] speed_limit = net_params.additional_params["speed_limit"] - types = [{"id": "highwayType", - "numLanes": repr(lanes), - "speed": repr(speed_limit)}] + types = [{ + "id": "highwayType", + "numLanes": repr(lanes), + "speed": repr(speed_limit) + }] return types diff --git a/flow/scenarios/highway/scenario.py b/flow/scenarios/highway/scenario.py index e397481eb..4ad83c275 100644 --- a/flow/scenarios/highway/scenario.py +++ b/flow/scenarios/highway/scenario.py @@ -2,7 +2,6 @@ from flow.core.params import InitialConfig from flow.core.traffic_lights import TrafficLights - ADDITIONAL_NET_PARAMS = { # length of the highway "length": 1000, @@ -14,8 +13,11 @@ class HighwayScenario(Scenario): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a highway scenario. diff --git a/flow/scenarios/loop/gen.py b/flow/scenarios/loop/gen.py index 80e5a1fc4..9f4b51ae2 100755 --- a/flow/scenarios/loop/gen.py +++ b/flow/scenarios/loop/gen.py @@ -7,6 +7,7 @@ class CircleGenerator(Generator): """ Generator for loop circle used in MIT traffic simulation. """ + def __init__(self, net_params, base): """ See parent class @@ -24,10 +25,23 @@ def specify_nodes(self, net_params): length = net_params.additional_params["length"] r = length / (2 * pi) - nodes = [{"id": "bottom", "x": repr(0), "y": repr(-r)}, - {"id": "right", "x": repr(r), "y": repr(0)}, - {"id": "top", "x": repr(0), "y": repr(r)}, - {"id": "left", "x": repr(-r), "y": repr(0)}] + nodes = [{ + "id": "bottom", + "x": repr(0), + "y": repr(-r) + }, { + "id": "right", + "x": repr(r), + "y": repr(0) + }, { + "id": "top", + "x": repr(0), + "y": repr(r) + }, { + "id": "left", + "x": repr(-r), + "y": repr(0) + }] return nodes @@ -40,36 +54,71 @@ def specify_edges(self, net_params): r = length / (2 * pi) edgelen = length / 4. - edges = [ - {"id": "bottom", - "type": "edgeType", - "from": "bottom", - "to": "right", - "length": repr(edgelen), - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(-pi / 2, 0, resolution)])}, - {"id": "right", - "type": "edgeType", - "from": "right", - "to": "top", - "length": repr(edgelen), - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(0, pi / 2, resolution)])}, - {"id": "top", - "type": "edgeType", - "from": "top", - "to": "left", - "length": repr(edgelen), - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(pi / 2, pi, resolution)])}, - {"id": "left", - "type": "edgeType", - "from": "left", - "to": "bottom", - "length": repr(edgelen), - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(pi, 3 * pi/2, resolution)])} - ] + edges = [{ + "id": + "bottom", + "type": + "edgeType", + "from": + "bottom", + "to": + "right", + "length": + repr(edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(-pi / 2, 0, resolution) + ]) + }, { + "id": + "right", + "type": + "edgeType", + "from": + "right", + "to": + "top", + "length": + repr(edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(0, pi / 2, resolution) + ]) + }, { + "id": + "top", + "type": + "edgeType", + "from": + "top", + "to": + "left", + "length": + repr(edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(pi / 2, pi, resolution) + ]) + }, { + "id": + "left", + "type": + "edgeType", + "from": + "left", + "to": + "bottom", + "length": + repr(edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(pi, 3 * pi / 2, resolution) + ]) + }] return edges @@ -80,9 +129,11 @@ def specify_types(self, net_params): lanes = net_params.additional_params["lanes"] speed_limit = net_params.additional_params["speed_limit"] - types = [{"id": "edgeType", - "numLanes": repr(lanes), - "speed": repr(speed_limit)}] + types = [{ + "id": "edgeType", + "numLanes": repr(lanes), + "speed": repr(speed_limit) + }] return types @@ -90,9 +141,11 @@ def specify_routes(self, net_params): """ See parent class """ - rts = {"top": ["top", "left", "bottom", "right"], - "left": ["left", "bottom", "right", "top"], - "bottom": ["bottom", "right", "top", "left"], - "right": ["right", "top", "left", "bottom"]} + rts = { + "top": ["top", "left", "bottom", "right"], + "left": ["left", "bottom", "right", "top"], + "bottom": ["bottom", "right", "top", "left"], + "right": ["right", "top", "left", "bottom"] + } return rts diff --git a/flow/scenarios/loop/loop_scenario.py b/flow/scenarios/loop/loop_scenario.py index 169ee232b..bb3ad575d 100755 --- a/flow/scenarios/loop/loop_scenario.py +++ b/flow/scenarios/loop/loop_scenario.py @@ -2,7 +2,6 @@ from flow.core.params import InitialConfig from flow.core.traffic_lights import TrafficLights - ADDITIONAL_NET_PARAMS = { # length of the ring road "length": 230, @@ -16,7 +15,11 @@ class LoopScenario(Scenario): - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a loop scenario. @@ -45,7 +48,7 @@ def specify_edge_starts(self): """ edgelen = self.length / 4 - edgestarts = [("bottom", 0), ("right", edgelen), - ("top", 2 * edgelen), ("left", 3 * edgelen)] + edgestarts = [("bottom", 0), ("right", edgelen), ("top", 2 * edgelen), + ("left", 3 * edgelen)] return edgestarts diff --git a/flow/scenarios/loop_merge/gen.py b/flow/scenarios/loop_merge/gen.py index 00d0fade7..b4e2da3ae 100644 --- a/flow/scenarios/loop_merge/gen.py +++ b/flow/scenarios/loop_merge/gen.py @@ -8,6 +8,7 @@ class TwoLoopOneMergingGenerator(Generator): Generator for a two-loop network in which both loops merge into a common lane. """ + def __init__(self, net_params, base): """ See parent class @@ -28,14 +29,27 @@ def specify_nodes(self, net_params): r = net_params.additional_params["ring_radius"] x = net_params.additional_params["lane_length"] - nodes = [{"id": "top_left", "x": repr(0), "y": repr(r), - "type": "priority"}, - {"id": "bottom_left", "x": repr(0), "y": repr(-r), - "type": "priority"}, - {"id": "top_right", "x": repr(x), "y": repr(r), - "type": "priority"}, - {"id": "bottom_right", "x": repr(x), "y": repr(-r), - "type": "priority"}] + nodes = [{ + "id": "top_left", + "x": repr(0), + "y": repr(r), + "type": "priority" + }, { + "id": "bottom_left", + "x": repr(0), + "y": repr(-r), + "type": "priority" + }, { + "id": "top_right", + "x": repr(x), + "y": repr(r), + "type": "priority" + }, { + "id": "bottom_right", + "x": repr(x), + "y": repr(-r), + "type": "priority" + }] return nodes @@ -49,36 +63,78 @@ def specify_edges(self, net_params): ring_edgelen = pi * r resolution = 40 - edges = [ - {"id": "center", "from": "bottom_left", "to": "top_left", - "type": "edgeType", "length": repr(ring_edgelen), - "priority": "46", "shape": " ".join( - ["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(- pi / 2, pi / 2, resolution)]), - "numLanes": str(self.inner_lanes)}, - - {"id": "top", "from": "top_right", "to": "top_left", - "type": "edgeType", "length": repr(x), "priority": "46", - "numLanes": str(self.outer_lanes)}, - - {"id": "bottom", "from": "bottom_left", "to": "bottom_right", - "type": "edgeType", "length": repr(x), - "numLanes": str(self.outer_lanes)}, - - {"id": "left", "from": "top_left", "to": "bottom_left", - "type": "edgeType", "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(pi / 2, 3 * pi / 2, resolution)]), - "numLanes": str(self.inner_lanes)}, - - {"id": "right", "from": "bottom_right", "to": "top_right", - "type": "edgeType", "length": repr(ring_edgelen), - "shape": " ".join( - ["%.2f,%.2f" % (x + r * cos(t), r * sin(t)) - for t in linspace(- pi / 2, pi / 2, resolution)]), - "numLanes": str(self.outer_lanes)} - ] + edges = [{ + "id": + "center", + "from": + "bottom_left", + "to": + "top_left", + "type": + "edgeType", + "length": + repr(ring_edgelen), + "priority": + "46", + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(-pi / 2, pi / 2, resolution) + ]), + "numLanes": + str(self.inner_lanes) + }, { + "id": "top", + "from": "top_right", + "to": "top_left", + "type": "edgeType", + "length": repr(x), + "priority": "46", + "numLanes": str(self.outer_lanes) + }, { + "id": "bottom", + "from": "bottom_left", + "to": "bottom_right", + "type": "edgeType", + "length": repr(x), + "numLanes": str(self.outer_lanes) + }, { + "id": + "left", + "from": + "top_left", + "to": + "bottom_left", + "type": + "edgeType", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(pi / 2, 3 * pi / 2, resolution) + ]), + "numLanes": + str(self.inner_lanes) + }, { + "id": + "right", + "from": + "bottom_right", + "to": + "top_right", + "type": + "edgeType", + "length": + repr(ring_edgelen), + "shape": + " ".join([ + "%.2f,%.2f" % (x + r * cos(t), r * sin(t)) + for t in linspace(-pi / 2, pi / 2, resolution) + ]), + "numLanes": + str(self.outer_lanes) + }] return edges @@ -95,10 +151,12 @@ def specify_routes(self, net_params): """ See parent class """ - rts = {"top": ["top", "left", "bottom", "right", "top"], - "bottom": ["bottom", "right", "top", "left", "bottom"], - "right": ["right", "top", "left", "bottom"], - "left": ["left", "center", "left"], - "center": ["center", "left", "center"]} + rts = { + "top": ["top", "left", "bottom", "right", "top"], + "bottom": ["bottom", "right", "top", "left", "bottom"], + "right": ["right", "top", "left", "bottom"], + "left": ["left", "center", "left"], + "center": ["center", "left", "center"] + } return rts diff --git a/flow/scenarios/loop_merge/scenario.py b/flow/scenarios/loop_merge/scenario.py index 06852358b..e20cd998d 100644 --- a/flow/scenarios/loop_merge/scenario.py +++ b/flow/scenarios/loop_merge/scenario.py @@ -2,11 +2,9 @@ from flow.core.params import InitialConfig from flow.core.traffic_lights import TrafficLights - from numpy import pi import numpy as np - ADDITIONAL_NET_PARAMS = { # radius of the loops "ring_radius": 50, @@ -24,7 +22,11 @@ class TwoLoopsOneMergingScenario(Scenario): - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a two loop scenario where one loop merging in and out of @@ -81,10 +83,10 @@ def specify_edge_starts(self): ("left", self.intersection_length), ("center", ring_edgelen + 2 * self.intersection_length), ("bottom", 2 * ring_edgelen + 2 * self.intersection_length), - ("right", 2 * ring_edgelen + lane_length - + 2 * self.intersection_length + self.junction_length), - ("top", 3 * ring_edgelen + lane_length - + 2 * self.intersection_length + 2 * self.junction_length) + ("right", 2 * ring_edgelen + lane_length + + 2 * self.intersection_length + self.junction_length), + ("top", 3 * ring_edgelen + lane_length + + 2 * self.intersection_length + 2 * self.junction_length) ] return edgestarts @@ -99,12 +101,12 @@ def specify_internal_edge_starts(self): ring_edgelen = pi * r internal_edgestarts = [ - (":top_left", 0), - (":bottom_left", ring_edgelen + self.intersection_length), - (":bottom_right", 2 * ring_edgelen + lane_length - + 2 * self.intersection_length), - (":top_right", 3 * ring_edgelen + lane_length - + 2 * self.intersection_length + self.junction_length) + (":top_left", 0), (":bottom_left", + ring_edgelen + self.intersection_length), + (":bottom_right", + 2 * ring_edgelen + lane_length + 2 * self.intersection_length), + (":top_right", 3 * ring_edgelen + lane_length + + 2 * self.intersection_length + self.junction_length) ] return internal_edgestarts @@ -154,8 +156,8 @@ def gen_custom_start_pos(self, initial_config, num_vehicles, **kwargs): / (num_vehicles - num_merge_vehicles) # x = [x0] * initial_config.lanes_distribution - if self.initial_config.additional_params.get("ring_from_right", - False): + if self.initial_config.additional_params.get( + "ring_from_right", False): x = [dict(self.edgestarts)["right"]] * \ self.net_params.additional_params["inner_lanes"] else: @@ -171,15 +173,15 @@ def gen_custom_start_pos(self, initial_config, num_vehicles, **kwargs): # find the location of the internal edge in # total_edgestarts, which has the edges ordered by position edges = [tup[0] for tup in self.total_edgestarts] - indx_edge = next(i for i, edge in enumerate(edges) - if edge == pos[0]) + indx_edge = next( + i for i, edge in enumerate(edges) if edge == pos[0]) # take the next edge in the list, and place the car at the # beginning of this edge - if indx_edge == len(edges)-1: + if indx_edge == len(edges) - 1: next_edge_pos = self.total_edgestarts[0] else: - next_edge_pos = self.total_edgestarts[indx_edge+1] + next_edge_pos = self.total_edgestarts[indx_edge + 1] x[lane_count] = next_edge_pos[1] pos = (next_edge_pos[0], 0) @@ -208,8 +210,8 @@ def gen_custom_start_pos(self, initial_config, num_vehicles, **kwargs): (length_merge - merge_bunching) * \ initial_config.lanes_distribution / num_merge_vehicles - if self.initial_config.additional_params.get("merge_from_top", - False): + if self.initial_config.additional_params.get( + "merge_from_top", False): x = [dict(self.edgestarts)["top"] - x0] * \ self.net_params.additional_params["outer_lanes"] else: @@ -226,15 +228,15 @@ def gen_custom_start_pos(self, initial_config, num_vehicles, **kwargs): # find the location of the internal edge in # total_edgestarts, which has the edges ordered by position edges = [tup[0] for tup in self.total_edgestarts] - indx_edge = next(i for i, edge in enumerate(edges) - if edge == pos[0]) + indx_edge = next( + i for i, edge in enumerate(edges) if edge == pos[0]) # take the next edge in the list, and place the car at the # beginning of this edge - if indx_edge == len(edges)-1: + if indx_edge == len(edges) - 1: next_edge_pos = self.total_edgestarts[0] else: - next_edge_pos = self.total_edgestarts[indx_edge+1] + next_edge_pos = self.total_edgestarts[indx_edge + 1] x[lane_count] = next_edge_pos[1] pos = (next_edge_pos[0], 0) diff --git a/flow/scenarios/merge/gen.py b/flow/scenarios/merge/gen.py index 96ce2abc5..44999dd74 100644 --- a/flow/scenarios/merge/gen.py +++ b/flow/scenarios/merge/gen.py @@ -13,7 +13,7 @@ def __init__(self, net_params, base): merge = net_params.additional_params["merge_length"] premerge = net_params.additional_params["pre_merge_length"] postmerge = net_params.additional_params["post_merge_length"] - length = merge + premerge + postmerge + 2*INFLOW_EDGE_LEN + 8.1 + length = merge + premerge + postmerge + 2 * INFLOW_EDGE_LEN + 8.1 h_lanes = net_params.additional_params["highway_lanes"] m_lanes = net_params.additional_params["merge_lanes"] self.name = "{}-{}m{}l-{}l".format(base, length, h_lanes, m_lanes) @@ -26,17 +26,36 @@ def specify_nodes(self, net_params): postmerge = net_params.additional_params["post_merge_length"] nodes = [ - {"id": "inflow_highway", - "x": repr(-INFLOW_EDGE_LEN), "y": repr(0)}, - {"id": "left", "y": repr(0), "x": repr(0)}, - {"id": "center", "y": repr(0), "x": repr(premerge)}, - {"id": "right", "y": repr(0), "x": repr(premerge+postmerge)}, - {"id": "inflow_merge", - "x": repr(premerge - (merge+INFLOW_EDGE_LEN)*cos(angle)), - "y": repr(-(merge+INFLOW_EDGE_LEN)*sin(angle))}, - {"id": "bottom", - "x": repr(premerge - merge*cos(angle)), - "y": repr(-merge*sin(angle))}, + { + "id": "inflow_highway", + "x": repr(-INFLOW_EDGE_LEN), + "y": repr(0) + }, + { + "id": "left", + "y": repr(0), + "x": repr(0) + }, + { + "id": "center", + "y": repr(0), + "x": repr(premerge) + }, + { + "id": "right", + "y": repr(0), + "x": repr(premerge + postmerge) + }, + { + "id": "inflow_merge", + "x": repr(premerge - (merge + INFLOW_EDGE_LEN) * cos(angle)), + "y": repr(-(merge + INFLOW_EDGE_LEN) * sin(angle)) + }, + { + "id": "bottom", + "x": repr(premerge - merge * cos(angle)), + "y": repr(-merge * sin(angle)) + }, ] return nodes @@ -46,20 +65,37 @@ def specify_edges(self, net_params): premerge = net_params.additional_params["pre_merge_length"] postmerge = net_params.additional_params["post_merge_length"] - edges = [ - {"id": "inflow_highway", "type": "highwayType", - "from": "inflow_highway", "to": "left", - "length": repr(INFLOW_EDGE_LEN)}, - {"id": "left", "type": "highwayType", - "from": "left", "to": "center", "length": repr(premerge)}, - {"id": "inflow_merge", "type": "mergeType", - "from": "inflow_merge", "to": "bottom", - "length": repr(INFLOW_EDGE_LEN)}, - {"id": "bottom", "type": "mergeType", - "from": "bottom", "to": "center", "length": repr(merge)}, - {"id": "center", "type": "highwayType", - "from": "center", "to": "right", "length": repr(postmerge)} - ] + edges = [{ + "id": "inflow_highway", + "type": "highwayType", + "from": "inflow_highway", + "to": "left", + "length": repr(INFLOW_EDGE_LEN) + }, { + "id": "left", + "type": "highwayType", + "from": "left", + "to": "center", + "length": repr(premerge) + }, { + "id": "inflow_merge", + "type": "mergeType", + "from": "inflow_merge", + "to": "bottom", + "length": repr(INFLOW_EDGE_LEN) + }, { + "id": "bottom", + "type": "mergeType", + "from": "bottom", + "to": "center", + "length": repr(merge) + }, { + "id": "center", + "type": "highwayType", + "from": "center", + "to": "right", + "length": repr(postmerge) + }] return edges @@ -68,18 +104,25 @@ def specify_types(self, net_params): m_lanes = net_params.additional_params["merge_lanes"] speed = net_params.additional_params["speed_limit"] - types = [{"id": "highwayType", "numLanes": repr(h_lanes), - "speed": repr(speed)}, - {"id": "mergeType", "numLanes": repr(m_lanes), - "speed": repr(speed)}] + types = [{ + "id": "highwayType", + "numLanes": repr(h_lanes), + "speed": repr(speed) + }, { + "id": "mergeType", + "numLanes": repr(m_lanes), + "speed": repr(speed) + }] return types def specify_routes(self, net_params): - rts = {"inflow_highway": ["inflow_highway", "left", "center"], - "left": ["left", "center"], - "center": ["center"], - "inflow_merge": ["inflow_merge", "bottom", "center"], - "bottom": ["bottom", "center"]} + rts = { + "inflow_highway": ["inflow_highway", "left", "center"], + "left": ["left", "center"], + "center": ["center"], + "inflow_merge": ["inflow_merge", "bottom", "center"], + "bottom": ["bottom", "center"] + } return rts diff --git a/flow/scenarios/merge/scenario.py b/flow/scenarios/merge/scenario.py index 5ab7da93a..598ae2e95 100644 --- a/flow/scenarios/merge/scenario.py +++ b/flow/scenarios/merge/scenario.py @@ -20,8 +20,11 @@ class MergeScenario(Scenario): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a merge scenario. @@ -47,13 +50,12 @@ def specify_edge_starts(self): premerge = self.net_params.additional_params["pre_merge_length"] postmerge = self.net_params.additional_params["post_merge_length"] - edgestarts = [ - ("inflow_highway", 0), - ("left", INFLOW_EDGE_LEN + 0.1), - ("center", INFLOW_EDGE_LEN + premerge + 8.1), - ("inflow_merge", INFLOW_EDGE_LEN + premerge + postmerge + 8.1), - ("bottom", 2*INFLOW_EDGE_LEN + premerge + postmerge + 8.2) - ] + edgestarts = [("inflow_highway", 0), ("left", INFLOW_EDGE_LEN + 0.1), + ("center", INFLOW_EDGE_LEN + premerge + 8.1), + ("inflow_merge", + INFLOW_EDGE_LEN + premerge + postmerge + 8.1), + ("bottom", + 2 * INFLOW_EDGE_LEN + premerge + postmerge + 8.2)] return edgestarts @@ -62,9 +64,9 @@ def specify_internal_edge_starts(self): postmerge = self.net_params.additional_params["post_merge_length"] internal_edgestarts = [ - (":left", INFLOW_EDGE_LEN), - (":center", INFLOW_EDGE_LEN + premerge + 0.1), - (":bottom", 2*INFLOW_EDGE_LEN + premerge + postmerge + 8.1) + (":left", INFLOW_EDGE_LEN), (":center", + INFLOW_EDGE_LEN + premerge + 0.1), + (":bottom", 2 * INFLOW_EDGE_LEN + premerge + postmerge + 8.1) ] return internal_edgestarts diff --git a/flow/scenarios/netfile/scenario.py b/flow/scenarios/netfile/scenario.py index af3c96f4b..71c3fa4ab 100644 --- a/flow/scenarios/netfile/scenario.py +++ b/flow/scenarios/netfile/scenario.py @@ -4,8 +4,11 @@ class NetFileScenario(Scenario): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a scenario from a .net.xml file. diff --git a/flow/scenarios/openstreetmap/scenario.py b/flow/scenarios/openstreetmap/scenario.py index 655620534..1b0ddaec9 100644 --- a/flow/scenarios/openstreetmap/scenario.py +++ b/flow/scenarios/openstreetmap/scenario.py @@ -4,8 +4,11 @@ class OpenStreetMapScenario(Scenario): - - def __init__(self, name, generator_class, vehicles, net_params, + def __init__(self, + name, + generator_class, + vehicles, + net_params, initial_config=InitialConfig(), traffic_lights=TrafficLights()): """Initializes a scenario from a .osm file. diff --git a/flow/utils/flow_warnings.py b/flow/utils/flow_warnings.py index 27b7be18f..9d25e1f6d 100644 --- a/flow/utils/flow_warnings.py +++ b/flow/utils/flow_warnings.py @@ -13,5 +13,6 @@ def deprecation_warning(obj, dep_from, dep_to): dep_to: str new name for the attribute """ - warnings.warn("The attribute {} in {} is deprecated, use {} instead.". - format(dep_from, obj.__class__.__name__, dep_to)) + warnings.warn( + "The attribute {} in {} is deprecated, use {} instead.".format( + dep_from, obj.__class__.__name__, dep_to)) diff --git a/flow/utils/leaderboard/evaluate.py b/flow/utils/leaderboard/evaluate.py index accc19ae0..38242636a 100644 --- a/flow/utils/leaderboard/evaluate.py +++ b/flow/utils/leaderboard/evaluate.py @@ -26,17 +26,19 @@ NUM_RUNS = 10 # dictionary containing all available benchmarks and their meta-parameters -AVAILABLE_BENCHMARKS = {"grid0": grid0, - "grid1": grid1, - "bottleneck0": bottleneck0, - "bottleneck1": bottleneck1, - "bottleneck2": bottleneck2, - "figureeight0": figureeight0, - "figureeight1": figureeight1, - "figureeight2": figureeight2, - "merge0": merge0, - "merge1": merge1, - "merge2": merge2} +AVAILABLE_BENCHMARKS = { + "grid0": grid0, + "grid1": grid1, + "bottleneck0": bottleneck0, + "bottleneck1": bottleneck1, + "bottleneck2": bottleneck2, + "figureeight0": figureeight0, + "figureeight1": figureeight1, + "figureeight2": figureeight2, + "merge0": merge0, + "merge1": merge1, + "merge2": merge2 +} def evaluate_policy(benchmark, _get_actions, _get_states=None): @@ -70,8 +72,8 @@ def evaluate_policy(benchmark, _get_actions, _get_states=None): If the specified benchmark is not available. """ if benchmark not in AVAILABLE_BENCHMARKS.keys(): - raise ValueError("benchmark {} is not available. Check spelling?". - format(benchmark)) + raise ValueError( + "benchmark {} is not available. Check spelling?".format(benchmark)) # get the flow params from the benchmark flow_params = AVAILABLE_BENCHMARKS[benchmark] @@ -94,25 +96,26 @@ def evaluate_policy(benchmark, _get_actions, _get_states=None): generator_class = getattr(module, flow_params["generator"]) # recreate the scenario and environment - scenario = scenario_class(name=exp_tag, - generator_class=generator_class, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) + scenario = scenario_class( + name=exp_tag, + generator_class=generator_class, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) # make sure the _get_states method of the environment is the one # specified by the user if _get_states is not None: + class _env_class(env_class): def get_state(self): return _get_states(self) env_class = _env_class - env = env_class(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = env_class( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) # create a SumoExperiment object with the "rl_actions" method as # described in the inputs. Note that the state may not be that which is @@ -120,8 +123,10 @@ def get_state(self): exp = SumoExperiment(env=env, scenario=scenario) # run the experiment and return the reward - res = exp.run(num_runs=NUM_RUNS, num_steps=env.env_params.horizon, - rl_actions=_get_actions) + res = exp.run( + num_runs=NUM_RUNS, + num_steps=env.env_params.horizon, + rl_actions=_get_actions) return np.mean(res["returns"]), np.std(res["returns"]) @@ -184,8 +189,8 @@ def get_compute_action_rllib(path_to_dir, checkpoint_num, alg): # create and register a gym+rllib env flow_params = get_flow_params(config) - create_env, env_name = make_create_env(params=flow_params, version=9999, - sumo_binary="sumo") + create_env, env_name = make_create_env( + params=flow_params, version=9999, sumo_binary="sumo") register_env(env_name, create_env) # recreate the agent diff --git a/flow/utils/leaderboard/run.py b/flow/utils/leaderboard/run.py index 594d7e38e..f288b5c56 100644 --- a/flow/utils/leaderboard/run.py +++ b/flow/utils/leaderboard/run.py @@ -5,8 +5,7 @@ sys.path.append(PATH) # Evaluate the solution -mean, stdev = evaluate_policy(benchmark=BENCHMARK, - _get_actions=get_actions, - _get_states=get_states) +mean, stdev = evaluate_policy( + benchmark=BENCHMARK, _get_actions=get_actions, _get_states=get_states) # Print results print(mean, stdev) diff --git a/flow/utils/registry.py b/flow/utils/registry.py index 3fde06683..7aaf9f96a 100644 --- a/flow/utils/registry.py +++ b/flow/utils/registry.py @@ -92,8 +92,7 @@ def create_env(*_): "env_params": env_params, "sumo_params": sumo_params, "scenario": scenario - } - ) + }) return gym.envs.make(env_name) return create_env, env_name diff --git a/flow/utils/rllib.py b/flow/utils/rllib.py index 82e009d05..43b18f460 100644 --- a/flow/utils/rllib.py +++ b/flow/utils/rllib.py @@ -65,8 +65,7 @@ def get_flow_params(config): for veh_params in flow_params["veh"]: module = __import__( "flow.controllers", - fromlist=[veh_params['acceleration_controller'][0]] - ) + fromlist=[veh_params['acceleration_controller'][0]]) acc_class = getattr(module, veh_params['acceleration_controller'][0]) lc_class = getattr(module, veh_params['lane_change_controller'][0]) @@ -90,12 +89,13 @@ def get_flow_params(config): veh_params["lane_change_controller"], \ veh_params["routing_controller"] - veh.add(acceleration_controller=acc_controller, - lane_change_controller=lc_controller, - routing_controller=rt_controller, - sumo_car_following_params=sumo_cf_params, - sumo_lc_params=sumo_lc_params, - **veh_params) + veh.add( + acceleration_controller=acc_controller, + lane_change_controller=lc_controller, + routing_controller=rt_controller, + sumo_car_following_params=sumo_cf_params, + sumo_lc_params=sumo_lc_params, + **veh_params) # convert all parameters from dict to their object form sumo = SumoParams() diff --git a/flow/visualize/visualizer_rllab.py b/flow/visualize/visualizer_rllab.py index 943329c08..178e8704e 100644 --- a/flow/visualize/visualizer_rllab.py +++ b/flow/visualize/visualizer_rllab.py @@ -6,18 +6,24 @@ from matplotlib import pyplot as plt from flow.core.util import emission_to_csv - if __name__ == "__main__": parser = argparse.ArgumentParser() - parser.add_argument('file', type=str, - help='path to the snapshot file') - parser.add_argument('--num_rollouts', type=int, default=100, - help='Number of rollouts we will average over') - parser.add_argument('--plotname', type=str, default="traffic_plot", - help='Prefix for all generated plots') - parser.add_argument('--emission_to_csv', action='store_true', - help='Specifies whether to convert the emission file ' - 'created by sumo into a csv file') + parser.add_argument('file', type=str, help='path to the snapshot file') + parser.add_argument( + '--num_rollouts', + type=int, + default=100, + help='Number of rollouts we will average over') + parser.add_argument( + '--plotname', + type=str, + default="traffic_plot", + help='Prefix for all generated plots') + parser.add_argument( + '--emission_to_csv', + action='store_true', + help='Specifies whether to convert the emission file ' + 'created by sumo into a csv file') args = parser.parse_args() @@ -45,8 +51,8 @@ sumo_params = unwrapped_env.sumo_params sumo_params.emission_path = "./test_time_rollout/" sumo_binary = 'sumo-gui' - unwrapped_env.restart_sumo(sumo_params=sumo_params, - sumo_binary=sumo_binary) + unwrapped_env.restart_sumo( + sumo_params=sumo_params, sumo_binary=sumo_binary) # Load data into arrays all_obs = np.zeros((args.num_rollouts, max_path_length, flat_obs)) @@ -87,34 +93,46 @@ # plot mean value for observation for each vehicle across rollouts plt.figure() for car in range(tot_cars): - center = np.mean(all_obs[:, :, tot_cars*obs_var_idx + car], axis=0) - plt.plot(range(max_path_length), center, lw=2.0, - label='Veh {}'.format(car)) + center = np.mean( + all_obs[:, :, tot_cars * obs_var_idx + car], axis=0) + plt.plot( + range(max_path_length), + center, + lw=2.0, + label='Veh {}'.format(car)) plt.ylabel(obs_var, fontsize=15) plt.xlabel("time (s)", fontsize=15) - plt.title("{2}, Autonomous Penetration: {0}/{1}". - format(rl_cars, tot_cars, obs_var), fontsize=16) + plt.title( + "{2}, Autonomous Penetration: {0}/{1}".format( + rl_cars, tot_cars, obs_var), + fontsize=16) plt.legend(loc=0) # save the plot in the "plots" directory - plt.savefig("plots/{0}_{1}.png".format(args.plotname, obs_var), - bbox="tight") + plt.savefig( + "plots/{0}_{1}.png".format(args.plotname, obs_var), bbox="tight") # plot mean values for the observations across all vehicles and all # rollouts - car_mean = np.mean(np.mean( - all_obs[:, :, tot_cars*obs_var_idx:tot_cars*(obs_var_idx + 1)], - axis=0), axis=1) + car_mean = np.mean( + np.mean( + all_obs[:, :, tot_cars * obs_var_idx:tot_cars * + (obs_var_idx + 1)], + axis=0), + axis=1) plt.figure() plt.plot(t, car_mean) plt.ylabel(obs_var, fontsize=15) plt.xlabel("time (s)", fontsize=15) - plt.title("Mean {2}, Autonomous Penetration: {0}/{1}". - format(rl_cars, tot_cars, obs_var), fontsize=16) + plt.title( + "Mean {2}, Autonomous Penetration: {0}/{1}".format( + rl_cars, tot_cars, obs_var), + fontsize=16) # save the plot in the "plots" directory - plt.savefig("plots/{0}_{1}_mean.png".format(args.plotname, obs_var), - bbox="tight") + plt.savefig( + "plots/{0}_{1}_mean.png".format(args.plotname, obs_var), + bbox="tight") # Make a figure for the mean rewards over the course of the rollout mean_reward = np.mean(all_rewards, axis=0) @@ -123,8 +141,9 @@ plt.plot(t, mean_reward, lw=2.0) plt.ylabel("reward", fontsize=15) plt.xlabel("time (s)", fontsize=15) - plt.title("Reward, Autonomous Penetration: {0}/{1}". - format(rl_cars, tot_cars), fontsize=16) + plt.title( + "Reward, Autonomous Penetration: {0}/{1}".format(rl_cars, tot_cars), + fontsize=16) # save the rewards plot in the "reward_plots" directory plt.savefig("plots/{0}_reward.png".format(args.plotname), bbox="tight") diff --git a/flow/visualize/visualizer_rllib.py b/flow/visualize/visualizer_rllib.py index 9c69d0c23..c9c95ffa9 100644 --- a/flow/visualize/visualizer_rllib.py +++ b/flow/visualize/visualizer_rllib.py @@ -37,25 +37,33 @@ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="[Flow] Evaluates a reinforcement learning agent " - "given a checkpoint.", epilog=EXAMPLE_USAGE) + "given a checkpoint.", + epilog=EXAMPLE_USAGE) # required input parameters -parser.add_argument("result_dir", type=str, - help="Directory containing results") -parser.add_argument("checkpoint_num", type=str, - help="Checkpoint number.") +parser.add_argument( + "result_dir", type=str, help="Directory containing results") +parser.add_argument("checkpoint_num", type=str, help="Checkpoint number.") # optional input parameters -parser.add_argument("--run", type=str, default='PPO', - help="The algorithm or model to train. This may refer to " - "the name of a built-on algorithm (e.g. RLLib's DQN " - "or PPO), or a user-defined trainable function or " - "class registered in the tune registry.") -parser.add_argument('--num_rollouts', type=int, default=1, - help="The number of rollouts to visualize.") -parser.add_argument('--emission_to_csv', action='store_true', - help='Specifies whether to convert the emission file ' - 'created by sumo into a csv file') +parser.add_argument( + "--run", + type=str, + default='PPO', + help="The algorithm or model to train. This may refer to " + "the name of a built-on algorithm (e.g. RLLib's DQN " + "or PPO), or a user-defined trainable function or " + "class registered in the tune registry.") +parser.add_argument( + '--num_rollouts', + type=int, + default=1, + help="The number of rollouts to visualize.") +parser.add_argument( + '--emission_to_csv', + action='store_true', + help='Specifies whether to convert the emission file ' + 'created by sumo into a csv file') if __name__ == "__main__": args = parser.parse_args() @@ -72,9 +80,8 @@ flow_params = get_flow_params(config) # Create and register a gym+rllib env - create_env, env_name = make_create_env(params=flow_params, - version=0, - sumo_binary="sumo") + create_env, env_name = make_create_env( + params=flow_params, version=0, sumo_binary="sumo") register_env(env_name, create_env) agent_cls = get_agent_class(args.run) @@ -92,11 +99,12 @@ module = __import__("flow.scenarios", fromlist=[flow_params["generator"]]) generator_class = getattr(module, flow_params["generator"]) - scenario = scenario_class(name=exp_tag, - generator_class=generator_class, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = scenario_class( + name=exp_tag, + generator_class=generator_class, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) # Start the environment with the gui turned on and a path for the # emission file @@ -107,9 +115,8 @@ sumo_params.sumo_binary = "sumo-gui" sumo_params.emission_path = "./test_time_rollout/" - env = env_class(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = env_class( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) # Run the environment in the presence of the pre-trained RL agent for the # requested number of time steps / rollouts diff --git a/scripts/ray_autoscale.yaml b/scripts/ray_autoscale.yaml index e81b12bb2..41c255f3c 100644 --- a/scripts/ray_autoscale.yaml +++ b/scripts/ray_autoscale.yaml @@ -70,7 +70,7 @@ file_mounts: { # path to your repo and the desired branch name #"/tmp/path": "/.git/refs/heads/", #"/tmp/ray_autoscaler_key": "", -"/tmp/path": "/Users/eugenevinitsky/Desktop/Research/Bayen/Code/rllab-multiagent/learning-traffic/.git/refs/heads/ars_runner", +"/tmp/path": "/Users/eugenevinitsky/Desktop/Research/Bayen/Code/flow/.git/refs/heads/raytesting", "/tmp/ray_autoscaler_key": "/Users/eugenevinitsky/.ssh/ray-autoscaler_1_us-west-1.pem", } @@ -99,4 +99,4 @@ head_start_ray_commands: # Command to start ray on worker nodes. You don't need to change this. worker_start_ray_commands: - ray stop - - ray start --redis-address=$RAY_HEAD_IP:6379 \ No newline at end of file + - ray start --redis-address=$RAY_HEAD_IP:6379 diff --git a/tests/fast_tests/test_collisions.py b/tests/fast_tests/test_collisions.py index 0dd0ba919..9342f219d 100644 --- a/tests/fast_tests/test_collisions.py +++ b/tests/fast_tests/test_collisions.py @@ -20,31 +20,42 @@ def test_collide(self): sumo_params = SumoParams(sim_step=1, sumo_binary="sumo") total_vehicles = 20 vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(SumoCarFollowingController, {}), - routing_controller=(GridRouter, {}), - sumo_car_following_params=SumoCarFollowingParams( - tau=0.1, carFollowModel="Krauss", minGap=2.5), - num_vehicles=total_vehicles, - speed_mode=0b00000) - grid_array = {"short_length": 100, "inner_length": 100, - "long_length": 100, "row_num": 1, - "col_num": 1, - "cars_left": int(total_vehicles / 4), - "cars_right": int(total_vehicles / 4), - "cars_top": int(total_vehicles / 4), - "cars_bot": int(total_vehicles / 4)} - - additional_net_params = {"speed_limit": 35, "grid_array": grid_array, - "horizontal_lanes": 1, "vertical_lanes": 1} - - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) - - self.env, self.scenario = grid_mxn_exp_setup(row_num=1, col_num=1, - sumo_params=sumo_params, - vehicles=vehicles, - net_params=net_params) + vehicles.add( + veh_id="idm", + acceleration_controller=(SumoCarFollowingController, {}), + routing_controller=(GridRouter, {}), + sumo_car_following_params=SumoCarFollowingParams( + tau=0.1, carFollowModel="Krauss", minGap=2.5), + num_vehicles=total_vehicles, + speed_mode=0b00000) + grid_array = { + "short_length": 100, + "inner_length": 100, + "long_length": 100, + "row_num": 1, + "col_num": 1, + "cars_left": int(total_vehicles / 4), + "cars_right": int(total_vehicles / 4), + "cars_top": int(total_vehicles / 4), + "cars_bot": int(total_vehicles / 4) + } + + additional_net_params = { + "speed_limit": 35, + "grid_array": grid_array, + "horizontal_lanes": 1, + "vertical_lanes": 1 + } + + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) + + self.env, self.scenario = grid_mxn_exp_setup( + row_num=1, + col_num=1, + sumo_params=sumo_params, + vehicles=vehicles, + net_params=net_params) # go through the env and set all the lights to green for i in range(self.env.rows * self.env.cols): @@ -62,36 +73,48 @@ def test_collide_inflows(self): sumo_params = SumoParams(sim_step=1, sumo_binary="sumo") total_vehicles = 12 vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(SumoCarFollowingController, {}), - routing_controller=(GridRouter, {}), - sumo_car_following_params=SumoCarFollowingParams( - tau=0.1, carFollowModel="Krauss", minGap=2.5), - num_vehicles=total_vehicles, - speed_mode=0b00000) - grid_array = {"short_length": 100, "inner_length": 100, - "long_length": 100, "row_num": 1, - "col_num": 1, - "cars_left": 3, - "cars_right": 3, - "cars_top": 3, - "cars_bot": 3} - - additional_net_params = {"speed_limit": 35, "grid_array": grid_array, - "horizontal_lanes": 1, "vertical_lanes": 1} + vehicles.add( + veh_id="idm", + acceleration_controller=(SumoCarFollowingController, {}), + routing_controller=(GridRouter, {}), + sumo_car_following_params=SumoCarFollowingParams( + tau=0.1, carFollowModel="Krauss", minGap=2.5), + num_vehicles=total_vehicles, + speed_mode=0b00000) + grid_array = { + "short_length": 100, + "inner_length": 100, + "long_length": 100, + "row_num": 1, + "col_num": 1, + "cars_left": 3, + "cars_right": 3, + "cars_top": 3, + "cars_bot": 3 + } + + additional_net_params = { + "speed_limit": 35, + "grid_array": grid_array, + "horizontal_lanes": 1, + "vertical_lanes": 1 + } inflows = InFlows() inflows.add(veh_type="idm", edge="bot0_0", vehs_per_hour=1000) inflows.add(veh_type="idm", edge="top0_1", vehs_per_hour=1000) - net_params = NetParams(no_internal_links=False, - in_flows=inflows, - additional_params=additional_net_params) - - self.env, self.scenario = grid_mxn_exp_setup(row_num=1, col_num=1, - sumo_params=sumo_params, - vehicles=vehicles, - net_params=net_params) + net_params = NetParams( + no_internal_links=False, + in_flows=inflows, + additional_params=additional_net_params) + + self.env, self.scenario = grid_mxn_exp_setup( + row_num=1, + col_num=1, + sumo_params=sumo_params, + vehicles=vehicles, + net_params=net_params) # go through the env and set all the lights to green for i in range(self.env.rows * self.env.cols): diff --git a/tests/fast_tests/test_controllers.py b/tests/fast_tests/test_controllers.py index ca66d5d3e..d011750be 100644 --- a/tests/fast_tests/test_controllers.py +++ b/tests/fast_tests/test_controllers.py @@ -19,12 +19,20 @@ class TestCFMController(unittest.TestCase): """ Tests that the CFM Controller returning mathematically accurate values. """ + def setUp(self): # add a few vehicles to the network using the requested model # also make sure that the input params are what is expected - contr_params = {"time_delay": 0, "k_d": 1, "k_v": 1, "k_c": 1, - "d_des": 1, "v_des": 8, "noise": 0} + contr_params = { + "time_delay": 0, + "k_d": 1, + "k_v": 1, + "k_c": 1, + "d_des": 1, + "v_des": 8, + "noise": 0 + } vehicles = Vehicles() vehicles.add( @@ -33,8 +41,7 @@ def setUp(self): routing_controller=(ContinuousRouter, {}), sumo_car_following_params=SumoCarFollowingParams( accel=20, decel=5), - num_vehicles=5 - ) + num_vehicles=5) # create the environment and scenario classes for a ring road self.env, scenario = ring_road_exp_setup(vehicles=vehicles) @@ -54,8 +61,10 @@ def test_get_action(self): for i, veh_id in enumerate(ids): self.env.vehicles.set_headway(veh_id, test_headways[i]) - requested_accel = [self.env.vehicles.get_acc_controller( - veh_id).get_action(self.env) for veh_id in ids] + requested_accel = [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] expected_accel = [12., 17., 22., 27., 32.] @@ -66,6 +75,7 @@ class TestBCMController(unittest.TestCase): """ Tests that the BCM Controller returning mathematically accurate values. """ + def setUp(self): # add a few vehicles to the network using the requested model # also make sure that the input params are what is expected @@ -80,8 +90,7 @@ def setUp(self): routing_controller=(ContinuousRouter, {}), sumo_car_following_params=SumoCarFollowingParams( accel=15, decel=5), - num_vehicles=5 - ) + num_vehicles=5) # create the environment and scenario classes for a ring road self.env, scenario = ring_road_exp_setup(vehicles=vehicles) @@ -101,8 +110,10 @@ def test_get_action(self): for i, veh_id in enumerate(ids): self.env.vehicles.set_headway(veh_id, test_headways[i]) - requested_accel = [self.env.vehicles.get_acc_controller( - veh_id).get_action(self.env) for veh_id in ids] + requested_accel = [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] expected_accel = [-12., 13., 13., 13., 13.] @@ -113,11 +124,19 @@ class TestOVMController(unittest.TestCase): """ Tests that the OVM Controller returning mathematically accurate values. """ + def setUp(self): # add a few vehicles to the network using the requested model # also make sure that the input params are what is expected - contr_params = {"time_delay": 0, "alpha": 1, "beta": 1, "h_st": 2, - "h_go": 15, "v_max": 30, "noise": 0} + contr_params = { + "time_delay": 0, + "alpha": 1, + "beta": 1, + "h_st": 2, + "h_go": 15, + "v_max": 30, + "noise": 0 + } vehicles = Vehicles() vehicles.add( @@ -126,8 +145,7 @@ def setUp(self): routing_controller=(ContinuousRouter, {}), sumo_car_following_params=SumoCarFollowingParams( accel=15, decel=5), - num_vehicles=5 - ) + num_vehicles=5) # create the environment and scenario classes for a ring road self.env, scenario = ring_road_exp_setup(vehicles=vehicles) @@ -147,8 +165,10 @@ def test_get_action(self): for i, veh_id in enumerate(ids): self.env.vehicles.set_headway(veh_id, test_headways[i]) - requested_accel = [self.env.vehicles.get_acc_controller( - veh_id).get_action(self.env) for veh_id in ids] + requested_accel = [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] expected_accel = [0., 20.319073, 3.772339, 3.772339, 3.772339] @@ -160,6 +180,7 @@ class TestLinearOVM(unittest.TestCase): Tests that the Linear OVM Controller returning mathematically accurate values. """ + def setUp(self): # add a few vehicles to the network using the requested model # also make sure that the input params are what is expected @@ -174,8 +195,7 @@ def setUp(self): routing_controller=(ContinuousRouter, {}), sumo_car_following_params=SumoCarFollowingParams( accel=15, decel=5), - num_vehicles=5 - ) + num_vehicles=5) # create the environment and scenario classes for a ring road self.env, scenario = ring_road_exp_setup(vehicles=vehicles) @@ -195,8 +215,10 @@ def test_get_action(self): for i, veh_id in enumerate(ids): self.env.vehicles.set_headway(veh_id, test_headways[i]) - requested_accel = [self.env.vehicles.get_acc_controller( - veh_id).get_action(self.env) for veh_id in ids] + requested_accel = [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] expected_accel = [0., 12.992308, 12.992308, 25.984615, 0.] @@ -207,11 +229,11 @@ class TestIDMController(unittest.TestCase): """ Tests that the IDM Controller returning mathematically accurate values. """ + def setUp(self): # add a few vehicles to the network using the requested model # also make sure that the input params are what is expected - contr_params = {"v0": 30, "b": 1.5, "delta": 4, - "s0": 2, "noise": 0} + contr_params = {"v0": 30, "b": 1.5, "delta": 4, "s0": 2, "noise": 0} vehicles = Vehicles() vehicles.add( @@ -220,8 +242,7 @@ def setUp(self): routing_controller=(ContinuousRouter, {}), sumo_car_following_params=SumoCarFollowingParams( tau=1, accel=1, decel=5), - num_vehicles=5 - ) + num_vehicles=5) # create the environment and scenario classes for a ring road self.env, scenario = ring_road_exp_setup(vehicles=vehicles) @@ -241,8 +262,10 @@ def test_get_action(self): for i, veh_id in enumerate(ids): self.env.vehicles.set_headway(veh_id, test_headways[i]) - requested_accel = [self.env.vehicles.get_acc_controller( - veh_id).get_action(self.env) for veh_id in ids] + requested_accel = [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] expected_accel = [0.96, 0.99, 0.995556, 0.9975, 0.9984] @@ -255,8 +278,10 @@ def test_get_action(self): # make sure the controller doesn't return a ZeroDivisionError when the # headway is zero - [self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) - for veh_id in ids] + [ + self.env.vehicles.get_acc_controller(veh_id).get_action(self.env) + for veh_id in ids + ] class TestInstantaneousFailsafe(unittest.TestCase): @@ -265,22 +290,31 @@ class TestInstantaneousFailsafe(unittest.TestCase): does not allow vehicles to crash under situations where they otherwise would. This is tested on two crash-prone controllers: OVM and LinearOVM """ + def setUp_failsafe(self, vehicles): - additional_env_params = {"target_velocity": 8, "max_accel": 3, - "max_decel": 3} + additional_env_params = { + "target_velocity": 8, + "max_accel": 3, + "max_decel": 3 + } env_params = EnvParams(additional_params=additional_env_params) - additional_net_params = {"length": 100, "lanes": 1, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 100, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) initial_config = InitialConfig(bunching=10) # create the environment and scenario classes for a ring road - env, scenario = ring_road_exp_setup(vehicles=vehicles, - env_params=env_params, - net_params=net_params, - initial_config=initial_config) + env, scenario = ring_road_exp_setup( + vehicles=vehicles, + env_params=env_params, + net_params=net_params, + initial_config=initial_config) # instantiate an experiment class self.exp = SumoExperiment(env, scenario) @@ -293,8 +327,9 @@ def test_no_crash_OVM(self): vehicles = Vehicles() vehicles.add( veh_id="test", - acceleration_controller=(OVMController, - {"fail_safe": "instantaneous"}), + acceleration_controller=(OVMController, { + "fail_safe": "instantaneous" + }), routing_controller=(ContinuousRouter, {}), num_vehicles=10, ) @@ -310,11 +345,11 @@ def test_no_crash_LinearOVM(self): vehicles = Vehicles() vehicles.add( veh_id="test", - acceleration_controller=(LinearOVM, - {"fail_safe": "instantaneous"}), + acceleration_controller=(LinearOVM, { + "fail_safe": "instantaneous" + }), routing_controller=(ContinuousRouter, {}), - num_vehicles=10 - ) + num_vehicles=10) self.setUp_failsafe(vehicles=vehicles) @@ -329,12 +364,14 @@ class TestSafeVelocityFailsafe(TestInstantaneousFailsafe): Tests that the safe velocity failsafe of the base acceleration controller does not fail under extreme conditions. """ + def test_no_crash_OVM(self): vehicles = Vehicles() vehicles.add( veh_id="test", - acceleration_controller=(OVMController, - {"fail_safe": "safe_velocity"}), + acceleration_controller=(OVMController, { + "fail_safe": "safe_velocity" + }), routing_controller=(ContinuousRouter, {}), num_vehicles=10, ) @@ -350,8 +387,9 @@ def test_no_crash_LinearOVM(self): vehicles = Vehicles() vehicles.add( veh_id="test", - acceleration_controller=(LinearOVM, - {"fail_safe": "safe_velocity"}), + acceleration_controller=(LinearOVM, { + "fail_safe": "safe_velocity" + }), routing_controller=(ContinuousRouter, {}), num_vehicles=10, ) @@ -369,10 +407,15 @@ class TestStaticLaneChanger(unittest.TestCase): Makes sure that vehicles with a static lane-changing controller do not change lanes. """ + def setUp(self): # add an extra lane to the ring road network - additional_net_params = {"length": 230, "lanes": 2, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 2, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a ring road diff --git a/tests/fast_tests/test_environment_base_class.py b/tests/fast_tests/test_environment_base_class.py index ac0bec333..9e64aaf8b 100644 --- a/tests/fast_tests/test_environment_base_class.py +++ b/tests/fast_tests/test_environment_base_class.py @@ -23,22 +23,25 @@ class TestStartingPositionShuffle(unittest.TestCase): def setUp(self): # turn on starting position shuffle - env_params = EnvParams(starting_position_shuffle=True, - additional_params=ADDITIONAL_ENV_PARAMS) + env_params = EnvParams( + starting_position_shuffle=True, + additional_params=ADDITIONAL_ENV_PARAMS) # place 5 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=5) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=5) initial_config = InitialConfig(x0=5) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(env_params=env_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + env_params=env_params, + initial_config=initial_config, + vehicles=vehicles) def tearDown(self): # terminate the traci instance @@ -77,22 +80,25 @@ class TestVehicleArrangementShuffle(unittest.TestCase): def setUp(self): # turn on vehicle arrangement shuffle - env_params = EnvParams(vehicle_arrangement_shuffle=True, - additional_params=ADDITIONAL_ENV_PARAMS) + env_params = EnvParams( + vehicle_arrangement_shuffle=True, + additional_params=ADDITIONAL_ENV_PARAMS) # place 5 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=5) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=5) initial_config = InitialConfig(x0=5) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(env_params=env_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + env_params=env_params, + initial_config=initial_config, + vehicles=vehicles) def tearDown(self): # terminate the traci instance @@ -145,29 +151,35 @@ class TestApplyingActionsWithSumo(unittest.TestCase): Tests the apply_acceleration, apply_lane_change, and choose_routes functions in base_env.py """ + def setUp(self): # create a 2-lane ring road network - additional_net_params = {"length": 230, "lanes": 3, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 3, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # turn on starting position shuffle - env_params = EnvParams(starting_position_shuffle=True, - additional_params=ADDITIONAL_ENV_PARAMS) + env_params = EnvParams( + starting_position_shuffle=True, + additional_params=ADDITIONAL_ENV_PARAMS) # place 5 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - sumo_car_following_params=SumoCarFollowingParams( - accel=1000, decel=1000), - num_vehicles=5) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + sumo_car_following_params=SumoCarFollowingParams( + accel=1000, decel=1000), + num_vehicles=5) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - env_params=env_params, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, env_params=env_params, vehicles=vehicles) def tearDown(self): # terminate the traci instance @@ -185,8 +197,8 @@ def test_apply_acceleration(self): """ ids = self.env.vehicles.get_ids() - vel0 = np.array([self.env.vehicles.get_speed(veh_id) - for veh_id in ids]) + vel0 = np.array( + [self.env.vehicles.get_speed(veh_id) for veh_id in ids]) # apply a certain set of accelerations to the vehicles in the network accel_step0 = np.array([0, 1, 4, 9, 16]) @@ -195,8 +207,10 @@ def test_apply_acceleration(self): # compare the new velocity of the vehicles to the expected velocity # given the accelerations - vel1 = np.array([self.env.traci_connection.vehicle.getSpeed(veh_id) - for veh_id in ids]) + vel1 = np.array([ + self.env.traci_connection.vehicle.getSpeed(veh_id) + for veh_id in ids + ]) expected_vel1 = (vel0 + accel_step0 * 0.1).clip(min=0) np.testing.assert_array_almost_equal(vel1, expected_vel1, 1) @@ -217,8 +231,10 @@ def test_apply_acceleration(self): # this time, some vehicles should be at 0 velocity (NOT less), and sum # are a result of the accelerations that took place - vel2 = np.array([self.env.traci_connection.vehicle.getSpeed(veh_id) - for veh_id in ids]) + vel2 = np.array([ + self.env.traci_connection.vehicle.getSpeed(veh_id) + for veh_id in ids + ]) expected_vel2 = (vel1 + accel_step1 * 0.1).clip(min=0) np.testing.assert_array_almost_equal(vel2, expected_vel2, 1) @@ -236,7 +252,9 @@ def test_apply_lane_change_errors(self): self.assertRaises( ValueError, - self.env.apply_lane_change, veh_ids=ids, direction=bad_directions) + self.env.apply_lane_change, + veh_ids=ids, + direction=bad_directions) def test_apply_lane_change_direction(self): """ @@ -247,8 +265,8 @@ def test_apply_lane_change_direction(self): """ self.env.reset() ids = self.env.vehicles.get_ids() - lane0 = np.array([self.env.vehicles.get_lane(veh_id) - for veh_id in ids]) + lane0 = np.array( + [self.env.vehicles.get_lane(veh_id) for veh_id in ids]) # perform lane-changing actions using the direction method direction0 = np.array([0, 1, 0, 1, -1]) @@ -257,9 +275,10 @@ def test_apply_lane_change_direction(self): # check that the lane vehicle lane changes to the correct direction # without skipping lanes - lane1 = np.array( - [self.env.traci_connection.vehicle.getLaneIndex(veh_id) - for veh_id in ids]) + lane1 = np.array([ + self.env.traci_connection.vehicle.getLaneIndex(veh_id) + for veh_id in ids + ]) expected_lane1 = (lane0 + np.sign(direction0)).clip( min=0, max=self.env.scenario.lanes - 1) @@ -282,9 +301,10 @@ def test_apply_lane_change_direction(self): # check that the lane vehicle lane changes to the correct direction # without skipping lanes - lane2 = np.array( - [self.env.traci_connection.vehicle.getLaneIndex(veh_id) - for veh_id in ids]) + lane2 = np.array([ + self.env.traci_connection.vehicle.getLaneIndex(veh_id) + for veh_id in ids + ]) expected_lane2 = (lane1 + np.sign(direction1)).clip( min=0, max=self.env.scenario.lanes - 1) @@ -301,14 +321,15 @@ class TestSorting(unittest.TestCase): def test_sorting(self): # setup a environment with the "sort_vehicles" attribute set to True additional_env_params = ADDITIONAL_ENV_PARAMS - env_params = EnvParams(additional_params=additional_env_params, - sort_vehicles=True) + env_params = EnvParams( + additional_params=additional_env_params, sort_vehicles=True) initial_config = InitialConfig(shuffle=True) vehicles = Vehicles() vehicles.add(veh_id="test", num_vehicles=5) - self.env, scenario = ring_road_exp_setup(env_params=env_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + env_params=env_params, + initial_config=initial_config, + vehicles=vehicles) self.env.reset() @@ -316,21 +337,23 @@ def test_sorting(self): positions = self.env.vehicles.get_absolute_position(sorted_ids) # ensure vehicles ids are in sorted order by positions - self.assertTrue(all(positions[i] <= positions[i + 1] - for i in range(len(positions) - 1))) + self.assertTrue( + all(positions[i] <= positions[i + 1] + for i in range(len(positions) - 1))) def test_no_sorting(self): # setup a environment with the "sort_vehicles" attribute set to False, # and shuffling so that the vehicles are not sorted by their ids additional_env_params = ADDITIONAL_ENV_PARAMS - env_params = EnvParams(additional_params=additional_env_params, - sort_vehicles=True) + env_params = EnvParams( + additional_params=additional_env_params, sort_vehicles=True) initial_config = InitialConfig(shuffle=True) vehicles = Vehicles() vehicles.add(veh_id="test", num_vehicles=5) - self.env, scenario = ring_road_exp_setup(env_params=env_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + env_params=env_params, + initial_config=initial_config, + vehicles=vehicles) self.env.reset() @@ -342,7 +365,6 @@ def test_no_sorting(self): class TestWarmUpSteps(unittest.TestCase): - """Ensures that the appropriate number of warmup steps are run when using flow.core.params.EnvParams.warmup_steps""" @@ -351,8 +373,8 @@ def test_it_works(self): # start an environment with a number of simulations per step greater # than one - env_params = EnvParams(warmup_steps=warmup_step, - additional_params=ADDITIONAL_ENV_PARAMS) + env_params = EnvParams( + warmup_steps=warmup_step, additional_params=ADDITIONAL_ENV_PARAMS) env, scenario = ring_road_exp_setup(env_params=env_params) # time before running a reset @@ -367,7 +389,6 @@ def test_it_works(self): class TestSimsPerStep(unittest.TestCase): - """Ensures that the appropriate number of simultaions are run at any given steps when using flow.core.params.EnvParams.sims_per_step""" @@ -376,8 +397,9 @@ def test_it_works(self): # start an environment with a number of simulations per step greater # than one - env_params = EnvParams(sims_per_step=sims_per_step, - additional_params=ADDITIONAL_ENV_PARAMS) + env_params = EnvParams( + sims_per_step=sims_per_step, + additional_params=ADDITIONAL_ENV_PARAMS) env, scenario = ring_road_exp_setup(env_params=env_params) env.reset() diff --git a/tests/fast_tests/test_experiment_base_class.py b/tests/fast_tests/test_experiment_base_class.py index b0e4d6262..81201a645 100644 --- a/tests/fast_tests/test_experiment_base_class.py +++ b/tests/fast_tests/test_experiment_base_class.py @@ -72,11 +72,12 @@ def test_rl_actions(*_): # create an environment using AccelEnv with 1 RL vehicle vehicles = Vehicles() - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="aggressive", - num_vehicles=1) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="aggressive", + num_vehicles=1) env, scenario = ring_road_exp_setup(vehicles=vehicles) diff --git a/tests/fast_tests/test_green_wave.py b/tests/fast_tests/test_green_wave.py index 90c02c75a..9ee0d1c4e 100644 --- a/tests/fast_tests/test_green_wave.py +++ b/tests/fast_tests/test_green_wave.py @@ -27,17 +27,22 @@ def test_split_edge(self): [left0_0, right0_0, bot0_0, top0_0, bot0_1, top0_1, left1_0, right1_0, :center0] and should be indexed as such """ - edges = ["left0_0", "right0_0", "bot0_0", "top0_0", "bot0_1", "top0_1", - "left1_0", "right1_0", ":center0"] + edges = [ + "left0_0", "right0_0", "bot0_0", "top0_0", "bot0_1", "top0_1", + "left1_0", "right1_0", ":center0" + ] for i in range(len(edges)): edge = edges[i] self.assertEqual(self.env._split_edge(edge), i + 1) def test_convert_edge(self): - edges = ["left0_0", "right0_0", "bot0_0", "top0_0", "bot0_1", "top0_1", - "left1_0", "right1_0", ":center0"] - self.assertEqual(sorted(self.env._convert_edge(edges)), - [i + 1 for i in range(len(edges))]) + edges = [ + "left0_0", "right0_0", "bot0_0", "top0_0", "bot0_1", "top0_1", + "left1_0", "right1_0", ":center0" + ] + self.assertEqual( + sorted(self.env._convert_edge(edges)), + [i + 1 for i in range(len(edges))]) class TestUtils(unittest.TestCase): @@ -67,8 +72,9 @@ def test_get_distance_to_intersection(self): # Obtain list of lists of vehicles on entrance # edges, then the distances. - veh_ids = [self.env.vehicles.get_ids_by_edge(e) - for e in self.gen_edges(1, 1)] + veh_ids = [ + self.env.vehicles.get_ids_by_edge(e) for e in self.gen_edges(1, 1) + ] dists = [self.env.get_distance_to_intersection(v) for v in veh_ids] grid = self.env.scenario.net_params.additional_params['grid_array'] short_length = grid['short_length'] @@ -89,16 +95,17 @@ def test_get_distance_to_intersection(self): while not ['center' in edge for edge in veh_edges]: print(self.env.vehicles.get_edge(self.env.vehicles.get_ids())) self.env.step(rl_actions=[]) - junction_veh = list(filter(lambda x: 'center' in x, - self.env.vehicles.get_ids())) + junction_veh = list( + filter(lambda x: 'center' in x, self.env.vehicles.get_ids())) for veh_id in junction_veh: self.assertEqual(0, self.env.get_distance_to_intersection(veh_id)) def test_sort_by_intersection_dist(self): self.env.reset() # Get the veh_ids by entrance edges. - veh_ids = [self.env.vehicles.get_ids_by_edge(e) - for e in self.gen_edges(1, 1)] + veh_ids = [ + self.env.vehicles.get_ids_by_edge(e) for e in self.gen_edges(1, 1) + ] # Each list in veh_ids is inherently sorted from # farthest to closest. We zip the lists together diff --git a/tests/fast_tests/test_params.py b/tests/fast_tests/test_params.py index 213c29819..57e4a6857 100644 --- a/tests/fast_tests/test_params.py +++ b/tests/fast_tests/test_params.py @@ -6,23 +6,23 @@ class TestSumoCarFollowingParams(unittest.TestCase): - """Tests flow.core.params.SumoCarFollowingParams""" def runTest(self): """Tests that the various parameters lead to correct assignments in the controller_params attribute of the class.""" # start a SumoCarFollowingParams with some attributes - cfm_params = SumoCarFollowingParams(accel=1.0, - decel=1.5, - sigma=0.5, - tau=0.5, - min_gap=1.0, - max_speed=30, - speed_factor=1.0, - speed_dev=0.1, - impatience=0.5, - car_follow_model="IDM") + cfm_params = SumoCarFollowingParams( + accel=1.0, + decel=1.5, + sigma=0.5, + tau=0.5, + min_gap=1.0, + max_speed=30, + speed_factor=1.0, + speed_dev=0.1, + impatience=0.5, + car_follow_model="IDM") # ensure that the attributes match their correct element in the # "controller_params" dict @@ -42,16 +42,17 @@ def test_deprecated(self): values to the correct attributes""" # start a SumoCarFollowingParams with some attributes, using the # deprecated attributes - cfm_params = SumoCarFollowingParams(accel=1.0, - decel=1.5, - sigma=0.5, - tau=0.5, - minGap=1.0, - maxSpeed=30, - speedFactor=1.0, - speedDev=0.1, - impatience=0.5, - carFollowModel="IDM") + cfm_params = SumoCarFollowingParams( + accel=1.0, + decel=1.5, + sigma=0.5, + tau=0.5, + minGap=1.0, + maxSpeed=30, + speedFactor=1.0, + speedDev=0.1, + impatience=0.5, + carFollowModel="IDM") # ensure that the attributes match their correct element in the # "controller_params" dict @@ -68,7 +69,6 @@ def test_deprecated(self): class TestSumoLaneChangeParams(unittest.TestCase): - """Tests flow.core.params.SumoLaneChangeParams""" def runTest(self): @@ -79,8 +79,10 @@ def runTest(self): lc_params_1 = SumoLaneChangeParams(model="LC2013") attributes_1 = list(lc_params_1.controller_params.keys()) # TODO: modify with all elements once the fix is added to sumo - expected_attributes_1 = ["laneChangeModel", "lcStrategic", - "lcCooperative", "lcSpeedGain", "lcKeepRight"] + expected_attributes_1 = [ + "laneChangeModel", "lcStrategic", "lcCooperative", "lcSpeedGain", + "lcKeepRight" + ] self.assertCountEqual(attributes_1, expected_attributes_1) # test for SL2015 @@ -105,27 +107,30 @@ def test_wrong_model(self): # ensure that the correct parameters are currently present attributes = list(lc_params.controller_params.keys()) - expected_attributes = ["laneChangeModel", "lcStrategic", - "lcCooperative", "lcSpeedGain", "lcKeepRight"] + expected_attributes = [ + "laneChangeModel", "lcStrategic", "lcCooperative", "lcSpeedGain", + "lcKeepRight" + ] self.assertCountEqual(attributes, expected_attributes) def test_deprecated(self): """Ensures that deprecated forms of the attribute still return proper values to the correct attributes""" # start a SumoLaneChangeParams with some attributes - lc_params = SumoLaneChangeParams(model="SL2015", - lcStrategic=1.0, - lcCooperative=1.0, - lcSpeedGain=1.0, - lcKeepRight=1.0, - lcLookaheadLeft=2.0, - lcSpeedGainRight=1.0, - lcSublane=1.0, - lcPushy=0, - lcPushyGap=0.6, - lcAssertive=1, - lcImpatience=0, - lcTimeToImpatience=float("inf")) + lc_params = SumoLaneChangeParams( + model="SL2015", + lcStrategic=1.0, + lcCooperative=1.0, + lcSpeedGain=1.0, + lcKeepRight=1.0, + lcLookaheadLeft=2.0, + lcSpeedGainRight=1.0, + lcSublane=1.0, + lcPushy=0, + lcPushyGap=0.6, + lcAssertive=1, + lcImpatience=0, + lcTimeToImpatience=float("inf")) # ensure that the attributes match their correct element in the # "controller_params" dict diff --git a/tests/fast_tests/test_scenario_base_class.py b/tests/fast_tests/test_scenario_base_class.py index d8d353f03..81b57cae6 100644 --- a/tests/fast_tests/test_scenario_base_class.py +++ b/tests/fast_tests/test_scenario_base_class.py @@ -84,21 +84,27 @@ def setUp_gen_start_pos(self, initial_config=InitialConfig()): contain MORE THAN TWO LANES. """ # create a multi-lane ring road network - additional_net_params = {"length": 230, "lanes": 4, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 4, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # place 5 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=15) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=15) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, + initial_config=initial_config, + vehicles=vehicles) def tearDown_gen_start_pos(self): # terminate the traci instance @@ -125,8 +131,9 @@ def test_base(self): # difference in position between the nth vehicle and the vehicle ahead # of it - nth_headway = np.mod(np.append(veh_pos[1:], veh_pos[0]) - veh_pos, - self.env.scenario.length) + nth_headway = np.mod( + np.append(veh_pos[1:], veh_pos[0]) - veh_pos, + self.env.scenario.length) # check that the position of the first vehicle is at 0 self.assertEqual(veh_pos[0], 0) @@ -156,8 +163,9 @@ def test_x0(self): # difference in position between the nth vehicle and the vehicle ahead # of it - nth_headway = np.mod(np.append(veh_pos[1:], veh_pos[0]) - veh_pos, - self.env.scenario.length) + nth_headway = np.mod( + np.append(veh_pos[1:], veh_pos[0]) - veh_pos, + self.env.scenario.length) # check that the position of the first vehicle is at 0 self.assertEqual(veh_pos[0], x0 % self.env.scenario.length) @@ -174,8 +182,7 @@ def test_bunching(self): """ # set the initial_config parameters with a modest bunching term bunching = 10 - initial_config = InitialConfig(bunching=bunching, - lanes_distribution=1) + initial_config = InitialConfig(bunching=bunching, lanes_distribution=1) # create the environment self.setUp_gen_start_pos(initial_config) @@ -186,8 +193,9 @@ def test_bunching(self): # difference in position between the nth vehicle and the vehicle ahead # of it - nth_headway = np.mod(np.append(veh_pos[1:], veh_pos[0]) - veh_pos, - self.env.scenario.length) + nth_headway = np.mod( + np.append(veh_pos[1:], veh_pos[0]) - veh_pos, + self.env.scenario.length) # check that all vehicles except the last vehicle have the same spacing self.assertEqual(np.unique(np.around(nth_headway[:-1], 2)).size, 1) @@ -205,8 +213,7 @@ def test_bunching_too_small(self): """ # set the initial_config parameters with a negative bunching term bunching = -10 - initial_config = InitialConfig(bunching=bunching, - lanes_distribution=1) + initial_config = InitialConfig(bunching=bunching, lanes_distribution=1) # create the environment self.setUp_gen_start_pos(initial_config) @@ -217,8 +224,9 @@ def test_bunching_too_small(self): # difference in position between the nth vehicle and the vehicle ahead # of it - nth_headway = np.mod(np.append(veh_pos[1:], veh_pos[0]) - veh_pos, - self.env.scenario.length) + nth_headway = np.mod( + np.append(veh_pos[1:], veh_pos[0]) - veh_pos, + self.env.scenario.length) # check that all vehicles, including the last vehicle, have the same # spacing @@ -245,9 +253,10 @@ def test_lanes_distribution(self): ids = self.env.vehicles.get_ids() veh_pos = [] for i in range(self.env.scenario.lanes): - veh_pos.append([self.env.get_x_by_id(veh_id) - for veh_id in ids - if self.env.vehicles.get_lane(veh_id) == i]) + veh_pos.append([ + self.env.get_x_by_id(veh_id) for veh_id in ids + if self.env.vehicles.get_lane(veh_id) == i + ]) # check that the vehicles are uniformly distributed in the number of # requested lanes @@ -304,9 +313,10 @@ def test_lanes_distribution_too_large(self): ids = self.env.vehicles.get_ids() veh_pos = [] for i in range(self.env.scenario.lanes): - veh_pos.append([self.env.get_x_by_id(veh_id) - for veh_id in ids - if self.env.vehicles.get_lane(veh_id) == i]) + veh_pos.append([ + self.env.get_x_by_id(veh_id) for veh_id in ids + if self.env.vehicles.get_lane(veh_id) == i + ]) # check that the vehicles are uniformly distributed in the number of # requested lanes lanes @@ -353,10 +363,10 @@ def test_num_vehicles(self): # check when "num_vehicles" is not specified startpos, startlanes = self.env.scenario.generate_starting_positions() - self.assertEqual(len(startpos), - self.env.scenario.vehicles.num_vehicles) - self.assertEqual(len(startlanes), - self.env.scenario.vehicles.num_vehicles) + self.assertEqual( + len(startpos), self.env.scenario.vehicles.num_vehicles) + self.assertEqual( + len(startlanes), self.env.scenario.vehicles.num_vehicles) # check when "num_vehicles" is specified startpos, startlanes = self.env.scenario.generate_starting_positions( @@ -376,18 +386,17 @@ class TestEvenStartPosInternalLinks(unittest.TestCase): def setUp(self): # place 15 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=15) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=15) initial_config = InitialConfig(x0=150) # create the environment and scenario classes for a ring road self.env, scenario = figure_eight_exp_setup( - initial_config=initial_config, - vehicles=vehicles - ) + initial_config=initial_config, vehicles=vehicles) def tearDown(self): # terminate the traci instance @@ -403,8 +412,9 @@ def runTest(self): # difference in position between the nth vehicle and the vehicle ahead # of it - nth_headway = np.mod(np.append(veh_pos[1:], veh_pos[0]) - veh_pos, - self.env.scenario.length) + nth_headway = np.mod( + np.append(veh_pos[1:], veh_pos[0]) - veh_pos, + self.env.scenario.length) try: # if all element are equal, there should only be one unique value @@ -417,10 +427,13 @@ def runTest(self): if nth_headway[i] - np.mean(nth_headway) > 0.001: # if not, check that the last or first vehicle is right # after an internal link, on position 0 - pos = [self.env.get_x_by_id(veh_id) for veh_id in - [ids[i + 1], ids[i]]] - rel_pos = [self.env.scenario.get_edge(pos_i)[1] for pos_i - in pos] + pos = [ + self.env.get_x_by_id(veh_id) + for veh_id in [ids[i + 1], ids[i]] + ] + rel_pos = [ + self.env.scenario.get_edge(pos_i)[1] for pos_i in pos + ] self.assertTrue(np.any(np.array(rel_pos) == 0)) @@ -435,21 +448,27 @@ def setUp_gen_start_pos(self, initial_config=InitialConfig()): initial_config.spacing = "random" # create a multi-lane ring road network - additional_net_params = {"length": 230, "lanes": 4, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 4, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # place 5 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=5) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=5) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - initial_config=initial_config, - vehicles=vehicles) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, + initial_config=initial_config, + vehicles=vehicles) def tearDown_gen_start_pos(self): # terminate the traci instance @@ -479,8 +498,8 @@ def test_edges_distribution(self): # set the initial_config parameters with an edges_distribution term for # only a few edges edges = ["top", "bottom"] - initial_config = InitialConfig(spacing="random", - edges_distribution=edges) + initial_config = InitialConfig( + spacing="random", edges_distribution=edges) # create the environment self.setUp_gen_start_pos(initial_config) @@ -496,10 +515,11 @@ class TestEvenStartPosVariableLanes(unittest.TestCase): def setUp(self): # place 15 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=50) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=50) initial_config = InitialConfig(lanes_distribution=5) @@ -537,10 +557,11 @@ class TestRandomStartPosVariableLanes(TestEvenStartPosVariableLanes): def setUp(self): # place 15 vehicles in the network (we need at least more than 1) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=50) + vehicles.add( + veh_id="test", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=50) initial_config = InitialConfig(spacing="random", lanes_distribution=5) @@ -559,8 +580,12 @@ def test_edge_length_edges(self): """ Tests the edge_length() method when called on edges """ - additional_net_params = {"length": 1000, "lanes": 2, - "speed_limit": 60, "resolution": 40} + additional_net_params = { + "length": 1000, + "lanes": 2, + "speed_limit": 60, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a figure eight @@ -572,10 +597,14 @@ def test_edge_length_junctions(self): """ Tests the speed_limit() method when called on junctions """ - additional_net_params = {"radius_ring": 30, "lanes": 1, - "speed_limit": 60, "resolution": 40} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + additional_net_params = { + "radius_ring": 30, + "lanes": 1, + "speed_limit": 60, + "resolution": 40 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) env, scenario = figure_eight_exp_setup(net_params=net_params) @@ -594,8 +623,12 @@ def test_speed_limit_edges(self): """ Tests the speed_limit() method when called on edges """ - additional_net_params = {"length": 230, "lanes": 2, - "speed_limit": 60, "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 2, + "speed_limit": 60, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a figure eight @@ -607,15 +640,19 @@ def test_speed_limit_junctions(self): """ Tests the speed_limit() method when called on junctions """ - additional_net_params = {"radius_ring": 30, "lanes": 1, - "speed_limit": 60, "resolution": 40} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + additional_net_params = { + "radius_ring": 30, + "lanes": 1, + "speed_limit": 60, + "resolution": 40 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) env, scenario = figure_eight_exp_setup(net_params=net_params) - self.assertAlmostEqual(scenario.speed_limit("bottom_upper_ring_in"), - 60) + self.assertAlmostEqual( + scenario.speed_limit("bottom_upper_ring_in"), 60) self.assertAlmostEqual(scenario.speed_limit(":top_upper_ring_0"), 60) @@ -628,8 +665,12 @@ def test_num_lanes_edges(self): """ Tests the num_lanes() method when called on edges """ - additional_net_params = {"length": 230, "lanes": 2, - "speed_limit": 30, "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 2, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a figure eight @@ -641,10 +682,14 @@ def test_num_lanes_junctions(self): """ Tests the num_lanes() method when called on junctions """ - additional_net_params = {"radius_ring": 30, "lanes": 3, - "speed_limit": 60, "resolution": 40} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + additional_net_params = { + "radius_ring": 30, + "lanes": 3, + "speed_limit": 60, + "resolution": 40 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) env, scenario = figure_eight_exp_setup(net_params=net_params) @@ -668,11 +713,12 @@ def tearDown(self): def runTest(self): edge_list = self.scenario.get_edge_list() - expected_edge_list = ["bottom_lower_ring", "right_lower_ring_in", - "right_lower_ring_out", "left_upper_ring", - "top_upper_ring", "right_upper_ring", - "bottom_upper_ring_in", "bottom_upper_ring_out", - "top_lower_ring", "left_lower_ring"] + expected_edge_list = [ + "bottom_lower_ring", "right_lower_ring_in", "right_lower_ring_out", + "left_upper_ring", "top_upper_ring", "right_upper_ring", + "bottom_upper_ring_in", "bottom_upper_ring_out", "top_lower_ring", + "left_lower_ring" + ] self.assertCountEqual(edge_list, expected_edge_list) diff --git a/tests/fast_tests/test_traffic_lights.py b/tests/fast_tests/test_traffic_lights.py index 04a884a9b..0c4c0ae80 100644 --- a/tests/fast_tests/test_traffic_lights.py +++ b/tests/fast_tests/test_traffic_lights.py @@ -31,13 +31,17 @@ def test_single_lane(self): traffic_lights.add("top") # create a ring road with one lane - additional_net_params = {"length": 230, "lanes": 1, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - traffic_lights=traffic_lights) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, traffic_lights=traffic_lights) self.env.reset() self.env.step([]) @@ -52,13 +56,17 @@ def test_multi_lane(self): traffic_lights.add("top") # create a ring road with two lanes - additional_net_params = {"length": 230, "lanes": 2, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 2, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - traffic_lights=traffic_lights) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, traffic_lights=traffic_lights) self.env.reset() self.env.step([]) @@ -79,13 +87,17 @@ def setUp(self): traffic_lights.add("top") # create a ring road with two lanes - additional_net_params = {"length": 230, "lanes": 2, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 2, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - traffic_lights=traffic_lights) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, traffic_lights=traffic_lights) def tearDown(self): # terminate the traci instance @@ -99,8 +111,8 @@ def test_all_lanes(self): self.env.reset() # set all states to something - self.env.traffic_lights.set_state(node_id="top", env=self.env, - state="rY") + self.env.traffic_lights.set_state( + node_id="top", env=self.env, state="rY") # run a new step self.env.step([]) @@ -115,8 +127,8 @@ def test_single_lane(self): self.env.reset() # set all state of lane 1 to something - self.env.traffic_lights.set_state(node_id="top", env=self.env, - state="R", link_index=1) + self.env.traffic_lights.set_state( + node_id="top", env=self.env, state="R", link_index=1) # run a new step self.env.step([]) @@ -134,15 +146,16 @@ class TestPOEnv(unittest.TestCase): def setUp(self): vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(GridRouter, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, tau=1.1), - num_vehicles=16) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(GridRouter, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, tau=1.1), + num_vehicles=16) - self.env, scenario = grid_mxn_exp_setup(row_num=1, col_num=3, - vehicles=vehicles) + self.env, scenario = grid_mxn_exp_setup( + row_num=1, col_num=3, vehicles=vehicles) def tearDown(self): # terminate the traci instance @@ -156,8 +169,8 @@ def compare_ordering(self, ordering): # print(ordering) for x in ordering: # print(x) - if not (x[0].startswith("bot") and x[1].startswith("right") and - x[2].startswith("top") and x[3].startswith("left")): + if not (x[0].startswith("bot") and x[1].startswith("right") + and x[2].startswith("top") and x[3].startswith("left")): return False return True @@ -181,14 +194,14 @@ def test_k_closest(self): k_closest = self.env.k_closest_to_intersection(c0_edges, 3) # check bot, right, top, left in that order - self.assertEqual(self.env.k_closest_to_intersection(c0_edges[0], 3), - k_closest[0:2]) - self.assertEqual(self.env.k_closest_to_intersection(c0_edges[1], 3), - k_closest[2:4]) + self.assertEqual( + self.env.k_closest_to_intersection(c0_edges[0], 3), k_closest[0:2]) + self.assertEqual( + self.env.k_closest_to_intersection(c0_edges[1], 3), k_closest[2:4]) self.assertEqual( len(self.env.k_closest_to_intersection(c0_edges[2], 3)), 0) - self.assertEqual(self.env.k_closest_to_intersection(c0_edges[3], 3), - k_closest[4:6]) + self.assertEqual( + self.env.k_closest_to_intersection(c0_edges[3], 3), k_closest[4:6]) for veh_id in k_closest: self.assertTrue(self.env.vehicles.get_edge(veh_id) in c0_edges) @@ -201,15 +214,16 @@ class TestItRuns(unittest.TestCase): def setUp(self): vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(GridRouter, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, tau=1.1), - num_vehicles=16) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(GridRouter, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, tau=1.1), + num_vehicles=16) - env, scenario = grid_mxn_exp_setup(row_num=1, col_num=3, - vehicles=vehicles) + env, scenario = grid_mxn_exp_setup( + row_num=1, col_num=3, vehicles=vehicles) self.exp = SumoExperiment(env, scenario) @@ -229,25 +243,44 @@ class TestIndividualLights(unittest.TestCase): def setUp(self): 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"}] + 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" + }] tl_logic.add("center0", phases=phases, programID=1) tl_logic.add("center1", phases=phases, programID=1, offset=1) - tl_logic.add("center2", tls_type="actuated", phases=phases, - programID=1) - tl_logic.add("center3", tls_type="actuated", phases=phases, - programID=1, maxGap=3.0, detectorGap=0.8, - showDetectors=True, - file="testindividuallights.xml", freq=100) - - env, scenario = grid_mxn_exp_setup(row_num=1, col_num=4, - tl_logic=tl_logic) + tl_logic.add( + "center2", tls_type="actuated", phases=phases, programID=1) + tl_logic.add( + "center3", + tls_type="actuated", + phases=phases, + programID=1, + maxGap=3.0, + detectorGap=0.8, + showDetectors=True, + file="testindividuallights.xml", + freq=100) + + env, scenario = grid_mxn_exp_setup( + row_num=1, col_num=4, tl_logic=tl_logic) self.exp = SumoExperiment(env, scenario) @@ -260,7 +293,6 @@ def test_it_runs(self): class TestCustomization(unittest.TestCase): - def setUp(self): # add a traffic light to the top node traffic_lights = TrafficLights() @@ -269,20 +301,31 @@ def setUp(self): self.green = 4 self.yellow = 1 self.red = 4 - phases = [{"duration": repr(self.green), "state": "G"}, - {"duration": repr(self.yellow), "state": "y"}, - {"duration": repr(self.red), "state": "r"}] + phases = [{ + "duration": repr(self.green), + "state": "G" + }, { + "duration": repr(self.yellow), + "state": "y" + }, { + "duration": repr(self.red), + "state": "r" + }] traffic_lights.add("top", phases=phases) # create a ring road with two lanes - additional_net_params = {"length": 230, "lanes": 1, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) # create the environment and scenario classes for a ring road - self.env, scenario = ring_road_exp_setup(net_params=net_params, - traffic_lights=traffic_lights) + self.env, scenario = ring_road_exp_setup( + net_params=net_params, traffic_lights=traffic_lights) def tearDown(self): # terminate the traci instance diff --git a/tests/fast_tests/test_two_loops_one_merging.py b/tests/fast_tests/test_two_loops_one_merging.py index 8ef5126b0..f3f0adae2 100644 --- a/tests/fast_tests/test_two_loops_one_merging.py +++ b/tests/fast_tests/test_two_loops_one_merging.py @@ -14,44 +14,53 @@ def two_loops_one_merging_exp_setup(vehicles=None): - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: vehicles = Vehicles() - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - lane_change_controller=(StaticLaneChanger, {}), - speed_mode="no_collide", - num_vehicles=1) - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - lane_change_controller=(StaticLaneChanger, {}), - speed_mode="no_collide", - num_vehicles=5) - vehicles.add(veh_id="merge-idm", - acceleration_controller=(IDMController, {}), - lane_change_controller=(StaticLaneChanger, {}), - speed_mode="no_collide", - num_vehicles=5) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + lane_change_controller=(StaticLaneChanger, {}), + speed_mode="no_collide", + num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + lane_change_controller=(StaticLaneChanger, {}), + speed_mode="no_collide", + num_vehicles=5) + vehicles.add( + veh_id="merge-idm", + acceleration_controller=(IDMController, {}), + lane_change_controller=(StaticLaneChanger, {}), + speed_mode="no_collide", + num_vehicles=5) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) - additional_net_params = {"ring_radius": 50, "lane_length": 75, - "inner_lanes": 3, "outer_lanes": 2, - "speed_limit": 30, "resolution": 40} + additional_net_params = { + "ring_radius": 50, + "lane_length": 75, + "inner_lanes": 3, + "outer_lanes": 2, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams( - no_internal_links=False, - additional_params=additional_net_params - ) + no_internal_links=False, additional_params=additional_net_params) - initial_config = InitialConfig(spacing="custom", - lanes_distribution=1, - additional_params={"merge_bunching": 0}) + initial_config = InitialConfig( + spacing="custom", + lanes_distribution=1, + additional_params={"merge_bunching": 0}) scenario = TwoLoopsOneMergingScenario( - "loop-merges", TwoLoopOneMergingGenerator, vehicles, net_params, + "loop-merges", + TwoLoopOneMergingGenerator, + vehicles, + net_params, initial_config=initial_config) env = TwoLoopsMergePOEnv(env_params, sumo_params, scenario) diff --git a/tests/fast_tests/test_util.py b/tests/fast_tests/test_util.py index 5558c7170..962724f9a 100644 --- a/tests/fast_tests/test_util.py +++ b/tests/fast_tests/test_util.py @@ -18,7 +18,6 @@ class TestEmissionToCSV(unittest.TestCase): - """Tests the emission_to_csv function on a small file. Ensures that the headers are correct, the length is correct, and some of @@ -58,7 +57,6 @@ def runTest(self): class TestWarnings(unittest.TestCase): - """Tests warning functions located in flow.utils.warnings""" def test_deprecation_warning(self): @@ -73,12 +71,11 @@ class Foo(object): # check the deprecation warning is printing what is expected self.assertWarnsRegex( UserWarning, "The attribute bar_deprecated in Foo is deprecated, " - "use bar_new instead.", - deprecation_warning, Foo(), dep_from, dep_to) + "use bar_new instead.", deprecation_warning, Foo(), dep_from, + dep_to) class TestRegistry(unittest.TestCase): - """Tests the methods located in flow/utils/registry.py""" def test_make_create_env(self): @@ -86,16 +83,20 @@ def test_make_create_env(self): the expected flow parameters.""" # use a flow_params dict derived from flow/benchmarks/figureeight0.py vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {"noise": 0.2}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=13) - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="no_collide", - num_vehicles=1) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, { + "noise": 0.2 + }), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=13) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="no_collide", + num_vehicles=1) flow_params = dict( exp_tag="figure_eight_0", @@ -162,8 +163,7 @@ def test_make_create_env(self): flow_params["net"].__dict__) self.assertEqual(env.env.scenario.initial_config.__dict__, flow_params["initial"].__dict__) - self.assertEqual(env.env.__class__.__name__, - flow_params["env_name"]) + self.assertEqual(env.env.__class__.__name__, flow_params["env_name"]) self.assertEqual(env.env.scenario.__class__.__name__, flow_params["scenario"]) self.assertEqual(env.env.scenario.generator_class.__name__, @@ -171,7 +171,6 @@ def test_make_create_env(self): class TestRllib(unittest.TestCase): - """Tests the methods located in flow/utils/rllib.py""" def test_encoder_and_get_flow_params(self): @@ -184,24 +183,36 @@ def test_encoder_and_get_flow_params(self): """ # use a flow_params dict derived from flow/benchmarks/merge0.py vehicles = Vehicles() - vehicles.add(veh_id="human", - acceleration_controller=(IDMController, {}), - speed_mode="no_collide", - num_vehicles=5) - vehicles.add(veh_id="rl", - acceleration_controller=(RLController, {}), - speed_mode="no_collide", - num_vehicles=0) + vehicles.add( + veh_id="human", + acceleration_controller=(IDMController, {}), + speed_mode="no_collide", + num_vehicles=5) + vehicles.add( + veh_id="rl", + acceleration_controller=(RLController, {}), + speed_mode="no_collide", + num_vehicles=0) inflow = InFlows() - inflow.add(veh_type="human", edge="inflow_highway", - vehs_per_hour=1800, - departLane="free", departSpeed=10) - inflow.add(veh_type="rl", edge="inflow_highway", - vehs_per_hour=200, - departLane="free", departSpeed=10) - inflow.add(veh_type="human", edge="inflow_merge", vehs_per_hour=100, - departLane="free", departSpeed=7.5) + inflow.add( + veh_type="human", + edge="inflow_highway", + vehs_per_hour=1800, + departLane="free", + departSpeed=10) + inflow.add( + veh_type="rl", + edge="inflow_highway", + vehs_per_hour=200, + departLane="free", + departSpeed=10) + inflow.add( + veh_type="human", + edge="inflow_merge", + vehs_per_hour=100, + departLane="free", + departSpeed=7.5) flow_params = dict( exp_tag="merge_0", @@ -245,15 +256,19 @@ def test_encoder_and_get_flow_params(self): config = {"env_config": {}} # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, - sort_keys=True, indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json # dump the config so we can fetch it json_out_file = 'params.json' with open(os.path.expanduser(json_out_file), 'w+') as outfile: - json.dump(config, outfile, cls=FlowParamsEncoder, - sort_keys=True, indent=4) + json.dump( + config, + outfile, + cls=FlowParamsEncoder, + sort_keys=True, + indent=4) # fetch values using utility function `get_flow_params` imported_flow_params = get_flow_params(config) @@ -273,25 +288,25 @@ def test_encoder_and_get_flow_params(self): flow_params["net"].in_flows = None # make sure the rest of the imported flow_params match the originals - self.assertTrue(imported_flow_params["env"].__dict__ == - flow_params["env"].__dict__) + self.assertTrue(imported_flow_params["env"].__dict__ == flow_params[ + "env"].__dict__) self.assertTrue(imported_flow_params["initial"].__dict__ == flow_params["initial"].__dict__) - self.assertTrue(imported_flow_params["tls"].__dict__ == - flow_params["tls"].__dict__) - self.assertTrue(imported_flow_params["sumo"].__dict__ == - flow_params["sumo"].__dict__) - self.assertTrue(imported_flow_params["net"].__dict__ == - flow_params["net"].__dict__) - - self.assertTrue(imported_flow_params["exp_tag"] == - flow_params["exp_tag"]) - self.assertTrue(imported_flow_params["env_name"] == - flow_params["env_name"]) - self.assertTrue(imported_flow_params["scenario"] == - flow_params["scenario"]) - self.assertTrue(imported_flow_params["generator"] == - flow_params["generator"]) + self.assertTrue(imported_flow_params["tls"].__dict__ == flow_params[ + "tls"].__dict__) + self.assertTrue(imported_flow_params["sumo"].__dict__ == flow_params[ + "sumo"].__dict__) + self.assertTrue(imported_flow_params["net"].__dict__ == flow_params[ + "net"].__dict__) + + self.assertTrue( + imported_flow_params["exp_tag"] == flow_params["exp_tag"]) + self.assertTrue( + imported_flow_params["env_name"] == flow_params["env_name"]) + self.assertTrue( + imported_flow_params["scenario"] == flow_params["scenario"]) + self.assertTrue( + imported_flow_params["generator"] == flow_params["generator"]) def search_dicts(obj1, obj2): """Searches through dictionaries as well as lists of dictionaries diff --git a/tests/fast_tests/test_vehicles.py b/tests/fast_tests/test_vehicles.py index ffe25dd18..09953df99 100644 --- a/tests/fast_tests/test_vehicles.py +++ b/tests/fast_tests/test_vehicles.py @@ -25,26 +25,29 @@ def runSpeedLaneChangeModes(self): speed modes """ vehicles = Vehicles() - vehicles.add("typeA", - acceleration_controller=(IDMController, {}), - speed_mode='no_collide', - lane_change_mode="no_lat_collide") + vehicles.add( + "typeA", + acceleration_controller=(IDMController, {}), + speed_mode='no_collide', + lane_change_mode="no_lat_collide") self.assertEqual(vehicles.get_speed_mode("typeA_0"), 1) self.assertEqual(vehicles.get_lane_change_mode("typeA_0"), 256) - vehicles.add("typeB", - acceleration_controller=(IDMController, {}), - speed_mode='aggressive', - lane_change_mode="strategic") + vehicles.add( + "typeB", + acceleration_controller=(IDMController, {}), + speed_mode='aggressive', + lane_change_mode="strategic") self.assertEqual(vehicles.get_speed_mode("typeB_0"), 0) self.assertEqual(vehicles.get_lane_change_mode("typeB_0"), 853) - vehicles.add("typeC", - acceleration_controller=(IDMController, {}), - speed_mode=31, - lane_change_mode=277) + vehicles.add( + "typeC", + acceleration_controller=(IDMController, {}), + speed_mode=31, + lane_change_mode=277) self.assertEqual(vehicles.get_speed_mode("typeC_0"), 31) self.assertEqual(vehicles.get_lane_change_mode("typeC_0"), 277) @@ -56,19 +59,21 @@ def test_controlled_id_params(self): # check that, if the vehicle is not a SumoCarFollowingController # vehicle, then its minGap is equal to 0 vehicles = Vehicles() - vehicles.add("typeA", - acceleration_controller=(IDMController, {}), - speed_mode='no_collide', - lane_change_mode="no_lat_collide") + vehicles.add( + "typeA", + acceleration_controller=(IDMController, {}), + speed_mode='no_collide', + lane_change_mode="no_lat_collide") self.assertEqual(vehicles.types[0]["type_params"]["minGap"], 0) # check that, if the vehicle is a SumoCarFollowingController vehicle, # then its minGap, accel, and decel are set to default vehicles = Vehicles() - vehicles.add("typeA", - acceleration_controller=(SumoCarFollowingController, {}), - speed_mode='no_collide', - lane_change_mode="no_lat_collide") + vehicles.add( + "typeA", + acceleration_controller=(SumoCarFollowingController, {}), + speed_mode='no_collide', + lane_change_mode="no_lat_collide") default_mingap = SumoCarFollowingParams().controller_params["minGap"] self.assertEqual(vehicles.types[0]["type_params"]["minGap"], default_mingap) @@ -85,12 +90,16 @@ def test_add_vehicles_human(self): vehicles.add("test_1", num_vehicles=1) # vehicles whose acceleration are controlled by sumo - vehicles.add("test_2", num_vehicles=2, - lane_change_controller=(StaticLaneChanger, {})) + vehicles.add( + "test_2", + num_vehicles=2, + lane_change_controller=(StaticLaneChanger, {})) # vehicles whose LC are controlled by sumo - vehicles.add("test_3", num_vehicles=4, - acceleration_controller=(IDMController, {})) + vehicles.add( + "test_3", + num_vehicles=4, + acceleration_controller=(IDMController, {})) self.assertEqual(vehicles.num_vehicles, 7) self.assertEqual(len(vehicles.get_ids()), 7) @@ -105,8 +114,10 @@ def test_add_vehicles_rl(self): and that the number of vehicles is correct. """ vehicles = Vehicles() - vehicles.add("test_rl", num_vehicles=10, - acceleration_controller=(RLController, {})) + vehicles.add( + "test_rl", + num_vehicles=10, + acceleration_controller=(RLController, {})) self.assertEqual(vehicles.num_vehicles, 10) self.assertEqual(len(vehicles.get_ids()), 10) @@ -123,8 +134,10 @@ def test_remove(self): # generate a vehicles class vehicles = Vehicles() vehicles.add("test", num_vehicles=10) - vehicles.add("test_rl", num_vehicles=10, - acceleration_controller=(RLController, {})) + vehicles.add( + "test_rl", + num_vehicles=10, + acceleration_controller=(RLController, {})) # remove one human-driven vehicle and on rl vehicle vehicles.remove("test_0") @@ -171,20 +184,26 @@ def test_no_junctions(self): # setup a network with no junctions and several vehicles # also, setup with a deterministic starting position to ensure that the # headways/lane leaders are what is expected - additional_net_params = {"length": 230, "lanes": 3, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 3, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) vehicles = Vehicles() - vehicles.add(veh_id="test", - acceleration_controller=(RLController, {}), - num_vehicles=21) + vehicles.add( + veh_id="test", + acceleration_controller=(RLController, {}), + num_vehicles=21) initial_config = InitialConfig(lanes_distribution=float("inf")) - env, scenario = ring_road_exp_setup(net_params=net_params, - vehicles=vehicles, - initial_config=initial_config) + env, scenario = ring_road_exp_setup( + net_params=net_params, + vehicles=vehicles, + initial_config=initial_config) env.reset() # check the lane leaders method is outputting the right values @@ -257,8 +276,7 @@ def run_test(self): # ensures that setting vehicles twice doesn't add an element vehicles.set_observed("test_0") - self.assertListEqual(vehicles.get_observed_ids(), - ["test_0", "test_1"]) + self.assertListEqual(vehicles.get_observed_ids(), ["test_0", "test_1"]) # test removing observed values vehicles.remove_observed("test_0") diff --git a/tests/fast_tests/test_visualizers.py b/tests/fast_tests/test_visualizers.py index 65f36c07a..e1028bec7 100644 --- a/tests/fast_tests/test_visualizers.py +++ b/tests/fast_tests/test_visualizers.py @@ -23,14 +23,14 @@ def runTest(self): # run the experiment and check it doesn't crash os.system("python %s/../flow/visualizer_flow.py " - "tests/test_files/params-collide.pkl --num_rollouts 1" - % current_path) + "tests/test_files/params-collide.pkl --num_rollouts 1" % + current_path) self.assert_(True) # open the generated observations file, and check it isn't all zeros - observations = pickle.load(open(current_path + "/observations.pkl", - "rb")) + observations = pickle.load( + open(current_path + "/observations.pkl", "rb")) self.assertNotEqual(np.sum(np.sum(observations)), 0) diff --git a/tests/setup_scripts.py b/tests/setup_scripts.py index d714e7ec1..130624e71 100644 --- a/tests/setup_scripts.py +++ b/tests/setup_scripts.py @@ -56,30 +56,36 @@ def ring_road_exp_setup(sumo_params=None, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: # set default vehicles configuration vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - speed_mode="aggressive", - num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + speed_mode="aggressive", + num_vehicles=1) if env_params is None: # set default env_params configuration - additional_env_params = {"target_velocity": 8, - "max_accel": 1, - "max_decel": 1, - "num_steps": 500} + additional_env_params = { + "target_velocity": 8, + "max_accel": 1, + "max_decel": 1, + "num_steps": 500 + } env_params = EnvParams(additional_params=additional_env_params) if net_params is None: # set default net_params configuration - additional_net_params = {"length": 230, "lanes": 1, "speed_limit": 30, - "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) if initial_config is None: @@ -91,17 +97,17 @@ def ring_road_exp_setup(sumo_params=None, traffic_lights = TrafficLights() # create the scenario - scenario = LoopScenario(name="RingRoadTest", - generator_class=CircleGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) + scenario = LoopScenario( + name="RingRoadTest", + generator_class=CircleGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) # create the environment - env = AccelEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = AccelEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -139,32 +145,38 @@ def figure_eight_exp_setup(sumo_params=None, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: # set default vehicles configuration vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - speed_mode="aggressive", - routing_controller=(ContinuousRouter, {}), - num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + speed_mode="aggressive", + routing_controller=(ContinuousRouter, {}), + num_vehicles=1) if env_params is None: # set default env_params configuration - additional_env_params = {"target_velocity": 8, - "max_accel": 1, - "max_decel": 1, - "num_steps": 500} + additional_env_params = { + "target_velocity": 8, + "max_accel": 1, + "max_decel": 1, + "num_steps": 500 + } env_params = EnvParams(additional_params=additional_env_params) if net_params is None: # set default net_params configuration - additional_net_params = {"radius_ring": 30, "lanes": 1, - "speed_limit": 30, "resolution": 40} - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + additional_net_params = { + "radius_ring": 30, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) if initial_config is None: # set default initial_config configuration @@ -175,17 +187,17 @@ def figure_eight_exp_setup(sumo_params=None, traffic_lights = TrafficLights() # create the scenario - scenario = Figure8Scenario(name="RingRoadTest", - generator_class=Figure8Generator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) + scenario = Figure8Scenario( + name="RingRoadTest", + generator_class=Figure8Generator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) # create the environment - env = AccelEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = AccelEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -223,30 +235,36 @@ def highway_exp_setup(sumo_params=None, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: # set default vehicles configuration vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - speed_mode="aggressive", - routing_controller=(ContinuousRouter, {}), - num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + speed_mode="aggressive", + routing_controller=(ContinuousRouter, {}), + num_vehicles=1) if env_params is None: # set default env_params configuration - additional_env_params = {"target_velocity": 8, - "max_accel": 1, - "max_decel": 1, - "num_steps": 500} + additional_env_params = { + "target_velocity": 8, + "max_accel": 1, + "max_decel": 1, + "num_steps": 500 + } env_params = EnvParams(additional_params=additional_env_params) if net_params is None: # set default net_params configuration - additional_net_params = {"length": 100, "lanes": 1, - "speed_limit": 30, "resolution": 40} + additional_net_params = { + "length": 100, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) if initial_config is None: @@ -258,17 +276,17 @@ def highway_exp_setup(sumo_params=None, traffic_lights = TrafficLights() # create the scenario - scenario = HighwayScenario(name="RingRoadTest", - generator_class=HighwayGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) + scenario = HighwayScenario( + name="RingRoadTest", + generator_class=HighwayGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) # create the environment - env = AccelEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = AccelEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -316,65 +334,75 @@ def grid_mxn_exp_setup(row_num=1, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=1, sumo_binary="sumo") if vehicles is None: total_vehicles = 20 vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - sumo_car_following_params=SumoCarFollowingParams( - min_gap=2.5, - tau=1.1, - max_speed=30 - ), - routing_controller=(GridRouter, {}), - num_vehicles=total_vehicles) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + sumo_car_following_params=SumoCarFollowingParams( + min_gap=2.5, tau=1.1, max_speed=30), + routing_controller=(GridRouter, {}), + num_vehicles=total_vehicles) if env_params is None: # set default env_params configuration - additional_env_params = {"target_velocity": 50, "num_steps": 100, - "switch_time": 3.0} + additional_env_params = { + "target_velocity": 50, + "num_steps": 100, + "switch_time": 3.0 + } - env_params = EnvParams(additional_params=additional_env_params, - horizon=100) + env_params = EnvParams( + additional_params=additional_env_params, horizon=100) if net_params is None: # set default net_params configuration total_vehicles = vehicles.num_vehicles - grid_array = {"short_length": 100, "inner_length": 300, - "long_length": 3000, "row_num": row_num, - "col_num": col_num, - "cars_left": int(total_vehicles / 4), - "cars_right": int(total_vehicles / 4), - "cars_top": int(total_vehicles / 4), - "cars_bot": int(total_vehicles / 4)} - - additional_net_params = {"length": 200, "lanes": 2, "speed_limit": 35, - "resolution": 40, "grid_array": grid_array, - "horizontal_lanes": 1, "vertical_lanes": 1} - - net_params = NetParams(no_internal_links=False, - additional_params=additional_net_params) + grid_array = { + "short_length": 100, + "inner_length": 300, + "long_length": 3000, + "row_num": row_num, + "col_num": col_num, + "cars_left": int(total_vehicles / 4), + "cars_right": int(total_vehicles / 4), + "cars_top": int(total_vehicles / 4), + "cars_bot": int(total_vehicles / 4) + } + + additional_net_params = { + "length": 200, + "lanes": 2, + "speed_limit": 35, + "resolution": 40, + "grid_array": grid_array, + "horizontal_lanes": 1, + "vertical_lanes": 1 + } + + net_params = NetParams( + no_internal_links=False, additional_params=additional_net_params) if initial_config is None: # set default initial_config configuration - initial_config = InitialConfig(spacing="uniform", - additional_params={"enter_speed": 30}) + initial_config = InitialConfig( + spacing="uniform", additional_params={"enter_speed": 30}) # create the scenario - scenario = SimpleGridScenario(name="Grid1x1Test", - generator_class=SimpleGridGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=tl_logic) + scenario = SimpleGridScenario( + name="Grid1x1Test", + generator_class=SimpleGridGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=tl_logic) # create the environment - env = GreenWaveTestEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = GreenWaveTestEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -413,30 +441,36 @@ def variable_lanes_exp_setup(sumo_params=None, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: # set default vehicles configuration vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - speed_mode="aggressive", - routing_controller=(ContinuousRouter, {}), - num_vehicles=1) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + speed_mode="aggressive", + routing_controller=(ContinuousRouter, {}), + num_vehicles=1) if env_params is None: # set default env_params configuration - additional_env_params = {"target_velocity": 8, - "max_accel": 1, - "max_decel": 1, - "num_steps": 500} + additional_env_params = { + "target_velocity": 8, + "max_accel": 1, + "max_decel": 1, + "num_steps": 500 + } env_params = EnvParams(additional_params=additional_env_params) if net_params is None: # set default net_params configuration - additional_net_params = {"length": 230, "lanes": 1, - "speed_limit": 30, "resolution": 40} + additional_net_params = { + "length": 230, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } net_params = NetParams(additional_params=additional_net_params) if initial_config is None: @@ -448,17 +482,17 @@ def variable_lanes_exp_setup(sumo_params=None, traffic_lights = TrafficLights() # create the scenario - scenario = LoopScenario(name="VariableLaneRingRoadTest", - generator_class=VariableLanesGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config, - traffic_lights=traffic_lights) + scenario = LoopScenario( + name="VariableLaneRingRoadTest", + generator_class=VariableLanesGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config, + traffic_lights=traffic_lights) # create the environment - env = AccelEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = AccelEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -474,59 +508,68 @@ def setup_bottlenecks(sumo_params=None, if sumo_params is None: # set default sumo_params configuration - sumo_params = SumoParams(sim_step=0.1, - sumo_binary="sumo") + sumo_params = SumoParams(sim_step=0.1, sumo_binary="sumo") if vehicles is None: vehicles = Vehicles() - vehicles.add(veh_id="human", - speed_mode=25, - lane_change_controller=(SumoLaneChangeController, {}), - routing_controller=(ContinuousRouter, {}), - lane_change_mode=1621, - num_vehicles=1 * scaling) + vehicles.add( + veh_id="human", + speed_mode=25, + lane_change_controller=(SumoLaneChangeController, {}), + routing_controller=(ContinuousRouter, {}), + lane_change_mode=1621, + num_vehicles=1 * scaling) if env_params is None: - additional_env_params = {"target_velocity": 40, - "max_accel": 1, - "max_decel": 1, - "lane_change_duration": 5, - "add_rl_if_exit": False, - "disable_tb": True, - "disable_ramp_metering": True} + additional_env_params = { + "target_velocity": 40, + "max_accel": 1, + "max_decel": 1, + "lane_change_duration": 5, + "add_rl_if_exit": False, + "disable_tb": True, + "disable_ramp_metering": True + } env_params = EnvParams(additional_params=additional_env_params) if inflow is None: inflow = InFlows() - inflow.add(veh_type="human", edge="1", vehsPerHour=1000, - departLane="random", departSpeed=10) + inflow.add( + veh_type="human", + edge="1", + vehsPerHour=1000, + departLane="random", + departSpeed=10) if traffic_lights is None: traffic_lights = TrafficLights() if net_params is None: additional_net_params = {"scaling": scaling} - net_params = NetParams(in_flows=inflow, - no_internal_links=False, - additional_params=additional_net_params) + net_params = NetParams( + in_flows=inflow, + no_internal_links=False, + additional_params=additional_net_params) if initial_config is None: - initial_config = InitialConfig(spacing="random", 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) + initial_config = InitialConfig( + spacing="random", + 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) # create the environment - env = AccelEnv(env_params=env_params, - sumo_params=sumo_params, - scenario=scenario) + env = AccelEnv( + env_params=env_params, sumo_params=sumo_params, scenario=scenario) return env, scenario @@ -539,23 +582,78 @@ def specify_edges(self, net_params): r = length / (2 * pi) edgelen = length / 4. - edges = [ - {"id": "bottom", "from": "bottom", "to": "right", "speed": str(v), - "length": repr(edgelen), "numLanes": "1", - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(-pi / 2, 0, resolution)])}, - {"id": "right", "from": "right", "to": "top", "speed": str(v), - "length": repr(edgelen), "numLanes": "3", - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(0, pi / 2, resolution)])}, - {"id": "top", "from": "top", "to": "left", "speed": str(v), - "length": repr(edgelen), "numLanes": "2", - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(pi / 2, pi, resolution)])}, - {"id": "left", "from": "left", "to": "bottom", "speed": str(v), - "length": repr(edgelen), "numLanes": "4", - "shape": " ".join(["%.2f,%.2f" % (r * cos(t), r * sin(t)) - for t in linspace(pi, 3*pi / 2, resolution)])} - ] + edges = [{ + "id": + "bottom", + "from": + "bottom", + "to": + "right", + "speed": + str(v), + "length": + repr(edgelen), + "numLanes": + "1", + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(-pi / 2, 0, resolution) + ]) + }, { + "id": + "right", + "from": + "right", + "to": + "top", + "speed": + str(v), + "length": + repr(edgelen), + "numLanes": + "3", + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(0, pi / 2, resolution) + ]) + }, { + "id": + "top", + "from": + "top", + "to": + "left", + "speed": + str(v), + "length": + repr(edgelen), + "numLanes": + "2", + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(pi / 2, pi, resolution) + ]) + }, { + "id": + "left", + "from": + "left", + "to": + "bottom", + "speed": + str(v), + "length": + repr(edgelen), + "numLanes": + "4", + "shape": + " ".join([ + "%.2f,%.2f" % (r * cos(t), r * sin(t)) + for t in linspace(pi, 3 * pi / 2, resolution) + ]) + }] return edges diff --git a/tests/slow_tests/test_ray.py b/tests/slow_tests/test_ray.py index b1826e1ef..20dfbd839 100644 --- a/tests/slow_tests/test_ray.py +++ b/tests/slow_tests/test_ray.py @@ -50,26 +50,37 @@ def test_ray(self): config["horizon"] = HORIZON config["sgd_batchsize"] = 4 - additional_env_params = {"target_velocity": 8, - "scenario_type": LoopScenario} - additional_net_params = {"length": 260, "lanes": 1, "speed_limit": 30, - "resolution": 40} - vehicle_params = [dict(veh_id="rl", num_vehicles=1, - acceleration_controller=(RLController, {}), - routing_controller=(ContinuousRouter, {})), - dict(veh_id="idm", num_vehicles=21, - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {})) - ] + additional_env_params = { + "target_velocity": 8, + "scenario_type": LoopScenario + } + additional_net_params = { + "length": 260, + "lanes": 1, + "speed_limit": 30, + "resolution": 40 + } + vehicle_params = [ + dict( + veh_id="rl", + num_vehicles=1, + acceleration_controller=(RLController, {}), + routing_controller=(ContinuousRouter, {})), + dict( + veh_id="idm", + num_vehicles=21, + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {})) + ] flow_params = dict( sumo=dict(sim_step=0.1, no_step_log=False), env=dict(horizon=HORIZON, additional_params=additional_env_params), - net=dict(no_internal_links=False, - additional_params=additional_net_params), + net=dict( + no_internal_links=False, + additional_params=additional_net_params), veh=vehicle_params, - initial=dict(spacing="uniform", bunching=30, min_gap=0) - ) + initial=dict(spacing="uniform", bunching=30, min_gap=0)) flow_env_name = "WaveAttenuationPOEnv" create_env, env_name = make_create_env(flow_env_name, flow_params, 0) @@ -77,8 +88,8 @@ def test_ray(self): # Register as rllib env registry.register_env(env_name, create_env) - alg = ppo.PPOAgent(env=env_name, registry=registry.get_registry(), - config=config) + alg = ppo.PPOAgent( + env=env_name, registry=registry.get_registry(), config=config) for i in range(1): alg.train() checkpoint_path = alg.save() @@ -102,11 +113,12 @@ def test_ray(self): config["horizon"] = HORIZON config["sgd_batchsize"] = 4 - config["model"].update( - {"fcnet_hiddens": [5, 3]}, ) - options = {"num_subpolicies": 2, - "fn_choose_subpolicy": fn_choose_subpolicy, - "hierarchical_fcnet_hiddens": [[3, 3]] * 2} + config["model"].update({"fcnet_hiddens": [5, 3]}, ) + options = { + "num_subpolicies": 2, + "fn_choose_subpolicy": fn_choose_subpolicy, + "hierarchical_fcnet_hiddens": [[3, 3]] * 2 + } config["model"].update({"custom_options": options}) def tearDown(self): diff --git a/tests/stress_tests/stress_test_rl.py b/tests/stress_tests/stress_test_rl.py index 17baa2210..2153ffa15 100644 --- a/tests/stress_tests/stress_test_rl.py +++ b/tests/stress_tests/stress_test_rl.py @@ -34,8 +34,7 @@ epilog=EXAMPLE_USAGE) # required input parameters -parser.add_argument("alg", type=str, - help="RL algorithm") +parser.add_argument("alg", type=str, help="RL algorithm") if __name__ == "__main__": args = parser.parse_args() @@ -76,8 +75,8 @@ config["timesteps_per_batch"] = PARALLEL_ROLLOUTS # save the flow params for replay - flow_json = json.dumps(flow_params, cls=FlowParamsEncoder, sort_keys=True, - indent=4) + flow_json = json.dumps( + flow_params, cls=FlowParamsEncoder, sort_keys=True, indent=4) config['env_config']['flow_params'] = flow_json # Register as rllib env @@ -91,7 +90,9 @@ **config }, "max_failures": 999, - "stop": {"training_iteration": 50000}, + "stop": { + "training_iteration": 50000 + }, "repeat": 1, "trial_resources": { "cpu": 1, @@ -103,4 +104,4 @@ end = time.time() - print("Stress test took " + str(end-start)) + print("Stress test took " + str(end - start)) diff --git a/tests/stress_tests/stress_test_start.py b/tests/stress_tests/stress_test_start.py index 5d195f658..645d1e210 100644 --- a/tests/stress_tests/stress_test_start.py +++ b/tests/stress_tests/stress_test_start.py @@ -19,10 +19,11 @@ def start(): sumo_params.sumo_binary = 'sumo' vehicles = Vehicles() - vehicles.add(veh_id="idm", - acceleration_controller=(IDMController, {}), - routing_controller=(ContinuousRouter, {}), - num_vehicles=22) + vehicles.add( + veh_id="idm", + acceleration_controller=(IDMController, {}), + routing_controller=(ContinuousRouter, {}), + num_vehicles=22) env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS) @@ -31,11 +32,12 @@ def start(): initial_config = InitialConfig(bunching=20) - scenario = LoopScenario(name="sugiyama", - generator_class=CircleGenerator, - vehicles=vehicles, - net_params=net_params, - initial_config=initial_config) + scenario = LoopScenario( + name="sugiyama", + generator_class=CircleGenerator, + vehicles=vehicles, + net_params=net_params, + initial_config=initial_config) env = AccelEnv(env_params, sumo_params, scenario) env._close()