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())
示例#11
0
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()