use a new function to create the fixed preceedings and use the information in the runway manager

This commit is contained in:
Sven Czarnian
2021-12-21 10:45:32 +01:00
parent a2ea26ab5d
commit 13837fdb62
4 changed files with 56 additions and 23 deletions

View File

@@ -7,7 +7,10 @@ from datetime import timedelta
import pytz import pytz
from aman.config.Airport import Airport
from aman.config.AirportSequencing import AirportSequencing
from aman.config.RHC import RHC from aman.config.RHC import RHC
from aman.sys.aco.Node import Node
from aman.sys.RecedingHorizonWindow import RecedingHorizonWindow from aman.sys.RecedingHorizonWindow import RecedingHorizonWindow
from aman.types.Inbound import Inbound from aman.types.Inbound import Inbound
@@ -106,19 +109,56 @@ class RecedingHorizonControl:
inbound.FixedSequence = index < self.FreezedIndex inbound.FixedSequence = index < self.FreezedIndex
self.Windows[index].Inbounds.sort(key = lambda x: x.PlannedArrivalTime if None != x.PlannedArrivalTime else x.EnrouteArrivalTime) self.Windows[index].Inbounds.sort(key = lambda x: x.PlannedArrivalTime if None != x.PlannedArrivalTime else x.EnrouteArrivalTime)
def lastFixedInboundOnRunway(self, runway : str): def latestFixedInbounds(self, configuration : Airport, sequenceConfiguration : AirportSequencing):
# no inbounds available
if 0 == len(self.Windows): if 0 == len(self.Windows):
return None return None, None
# search from the back to the front to find the last inbound # create the runway tree
runwayInbounds = {}
for runway in sequenceConfiguration.ActiveArrivalRunways:
runwayInbounds[runway.Runway.Name] = None
# create the IAF tree
iafInbounds = {}
for star in configuration.ArrivalRouteConstraints:
altitude = configuration.ArrivalRouteConstraints[star][0].Altitude
iaf = configuration.ArrivalRouteConstraints[star][0].Name
if iaf not in iafInbounds:
iafInbounds[iaf] = { altitude : None }
elif altitude not in iafInbounds[iaf]:
iafInbounds[iaf][altitude] = None
# associate the inbounds to the runways and the IAFs
for i in range(min(self.FreezedIndex, len(self.Windows)), -1, -1): for i in range(min(self.FreezedIndex, len(self.Windows)), -1, -1):
for inbound in self.Windows[i].Inbounds: for inbound in self.Windows[i].Inbounds:
if None != inbound.PlannedRunway and runway == inbound.PlannedRunway.Name: if None == inbound.PlannedRunway or None == inbound.PlannedArrivalRoute:
return inbound continue
# no inbound found node = Node(inbound, None, None, None, None)
return None node.EstimatedTouchdownTime = inbound.PlannedArrivalTime
node.EstimatedIafAltitude = inbound.PlannedArrivalRoute[0].Altitude
node.EstimatedIafTime = inbound.PlannedArrivalRoute[0].PTA
if inbound.PlannedRunway.Name in runwayInbounds:
if None == runwayInbounds[inbound.PlannedRunway.Name] or runwayInbounds[inbound.PlannedRunway.Name].EstimatedTouchdownTime < node.EstimatedTouchdownTime:
runwayInbounds[inbound.PlannedRunway.Name] = node
if inbound.PlannedArrivalRoute[0].Name in iafInbounds:
delta = 100000.0
targetLevel = None
for level in iafInbounds[inbound.PlannedArrivalRoute[0].Name]:
difference = abs(level - inbound.PlannedArrivalRoute[0].Altitude)
if difference < delta:
delta = difference
targetLevel = level
if None == iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel]:
iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel] = Node
elif iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel].EstimatedIafTime < node.EstimatedIafTime:
iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel] = Node
return runwayInbounds, iafInbounds
def optimizationRelevantInbounds(self): def optimizationRelevantInbounds(self):
# no new inbounds # no new inbounds

View File

@@ -102,16 +102,12 @@ class Worker(Thread):
# get the last landing aircrafts per runway before the RHC stage to check for constraints # get the last landing aircrafts per runway before the RHC stage to check for constraints
# this is required to handle the overlap between windows # this is required to handle the overlap between windows
preceedingInbounds = {} runways, iafs = self.RecedingHorizonControl.latestFixedInbounds(self.Configuration, self.SequencingConfiguration)
for runway in self.SequencingConfiguration.ActiveArrivalRunways:
inbound = self.RecedingHorizonControl.lastFixedInboundOnRunway(runway.Runway.Name)
if None != inbound:
preceedingInbounds[runway.Runway.Name] = Node(inbound, None, None, None, None)
# configure the ACO run # configure the ACO run
acoConfig = Configuration(constraints = self.SequencingConfiguration, config = self.Configuration, acoConfig = Configuration(constraints = self.SequencingConfiguration, config = self.Configuration,
earliest = earliestArrivalTime, weather = self.WeatherModel, earliest = earliestArrivalTime, weather = self.WeatherModel,
preceeding = None if 0 == len(preceedingInbounds) else preceedingInbounds, preceedingRunways = runways, preceedingIafs = iafs,
ants = 5 * len(relevantInbounds), generations = 5 * len(relevantInbounds)) ants = 5 * len(relevantInbounds), generations = 5 * len(relevantInbounds))
# perform the ACO run # perform the ACO run

View File

@@ -6,7 +6,8 @@ class Configuration:
def __init__(self, **kwargs): def __init__(self, **kwargs):
# the AMAN specific information # the AMAN specific information
self.RunwayConstraints = kwargs.get('constraints', None) self.RunwayConstraints = kwargs.get('constraints', None)
self.PreceedingInbounds = kwargs.get('preceeding', None) self.PreceedingRunwayInbounds = kwargs.get('preceedingRunways', None)
self.PreceedingIafInbounds = kwargs.get('preceedingIafs', None)
self.EarliestArrivalTime = kwargs.get('earliest', None) self.EarliestArrivalTime = kwargs.get('earliest', None)
self.WeatherModel = kwargs.get('weather', None) self.WeatherModel = kwargs.get('weather', None)
self.AirportConfiguration = kwargs.get('config', None) self.AirportConfiguration = kwargs.get('config', None)

View File

@@ -1,5 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
import copy
from datetime import datetime, timedelta from datetime import datetime, timedelta
from aman.config.RunwaySequencing import RunwayAssignmentType from aman.config.RunwaySequencing import RunwayAssignmentType
@@ -11,15 +13,9 @@ class RunwayManager:
def __init__(self, configuration : Configuration): def __init__(self, configuration : Configuration):
self.Spacings = SpacingConstraints() self.Spacings = SpacingConstraints()
self.Configuration = configuration self.Configuration = configuration
self.RunwayInbounds = copy.deepcopy(configuration.PreceedingRunwayInbounds)
self.IafInbounds = copy.deepcopy(configuration.PreceedingIafInbounds)
# initialize the tracker which inbound arrives at which runway
self.RunwayInbounds = {}
if None != configuration.PreceedingInbounds:
for runway in configuration.PreceedingInbounds:
self.RunwayInbounds[runway] = configuration.PreceedingInbounds[runway]
for runway in configuration.RunwayConstraints.ActiveArrivalRunways:
if not runway.Runway.Name in self.RunwayInbounds:
self.RunwayInbounds[runway.Runway.Name] = None
def calculateEarliestArrivalTime(self, runway : str, node : Node, earliestArrivalTime : datetime): def calculateEarliestArrivalTime(self, runway : str, node : Node, earliestArrivalTime : datetime):
constrainedETA = None constrainedETA = None