Worker.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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.config.Airport import Airport
  7. from aman.sys.aco.Configuration import Configuration
  8. from aman.sys.WeatherModel import WeatherModel
  9. from aman.sys.RecedingHorizonControl import RecedingHorizonControl
  10. from aman.types.Inbound import Inbound
  11. from aman.types.PerformanceData import PerformanceData
  12. class Worker(Thread):
  13. def __init__(self):
  14. Thread.__init__(self)
  15. self.StopThread = None
  16. self.Icao = None
  17. self.Configuration = 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 = configuration.DefaultSequencing
  30. self.PerformanceData = performance
  31. self.UpdateLock = Lock()
  32. self.ReportQueue = {}
  33. self.WeatherModel = WeatherModel(configuration.GaforId, weather)
  34. self.RecedingHorizonControl = RecedingHorizonControl(configuration.RecedingHorizonControl)
  35. # merge the constraint information with the GNG information
  36. for runway in self.Configuration.GngData.ArrivalRoutes:
  37. for star in self.Configuration.GngData.ArrivalRoutes[runway]:
  38. for name in self.Configuration.ArrivalRouteConstraints:
  39. if name == star.Name:
  40. for constraint in self.Configuration.ArrivalRouteConstraints[name]:
  41. foundWaypoint = False
  42. for waypoint in star.Route:
  43. if constraint.Name == waypoint.Name:
  44. waypoint.Altitude = constraint.Altitude
  45. waypoint.Speed = constraint.Speed
  46. waypoint.BaseTurn = constraint.BaseTurn
  47. waypoint.FinalTurn = constraint.FinalTurn
  48. foundWaypoint = True
  49. break
  50. if False == foundWaypoint:
  51. sys.stderr.write('Unable to find ' + constraint.Name + ' in ' + name)
  52. sys.exit(-1)
  53. break
  54. self.start()
  55. def acquireLock(self):
  56. if None != self.UpdateLock:
  57. self.UpdateLock.acquire()
  58. def release(self):
  59. self.StopThread = True
  60. self.join()
  61. def releaseLock(self):
  62. if None != self.UpdateLock:
  63. self.UpdateLock.release()
  64. def run(self):
  65. counter = 0
  66. while None == self.StopThread:
  67. time.sleep(1)
  68. counter += 1
  69. if 0 != (counter % 10):
  70. continue
  71. self.acquireLock()
  72. # perform some book-keeping
  73. self.RecedingHorizonControl.cleanupWindows()
  74. # update the aircraft information in RHC
  75. for callsign in self.ReportQueue:
  76. report = self.ReportQueue[callsign]
  77. if 0 != report.distanceToIAF and '' != report.initialApproachFix:
  78. inbound = Inbound(report, self.sequencingConfiguration, self.Configuration.GngData, self.PerformanceData, self.WeatherModel)
  79. if None != inbound.PlannedRunway and None != inbound.PlannedStar:
  80. self.RecedingHorizonControl.update(inbound)
  81. else:
  82. print('Unable to find all data of ' + report.aircraft.callsign)
  83. self.ReportQueue.clear()
  84. if 0 != len(self.RecedingHorizonControl.Windows):
  85. print('FCFS run:')
  86. for window in self.RecedingHorizonControl.Windows:
  87. for inbound in window.Inbounds:
  88. print(' ' + inbound.Report.aircraft.callsign + ': ' + str(inbound.EstimatedArrivalTime) + '; ' + str(inbound.EarliestArrivalTime))
  89. # get the last landing aircrafts per runway before the RHC stage to check for constraints
  90. # this is required to handle the overlap between windows
  91. preceedingInbounds = {}
  92. for runway in self.sequencingConfiguration.ActiveArrivalRunways:
  93. inbound = self.RecedingHorizonControl.lastFixedInboundOnRunway(runway.Runway.Name)
  94. if None != inbound:
  95. preceedingInbounds[runway.Runway.Name] = inbound
  96. # search the ACO relevant aircrafts
  97. relevantInbounds = self.RecedingHorizonControl.optimizationRelevantInbounds()
  98. if None != relevantInbounds:
  99. print('Relevant inbounds: ' + str(len(relevantInbounds)))
  100. # configure the ACO run
  101. acoConfig = Configuration(self.sequencingConfiguration, 5 * len(relevantInbounds), 5 * len(relevantInbounds))
  102. if 0 != len(preceedingInbounds):
  103. acoConfig.PreceedingInbounds = preceedingInbounds
  104. acoConfig.Inbounds = relevantInbounds
  105. # TODO perform the ACO run
  106. # TODO update the RHC stages based on the ACO run result
  107. else:
  108. print('No relevant inbounds found for the optimization in ' + self.Icao)
  109. self.releaseLock()