Beispiel #1
0
    def __init__(self,
                 new_start=None,
                 new_end=None,
                 new_max_speed=ROAD_DEFAULT_MAX_SPEED):
        """
        Constructor method : creates a new road.
        """

        self.start = new_start
        self.end = new_end
        self.max_speed = new_max_speed

        self.lanes = [Lane(self, i) for i in range(ROAD_DEFAULT_LANES)]

        self.traffic_lights_update = [lib.clock(), lib.clock()]
        self.traffic_lights = [True, False]  # [at the beginning, at the end]

        #   In order not to compute the unit vectors of the road several times, they are stored once they are computed
        self.parallel = None
        self.orthogonal = None

        self.start.host_road(self)
        self.end.host_road(self)

        width = 0
        for lane in self.lanes:
            width += lane.width
        self.width = width
Beispiel #2
0
 def __init__(self,
              new_track,
              new_x, 
              new_y, 
              new_spawning   = False, 
              new_radius     = ROUNDABOUT_RADIUS_DEFAULT):
     """
     Constructor method : creates a new roundabout.
     """
     
     self.track          = new_track
     self.position       = Vector(TRACK_SCALE * new_x + TRACK_OFFSET_X, 
                                  TRACK_SCALE * new_y + TRACK_OFFSET_Y)
     self.radius         = new_radius
     
     self.incoming_roads = []
     self.leaving_roads  = []
     self.cars           = []
     self.to_kill        = [] 
     self.slots_cars     = {}
     
     self.max_cars       = ROUNDABOUT_DEFAULT_MAX_CARS
     self.num_slots      = ROUNDABOUT_DEFAULT_NUM_SLOTS
     self.rotation_speed = ROUNDABOUT_DEFAULT_ROTATION_SPEED
     
     self.spawning       = new_spawning
     self.spawn_timer    = lib.clock()
     self.last_shift     = lib.clock()
     self.spawn_time     = SPAWN_TIME
     self.slots_roads    = [None] * self.num_slots
     self.local_load     = 0
     
     self.name = id(self)
     
     self.car_spiraling_time = {}
Beispiel #3
0
    def __init__(self,
                 new_track,
                 new_x,
                 new_y,
                 new_spawning=False,
                 new_radius=ROUNDABOUT_RADIUS_DEFAULT):
        """
        Constructor method : creates a new roundabout.
        """

        self.track = new_track
        self.position = Vector(TRACK_SCALE * new_x + TRACK_OFFSET_X,
                               TRACK_SCALE * new_y + TRACK_OFFSET_Y)
        self.radius = new_radius

        self.incoming_roads = []
        self.leaving_roads = []
        self.cars = []
        self.to_kill = []
        self.slots_cars = {}

        self.max_cars = ROUNDABOUT_DEFAULT_MAX_CARS
        self.num_slots = ROUNDABOUT_DEFAULT_NUM_SLOTS
        self.rotation_speed = ROUNDABOUT_DEFAULT_ROTATION_SPEED

        self.spawning = new_spawning
        self.spawn_timer = lib.clock()
        self.last_shift = lib.clock()
        self.spawn_time = SPAWN_TIME
        self.slots_roads = [None] * self.num_slots
        self.local_load = 0

        self.name = id(self)

        self.car_spiraling_time = {}
Beispiel #4
0
    def update_car(self, car):
        """
        Updates a given car on the roundabout 
        """
        
        if not (car in self.car_spiraling_time):
            self.car_spiraling_time[car] = [car.total_waiting_time, lib.clock()]
            
        car.total_waiting_time = self.car_spiraling_time[car][0] + lib.clock() - self.car_spiraling_time[car][1]
        
        if not(car.path is None) and self.leaving_roads:
            next_way = car.next_way(True) # Just read the next_way unless you really go there
            car_slot = lib.find_key(self.slots_cars, car)

            #   The car has lost its slot   
            if car_slot is None:
                raise Exception("ERROR (in Roundabout.update_car()) : a car has no slot !")
            
            #   The car's slot is in front of a leaving road
            if self.slots_roads[car_slot] in self.leaving_roads:            
                if (self.leaving_roads[next_way].is_free) and self.slots_roads[car_slot] == self.leaving_roads[next_way]:
                #la route sur laquelle on veut aller est vidée et surtout _en face_  du slot de la voiture
                    car.join(self.leaving_roads[car.next_way(False) % len(self.leaving_roads)].get_free_lane()) # cette fois on fait une lecture destructive

        #la voiture n'a pas d'endroit où aller : on la met dans le couloir de la mort
        else:
            self.to_kill.append(car)
