"""
Tests the assignment algorithm.

Assignment algorithm: find all flights that arrive at the virtual hub within a 
certain time window of each other and group them by maximizing the available 
slack.
"""
from lib.intervals import Interval, group

if __name__ == "__main__":

    print group(
        [
            Interval("G", 0, 2),
            Interval("B", 2, 4),
            Interval("C", 1, 3),
            Interval("D", 3, 5),
            Interval("A", 1, 3),
            Interval("E", 4, 6),
            Interval("F", 2, 4),
        ]
    )
Example #2
0
    def allocate(self, aircraft):
        
        p('debug', 'Starting formation allocation for %s' % aircraft)
        
        # Do not perform allocation if no hub exists in the flight route.
        if len(aircraft.route.segments) == 0:
            return

        self.formations = []
        intervals       = []
        candidates      = self.aircraft_queue
        hub             = aircraft.route.waypoints[0]

        # This is bad. We don't want to filter anything. 
        # @todo: pre-process at a higher level.
        # Only consider other aircraft flying to the same hub
        candidates = filter(lambda a: a.route.waypoints[0] is hub, 
                            candidates)
        
        p('debug', 'Full candidate set: %s' % candidates)

        # Only consider aircraft having a maximum heading difference between
        # the hub and their destination
        segment = Segment(aircraft.hub, aircraft.destination)
        leader_heading = segment.get_initial_bearing()

        def heading_filter(buddy):

            segment = Segment(buddy.hub, buddy.destination)
            buddy_heading = segment.get_initial_bearing()
            phi_obs = abs(leader_heading - buddy_heading)
            p(
                'debug',
                'delta phi observed for %s (phi: %.2f) against %s (phi: %.2f)'
                ': %.2f degrees' % (
                    aircraft, leader_heading, buddy, buddy_heading, phi_obs
                )
            )
            return phi_obs <= (config.phi_max/2)

        candidates = filter(heading_filter, candidates)

        # Other interesting filters
        if 'same-airline' in config.restrictions:
            airline = aircraft.label[0:2]
            candidates = filter(lambda a: a.label[0:2] == airline,
                                candidates)
        if 'same-aircraft-type' in config.restrictions:
            aircraft_type = aircraft.aircraft_type
            candidates = filter(lambda a: a.aircraft_type == aircraft_type,
                                candidates)
        
        p('debug', 'Reduced candidate set: %s' % candidates)

        for candidate in candidates:

            # Quick and dirty: recalc position. Instead, pull eta from var.
            candidate.controller.update_position()
            tth = candidate.time_to_waypoint() # time to hub
            hub_eta = sim.time + tth
            
            # From the moment the aircraft enters the lock area, the slack
            # decreases linearly to zero upon hub arrival.
            if tth < config.lock_time:
                slack = tth * config.etah_slack / config.lock_time
            else:
                slack = config.etah_slack

            p('Time = %s, Hub (= %s) eta %s for candidate %s' %\
              (sim.time, hub, hub_eta, candidate))
            intervals.append(Interval(
                candidate,
                int(hub_eta) - slack,
                int(hub_eta) + slack
            ))
            
        for interval_group in group(intervals):
            formation = Formation()
            for interval in interval_group:
                formation.append(interval.obj)
            self.formations.append(formation)
Example #3
0
"""
Tests the assignment algorithm.

Assignment algorithm: find all flights that arrive at the virtual hub within a 
certain time window of each other and group them by maximizing the available 
slack.
"""
from lib.intervals import Interval, group

if __name__ == '__main__':

    print group([
        Interval('G', 0, 2),
        Interval('B', 2, 4),
        Interval('C', 1, 3),
        Interval('D', 3, 5),
        Interval('A', 1, 3),
        Interval('E', 4, 6),
        Interval('F', 2, 4),
    ])
    def allocate(self, aircraft):

        p('debug', 'Starting formation allocation for %s' % aircraft)

        # Do not perform allocation if no hub exists in the flight route.
        if len(aircraft.route.segments) == 0:
            return

        self.formations = []
        intervals = []
        candidates = self.aircraft_queue
        hub = aircraft.route.waypoints[0]

        # This is bad. We don't want to filter anything.
        # @todo: pre-process at a higher level.
        # Only consider other aircraft flying to the same hub
        candidates = filter(lambda a: a.route.waypoints[0] is hub, candidates)

        p('debug', 'Full candidate set: %s' % candidates)

        # Only consider aircraft having a maximum heading difference between
        # the hub and their destination
        segment = Segment(aircraft.hub, aircraft.destination)
        leader_heading = segment.get_initial_bearing()

        def heading_filter(buddy):

            segment = Segment(buddy.hub, buddy.destination)
            buddy_heading = segment.get_initial_bearing()
            phi_obs = abs(leader_heading - buddy_heading)
            p(
                'debug',
                'delta phi observed for %s (phi: %.2f) against %s (phi: %.2f)'
                ': %.2f degrees' %
                (aircraft, leader_heading, buddy, buddy_heading, phi_obs))
            return phi_obs <= (config.phi_max / 2)

        candidates = filter(heading_filter, candidates)

        # Other interesting filters
        if 'same-airline' in config.restrictions:
            airline = aircraft.label[0:2]
            candidates = filter(lambda a: a.label[0:2] == airline, candidates)
        if 'same-aircraft-type' in config.restrictions:
            aircraft_type = aircraft.aircraft_type
            candidates = filter(lambda a: a.aircraft_type == aircraft_type,
                                candidates)

        p('debug', 'Reduced candidate set: %s' % candidates)

        for candidate in candidates:

            # Quick and dirty: recalc position. Instead, pull eta from var.
            candidate.controller.update_position()
            tth = candidate.time_to_waypoint()  # time to hub
            hub_eta = sim.time + tth

            # From the moment the aircraft enters the lock area, the slack
            # decreases linearly to zero upon hub arrival.
            if tth < config.lock_time:
                slack = tth * config.etah_slack / config.lock_time
            else:
                slack = config.etah_slack

            p('Time = %s, Hub (= %s) eta %s for candidate %s' %\
              (sim.time, hub, hub_eta, candidate))
            intervals.append(
                Interval(candidate,
                         int(hub_eta) - slack,
                         int(hub_eta) + slack))

        for interval_group in group(intervals):
            formation = Formation()
            for interval in interval_group:
                formation.append(interval.obj)
            self.formations.append(formation)