123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- #!/usr/bin/env python
- from threading import Thread, Lock
- import time
- from aman.com import Weather
- from aman.config.Airport import Airport
- from aman.sys.aco.Configuration import Configuration
- from aman.sys.WeatherModel import WeatherModel
- from aman.sys.RecedingHorizonControl import RecedingHorizonControl
- from aman.types.Inbound import Inbound
- from aman.types.PerformanceData import PerformanceData
- class Worker(Thread):
- def __init__(self):
- Thread.__init__(self)
- self.StopThread = None
- self.Icao = None
- self.Configuration = None
- self.PerformanceData = None
- self.UpdateLock = None
- self.ReportQueue = {}
- self.WeatherModel = None
- self.RecedingHorizonControl = None
- def __del__(self):
- self.release()
- def acquire(self, icao : str, configuration : Airport, weather : Weather, performance : PerformanceData):
- self.StopThread = None
- self.Icao = icao
- self.Configuration = configuration
- self.sequencingConfiguration = configuration.DefaultSequencing
- self.PerformanceData = performance
- self.UpdateLock = Lock()
- self.ReportQueue = {}
- self.WeatherModel = WeatherModel(configuration.GaforId, weather)
- self.RecedingHorizonControl = RecedingHorizonControl(configuration.RecedingHorizonControl)
- self.start()
- def acquireLock(self):
- if None != self.UpdateLock:
- self.UpdateLock.acquire()
- def release(self):
- self.StopThread = True
- self.join()
- def releaseLock(self):
- if None != self.UpdateLock:
- self.UpdateLock.release()
- def run(self):
- counter = 0
- while None == self.StopThread:
- time.sleep(1)
- counter += 1
- if 0 != (counter % 10):
- continue
- self.acquireLock()
- # perform some book-keeping
- self.RecedingHorizonControl.cleanupWindows()
- # update the aircraft information in RHC
- for callsign in self.ReportQueue:
- report = self.ReportQueue[callsign]
- if 0 != report.distanceToIAF and '' != report.initialApproachFix:
- inbound = Inbound(report, self.sequencingConfiguration, self.Configuration.GngData, self.PerformanceData, self.WeatherModel)
- if None != inbound.PlannedRunway and None != inbound.PlannedStar:
- self.RecedingHorizonControl.update(inbound)
- else:
- print('Unable to find all data of ' + report.aircraft.callsign)
- self.ReportQueue.clear()
- if 0 != len(self.RecedingHorizonControl.Windows):
- print('FCFS run:')
- for window in self.RecedingHorizonControl.Windows:
- for inbound in window.Inbounds:
- print(' ' + inbound.Report.aircraft.callsign + ': ' + str(inbound.EstimatedArrivalTime))
- # 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
- # search the ACO relevant aircrafts
- relevantInbounds = self.RecedingHorizonControl.optimizationRelevantInbounds()
- if None != relevantInbounds:
- print('Relevant inbounds: ' + str(len(relevantInbounds)))
- # configure the ACO run
- acoConfig = Configuration(self.sequencingConfiguration, 5 * len(relevantInbounds), 5 * len(relevantInbounds))
- if 0 != len(preceedingInbounds):
- acoConfig.PreceedingInbounds = preceedingInbounds
- acoConfig.Inbounds = relevantInbounds
- # TODO perform the ACO run
- # TODO update the RHC stages based on the ACO run result
- else:
- print('No relevant inbounds found for the optimization in ' + self.Icao)
- self.releaseLock()
|