123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- #!/usr/bin/env python
- from threading import Thread, Lock
- import sys
- import time
- from aman.com import Weather
- from aman.com.Euroscope import Euroscope
- from aman.config.Airport import Airport
- from aman.config.AirportSequencing import AirportSequencing
- from aman.sys.aco.Colony import Colony
- from aman.sys.aco.Configuration import Configuration
- from aman.sys.aco.Node import Node
- 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, icao : str, configuration : Airport, weather : Weather,
- performance : PerformanceData, euroscope : Euroscope):
- Thread.__init__(self)
- self.StopThread = None
- self.Icao = icao
- self.Configuration = configuration
- self.SequencingConfiguration = configuration.DefaultSequencing
- self.PerformanceData = performance
- self.UpdateLock = Lock()
- self.ReportQueue = {}
- if None != weather:
- self.WeatherModel = WeatherModel(configuration.GaforId, weather)
- else:
- self.WeatherModel = WeatherModel(0, None)
- self.RecedingHorizonControl = RecedingHorizonControl(configuration.RecedingHorizonControl)
- self.Euroscope = euroscope
- # merge the constraint information with the GNG information
- for runway in self.Configuration.GngData.ArrivalRoutes:
- for star in self.Configuration.GngData.ArrivalRoutes[runway]:
- for name in self.Configuration.ArrivalRouteConstraints:
- if name == star.Name:
- for constraint in self.Configuration.ArrivalRouteConstraints[name]:
- foundWaypoint = False
- for waypoint in star.Route:
- if constraint.Name == waypoint.Name:
- waypoint.Altitude = constraint.Altitude
- waypoint.Speed = constraint.Speed
- waypoint.BaseTurn = constraint.BaseTurn
- waypoint.FinalTurn = constraint.FinalTurn
- foundWaypoint = True
- break
- if False == foundWaypoint:
- sys.stderr.write('Unable to find ' + constraint.Name + ' in ' + name)
- sys.exit(-1)
- break
- self.setDaemon(True)
- self.start()
- def acquireLock(self):
- if None != self.UpdateLock:
- self.UpdateLock.acquire()
- 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 % 60):
- 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 '' != report.initialApproachFix:
- inbound = Inbound(report, self.PerformanceData)
- Node(inbound, inbound.ReportTime, self.WeatherModel, self.Configuration, self.SequencingConfiguration)
- if None != inbound.EnrouteArrivalTime:
- self.RecedingHorizonControl.updateReport(inbound)
- else:
- print('Unable to find all data of ' + report.aircraft.callsign)
- self.ReportQueue.clear()
- # search the ACO relevant aircrafts
- relevantInbounds, earliestArrivalTime = self.RecedingHorizonControl.optimizationRelevantInbounds()
- if None != relevantInbounds:
- start = time.process_time()
- # get the last landing aircrafts per runway before the RHC stage to check for constraints
- # this is required to handle the overlap between windows
- runways, iafs = self.RecedingHorizonControl.latestFixedInbounds(self.Configuration, self.SequencingConfiguration)
- # configure the ACO run
- acoConfig = Configuration(constraints = self.SequencingConfiguration, config = self.Configuration,
- earliest = earliestArrivalTime, weather = self.WeatherModel,
- preceedingRunways = runways, preceedingIafs = iafs,
- ants = 5 * len(relevantInbounds), generations = 5 * len(relevantInbounds))
- # run the optimizer outside the locking functions
- self.releaseLock()
- # perform the ACO run
- aco = Colony(relevantInbounds, acoConfig)
- aco.optimize()
- self.acquireLock()
- if None != aco.Result:
- for node in aco.Result:
- self.RecedingHorizonControl.resequenceInbound(node.Inbound)
- # measure the exuction time of the overall optimization process
- executionTime = time.process_time() - start
- if 60.0 <= executionTime:
- print('Optimized ' + str(len(aco.Result)) + ' inbounds in ' + str(executionTime) + ' seconds')
- self.releaseLock()
- def inboundSequence(self):
- self.acquireLock()
- sequence = self.RecedingHorizonControl.sequence()
- self.releaseLock()
- return sequence
- def configure(self, configuration : AirportSequencing):
- self.acquireLock()
- self.SequencingConfiguration = configuration
- self.releaseLock()
|