|
@@ -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]
|
|
|
-
|
|
|
- # 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
|
|
|
+ self.insertInWindow(inbound, False)
|
|
|
+
|
|
|
+ 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
|