diff --git a/flow/envs/green_wave_env.py b/flow/envs/green_wave_env.py index 698cd916..2c5b8cc2 100644 --- a/flow/envs/green_wave_env.py +++ b/flow/envs/green_wave_env.py @@ -290,51 +290,6 @@ def _split_edge(self, edge): else: return 0 - def additional_command(self): - """Used to insert vehicles that are on the exit edge and place them - back on their entrance edge.""" - for veh_id in self.vehicles.get_ids(): - self._reroute_if_final_edge(veh_id) - - def _reroute_if_final_edge(self, veh_id): - """Checks if an edge is the final edge. If it is return the route it - should start off at.""" - edge = self.vehicles.get_edge(veh_id) - if edge == "": - return - if edge[0] == ":": # center edge - return - pattern = re.compile(r"[a-zA-Z]+") - edge_type = pattern.match(edge).group() - edge = edge.split(edge_type)[1].split('_') - row_index, col_index = [int(x) for x in edge] - - # find the route that we're going to place the vehicle on if we are - # going to remove it - route_id = None - if edge_type == 'bot' and col_index == self.cols: - route_id = "bot{}_0".format(row_index) - elif edge_type == 'top' and col_index == 0: - route_id = "top{}_{}".format(row_index, self.cols) - elif edge_type == 'left' and row_index == 0: - route_id = "left{}_{}".format(self.rows, col_index) - elif edge_type == 'right' and row_index == self.rows: - route_id = "right0_{}".format(col_index) - - if route_id is not None: - route_id = "route" + route_id - # remove the vehicle - self.traci_connection.vehicle.remove(veh_id) - # reintroduce it at the start of the network - 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), - departLane=str(lane_index), - departPos="0", departSpeed="max") - speed_mode = self.vehicles.type_parameters[type_id]["speed_mode"] - self.traci_connection.vehicle.setSpeedMode(veh_id, speed_mode) - def k_closest_to_intersection(self, edges, k): """ Return the veh_id of the k closest vehicles to an intersection for diff --git a/tests/fast_tests/test_collisions.py b/tests/fast_tests/test_collisions.py index 0dd0ba91..5502e392 100644 --- a/tests/fast_tests/test_collisions.py +++ b/tests/fast_tests/test_collisions.py @@ -58,7 +58,7 @@ def test_collide(self): def test_collide_inflows(self): """Tests collisions in the presence of inflows.""" - # create the environment and scenario classes for a ring road + # create the environment and scenario classes for a 1x1 grid sumo_params = SumoParams(sim_step=1, sumo_binary="sumo") total_vehicles = 12 vehicles = Vehicles() diff --git a/tests/fast_tests/test_controllers.py b/tests/fast_tests/test_controllers.py index ca66d5d3..ec966217 100644 --- a/tests/fast_tests/test_controllers.py +++ b/tests/fast_tests/test_controllers.py @@ -385,7 +385,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_static_lane_changer(self): self.env.reset() ids = self.env.vehicles.get_ids() diff --git a/tests/fast_tests/test_environment_base_class.py b/tests/fast_tests/test_environment_base_class.py index ac0bec33..732220c4 100644 --- a/tests/fast_tests/test_environment_base_class.py +++ b/tests/fast_tests/test_environment_base_class.py @@ -47,7 +47,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_starting_pos(self): ids = self.env.vehicles.get_ids() # position of vehicles before reset @@ -101,7 +101,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_shuffle(self): ids = self.env.vehicles.get_ids() # position of vehicles before reset @@ -136,7 +136,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_emission(self): self.assertIsNone(self.env.sumo_params.emission_path) diff --git a/tests/fast_tests/test_experiment_base_class.py b/tests/fast_tests/test_experiment_base_class.py index 599018ac..bd6b6063 100644 --- a/tests/fast_tests/test_experiment_base_class.py +++ b/tests/fast_tests/test_experiment_base_class.py @@ -27,7 +27,7 @@ def tearDown(self): # free up used memory self.exp = None - def runTest(self): + def test_steps(self): self.exp.run(num_runs=1, num_steps=10) self.assertEqual(self.exp.env.time_counter, 10) @@ -39,7 +39,7 @@ class TestNumRuns(unittest.TestCase): after the correct number of iterations. """ - def runTest(self): + def test_num_runs(self): # run the experiment for 1 run and collect the last position of all # vehicles env, scenario = ring_road_exp_setup() @@ -66,7 +66,7 @@ class TestRLActions(unittest.TestCase): and does not break the simulation when it is left blank. """ - def runTest(self): + def test_rl_actions(self): def test_rl_actions(*_): return [1] # actions are always an acceleration of 1 for one veh diff --git a/tests/fast_tests/test_params.py b/tests/fast_tests/test_params.py index 213c2981..c880c7d9 100644 --- a/tests/fast_tests/test_params.py +++ b/tests/fast_tests/test_params.py @@ -9,7 +9,7 @@ class TestSumoCarFollowingParams(unittest.TestCase): """Tests flow.core.params.SumoCarFollowingParams""" - def runTest(self): + def test_params(self): """Tests that the various parameters lead to correct assignments in the controller_params attribute of the class.""" # start a SumoCarFollowingParams with some attributes @@ -71,7 +71,7 @@ class TestSumoLaneChangeParams(unittest.TestCase): """Tests flow.core.params.SumoLaneChangeParams""" - def runTest(self): + def test_lc_params(self): """Tests basic usage of the SumoLaneChangeParams object. Ensures that the controller_params attribute contains different elements depending on whether LC2103 or SL2015 is being used as the model.""" diff --git a/tests/fast_tests/test_scenario_base_class.py b/tests/fast_tests/test_scenario_base_class.py index d8d353f0..c0649aa6 100644 --- a/tests/fast_tests/test_scenario_base_class.py +++ b/tests/fast_tests/test_scenario_base_class.py @@ -30,7 +30,7 @@ def tearDown(self): # free data used by the class self.scenario = None - def runTest(self): + def test_getx(self): # test for an edge in the lanes edge_1 = "bottom_lower_ring" pos_1 = 4.72 @@ -57,7 +57,7 @@ def tearDown(self): # free data used by the class self.scenario = None - def runTest(self): + def test_get_edge(self): # test for a position in the lanes x1 = 5 self.assertTupleEqual( @@ -396,7 +396,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_even_start_pos_internal(self): # get the positions of all vehicles ids = self.env.vehicles.get_ids() veh_pos = np.array([self.env.get_x_by_id(veh_id) for veh_id in ids]) @@ -451,7 +451,7 @@ def setUp_gen_start_pos(self, initial_config=InitialConfig()): initial_config=initial_config, vehicles=vehicles) - def tearDown_gen_start_pos(self): + def tearDown(self): # terminate the traci instance self.env.terminate() @@ -515,7 +515,7 @@ def tearDown(self): # free data used by the class self.env = None - def runTest(self): + def test_even_start_pos_coverage(self): """ Ensures that enough vehicles are placed in the network, and they cover all possible lanes. @@ -666,7 +666,7 @@ def tearDown(self): # free data used by the class self.scenario = None - def runTest(self): + def test_get_edge_list(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", @@ -691,7 +691,7 @@ def tearDown(self): # free data used by the class self.scenario = None - def runTest(self): + def test_get_junction_list(self): junction_list = self.scenario.get_junction_list() expected_junction_list = \ [':right_upper_ring_0', ':right_lower_ring_in_0', diff --git a/tests/fast_tests/test_vehicles.py b/tests/fast_tests/test_vehicles.py index f7b356bb..cd137177 100644 --- a/tests/fast_tests/test_vehicles.py +++ b/tests/fast_tests/test_vehicles.py @@ -3,13 +3,16 @@ import numpy as np from flow.core.vehicles import Vehicles -from flow.core.params import SumoCarFollowingParams, NetParams, InitialConfig +from flow.core.params import SumoCarFollowingParams, NetParams, InitialConfig \ + , SumoParams, InFlows from flow.controllers.car_following_models import IDMController, \ SumoCarFollowingController from flow.controllers.lane_change_controllers import StaticLaneChanger from flow.controllers.rlcontroller import RLController +from flow.core.experiment import SumoExperiment +from flow.controllers.routing_controllers import GridRouter +from tests.setup_scripts import ring_road_exp_setup, grid_mxn_exp_setup -from tests.setup_scripts import ring_road_exp_setup os.environ["TEST_FLAG"] = "True" @@ -232,17 +235,17 @@ def tearDown(self): self.env.terminate() self.env = None - def runTest(self): + def test_ids_by_edge(self): self.env.reset() ids = self.env.vehicles.get_ids_by_edge("bottom") expected_ids = ["test_0", "test_1", "test_2", "test_3", "test_4"] - self.assertCountEqual(ids, expected_ids) + self.assertListEqual(sorted(ids), sorted(expected_ids)) class TestObservedIDs(unittest.TestCase): """Tests the observed_ids methods, which are used for visualization.""" - def run_test(self): + def test_obs_ids(self): vehicles = Vehicles() vehicles.add(veh_id="test", num_vehicles=10) @@ -261,13 +264,97 @@ def run_test(self): # test removing observed values vehicles.remove_observed("test_0") - self.assertCountEqual(vehicles.get_observed_ids(), ["test_1"]) + self.assertListEqual(vehicles.get_observed_ids(), ["test_1"]) # ensures that removing a value that does not exist does not lead to # an error vehicles.remove_observed("test_0") self.assertCountEqual(vehicles.get_observed_ids(), ["test_1"]) +class TestOutflowInfo(unittest.TestCase): + """Tests that the out methods return the correct values""" + def test_inflows(self): + vehicles = Vehicles() + self.assertEqual(0, vehicles.get_outflow_rate(10000), + "outflow should be zero when there are no vehicles") + + # now construct a scenario where a vehicles is going to leave + # create the environment and scenario classes for a 1x1 grid + + sumo_params = SumoParams(sim_step=1, sumo_binary="sumo") + total_vehicles = 4 + vehicles = Vehicles() + vehicles.add(veh_id="krauss", + acceleration_controller=(RLController, {}), + routing_controller=(GridRouter, {}), + num_vehicles=total_vehicles, + speed_mode="all_checks") + grid_array = {"short_length": 30, "inner_length": 30, + "long_length": 30, "row_num": 1, + "col_num": 1, + "cars_left": 1, + "cars_right": 1, + "cars_top": 1, + "cars_bot": 1} + + 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): + self.env.traci_connection.trafficlight.setRedYellowGreenState( + 'center' + str(i), "gggrrrgggrrr") + + + # instantiate an experiment class + self.exp = SumoExperiment(self.env, self.scenario) + + self.exp.run(1, 15) + + # test outflow rate + self.assertAlmostEqual(2*3600.0/15.0, vehicles.get_outflow_rate(100)) + + # test get num arrived + + # test get initial speed + + # test get speed + + # test get position + + # test get edge + + # test get lane + + # test get/set length + + # test get_acc_controller + + # test get_lane_changing_controller + + # test get_routing_controller + + # test get_route + + # test get_leader + + # test get_follower + + # test get_lane_headways + + # test get_lane_leaders + + # test get_lane_tailways + + # test get_lane_followers -if __name__ == '__main__': +if __name__=='__main__': unittest.main() diff --git a/tests/fast_tests/test_visualizers.py b/tests/fast_tests/test_visualizers.py index 65f36c07..12b69990 100644 --- a/tests/fast_tests/test_visualizers.py +++ b/tests/fast_tests/test_visualizers.py @@ -17,7 +17,7 @@ class TestVisualizerFlow(unittest.TestCase): # TODO fix this test @unittest.skipUnless(BROKEN_TESTS, "broken test (known issue)") - def runTest(self): + def test_visualizer(self): # current path current_path = os.path.realpath(__file__).rsplit("/", 1)[0]