def test_sfo_terminal_2_all(self): airport_code = "sfo-terminal-2" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes routing_expert = RoutingExpert(links, nodes, True) runway_start = self.airport.surface.get_link("10R/28L").start # Checks the gate that is far from the runway (G53) gate_names = [ "50", "55", "53", "52", "54A", "51A", "51B", "54B", "56B", "56A", "57", "59", "58B", "58A" ] for gate_name in gate_names: gate = self.airport.surface.get_node(gate_name) route = routing_expert.get_shortest_route(gate, runway_start) # Make sure they all have a route to go to the runway self.assertTrue(len(route.nodes) >= 2) self.assertTrue(len(route.links) >= 1) self.assertTrue(route.distance > 0.0)
def test_overlapped_link(self): routing_expert = RoutingExpert(self.links, self.nodes, False) route = routing_expert.get_shortest_route(self.G1, self.S1) # Checks if the shortest route uses L1 self.assertEqual(route.links[1], self.L1) # Checks if the shortest distance is expected self.assertAlmostEqual(route.distance, 218489.353890, 5)
def test_cache(self): # Try cache so we starts routing expert twice RoutingExpert(self.links, self.nodes, True) routing_expert = RoutingExpert(self.links, self.nodes, True) route = routing_expert.get_shortest_route(self.G1, self.S1) # Checks if the shortest route uses L1 self.assertEqual(route.links[1], self.L1) # Checks if the shortest distance is expected self.assertAlmostEqual(route.distance, 218489.353890, 6)
def __init__(self): params = Config.params # Setups the logger self.logger = logging.getLogger(__name__) # Setups the clock self.clock = Clock() # Sets up the airport airport_name = params["airport"] self.airport = Airport.create(airport_name) # Sets up the scenario self.scenario = Scenario.create( airport_name, self.airport.surface) # Sets up the routing expert monitoring the airport surface self.routing_expert = RoutingExpert(self.airport.surface.links, self.airport.surface.nodes, params["simulation"]["cache"]) # Sets up the uncertainty module self.uncertainty = (Uncertainty(params["uncertainty"]["prob_hold"], params["uncertainty"]["speed_bias_sigma"], params["uncertainty"]["speed_bias_mu"]) if params["uncertainty"]["enabled"] else None) # Loads the requested scheduler self.scheduler = get_scheduler() if not params["simulator"]["test_mode"]: # Sets up the analyst self.analyst = Analyst(self) # Sets up the state logger self.state_logger = StateLogger() # Initializes the previous schedule time self.last_schedule_time = None # Initializes the last execution time for rescheduling to None self.last_schedule_exec_time = None self.__print_stats()
def test_simple_data(self): airport_code = "simple" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes # Sets up the routing expert monitoring the airport surface routing_expert = RoutingExpert(links, nodes, False) routeG3toR1 = routing_expert.get_shortest_route( nodes[2], links[0].start) self.assertEqual(len(routeG3toR1.nodes), 8) self.assertAlmostEqual(routeG3toR1.distance, 1352.6500035604972, 5)
def test_real_west_all_terminals_furthest(self): airport_code = "real-west-all-terminals" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes routing_expert = RoutingExpert(links, nodes, True) runway_start = self.airport.surface.get_link("10R/28L").start # Checks the gate that is far from the runway (G53) gate_53 = self.airport.surface.get_node("53") routeG53to10R = \ routing_expert.get_shortest_route(gate_53, runway_start) self.assertAlmostEqual(routeG53to10R.distance, 17167.291795099998, 5) self.assertEqual(len(routeG53to10R.nodes), 19) self.assertEqual(len(routeG53to10R.links), 18)
def test_real_west_all_terminals_closest(self): airport_code = "real-west-all-terminals" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes routing_expert = RoutingExpert(links, nodes, True) runway_start = self.airport.surface.get_link("10R/28L").start # Checks the gate that is near to the runway (G58B) gate_58B = self.airport.surface.get_node("58B") routeG58Bto10R = \ routing_expert.get_shortest_route(gate_58B, runway_start) self.assertAlmostEqual(routeG58Bto10R.distance, 15500.519095, 5) self.assertEqual(len(routeG58Bto10R.nodes), 21) self.assertEqual(len(routeG58Bto10R.links), 20)
def test_sfo_terminal_2_furthest(self): airport_code = "sfo-terminal-2" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes routing_expert = RoutingExpert(links, nodes, True) runway_start = self.airport.surface.get_link("10R/28L").start # Checks the gate that is far from the runway (G53) gate_53 = self.airport.surface.get_node("53") routeG53to10R = \ routing_expert.get_shortest_route(gate_53, runway_start) self.assertAlmostEqual(routeG53to10R.distance, 10014.749180929799, 5) self.assertEqual(len(routeG53to10R.nodes), 39) self.assertEqual(len(routeG53to10R.links), 38)
def test_sfo_terminal_2_closest(self): airport_code = "sfo-terminal-2" # Sets up the airport self.airport = Airport.create(airport_code) # Sets up the scenario self.scenario = Scenario.create(airport_code, self.airport.surface) links = self.airport.surface.links nodes = self.airport.surface.nodes routing_expert = RoutingExpert(links, nodes, True) runway_start = self.airport.surface.get_link("10R/28L").start # Checks the gate that is near to the runway (G58B) gate_58B = self.airport.surface.get_node("58B") routeG58Bto10R = \ routing_expert.get_shortest_route(gate_58B, runway_start) self.assertAlmostEqual(routeG58Bto10R.distance, 8198.5613013809, 5) self.assertEqual(len(routeG58Bto10R.nodes), 32) self.assertEqual(len(routeG58Bto10R.links), 31)
class Simulation: """Simulation, representing a simulation day, holds both static and dynamic states of the current airport, and implements `tick()` functions for the caller to simulation to the next state. """ def __init__(self): params = Config.params # Setups the logger self.logger = logging.getLogger(__name__) # Setups the clock self.clock = Clock() # Sets up the airport airport_name = params["airport"] self.airport = Airport.create(airport_name) # Sets up the scenario self.scenario = Scenario.create( airport_name, self.airport.surface) # Sets up the routing expert monitoring the airport surface self.routing_expert = RoutingExpert(self.airport.surface.links, self.airport.surface.nodes, params["simulation"]["cache"]) # Sets up the uncertainty module self.uncertainty = (Uncertainty(params["uncertainty"]["prob_hold"], params["uncertainty"]["speed_bias_sigma"], params["uncertainty"]["speed_bias_mu"]) if params["uncertainty"]["enabled"] else None) # Loads the requested scheduler self.scheduler = get_scheduler() if not params["simulator"]["test_mode"]: # Sets up the analyst self.analyst = Analyst(self) # Sets up the state logger self.state_logger = StateLogger() # Initializes the previous schedule time self.last_schedule_time = None # Initializes the last execution time for rescheduling to None self.last_schedule_exec_time = None self.__print_stats() def tick(self): """Moves the states of this simulation to the next state.""" self.logger.debug("\nCurrent Time: %s", self.now) try: # # Reschedule happens before the tick. It will resolve conflict here # if self.__is_time_to_reschedule(): # self.logger.info("Time to reschedule") # start = time.time() # self.__reschedule() # it will try to resolve conflict # self.last_schedule_exec_time = time.time() - start # seconds # self.last_schedule_time = self.now # self.logger.info("Last schedule time is updated to %s", # self.last_schedule_time) # Add aircraft self.airport.add_aircrafts(self.scenario, self.now, self.clock.sim_time, self.scheduler) start = time.time() self.__reschedule() # it will try to resolve conflict self.last_schedule_exec_time = time.time() - start # seconds self.last_schedule_time = self.now self.logger.info("Last schedule time is updated to %s", self.last_schedule_time) # # Inject uncertainties # if self.uncertainty: # self.uncertainty.inject(self) # Tick self.airport.tick() state = None aircrafts = self.airport.control_takeoff() if not Config.params["simulator"]["test_mode"]: state = self.state_logger.log_on_tick(self) self.clock.tick() # print(len(state["aircrafts"])) # if len(state["aircrafts"]) >= 1: # print(state["aircrafts"][0]["callsign"] + " "+state["aircrafts"][0]["state"]) # Remove aircraft close to the runway self.airport.remove_aircrafts(self.scenario) self.airport.remove_departure_aircrafts(aircrafts) # Abort on conflict conflicts, conflicts_dist = self.airport.conflicts if conflicts: for idx, conflict in enumerate(conflicts): dist = conflicts_dist[idx] print("Found %s", conflict) print("Conflict distance: %d", dist) print(conflict.detailed_description) self.logger.error("Found %s", conflict) self.logger.error("Conflict distance: %d", dist) self.logger.error(conflict.detailed_description) for aircraft in self.airport.aircrafts: self.logger.error(aircraft) print(aircraft.model) aircraft.has_conflict = True # for conflict in conflicts: # self.logger.error("Found %s", conflict) # self.logger.error("Conflict distance: ", dist) # self.logger.error(conflict.detailed_description) # for aircraft in self.airport.aircrafts: # self.logger.error(aircraft) # change color for crashing airplanes # print(pair[0].model, pair[1].model) # pair[0].has_conflict = True # pair[1].has_conflict = True # raise SimulationException("Conflict found") # Observe if not Config.params["simulator"]["test_mode"]: self.analyst.observe_on_tick(self) # return current state for streaming visualization return state except ClockException as error: # Finishes if not Config.params["simulator"]["test_mode"]: self.analyst.save() raise error except SimulationException as error: raise error except Exception as error: self.logger.error(traceback.format_exc()) raise error def __is_time_to_reschedule(self): reschedule_cycle = Config.params["simulation"]["reschedule_cycle"] last_time = self.last_schedule_time next_time = (get_seconds_after(last_time, reschedule_cycle) if last_time is not None else None) return last_time is None or next_time <= self.now def __reschedule(self): schedule, priority = self.scheduler.schedule(self) self.airport.apply_schedule(schedule) self.airport.apply_priority(priority) if not Config.params["simulator"]["test_mode"]: self.analyst.observe_on_reschedule(self) @property def now(self): """Return the current time of the simulation.""" return self.clock.now def __print_stats(self): self.scenario.print_stats() self.airport.print_stats() def __getstate__(self): __dict = dict(self.__dict__) del __dict["logger"] __dict["uncertainty"] = None __dict["routing_expert"] = None return __dict def __setstate__(self, new_dict): self.__dict__.update(new_dict) def set_quiet(self, logger): """Sets the simulation and its subclass to quiet mode where the logger doesn't print that many stuff. """ self.logger = logger self.airport.set_quiet(logger) self.scenario.set_quiet(logger) self.routing_expert.set_quiet(logger) @property def copy(self): """Obtains a immutable copy of this simulation.""" # NOTE: If uncertainty is not None, call inject() in tick(). return ClonedSimulation(self)
return { "airport_name": airport_name, "airport_center": airport_center, "pushback_ways": pushback_ways, "taxiways": taxiways, "runways": runways, "gates": gates, "spots": spots, "inters": inters } surface = SurfaceFactory.create(AIRPORT_DATA_FOLDER + "real-west-all-terminals/build/") routing_expert = RoutingExpert(surface.links, surface.nodes, False) G = GraphVisualization() def get_arrival_runway_node(): for runway in surface.runways: if runway.name == arrival_runway_node_name: return runway.nodes[0] def get_departure_runway_node(): for runway in surface.runways: if runway.name == departure_runway_node_name: return runway.nodes[0]
class Simulation: """Simulation, representing a simulation day, holds both static and dynamic states of the current airport, and implements `tick()` functions for the caller to simulation to the next state. """ def __init__(self): params = Config.params # Setups the logger self.logger = logging.getLogger(__name__) # Setups the clock self.clock = Clock() # Sets up the airport airport_name = params["airport"] self.airport = Airport.create(airport_name) # Sets up the scenario self.scenario = Scenario.create(airport_name, self.airport.surface) # Sets up the routing expert monitoring the airport surface self.routing_expert = RoutingExpert(self.airport.surface.links, self.airport.surface.nodes, params["simulation"]["cache"]) # Sets up the uncertainty module self.uncertainty = (Uncertainty(params["uncertainty"]["prob_hold"]) if params["uncertainty"]["enabled"] else (None)) # Loads the requested scheduler self.scheduler = get_scheduler() if not params["simulator"]["test_mode"]: # Sets up the analyst self.analyst = Analyst(self) # Sets up the state logger self.state_logger = StateLogger() # Initializes the previous schedule time self.last_schedule_time = None # Initializes the last execution time for rescheduling to None self.last_schedule_exec_time = None self.__print_stats() def tick(self): """Moves the states of this simulation to the next state.""" self.logger.debug("\nCurrent Time: %s", self.now) try: # Reschedule happens before the tick if self.__is_time_to_reschedule(): self.logger.info("Time to reschedule") start = time.time() self.__reschedule() self.last_schedule_exec_time = time.time() - start # seconds self.last_schedule_time = self.now self.logger.info("Last schedule time is updated to %s", self.last_schedule_time) # Adds aircrafts self.airport.add_aircrafts(self.scenario, self.now, self.clock.sim_time) # Injects uncertainties if self.uncertainty: self.uncertainty.inject(self) # Ticks self.airport.tick() if not Config.params["simulator"]["test_mode"]: self.state_logger.log_on_tick(self) self.clock.tick() # Removes aircrafts self.airport.remove_aircrafts(self.scenario) # Abort on conflict conflicts = self.airport.conflicts if conflicts: for conflict in conflicts: self.logger.error("Found %s", conflict) raise SimulationException("Conflict found") # Observe if not Config.params["simulator"]["test_mode"]: self.analyst.observe_on_tick(self) except ClockException as error: # Finishes if not Config.params["simulator"]["test_mode"]: self.analyst.save() raise error except SimulationException as error: raise error except Exception as error: self.logger.error(traceback.format_exc()) raise error def __is_time_to_reschedule(self): reschedule_cycle = Config.params["simulation"]["reschedule_cycle"] last_time = self.last_schedule_time next_time = (get_seconds_after(last_time, reschedule_cycle) if last_time is not None else None) return last_time is None or next_time <= self.now def __reschedule(self): schedule = self.scheduler.schedule(self) self.airport.apply_schedule(schedule) if not Config.params["simulator"]["test_mode"]: self.analyst.observe_on_reschedule(self) @property def now(self): """Return the current time of the simulation.""" return self.clock.now def __print_stats(self): self.scenario.print_stats() self.airport.print_stats() def __getstate__(self): __dict = dict(self.__dict__) del __dict["logger"] __dict["uncertainty"] = None __dict["routing_expert"] = None return __dict def __setstate__(self, new_dict): self.__dict__.update(new_dict) def set_quiet(self, logger): """Sets the simulation and its subclass to quiet mode where the logger doesn't print that many stuff. """ self.logger = logger self.airport.set_quiet(logger) self.scenario.set_quiet(logger) self.routing_expert.set_quiet(logger) @property def copy(self): """Obtains a immutable copy of this simulation.""" # NOTE: If uncertainty is not None, call inject() in tick(). return ClonedSimulation(self)