Beispiel #5
0
    def __init__(   self,
                    new_start       = None,
                    new_end         = None,
                    new_max_speed   = ROAD_DEFAULT_MAX_SPEED):
        """
        Constructor method : creates a new road.
        """

        self.start      = new_start
        self.end        = new_end
        self.max_speed  = new_max_speed
        
        self.lanes      = [Lane(self, i) for i in range(ROAD_DEFAULT_LANES)]
        
        self.traffic_lights_update   = [lib.clock(), lib.clock()]
        self.traffic_lights          = [True, False]    # [at the beginning, at the end]
       
        #   In order not to compute the unit vectors of the road several times, they are stored once they are computed
        self.parallel   = None
        self.orthogonal = None
        
        self.start.host_road(self)
        self.end.host_road(self)
        
        width = 0
        for lane in self.lanes:
            width += lane.width
        self.width = width
Beispiel #6
0
    def update_car(self, car):
        """
        Updates a given car on the roundabout 
        """

        if not (car in self.car_spiraling_time):
            self.car_spiraling_time[car] = [
                car.total_waiting_time, lib.clock()
            ]

        car.total_waiting_time = self.car_spiraling_time[car][0] + lib.clock(
        ) - self.car_spiraling_time[car][1]

        if not (car.path is None) and self.leaving_roads:
            next_way = car.next_way(
                True)  # Just read the next_way unless you really go there
            car_slot = lib.find_key(self.slots_cars, car)

            #   The car has lost its slot
            if car_slot is None:
                raise Exception(
                    "ERROR (in Roundabout.update_car()) : a car has no slot !")

            #   The car's slot is in front of a leaving road
            if self.slots_roads[car_slot] in self.leaving_roads:
                if (self.leaving_roads[next_way].is_free) and self.slots_roads[
                        car_slot] == self.leaving_roads[next_way]:
                    #la route sur laquelle on veut aller est vidée et surtout _en face_  du slot de la voiture
                    car.join(self.leaving_roads[car.next_way(False) % len(
                        self.leaving_roads)].get_free_lane()
                             )  # cette fois on fait une lecture destructive

        #la voiture n'a pas d'endroit où aller : on la met dans le couloir de la mort
        else:
            self.to_kill.append(car)
Beispiel #7
0
    def last_gate_update(self, gate):
        """
        Return the time (in milliseconds) since the last update of a gate (0 or 1).
        """

        current_time = lib.clock()
        return (current_time - self.traffic_lights_update[gate])
Beispiel #8
0
    def last_gate_update(self, gate):
        """
        Return the time (in milliseconds) since the last update of a gate (0 or 1).
        """

        current_time = lib.clock()
        return (current_time - self.traffic_lights_update[gate])
Beispiel #9
0
 def timerEvent(self, event):
     """
     /!\ Qt specific (please don't rename)
     Passes or uses timer events to update the simulation
     """
     if event.timerId() == self.timer.timerId():
         # Manage internal time events
         lib.delta_t = lib.clock() - self.last_update
         self.last_update = lib.clock()
         
         # Update the simulation and informations
         self.update_simulation()
         self.update_information()
         self.histogram.update()
         self.scene.update()
         
     else:
         QtGui.QFrame.timerEvent(self, event)
Beispiel #10
0
    def timerEvent(self, event):
        """
        /!\ Qt specific (please don't rename)
        Passes or uses timer events to update the simulation
        """
        if event.timerId() == self.timer.timerId():
            # Manage internal time events
            lib.delta_t = lib.clock() - self.last_update
            self.last_update = lib.clock()

            # Update the simulation and informations
            self.update_simulation()
            self.update_information()
            self.histogram.update()
            self.scene.update()

        else:
            QtGui.QFrame.timerEvent(self, event)
Beispiel #11
0
    def update(self):
        """
        Updates the roundabout : rotate the cars, dispatch them...
        """
        #self.incoming_roads = sorted(self.incoming_roads, compa)
        #   Make the cars rotate
        if lib.clock() - self.last_shift > ROUNDABOUT_ROTATION_RATE:
            self.last_shift = lib.clock()
            self.slots_roads = lib.shift_list(self.slots_roads)

        #   Spawning mode
        if self.spawning and len(self.leaving_roads) and (
                lib.clock() - self.spawn_timer > self.spawn_time):
            self.spawn_timer = lib.clock()
            num_possible_roads = len(self.leaving_roads)
            # Possible ways out. NB : the "1000/ " thing ensures *integer* probabilities.
            possible_roads_events = [(self.leaving_roads[i],
                                      1000 / num_possible_roads)
                                     for i in range(num_possible_roads)]

            chosen_road = lib.proba_poll(possible_roads_events)
            if chosen_road.is_free:
                car_type_events = [(STANDARD_CAR, 80), (TRUCK, 15),
                                   (SPEED_CAR, 5)]

                new_car = __car__.Car(chosen_road.get_free_lane(),
                                      lib.proba_poll(car_type_events))

        #   Update traffic lights
        self._update_traffic_lights()

        #   Update cars
        for car in self.cars:
            self.update_car(car)

        #   Kill cars that have reached their destination
        for car in self.to_kill:
            car_slot = lib.find_key(self.slots_cars, car)
            self.slots_cars[car_slot] = None
            car.die()

        self.to_kill = []
