diff --git a/aman/sys/RecedingHorizonControl.py b/aman/sys/RecedingHorizonControl.py index d15b2fe..70c8c3b 100644 --- a/aman/sys/RecedingHorizonControl.py +++ b/aman/sys/RecedingHorizonControl.py @@ -32,26 +32,20 @@ class RecedingHorizonControl: plannedInbound = self.Windows[index].inbound(inbound.Report.aircraft.callsign) plannedInbound.CurrentPosition = inbound.CurrentPosition plannedInbound.MaximumTimeToGain = inbound.MaximumTimeToGain + plannedInbound.ArrivalCandidates = inbound.ArrivalCandidates - # get the reference time and update some times in case no replacement is needed - if plannedInbound.InitialArrivalTime == plannedInbound.EarliestArrivalTime + plannedInbound.MaximumTimeToGain: - plannedInbound.InitialArrivalTime = inbound.InitialArrivalTime - plannedInbound.EarliestArrivalTime = inbound.EarliestArrivalTime - plannedInbound.EstimatedArrivalTime = inbound.EstimatedArrivalTime - reference = inbound.EarliestArrivalTime - else: - plannedInbound.InitialArrivalTime = inbound.InitialArrivalTime - if plannedInbound.EarliestArrivalTime < inbound.EarliestArrivalTime: + # check if we need to update the inbound + if plannedInbound.PlannedArrivalTime < inbound.EarliestArrivalTime: + if inbound.EarliestArrivalTime < self.Windows[index].StartTime or inbound.EarliestArrivalTime >= self.Windows[index].EndTime: + self.Windows[index].remove(inbound.Report.aircraft.callsign) + self.AssignedWindow.pop(inbound.Report.aircraft.callsign) + self.update(inbound) + else: + plannedInbound.PlannedStar = inbound.PlannedStar + plannedInbound.PlannedRunway = inbound.PlannedRunway + plannedInbound.InitialArrivalTime = inbound.InitialArrivalTime plannedInbound.EarliestArrivalTime = inbound.EarliestArrivalTime - if plannedInbound.EstimatedArrivalTime < inbound.EstimatedArrivalTime: - plannedInbound.EstimatedArrivalTime = inbound.EstimatedArrivalTime - reference = plannedInbound.EarliestArrivalTime - - # update the windows - if reference < self.Windows[index].StartTime or reference >= self.Windows[index].EndTime: - self.Windows[index].remove(inbound.Report.aircraft.callsign) - self.AssignedWindow.pop(inbound.Report.aircraft.callsign) - self.update(inbound) + plannedInbound.PlannedArrivalTime = inbound.EarliestArrivalTime else: inserted = False for i in range(0, len(self.Windows)): @@ -61,6 +55,7 @@ class RecedingHorizonControl: if window.StartTime <= inbound.EarliestArrivalTime and window.EndTime > inbound.EarliestArrivalTime: if i > self.FreezedIndex: self.AssignedWindow[inbound.Report.aircraft.callsign] = [ i, 0 ] + inbound.PlannedArrivalTime = inbound.EarliestArrivalTime window.insert(inbound) inserted = True break @@ -78,7 +73,8 @@ class RecedingHorizonControl: if self.Windows[-1].EndTime > inbound.EarliestArrivalTime: self.AssignedWindow[inbound.Report.aircraft.callsign] = [ len(self.Windows) - 1, 0 ] self.Windows[-1].insert(inbound) - self.Windows[-1].Inbounds.sort(key = lambda x: x.EarliestArrivalTime) + 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 @@ -99,20 +95,24 @@ class RecedingHorizonControl: def optimizationRelevantInbounds(self): # no new inbounds if len(self.Windows) <= self.FreezedIndex: - return None + return None, None inbounds = [] + 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(self.FreezedIndex + 1, min(len(self.Windows), self.FreezedIndex + 1 + self.Configuration.WindowOverlap)): + for i in range(0, len(self.Windows)): + if None == earliestArrivalTime: + earliestArrivalTime = self.Windows[i].StartTime for inbound in self.Windows[i].Inbounds: inbounds.append(inbound) # check if we found relevant inbounds if 0 != len(inbounds): - return inbounds + return inbounds, earliestArrivalTime else: - return None + return None, None def cleanupWindows(self): currentUtc = dt.utcfromtimestamp(int(time.time())).replace(tzinfo = pytz.UTC) diff --git a/aman/sys/Worker.py b/aman/sys/Worker.py index fa079d1..3779dbe 100644 --- a/aman/sys/Worker.py +++ b/aman/sys/Worker.py @@ -105,19 +105,19 @@ class Worker(Thread): print('FCFS run:') for window in self.RecedingHorizonControl.Windows: for inbound in window.Inbounds: - print(' ' + inbound.Report.aircraft.callsign + ': ' + str(inbound.EstimatedArrivalTime) + '; ' + str(inbound.EarliestArrivalTime)) - - # get the last landing aircrafts per runway before the RHC stage to check for constraints - # this is required to handle the overlap between windows - preceedingInbounds = {} - for runway in self.sequencingConfiguration.ActiveArrivalRunways: - inbound = self.RecedingHorizonControl.lastFixedInboundOnRunway(runway.Runway.Name) - if None != inbound: - preceedingInbounds[runway.Runway.Name] = inbound + print(' ' + inbound.Report.aircraft.callsign + ': ' + str(inbound.InitialArrivalTime) + '; ' + str(inbound.EarliestArrivalTime)) # search the ACO relevant aircrafts - relevantInbounds = self.RecedingHorizonControl.optimizationRelevantInbounds() + relevantInbounds, earliestArrivalTime = self.RecedingHorizonControl.optimizationRelevantInbounds() if None != relevantInbounds: + # get the last landing aircrafts per runway before the RHC stage to check for constraints + # this is required to handle the overlap between windows + preceedingInbounds = {} + for runway in self.sequencingConfiguration.ActiveArrivalRunways: + inbound = self.RecedingHorizonControl.lastFixedInboundOnRunway(runway.Runway.Name) + if None != inbound: + preceedingInbounds[runway.Runway.Name] = inbound + print('Relevant inbounds: ' + str(len(relevantInbounds))) # configure the ACO run diff --git a/aman/types/Inbound.py b/aman/types/Inbound.py index a43200e..de63df5 100644 --- a/aman/types/Inbound.py +++ b/aman/types/Inbound.py @@ -32,7 +32,7 @@ class Inbound: self.ReportTime = datetime.strptime(report.reportTime + '+0000', '%Y%m%d%H%M%S%z').replace(tzinfo = pytz.UTC) self.InitialArrivalTime = None self.EarliestArrivalTime = None - self.EstimatedArrivalTime = None + self.PlannedArrivalTime = None self.EstimatedStarEntryTime = None self.PlannedRunway = None self.PlannedStar = None @@ -67,9 +67,8 @@ class Inbound: self.EstimatedStarEntryTime = self.ReportTime + self.ArrivalCandidates[candidate].FlightTimeUntilIaf self.PlannedStar = self.ArrivalCandidates[candidate].Star - self.EstimatedArrivalTime = self.InitialArrivalTime if None != self.PlannedStar: - for runway in navData.Runways[self.Report.destination]: + for runway in navData.Runways[self.Report.destination.upper()]: if runway.Name == self.PlannedStar.Runway: self.PlannedRunway = runway break