From 5c235f7d2af534a6cd9684f523ed0314e5900817 Mon Sep 17 00:00:00 2001 From: Sven Czarnian Date: Thu, 11 Nov 2021 11:03:41 +0100 Subject: [PATCH] extend the interface of the windows and allow resequencing --- aman/sys/RecedingHorizonControl.py | 100 +++++++++++++++++++---------- 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/aman/sys/RecedingHorizonControl.py b/aman/sys/RecedingHorizonControl.py index be52932..b3a6ae3 100644 --- a/aman/sys/RecedingHorizonControl.py +++ b/aman/sys/RecedingHorizonControl.py @@ -19,7 +19,50 @@ class RecedingHorizonControl: self.Configuration = config self.FreezedIndex = int(self.Configuration.FixedBeforeArrival.seconds / self.Configuration.WindowSize) - def update(self, inbound : Inbound): + def insertInWindow(self, inbound : Inbound, usePTA : bool): + if False == usePTA: + referenceTime = inbound.EarliestArrivalTime + else: + referenceTime = inbound.PlannedArrivalTime + + inserted = False + for i in range(0, len(self.Windows)): + window = self.Windows[i] + + # find the correct window + if window.StartTime <= referenceTime and window.EndTime > referenceTime: + if i > self.FreezedIndex: + self.AssignedWindow[inbound.Callsign] = [ i, 0 ] + if False == usePTA: + inbound.PlannedArrivalTime = inbound.EarliestArrivalTime + window.insert(inbound) + inserted = True + break + + # create the new window + if False == inserted: + if 0 != len(self.Windows): + lastWindowTime = self.Windows[-1].EndTime + else: + lastWindowTime = dt.utcfromtimestamp(int(time.time())).replace(tzinfo = pytz.UTC) + timestep = timedelta(seconds = self.Configuration.WindowSize) + + while True: + self.Windows.append(RecedingHorizonWindow(lastWindowTime, lastWindowTime + timestep)) + if self.Windows[-1].EndTime > referenceTime: + window = self.Windows[-1] + + self.AssignedWindow[inbound.Callsign] = [ len(self.Windows) - 1, 0 ] + window.insert(inbound) + if False == usePTA: + inbound.PlannedArrivalTime = max(window.StartTime, inbound.EarliestArrivalTime) + + break + lastWindowTime = self.Windows[-1].EndTime + + window.Inbounds.sort(key = lambda x: x.PlannedArrivalTime) + + def updateReport(self, inbound : Inbound): # check if we need to update if inbound.Callsign in self.AssignedWindow: index = self.AssignedWindow[inbound.Callsign][0] @@ -39,44 +82,25 @@ class RecedingHorizonControl: if inbound.EarliestArrivalTime < self.Windows[index].StartTime or inbound.EarliestArrivalTime >= self.Windows[index].EndTime: self.Windows[index].remove(inbound.Callsign) self.AssignedWindow.pop(inbound.Callsign) - self.update(inbound) + self.updateReport(inbound) else: plannedInbound.PlannedStar = inbound.PlannedStar plannedInbound.PlannedRunway = inbound.PlannedRunway plannedInbound.InitialArrivalTime = inbound.InitialArrivalTime + if plannedInbound.PlannedArrivalTime == plannedInbound.EarliestArrivalTime: + plannedInbound.PlannedArrivalTime = inbound.EarliestArrivalTime plannedInbound.EarliestArrivalTime = inbound.EarliestArrivalTime - plannedInbound.PlannedArrivalTime = inbound.EarliestArrivalTime else: - inserted = False - for i in range(0, len(self.Windows)): - window = self.Windows[i] + self.insertInWindow(inbound, False) - # find the correct window - if window.StartTime <= inbound.EarliestArrivalTime and window.EndTime > inbound.EarliestArrivalTime: - if i > self.FreezedIndex: - self.AssignedWindow[inbound.Callsign] = [ i, 0 ] - inbound.PlannedArrivalTime = inbound.EarliestArrivalTime - window.insert(inbound) - inserted = True - break - - # create the new window - if False == inserted: - if 0 != len(self.Windows): - lastWindowTime = self.Windows[-1].EndTime - else: - lastWindowTime = dt.utcfromtimestamp(int(time.time())).replace(tzinfo = pytz.UTC) - timestep = timedelta(seconds = self.Configuration.WindowSize) - - while True: - self.Windows.append(RecedingHorizonWindow(lastWindowTime, lastWindowTime + timestep)) - if self.Windows[-1].EndTime > inbound.EarliestArrivalTime: - self.AssignedWindow[inbound.Callsign] = [ len(self.Windows) - 1, 0 ] - self.Windows[-1].insert(inbound) - inbound.PlannedArrivalTime = max(self.Windows[-1].StartTime, inbound.EarliestArrivalTime) - self.Windows[-1].Inbounds.sort(key = lambda x: x.PlannedArrivalTime) - break - lastWindowTime = self.Windows[-1].EndTime + def resequenceInbound(self, inbound : Inbound): + index = self.AssignedWindow[inbound.Callsign][0] + if inbound.PlannedArrivalTime < self.Windows[index].StartTime or inbound.PlannedArrivalTime >= self.Windows[index].EndTime: + self.Windows[index].remove(inbound.Callsign) + self.AssignedWindow.pop(inbound.Callsign) + self.insertInWindow(inbound, True) + else: + self.Windows[index].Inbounds.sort(key = lambda x: x.PlannedArrivalTime) def lastFixedInboundOnRunway(self, runway : str): # no inbounds available @@ -101,7 +125,8 @@ class RecedingHorizonControl: earliestArrivalTime = None # check the overlapping windows - for i in range(self.FreezedIndex + 1, min(len(self.Windows), self.FreezedIndex + 1 + self.Configuration.WindowOverlap)): + for i in range(0, len(self.Windows)): + #for i in range(self.FreezedIndex + 1, min(len(self.Windows), self.FreezedIndex + 1 + self.Configuration.WindowOverlap)): if None == earliestArrivalTime: earliestArrivalTime = self.Windows[i].StartTime for inbound in self.Windows[i].Inbounds: @@ -114,6 +139,15 @@ class RecedingHorizonControl: else: return None, None + def sequence(self): + inbounds = [] + + for i in range(0, len(self.Windows)): + for inbound in self.Windows[i].Inbounds: + inbounds.append(inbound) + + return inbounds + def cleanupWindows(self): currentUtc = dt.utcfromtimestamp(int(time.time())).replace(tzinfo = pytz.UTC) offsetCorrection = 0