class SimMain: def __init__(self): """Initialize""" self.dataStorage = DataLogging() """Initialize PyGame""" pygame.init() """Set the window Size""" self.width = WIDTH self.height = HEIGHT """Create the Screen""" self.screen = pygame.display.set_mode((self.width, self.height)) pygame.display.set_caption('Traffic Control Simulation') # Initialize font self.font = pygame.font.SysFont('monospace', 14) # Define vehicles to be used self.vehicles = [VehicleCar, VehicleTruck] self.intersection = Intersection( center=Coord(x=WIDTH * 0.5, y=HEIGHT * 0.5)) # Add traffic light traffic_lightWE = TrafficLight(strategy='classic', id_=0) traffic_lightEW = TrafficLight(strategy='classic', id_=1) traffic_lightSN = TrafficLight(strategy='classic', id_=2) traffic_lightNS = TrafficLight(strategy='classic', id_=3) # Add a few dummy lanes self.intersection.add_lane(direction=Coord(1, 0), towards=False, order=0) #0 self.intersection.add_lane(direction=Coord(1, 0), towards=True, order=0, light=traffic_lightWE) #1 self.intersection.add_lane(direction=Coord(-1, 0), towards=True, order=0, light=traffic_lightEW) #2 self.intersection.add_lane(direction=Coord(-1, 0), towards=False, order=0) #3 self.intersection.add_lane(direction=Coord(0, -1), towards=False, order=0) #4 self.intersection.add_lane(direction=Coord(0, -1), towards=True, order=0, light=traffic_lightSN) #5 self.intersection.add_lane(direction=Coord(0, 1), towards=False, order=0) #6 self.intersection.add_lane(direction=Coord(0, 1), towards=True, order=0, light=traffic_lightNS) #7 self.controller = Controller(self.intersection.get_lanes()) self.frame_timing = pygame.time.Clock() self.carframecounter = 0 self.total_frames = 0 def main_loop(self): # Create the background self.background = pygame.Surface(self.screen.get_size()) self.background = self.background.convert() self.background.fill((20, 50, 50)) running = True while running: frame_start = dt.datetime.now() # Do the drawing self.screen.blit(self.background, (0, 0)) # Update traffic light and car self.maybe_add_car() self.controller.update() self.intersection.render(self.screen) self.intersection.update_lanes(self.screen) # Handle events running = self.handle_events() self.display_fps() pygame.display.flip() frame_time = (dt.datetime.now() - frame_start).total_seconds() # pygame.time.delay(int(max(0, (1.0 / FRAMERATE) - frame_time) * 1000)) time.sleep(max(0, (1.0 / FRAMERATE) - frame_time)) self.frame_timing.tick() self.total_frames += 1 if self.total_frames > RUN_TIME: running = False # Store results to a pickle file results = self.dataStorage.get_results(np.median) os.makedirs('results', exist_ok=True) name = os.path.join('results/', METHOD + '_' + str(TEST_RUN_NUMBER) + '.pkl') pickle.dump(results, open(name, 'wb')) @staticmethod def handle_events(): events = pygame.event.get() for event in events: if event.type == pygame.KEYDOWN: # Key press if event.key == pygame.K_ESCAPE: return False return True def display_fps(self): fps = round(self.frame_timing.get_fps()) fps_text = self.font.render('FPS: ' + str(fps), 0, (255, 255, 255)) self.screen.blit(fps_text, (0, 0)) def maybe_add_car(self): routes = [ (1, 0, 'E', 'E'), (1, 4, 'E', 'N'), (1, 6, 'E', 'S'), (2, 3, 'W', 'W'), (2, 4, 'W', 'N'), (2, 6, 'W', 'S'), (5, 4, 'N', 'N'), (5, 3, 'N', 'W'), (5, 0, 'N', 'E'), (7, 6, 'S', 'S'), (7, 3, 'S', 'W'), (7, 0, 'S', 'E'), ] if self.carframecounter == 0: route = routes[random.randint(0, len(routes) - 1)] next_lane = (self.intersection.lanes[route[1]], route[3]) # Select type of vehicle distribution = [x.spawn_rate for x in self.vehicles] chosen = np.random.choice(self.vehicles, size=1, p=distribution)[0] vehicle = chosen() self.intersection.lanes[route[0]].addCar( Vehicle(vehicle.name, vehicle.speed, vehicle.max_speed, vehicle.acceleration, vehicle.braking, vehicle.turning_rate, vehicle.scale, route[2], self.dataStorage, next_lane, debug=DEBUG)) # Potentially add emergency vehicle according to chance roll if chance(VehicleEmergency().spawn_rate): vehicle = VehicleEmergency() self.intersection.lanes[route[0]].add_emerg_vehicle( Vehicle(vehicle.name, vehicle.speed, vehicle.max_speed, vehicle.acceleration, vehicle.braking, vehicle.turning_rate, vehicle.scale, route[2], self.dataStorage, next_lane, debug=DEBUG)) self.carframecounter += 1 if self.carframecounter == CAR_EVERY_FRAMES: self.carframecounter = 0