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)
Exemple #4
0
    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)
Exemple #10
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"],
                                        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)