def test_coordination_ticks(self): channel = Channel() car = Car(name=1, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) self.assertEqual(None, car.get_supervisor_car()) do_round(cars=[car], channel=channel) car.enter_intersection() do_round(cars=[car], channel=channel) self.assertTrue(1 in car.get_graph()) self.assertEqual([], list(car.get_following_cars().keys())) self.assertEqual(1, car.get_supervisor_car()) self.assertEqual(None, car.get_second_at_charge())
def test_info_messages(self): channel = Channel() sup_car = Car(name=1, lane=0, intention='s', channel=channel, pos_x=1, pos_y=1) second_car = Car(name=2, lane=1, intention='s', channel=channel, pos_x=2, pos_y=2) normal_car = Car(name=3, lane=3, intention='l', channel=channel, pos_x=3, pos_y=3) # Car 1 enters do_round([sup_car], channel) sup_car.enter_intersection() self.assertTrue(1 in sup_car.get_leaf_cars()) # Car 2 enters and Car 1 becomes supervisor, Car 1 sends info message before Car 2 enters do_round([sup_car, second_car], channel) second_car.enter_intersection() # Car 3 enters and Car2 receives WelcomeMessage and Second At Charge, Car 1 and Car 2 send Info # before Car 3 enters do_round([sup_car, second_car, normal_car], channel) # Check leaf cars update self.assertEqual({2}, sup_car.get_leaf_cars()) self.assertEqual({2}, second_car.get_leaf_cars()) # Check info message from sup_car and follow lists self.assertEqual({}, sup_car.get_following_cars()) self.assertEqual([1], list(second_car.get_following_cars().keys())) self.assertEqual(1, second_car.get_following_cars()[1]['pos_x']) normal_car.enter_intersection() # Car 3 receives Welcome Message do_round([sup_car, second_car, normal_car], channel) self.assertEqual({3}, sup_car.get_leaf_cars()) self.assertEqual({3}, second_car.get_leaf_cars()) self.assertEqual({3}, normal_car.get_leaf_cars()) self.assertEqual([1], list(second_car.get_following_cars().keys())) self.assertEqual([2], list(normal_car.get_following_cars().keys())) self.assertTrue(2, normal_car.get_following_cars()[2]['pos_x'])
def test_enter_intersection(self): channel = Channel() car = random_car(name=1, initial_speed=20, full_intersection=self.full_intersection_rect, channel=channel, inner_intersection=self.inner_intersection_rect, lane=0, intention='s') self.assertFalse(car.get_inside_full_rectangle()) self.assertFalse(car.inside_full_intersection()) self.assertTrue(car not in channel.get_cars()) for _ in range(25): do_round([car], channel) self.assertTrue(car in channel.get_cars()) self.assertTrue(car.get_inside_full_rectangle()) self.assertTrue(car.inside_full_intersection())
def simulate_stop_before_crash(first_car_speed=10.0, follower_car_speed=40.0, first_lane=0, follower_lane=0, first_intention='s', follower_intention='s', iterations=1000): screen, background, intersection_background, font = init_graphic_environment() channel = Channel() # coordinates before the inner intersection for a car coming from lane 0 if first_lane == 0: before_intersection_x = 435 before_intersection_y = inner_intersection_rect.top + inner_intersection_rect.height + 50 elif first_lane == 1: before_intersection_x = inner_intersection_rect.left + inner_intersection_rect.width + 50 before_intersection_y = 335 elif first_lane == 2: before_intersection_x = 335 before_intersection_y = inner_intersection_rect.top - 50 else: before_intersection_x = inner_intersection_rect.left - 50 before_intersection_y = 435 # this car doesn't move first_car = random_car(pos_x=before_intersection_x, pos_y=before_intersection_y, name=1, initial_speed=first_car_speed, acceleration_rate=0, full_intersection=full_intersection_rect, channel=channel, inner_intersection=inner_intersection_rect, lane=first_lane, intention=first_intention, create_sensor_flag=False) follower_car = random_car(name=2, initial_speed=follower_car_speed, full_intersection=full_intersection_rect, channel=channel, inner_intersection=inner_intersection_rect, lane=follower_lane, intention=follower_intention, create_sensor_flag=True) for i in range(iterations): screen.blit(background, (0, 0)) screen.blit(intersection_background, (0, 0)) draw_collision_points(screen) for car in [first_car, follower_car]: screen.blit(car.rotated_image, car.screen_car) pygame.display.update(screen.get_rect()) do_round([first_car, follower_car], channel) pygame.display.quit()
def test_three_car_coordination(self): channel = Channel() sup_car = Car(name=1, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) second_car = Car(name=2, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) normal_car = Car(name=3, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) do_round([sup_car], channel) sup_car.enter_intersection() do_round([sup_car, second_car], channel) second_car.enter_intersection() do_round([sup_car, second_car, normal_car], channel) normal_car.enter_intersection() do_round([sup_car, second_car, normal_car], channel) self.assertEqual(1, normal_car.get_supervisor_car()) self.assertEqual(2, normal_car.get_second_at_charge()) self.assertFalse(normal_car.is_supervisor() or normal_car.is_second_at_charge())
def test_add_car(self): channel = Channel() cars = [] lanes = [0, 2, 1, 2, 3, 2] intentions = ['s', 's', 'r', 's', 'l', 'l'] for i in range(6): car = Car(name=(i + 1), lane=lanes[i], intention=intentions[i], channel=channel) cars.append(car) do_round(cars, channel) car.enter_intersection() do_round(cars, channel) # This should be the resulting graph after adding the 6 cars and the leaf cars should only contain the last car # number 6 nodes = [ Node(name=1, lane=0, intention='s', follow_list=[]), Node(name=2, lane=2, intention='s', follow_list=[]), Node(name=3, lane=1, intention='r', follow_list=[1]), Node(name=4, lane=2, intention='s', follow_list=[2]), Node(name=5, lane=3, intention='l', follow_list=[3, 4]), Node(name=6, lane=2, intention='l', follow_list=[5]) ] graph = {} for node in nodes: graph[node.get_name()] = node for car in cars: # graph_to_string(car) self.assertEqual(graph, car.get_graph()) self.assertEqual({6}, car.get_leaf_cars()) car = Car(name=7, lane=1, intention='s', channel=channel) new_node = Node(name=7, lane=1, intention='s', follow_list=[6]) graph[new_node.get_name()] = new_node # Note: the new leaf cars should be just number 7 cars.append(car) do_round(cars, channel) car.enter_intersection() do_round(cars, channel) # asserting that the graphs are the same checks that the nodes contain the same information for car in cars: self.assertEqual(graph, car.get_graph()) self.assertEqual({7}, car.get_leaf_cars())
def test_second_at_charge_message(self): channel = Channel() sup_car = Car(name=1, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) second_car = Car(name=2, lane=randint(0, 3), intention=choice(self.intention_list), channel=channel, pos_x=randint(0, 3), pos_y=randint(0, 3)) do_round([sup_car], channel) sup_car.enter_intersection() self.assertEqual(None, sup_car.get_supervisor_car()) do_round([sup_car, second_car], channel) second_car.enter_intersection() self.assertTrue(sup_car.is_supervisor()) self.assertTrue(1 in sup_car.get_graph() and 2 in sup_car.get_graph()) self.assertEqual(None, second_car.get_supervisor_car()) do_round([sup_car, second_car], channel) self.assertEqual(1, second_car.get_supervisor_car()) self.assertTrue(second_car.is_second_at_charge())
def test_inner_intersection(self): channel = Channel() car = random_car(name=1, initial_speed=20, full_intersection=self.full_intersection_rect, channel=channel, inner_intersection=self.inner_intersection_rect, lane=0, intention='s') self.assertFalse(car.inside_inner_intersection()) for _ in range(91): do_round([car], channel) self.assertTrue(car.inside_inner_intersection()) self.assertFalse(car.check_left_inner_intersection()) for _ in range(66): do_round([car], channel) self.assertTrue(car not in channel.get_cars()) self.assertTrue(car.check_left_inner_intersection()) self.assertFalse(car.inside_inner_intersection()) self.assertTrue(car.inside_full_intersection()) # Checks that it continues working after being removed from the channel for _ in range(90): do_round([car], channel)
def test_second_at_charge_leave(self): channel = Channel() car1 = Car(name=1, lane=0, intention='l', channel=channel) do_round([car1], channel) car1.enter_intersection() for i in range(4): do_round([car1], channel) self.assertTrue(car1.is_supervisor()) car2 = Car(name=2, lane=1, intention='l', channel=channel) do_round([car1, car2], channel) car2.enter_intersection() car3 = Car(name=3, lane=2, intention='s', channel=channel) do_round([car1, car2, car3], channel) car3.enter_intersection() car4 = Car(name=4, lane=2, intention='r', channel=channel) do_round([car1, car2, car3, car4], channel) car4.enter_intersection() # follow lists: # 1: [] # 2: [1] # 3: [2] # 4: [3] channel.do_round() for car in [car1, car2, car3, car4]: self.assertEqual([1, 2], [car.get_supervisor_car(), car.get_second_at_charge()]) # Before car 2 leaves self.assertEqual([], list(car1.get_following_cars().keys())) self.assertEqual([1], list(car2.get_following_cars().keys())) self.assertEqual([2], list(car3.get_following_cars().keys())) self.assertEqual([3], list(car4.get_following_cars().keys())) for car in [car1, car2, car3, car4]: self.assertEqual({4}, car.get_leaf_cars()) do_round([car1, car2, car3, car4], channel) car2.leave_inner_intersection() do_round([car1, car2, car3, car4], channel) for car in [car1, car3, car4]: self.assertEqual([1, 3], [car.get_supervisor_car(), car.get_second_at_charge()]) self.assertEqual([1, None], [car2.get_supervisor_car(), car2.get_second_at_charge()]) self.assertTrue(car1.is_supervisor()) self.assertTrue(car3.is_second_at_charge()) self.assertFalse(car4.is_supervisor()) self.assertFalse(car4.is_second_at_charge()) for car in [car1, car2, car3, car4]: self.assertTrue(2 not in car.get_graph()) for node in car.get_graph().values(): self.assertTrue(2 not in node.get_follow_list()) # After self.assertEqual([], list(car1.get_following_cars().keys())) self.assertEqual([1], list(car2.get_following_cars().keys())) self.assertEqual([], list(car3.get_following_cars().keys())) self.assertEqual([3], list(car4.get_following_cars().keys()))
def test_leave_intersection_supervisor(self): channel = Channel() sup_car = Car(name=1, lane=0, intention='s', channel=channel, pos_x=1, pos_y=1) second_car = Car(name=2, lane=1, intention='s', channel=channel, pos_x=2, pos_y=2) normal_car = Car(name=3, lane=3, intention='l', channel=channel, pos_x=3, pos_y=3) last_car = Car(name=4, lane=3, intention='l', channel=channel, pos_x=4, pos_y=4) # Car 1 enters do_round([sup_car], channel) sup_car.enter_intersection() # Car 2 enters and Car 1 becomes supervisor do_round([sup_car, second_car], channel) second_car.enter_intersection() # Car 3 enters and Car2 receives WelcomeMessage and Second At Charge do_round([sup_car, second_car, normal_car], channel) normal_car.enter_intersection() # Car 3 receives Welcome Message do_round([sup_car, second_car, normal_car, last_car], channel) last_car.enter_intersection() # Last car receives Welcome here do_round([sup_car, second_car, normal_car, last_car], channel) # Extra round do_round([sup_car, second_car, normal_car, last_car], channel) sup_car.leave_inner_intersection() self.assertTrue(second_car.is_supervisor()) self.assertEqual(2, second_car.get_supervisor_car()) self.assertEqual(3, second_car.get_second_at_charge()) self.assertEqual(2, normal_car.get_supervisor_car()) self.assertEqual(None, normal_car.get_second_at_charge()) self.assertEqual(2, last_car.get_supervisor_car()) self.assertEqual(None, last_car.get_second_at_charge()) # Car3 receives SecondAtChargeMessage from Car 2 do_round([sup_car, second_car, normal_car, last_car], channel) self.assertTrue(normal_car.is_second_at_charge()) self.assertEqual(3, last_car.get_second_at_charge())
def run_simulation(ticks, algorithm_flag=True, graphic_display=True, info_display=False, limit=150, car_limit=15): from utils.utils import init_graphic_environment, do_round from models.channel import Channel import pygame channel = Channel() cars = read_simulation_file(ticks) created_cars = {} car_queue = [] if graphic_display: screen, background, intersection_background, font = init_graphic_environment( ) for tick in range(ticks): if tick == limit: break # print(tick) if car_limit >= len(list(created_cars.keys())): for index in range(len(cars['cars'])): if car_queue: new_queue = [] for ind in range(len(car_queue)): car = car_queue[ind] lane = int(car['lane']) length = 1 if channel.get_recent_entering()[lane] is not None: length = channel.get_recent_entering( )[lane].get_car_length() coordinates = car['initial_coordinates'] rect = pygame.Rect(float(coordinates['x_coordinate']), float(coordinates['y_coordinate']), length, length) rect.center = (float(coordinates['x_coordinate']), float(coordinates['y_coordinate'])) collides = collides_at_spawn( rect, channel.get_recent_entering()[lane]) if collides: new_queue.append(car) else: created_cars[int(car['name'])] = recreate_car( car, channel, algorithm_flag=algorithm_flag) car_queue = new_queue lane = int(cars['cars'][index]['lane']) length = 1 if channel.get_recent_entering()[lane] is not None: length = channel.get_recent_entering( )[lane].get_car_length() car = cars['cars'][index] if int(car['creation_time']) <= tick: coordinates = car['initial_coordinates'] rect = pygame.Rect(float(coordinates['x_coordinate']), float(coordinates['y_coordinate']), length, length) rect.center = (float(coordinates['x_coordinate']), float(coordinates['y_coordinate'])) collides = collides_at_spawn( rect, channel.get_recent_entering()[lane]) #print(channel.get_recent_entering()[lane].get_acceleration()) #print(created_cars) if collides: car_queue.append(car) else: created_cars[int(car['name'])] = recreate_car( car, channel, algorithm_flag=algorithm_flag) else: cars['cars'] = cars['cars'][index:] break if graphic_display: screen.blit(background, (0, 0)) screen.blit(intersection_background, (0, 0)) for car in created_cars.values(): screen.blit(car.rotated_image, car.screen_car) pygame.display.update(screen.get_rect()) do_round(list(created_cars.values()), channel) if info_display: for car in created_cars.values(): print('name: ' + str(car.get_name()) + ' controller: ' + car.get_controller().__name__ + ' left: ' + ' left_inner: ' + str(car.left_inner_rectangle) + ' tick: ' + str(tick) + ' is_supervisor: ' + str(car.is_supervisor()) + ' is_second: ' + str(car.is_second_at_charge()) + ' inside_full: ' + str(car.inside_full_rectangle)) pygame.display.quit()