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 None | ||||
|  | ||||
|     def findDependentRunway(self, identifier : str): | ||||
|     def findDependentRunways(self, identifier : str): | ||||
|         # runway is unknown | ||||
|         index = self.runwayIndex(identifier) | ||||
|         if 0 > index: | ||||
|             return None | ||||
|             return [] | ||||
|  | ||||
|         # search the dependency pair | ||||
|         dependencies = [] | ||||
|         for dependency in self.RunwayDependencies: | ||||
|             if index == dependency[0]: | ||||
|                 return self.ActiveArrivalRunways[dependency[1]] | ||||
|             if index == dependency[0] and not self.ActiveArrivalRunways[dependency[1]] in dependencies: | ||||
|                 dependencies.append(self.ActiveArrivalRunways[dependency[1]]) | ||||
|  | ||||
|         # no dependencies found | ||||
|         return None | ||||
|         return dependencies | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| #!/usr/bin/env python | ||||
|  | ||||
| from datetime import timedelta | ||||
| from datetime import datetime, timedelta | ||||
|  | ||||
| from aman.sys.aco.Configuration import Configuration | ||||
| from aman.sys.aco.Constraints import SpacingConstraints | ||||
| @@ -22,57 +22,52 @@ class RunwayManager: | ||||
|  | ||||
|     def validateWtc(inbound : Inbound): | ||||
|         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 | ||||
|         else: | ||||
|             return None | ||||
|  | ||||
|     def calculateEarliestArrivalTime(self, runway : str, inbound : Inbound): | ||||
|         if None == self.RunwayInbounds[runway]: | ||||
|             return inbound.ArrivalCandidates[runway].EarliestArrivalTime | ||||
|     def calculateEarliestArrivalTime(self, runway : str, inbound : Inbound, useITA : bool, earliestArrivalTime : datetime): | ||||
|         earliestArrivalTimes = [] | ||||
|  | ||||
|         preceedingInbound = self.RunwayInbounds[runway] | ||||
|  | ||||
|         # get the WTC constrained ETA | ||||
|         wtcPre = RunwayManager.validateWtc(preceedingInbound) | ||||
|         wtcThis = RunwayManager.validateWtc(inbound) | ||||
|         if None == wtcPre or None == wtcThis: | ||||
|             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 | ||||
|         if None != self.RunwayInbounds[runway]: | ||||
|             # get the WTC based ETA | ||||
|             wtcPre = RunwayManager.validateWtc(self.RunwayInbounds[runway]) | ||||
|             wtcThis = RunwayManager.validateWtc(inbound) | ||||
|             if None == wtcPre or None == wtcThis: | ||||
|                 spacing = 3 | ||||
|             else: | ||||
|                 staggeredEarliestArrivalTime = wtcEarliestArrivalTime | ||||
|         # no neighbor or no dependent runway (IPA) | ||||
|                 spacing = self.Spacings[wtcPre][wtcThis] | ||||
|             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: | ||||
|             staggeredEarliestArrivalTime = wtcEarliestArrivalTime | ||||
|             arrivalTime = inbound.ArrivalCandidates[runway].InitialArrivalTime | ||||
|  | ||||
|         # get the runway time spacing | ||||
|         spacing = self.Configuration.RunwayConstraints.findRunway(runway).Spacing | ||||
|         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 | ||||
|         if 0 == len(earliestArrivalTimes): | ||||
|             return arrivalTime, timedelta(seconds = 0) | ||||
|         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 = [] | ||||
|         for runway in self.Configuration.RunwayConstraints.ActiveArrivalRunways: | ||||
|             availableRunways.append(runway) | ||||
| @@ -85,17 +80,19 @@ class RunwayManager: | ||||
|         # fallback to check if we have available runways | ||||
|         if 0 == len(availableRunways): | ||||
|             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 | ||||
|         selectedRunway = None | ||||
|         lostTime = None | ||||
|         eta = None | ||||
|  | ||||
|         # get the runway with the earliest ETA | ||||
|         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: | ||||
|                 selectedRunway = runway.Runway | ||||
|                 lostTime = delta | ||||
|                 eta = candidate | ||||
|  | ||||
|         return selectedRunway, eta | ||||
|         return selectedRunway, eta, lostTime | ||||
|   | ||||
		Reference in New Issue
	
	Block a user