Beispiel #12
0
    def change_waiting_attitude(self, new_attitude):
        """
        Changes, if needed, the waiting attitude of a car
        """

        #   There is no change : do nothing
        if new_attitude == self.is_waiting:
            return None
        
        #   Start a "waiting" phase : reset the counter
        if new_attitude:
            self.is_waiting         = True
            self.start_waiting_time = lib.clock()
            self.last_waiting_time  = 0
        
        #   Stop a "waiting" phase : look at the clock
        else:
            self.is_waiting         = False
            self.last_waiting_time  = lib.clock() - self.start_waiting_time
            self.total_waiting_time += self.last_waiting_time
Beispiel #13
0
    def change_waiting_attitude(self, new_attitude):
        """
        Changes, if needed, the waiting attitude of a car
        """

        #   There is no change : do nothing
        if new_attitude == self.is_waiting:
            return None

        #   Start a "waiting" phase : reset the counter
        if new_attitude:
            self.is_waiting = True
            self.start_waiting_time = lib.clock()
            self.last_waiting_time = 0

        #   Stop a "waiting" phase : look at the clock
        else:
            self.is_waiting = False
            self.last_waiting_time = lib.clock() - self.start_waiting_time
            self.total_waiting_time += self.last_waiting_time
Beispiel #14
0
    def update(self):
        """
        Updates the roundabout : rotate the cars, dispatch them...
        """
        #self.incoming_roads = sorted(self.incoming_roads, compa)
        #   Make the cars rotate
        if lib.clock() - self.last_shift > ROUNDABOUT_ROTATION_RATE:
            self.last_shift = lib.clock()
            self.slots_roads = lib.shift_list(self.slots_roads)

        #   Spawning mode
        if self.spawning and len(self.leaving_roads) and (lib.clock() - self.spawn_timer > self.spawn_time):
            self.spawn_timer = lib.clock() 
            num_possible_roads    = len(self.leaving_roads)
            # Possible ways out. NB : the "1000/ " thing ensures *integer* probabilities.
            possible_roads_events = [(self.leaving_roads[i], 1000/num_possible_roads) for i in range(num_possible_roads)]
        
            chosen_road = lib.proba_poll(possible_roads_events)
            if chosen_road.is_free:
                car_type_events = [(STANDARD_CAR, 80), 
                                   (TRUCK       , 15), 
                                   (SPEED_CAR   ,  5)]
                                   
                new_car = __car__.Car(chosen_road.get_free_lane(), lib.proba_poll(car_type_events))

        #   Update traffic lights
        self._update_traffic_lights()
                
        #   Update cars
        for car in self.cars:
            self.update_car(car)
        
        #   Kill cars that have reached their destination
        for car in self.to_kill:
            car_slot = lib.find_key(self.slots_cars, car)
            self.slots_cars[car_slot] = None
            car.die()

        self.to_kill = []
Beispiel #15
0
 def set_gate(self, road, state):
     """
     Sets the state of the traffic lights on the road.
         road    (Road)  :   the road whose traffic lights are affected
         state   (bool)   :   the state (False = red, True = green) of the gate
     """
     #   Set which gate is to be updated
     if id(road.start) == id(self):
         current_gate = ENTRANCE
     else:
         current_gate = EXIT
     
     #   Update if necessary
     if road.traffic_lights[current_gate] != state:
         road.traffic_lights_update[current_gate] = lib.clock()
         road.traffic_lights[current_gate]        = state
Beispiel #16
0
    def set_gate(self, road, state):
        """
        Sets the state of the traffic lights on the road.
            road    (Road)  :   the road whose traffic lights are affected
            state   (bool)   :   the state (False = red, True = green) of the gate
        """
        #   Set which gate is to be updated
        if id(road.start) == id(self):
            current_gate = ENTRANCE
        else:
            current_gate = EXIT

        #   Update if necessary
        if road.traffic_lights[current_gate] != state:
            road.traffic_lights_update[current_gate] = lib.clock()
            road.traffic_lights[current_gate] = state
