Worker.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #!/usr/bin/env python
  2. from threading import Thread, Lock
  3. import sys
  4. import time
  5. from aman.com import Weather
  6. from aman.com.Euroscope import Euroscope
  7. from aman.config.Airport import Airport
  8. from aman.config.AirportSequencing import AirportSequencing
  9. from aman.sys.aco.Colony import Colony
  10. from aman.sys.aco.Configuration import Configuration
  11. from aman.sys.aco.Node import Node
  12. from aman.sys.WeatherModel import WeatherModel
  13. from aman.sys.RecedingHorizonControl import RecedingHorizonControl
  14. from aman.types.Inbound import Inbound
  15. from aman.types.PerformanceData import PerformanceData
  16. class Worker(Thread):
  17. def __init__(self, icao : str, configuration : Airport, weather : Weather,
  18. performance : PerformanceData, euroscope : Euroscope):
  19. Thread.__init__(self)
  20. self.StopThread = None
  21. self.Icao = icao
  22. self.Configuration = configuration
  23. self.SequencingConfiguration = configuration.DefaultSequencing
  24. self.PerformanceData = performance
  25. self.UpdateLock = Lock()
  26. self.ReportQueue = {}
  27. if None != weather:
  28. self.WeatherModel = WeatherModel(configuration.GaforId, weather)
  29. else:
  30. self.WeatherModel = WeatherModel(0, None)
  31. self.RecedingHorizonControl = RecedingHorizonControl(configuration.RecedingHorizonControl)
  32. self.Euroscope = euroscope
  33. # merge the constraint information with the GNG information
  34. for runway in self.Configuration.GngData.ArrivalRoutes:
  35. for star in self.Configuration.GngData.ArrivalRoutes[runway]:
  36. for name in self.Configuration.ArrivalRouteConstraints:
  37. if name == star.Name:
  38. for constraint in self.Configuration.ArrivalRouteConstraints[name]:
  39. foundWaypoint = False
  40. for waypoint in star.Route:
  41. if constraint.Name == waypoint.Name:
  42. waypoint.Altitude = constraint.Altitude
  43. waypoint.Speed = constraint.Speed
  44. waypoint.BaseTurn = constraint.BaseTurn
  45. waypoint.FinalTurn = constraint.FinalTurn
  46. foundWaypoint = True
  47. break
  48. if False == foundWaypoint:
  49. sys.stderr.write('Unable to find ' + constraint.Name + ' in ' + name)
  50. sys.exit(-1)
  51. break
  52. self.setDaemon(True)
  53. self.start()
  54. def acquireLock(self):
  55. if None != self.UpdateLock:
  56. self.UpdateLock.acquire()
  57. def releaseLock(self):
  58. if None != self.UpdateLock:
  59. self.UpdateLock.release()
  60. def run(self):
  61. counter = 0
  62. while None == self.StopThread:
  63. time.sleep(1)
  64. counter += 1
  65. if 0 != (counter % 60):
  66. continue
  67. self.acquireLock()
  68. # perform some book-keeping
  69. self.RecedingHorizonControl.cleanupWindows()
  70. # update the aircraft information in RHC
  71. for callsign in self.ReportQueue:
  72. report = self.ReportQueue[callsign]
  73. if '' != report.initialApproachFix:
  74. inbound = Inbound(report, self.PerformanceData)
  75. Node(inbound, inbound.ReportTime, self.WeatherModel, self.Configuration, self.SequencingConfiguration)
  76. if None != inbound.EnrouteArrivalTime:
  77. self.RecedingHorizonControl.updateReport(inbound)
  78. else:
  79. print('Unable to find all data of ' + report.aircraft.callsign)
  80. self.ReportQueue.clear()
  81. # search the ACO relevant aircrafts
  82. relevantInbounds, earliestArrivalTime = self.RecedingHorizonControl.optimizationRelevantInbounds()
  83. if None != relevantInbounds:
  84. start = time.process_time()
  85. # get the last landing aircrafts per runway before the RHC stage to check for constraints
  86. # this is required to handle the overlap between windows
  87. runways, iafs = self.RecedingHorizonControl.latestFixedInbounds(self.Configuration, self.SequencingConfiguration)
  88. # configure the ACO run
  89. acoConfig = Configuration(constraints = self.SequencingConfiguration, config = self.Configuration,
  90. earliest = earliestArrivalTime, weather = self.WeatherModel,
  91. preceedingRunways = runways, preceedingIafs = iafs,
  92. ants = 5 * len(relevantInbounds), generations = 5 * len(relevantInbounds))
  93. # run the optimizer outside the locking functions
  94. self.releaseLock()
  95. # perform the ACO run
  96. aco = Colony(relevantInbounds, acoConfig)
  97. aco.optimize()
  98. self.acquireLock()
  99. if None != aco.Result:
  100. for node in aco.Result:
  101. self.RecedingHorizonControl.resequenceInbound(node.Inbound)
  102. # measure the exuction time of the overall optimization process
  103. executionTime = time.process_time() - start
  104. if 60.0 <= executionTime:
  105. print('Optimized ' + str(len(aco.Result)) + ' inbounds in ' + str(executionTime) + ' seconds')
  106. self.releaseLock()
  107. def inboundSequence(self):
  108. self.acquireLock()
  109. sequence = self.RecedingHorizonControl.sequence()
  110. self.releaseLock()
  111. return sequence
  112. def configure(self, configuration : AirportSequencing):
  113. self.acquireLock()
  114. self.SequencingConfiguration = configuration
  115. self.releaseLock()