Worker.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. from threading import Thread, Lock
  3. import time
  4. from aman.com import Weather
  5. from aman.config.Airport import Airport
  6. from aman.sys.aco.Configuration import Configuration
  7. from aman.sys.WeatherModel import WeatherModel
  8. from aman.sys.RecedingHorizonControl import RecedingHorizonControl
  9. from aman.types.Inbound import Inbound
  10. from aman.types.PerformanceData import PerformanceData
  11. class Worker(Thread):
  12. def __init__(self):
  13. Thread.__init__(self)
  14. self.stopThread = None
  15. self.icao = None
  16. self.configuration = None
  17. self.arrivalRoutes = None
  18. self.performanceData = None
  19. self.updateLock = None
  20. self.reportQueue = {}
  21. self.weatherModel = None
  22. self.RecedingHorizonControl = None
  23. def __del__(self):
  24. self.release()
  25. def acquire(self, icao : str, configuration : Airport, weather : Weather, performance : PerformanceData):
  26. self.stopThread = None
  27. self.icao = icao
  28. self.configuration = configuration
  29. self.sequencingConfiguration = self.configuration.DefaultSequencing
  30. self.performanceData = performance
  31. self.arrivalRoutes = configuration.GngData.arrivalRoutes
  32. self.updateLock = Lock()
  33. self.reportQueue = {}
  34. self.weatherModel = WeatherModel(self.configuration.GaforId, weather)
  35. self.RecedingHorizonControl = RecedingHorizonControl(self.configuration.RecedingHorizonControl)
  36. self.start()
  37. def acquireLock(self):
  38. if None != self.updateLock:
  39. self.updateLock.acquire()
  40. def release(self):
  41. self.stopThread = True
  42. self.join()
  43. def releaseLock(self):
  44. if None != self.updateLock:
  45. self.updateLock.release()
  46. def run(self):
  47. counter = 0
  48. while None == self.stopThread:
  49. time.sleep(1)
  50. counter += 1
  51. if 0 != (counter % 10):
  52. continue
  53. self.acquireLock()
  54. # perform some book-keeping
  55. self.RecedingHorizonControl.cleanupWindows()
  56. # update the aircraft information in RHC
  57. for callsign in self.reportQueue:
  58. report = self.reportQueue[callsign]
  59. if 0 != report.distanceToIAF and '' != report.initialApproachFix:
  60. inbound = Inbound(report, self.sequencingConfiguration, self.configuration.GngData, self.performanceData, self.weatherModel)
  61. if None != inbound.PlannedRunway and None != inbound.PlannedStar:
  62. self.RecedingHorizonControl.update(inbound)
  63. else:
  64. print('Unable to find all data of ' + report.aircraft.callsign)
  65. self.reportQueue.clear()
  66. if 0 != len(self.RecedingHorizonControl.Windows):
  67. print('FCFS run:')
  68. for window in self.RecedingHorizonControl.Windows:
  69. for inbound in window.Inbounds:
  70. print(' ' + inbound.Report.aircraft.callsign + ': ' + str(inbound.EstimatedArrivalTime))
  71. # get the last landing aircrafts per runway before the RHC stage to check for constraints
  72. # this is required to handle the overlap between windows
  73. preceedingInbounds = {}
  74. for runway in self.sequencingConfiguration.ActiveArrivalRunways:
  75. inbound = self.RecedingHorizonControl.lastFixedInboundOnRunway(runway.Runway.name)
  76. if None != inbound:
  77. preceedingInbounds[runway.Runway.name] = inbound
  78. # search the ACO relevant aircrafts
  79. relevantInbounds = self.RecedingHorizonControl.optimizationRelevantInbounds()
  80. if None != relevantInbounds:
  81. print('Relevant inbounds: ' + str(len(relevantInbounds)))
  82. # configure the ACO run
  83. acoConfig = Configuration(self.sequencingConfiguration, 5 * len(relevantInbounds), 5 * len(relevantInbounds))
  84. if 0 != len(preceedingInbounds):
  85. acoConfig.PreceedingInbounds = preceedingInbounds
  86. acoConfig.Inbounds = relevantInbounds
  87. # TODO perform the ACO run
  88. # TODO update the RHC stages based on the ACO run result
  89. else:
  90. print('No relevant inbounds found for the optimization in ' + self.icao)
  91. self.releaseLock()