fix some bugs in the runway manager during the ETA calculation
This commit is contained in:
		| @@ -74,16 +74,16 @@ class AirportSequencing: | |||||||
|                 return runway |                 return runway | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
|     def findDependentRunway(self, identifier : str): |     def findDependentRunways(self, identifier : str): | ||||||
|         # runway is unknown |         # runway is unknown | ||||||
|         index = self.runwayIndex(identifier) |         index = self.runwayIndex(identifier) | ||||||
|         if 0 > index: |         if 0 > index: | ||||||
|             return None |             return [] | ||||||
|  |  | ||||||
|         # search the dependency pair |         # search the dependency pair | ||||||
|  |         dependencies = [] | ||||||
|         for dependency in self.RunwayDependencies: |         for dependency in self.RunwayDependencies: | ||||||
|             if index == dependency[0]: |             if index == dependency[0] and not self.ActiveArrivalRunways[dependency[1]] in dependencies: | ||||||
|                 return self.ActiveArrivalRunways[dependency[1]] |                 dependencies.append(self.ActiveArrivalRunways[dependency[1]]) | ||||||
|  |  | ||||||
|         # no dependencies found |         return dependencies | ||||||
|         return None |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| #!/usr/bin/env python | #!/usr/bin/env python | ||||||
|  |  | ||||||
| from datetime import timedelta | from datetime import datetime, timedelta | ||||||
|  |  | ||||||
| from aman.sys.aco.Configuration import Configuration | from aman.sys.aco.Configuration import Configuration | ||||||
| from aman.sys.aco.Constraints import SpacingConstraints | from aman.sys.aco.Constraints import SpacingConstraints | ||||||
| @@ -22,57 +22,52 @@ class RunwayManager: | |||||||
|  |  | ||||||
|     def validateWtc(inbound : Inbound): |     def validateWtc(inbound : Inbound): | ||||||
|         wtc = inbound.Report.aircraft.wtc.upper() |         wtc = inbound.Report.aircraft.wtc.upper() | ||||||
|         if 'L' == wtc or 'M' == wtc or 'H' == None or 'J' == None: |         if 'L' == wtc or 'M' == wtc or 'H' == wtc or 'J' == wtc: | ||||||
|             return wtc |             return wtc | ||||||
|         else: |         else: | ||||||
|             return None |             return None | ||||||
|  |  | ||||||
|     def calculateEarliestArrivalTime(self, runway : str, inbound : Inbound): |     def calculateEarliestArrivalTime(self, runway : str, inbound : Inbound, useITA : bool, earliestArrivalTime : datetime): | ||||||
|         if None == self.RunwayInbounds[runway]: |         earliestArrivalTimes = [] | ||||||
|             return inbound.ArrivalCandidates[runway].EarliestArrivalTime |  | ||||||
|  |  | ||||||
|         preceedingInbound = self.RunwayInbounds[runway] |         if None != self.RunwayInbounds[runway]: | ||||||
|  |             # get the WTC based ETA | ||||||
|         # get the WTC constrained ETA |             wtcPre = RunwayManager.validateWtc(self.RunwayInbounds[runway]) | ||||||
|         wtcPre = RunwayManager.validateWtc(preceedingInbound) |             wtcThis = RunwayManager.validateWtc(inbound) | ||||||
|         wtcThis = RunwayManager.validateWtc(inbound) |             if None == wtcPre or None == wtcThis: | ||||||
|         if None == wtcPre or None == wtcThis: |                 spacing = 3 | ||||||
|             spacing = 3 |  | ||||||
|         else: |  | ||||||
|             spacing = self.Spacings[wtcPre][wtcThis] |  | ||||||
|         delay = timedelta(minutes = spacing / (inbound.PerformanceData.SpeedApproach / 60)) |  | ||||||
|         wtcEarliestArrivalTime = preceedingInbound.PlannedArrivalTime + delay |  | ||||||
|  |  | ||||||
|         # get the staggered time spacing |  | ||||||
|         dependentRunway = self.Configuration.RunwayConstraints.findDependentRunway(runway) |  | ||||||
|         if None != dependentRunway and None != self.RunwayInbounds[dependentRunway.Runway.Name]: |  | ||||||
|             # check if the one on the same runway lands before the one on the parallel runway |  | ||||||
|             if preceedingInbound.PlannedArrivalTime < self.RunwayInbounds[dependentRunway.Runway.Name].PlannedArrivalTime: |  | ||||||
|                 delay = timedelta(minutes = 3 / (inbound.PerformanceData.SpeedApproach / 60)) |  | ||||||
|                 staggeredEarliestArrivalTime = self.RunwayInbounds[dependentRunway.Runway.Name].PlannedArrivalTime + delay |  | ||||||
|             # landing on the same runway |  | ||||||
|             else: |             else: | ||||||
|                 staggeredEarliestArrivalTime = wtcEarliestArrivalTime |                 spacing = self.Spacings[wtcPre][wtcThis] | ||||||
|         # no neighbor or no dependent runway (IPA) |             delay = timedelta(minutes = spacing / (inbound.PerformanceData.SpeedApproach / 60)) | ||||||
|  |             earliestArrivalTimes.append(self.RunwayInbounds[runway].PlannedArrivalTime + delay) | ||||||
|  |  | ||||||
|  |             # get the runway time spacing | ||||||
|  |             spacing = self.Configuration.RunwayConstraints.findRunway(runway).Spacing | ||||||
|  |             delay = timedelta(minutes = spacing / (inbound.PerformanceData.SpeedApproach / 60)) | ||||||
|  |             earliestArrivalTimes.append(self.RunwayInbounds[runway].PlannedArrivalTime + delay) | ||||||
|  |  | ||||||
|  |         # calculate the arrival times for the dependent inbounds | ||||||
|  |         for dependentRunway in self.Configuration.RunwayConstraints.findDependentRunways(runway): | ||||||
|  |             if None != self.RunwayInbounds[dependentRunway.Runway.Name]: | ||||||
|  |                 delay = timedelta(minutes = 3 / (inbound.PerformanceData.SpeedApproach / 60)) | ||||||
|  |                 earliestArrivalTimes.append(self.RunwayInbounds[dependentRunway.Runway.Name].PlannedArrivalTime + delay) | ||||||
|  |  | ||||||
|  |         # get the arrival time on the runway of the inbound | ||||||
|  |         if True == useITA: | ||||||
|  |             arrivalTime = inbound.ArrivalCandidates[runway].EarliestArrivalTime | ||||||
|         else: |         else: | ||||||
|             staggeredEarliestArrivalTime = wtcEarliestArrivalTime |             arrivalTime = inbound.ArrivalCandidates[runway].InitialArrivalTime | ||||||
|  |  | ||||||
|         # get the runway time spacing |         if 0 == len(earliestArrivalTimes): | ||||||
|         spacing = self.Configuration.RunwayConstraints.findRunway(runway).Spacing |             return arrivalTime, timedelta(seconds = 0) | ||||||
|         delay = timedelta(minutes = spacing / (inbound.PerformanceData.SpeedApproach / 60)) |  | ||||||
|         runwayEarliestArrivalTime = preceedingInbound.PlannedArrivalTime + delay |  | ||||||
|  |  | ||||||
|         # the candidate with the latest ETA is used -> ensure all safety and procedure constraints |  | ||||||
|         candidate = max(max(wtcEarliestArrivalTime, staggeredEarliestArrivalTime), runwayEarliestArrivalTime) |  | ||||||
|  |  | ||||||
|         # check if inbound comes later than the latest possible ETA |  | ||||||
|         if candidate < inbound.ArrivalCandidates[runway].EarliestArrivalTime: |  | ||||||
|             return inbound.ArrivalCandidates[runway].EarliestArrivalTime |  | ||||||
|         # candidate fits into earliest arrival time or is later than this |  | ||||||
|         else: |         else: | ||||||
|             return candidate |             eta = max(earliestArrivalTimes) | ||||||
|  |             if eta < arrivalTime: | ||||||
|  |                 return arrivalTime, arrivalTime - eta | ||||||
|  |             else: | ||||||
|  |                 return eta, timedelta(seconds = 0) | ||||||
|  |  | ||||||
|     def selectArrivalRunway(self, inbound : Inbound): |     def selectArrivalRunway(self, inbound : Inbound, useITA : bool, earliestArrivalTime : datetime): | ||||||
|         availableRunways = [] |         availableRunways = [] | ||||||
|         for runway in self.Configuration.RunwayConstraints.ActiveArrivalRunways: |         for runway in self.Configuration.RunwayConstraints.ActiveArrivalRunways: | ||||||
|             availableRunways.append(runway) |             availableRunways.append(runway) | ||||||
| @@ -85,17 +80,19 @@ class RunwayManager: | |||||||
|         # fallback to check if we have available runways |         # fallback to check if we have available runways | ||||||
|         if 0 == len(availableRunways): |         if 0 == len(availableRunways): | ||||||
|             runway = self.Configuration.RunwayConstraints.ActiveArrivalRunways[0] |             runway = self.Configuration.RunwayConstraints.ActiveArrivalRunways[0] | ||||||
|             return runway, self.calculateEarliestArrivalTime(runway.Runway.Name, inbound) |             return runway, self.calculateEarliestArrivalTime(runway.Runway.Name, inbound, useITA, earliestArrivalTime) | ||||||
|  |  | ||||||
|         # start with the beginning |         # start with the beginning | ||||||
|         selectedRunway = None |         selectedRunway = None | ||||||
|  |         lostTime = None | ||||||
|         eta = None |         eta = None | ||||||
|  |  | ||||||
|         # get the runway with the earliest ETA |         # get the runway with the earliest ETA | ||||||
|         for runway in availableRunways: |         for runway in availableRunways: | ||||||
|             candidate = self.calculateEarliestArrivalTime(runway.Runway.Name, inbound) |             candidate, delta = self.calculateEarliestArrivalTime(runway.Runway.Name, inbound, useITA, earliestArrivalTime) | ||||||
|             if None == eta or eta > candidate: |             if None == eta or eta > candidate: | ||||||
|                 selectedRunway = runway.Runway |                 selectedRunway = runway.Runway | ||||||
|  |                 lostTime = delta | ||||||
|                 eta = candidate |                 eta = candidate | ||||||
|  |  | ||||||
|         return selectedRunway, eta |         return selectedRunway, eta, lostTime | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user