Beispiel #17
0
    def __init__(self, parent=None):
        """
        Builds the main window.
        """
        QtGui.QMainWindow.__init__(self, parent)

        #   Set parameters
        lib.delta_t = 0
        self.last_update = lib.clock()
        self.selected_car = None
        self.selected_roundabout = None

        #   Set the interface
        self.setup_interface()

        #   Start the timer
        self.timer = QtCore.QBasicTimer()
        self.timer.start(10, self)
Beispiel #18
0
    def __init__(self, parent = None):
        """
        Builds the main window.
        """
        QtGui.QMainWindow.__init__(self, parent)

        #   Set parameters
        lib.delta_t                 = 0
        self.last_update            = lib.clock()
        self.selected_car           = None
        self.selected_roundabout    = None
        
        #   Set the interface
        self.setup_interface()
        
        #   Start the timer
        self.timer = QtCore.QBasicTimer()
        self.timer.start(10, self)
Beispiel #19
0
    def find_path(self, origin, destination, max_time = 1):
        """
        Performs an A* pathfinding to get a path from origin to destination.
        Returns a list of integers, representing the roads to take.
        
            origin (Roundabout)
            destination   (Roundabout)
            max_time   (float)     : maximum time allowed for the pathfinding algorithm (in seconds)
        """
        
        #   Before we start, let's check we need to do something
        if origin == destination or self._heuristic_weight(origin, destination) == 0:
            return None
        
        #   Add the starting point to the "open" list
        self.open_list.append(origin)
        self.g_cost[origin] = 0
        self.h_cost[origin] = self.f_cost[origin] = self._heuristic_weight(origin, destination)
        
        self.start_time = lib.clock()
        nearest_parent  = {}
        self.path       = PATH_INEXISTENT
        
        #while (lib.clock() - self.start_time) < max_time:
        while len(self.open_list):
            #   The "parent" node, around which we look, is always the first node of the "open" list
            #   This node is transferred to the "closed" list
            current_parent = self.open_list[0]
            self.closed_list.append(current_parent)
            del self.open_list[0]

            #   The "parent" node is the destination : the path has been found.
            if current_parent == destination:
                self.path = PATH_FOUND
                break

            #   Set the first element of the open list as the one that has the smallest F-cost
            for (i, node) in enumerate(self.open_list):
                if self.f_cost[self.open_list[0]] > self.f_cost[node]:
                    (self.open_list[i], self.open_list[0]) = (self.open_list[0], node)
            
            #   Check the adjacent nodes
            children = [road.end for road in current_parent.leaving_roads]
            
            for child in children:
                #   Not already in the closed list neither in the open list
                if not (child in self.closed_list) and not (child in self.open_list):
                    #   Compute its G-cost, H-cost and F-cost
                    self.g_cost[child] = self.g_cost[current_parent] + road.weight
                    self.h_cost[child] = self._heuristic_weight(child, destination)
                    self.f_cost[child] = self.g_cost[child] + self.h_cost[child]
                    
                    nearest_parent[child] = current_parent
                    
                    #   Add the node to the open list, keeping the order (the first node has the smallest F-cost)
                    if len(self.open_list) and (self.f_cost[self.open_list[0]] > self.f_cost[child]):
                        self.open_list.insert(0, child)
                    else:
                        self.open_list.append(child)

                #   Already in the open list : check to see if this path is a better one than the currently known path
                elif child in self.open_list:
                    #   Compute the G-cost of this possible new path
                    current_g_cost = self.g_cost[current_parent] + road.weight
                        
                    #   This path is shorter (lower G-cost) : store this path as default to reach this node
                    if current_g_cost < self.g_cost[child]:
                        #   Set this path as the shortest path to reach this node
                        nearest_parent[child]    = current_parent
                        self.g_cost[child]       = current_g_cost
                        self.f_cost[child]       = self.g_cost[current_parent] + self.h_cost[child]   # Do not forget to update the F-cost !
                        
                        #   Check if the open list is still in the right order
                        if self.f_cost[self.open_list[0]] > self.f_cost[child]:
                            i = self.open_list.index(child)
                            (self.open_list[0], self.open_list[i]) = (self.open_list[i], self.open_list[0])

        #   Save the path if it exists.
        if self.path == PATH_FOUND:
            
            current_node        = destination
            self.path           = []
            self.path_length = 0
            
            while current_node != origin:
                self.path.insert(0, current_node)
                if current_node in nearest_parent:
                    current_node = nearest_parent[current_node]
                else:
                    raise Exception('ERROR (in gps.find_path()): ill-formed parent list, a node has no parent.')
                    
                self.path_length += 1
            return self._build_path()

        return None