|
@@ -7,7 +7,10 @@ from datetime import timedelta
|
|
|
|
|
|
import pytz
|
|
|
|
|
|
+from aman.config.Airport import Airport
|
|
|
+from aman.config.AirportSequencing import AirportSequencing
|
|
|
from aman.config.RHC import RHC
|
|
|
+from aman.sys.aco.Node import Node
|
|
|
from aman.sys.RecedingHorizonWindow import RecedingHorizonWindow
|
|
|
from aman.types.Inbound import Inbound
|
|
|
|
|
@@ -106,19 +109,56 @@ class RecedingHorizonControl:
|
|
|
inbound.FixedSequence = index < self.FreezedIndex
|
|
|
self.Windows[index].Inbounds.sort(key = lambda x: x.PlannedArrivalTime if None != x.PlannedArrivalTime else x.EnrouteArrivalTime)
|
|
|
|
|
|
- def lastFixedInboundOnRunway(self, runway : str):
|
|
|
- # no inbounds available
|
|
|
+ def latestFixedInbounds(self, configuration : Airport, sequenceConfiguration : AirportSequencing):
|
|
|
if 0 == len(self.Windows):
|
|
|
- return None
|
|
|
+ return None, None
|
|
|
+
|
|
|
+ # create the runway tree
|
|
|
+ runwayInbounds = {}
|
|
|
+ for runway in sequenceConfiguration.ActiveArrivalRunways:
|
|
|
+ runwayInbounds[runway.Runway.Name] = None
|
|
|
+
|
|
|
+ # create the IAF tree
|
|
|
+ iafInbounds = {}
|
|
|
+ for star in configuration.ArrivalRouteConstraints:
|
|
|
+ altitude = configuration.ArrivalRouteConstraints[star][0].Altitude
|
|
|
+ iaf = configuration.ArrivalRouteConstraints[star][0].Name
|
|
|
|
|
|
- # search from the back to the front to find the last inbound
|
|
|
+ if iaf not in iafInbounds:
|
|
|
+ iafInbounds[iaf] = { altitude : None }
|
|
|
+ elif altitude not in iafInbounds[iaf]:
|
|
|
+ iafInbounds[iaf][altitude] = None
|
|
|
+
|
|
|
+ # associate the inbounds to the runways and the IAFs
|
|
|
for i in range(min(self.FreezedIndex, len(self.Windows)), -1, -1):
|
|
|
for inbound in self.Windows[i].Inbounds:
|
|
|
- if None != inbound.PlannedRunway and runway == inbound.PlannedRunway.Name:
|
|
|
- return inbound
|
|
|
-
|
|
|
- # no inbound found
|
|
|
- return None
|
|
|
+ if None == inbound.PlannedRunway or None == inbound.PlannedArrivalRoute:
|
|
|
+ continue
|
|
|
+
|
|
|
+ node = Node(inbound, None, None, None, None)
|
|
|
+ node.EstimatedTouchdownTime = inbound.PlannedArrivalTime
|
|
|
+ node.EstimatedIafAltitude = inbound.PlannedArrivalRoute[0].Altitude
|
|
|
+ node.EstimatedIafTime = inbound.PlannedArrivalRoute[0].PTA
|
|
|
+
|
|
|
+ if inbound.PlannedRunway.Name in runwayInbounds:
|
|
|
+ if None == runwayInbounds[inbound.PlannedRunway.Name] or runwayInbounds[inbound.PlannedRunway.Name].EstimatedTouchdownTime < node.EstimatedTouchdownTime:
|
|
|
+ runwayInbounds[inbound.PlannedRunway.Name] = node
|
|
|
+
|
|
|
+ if inbound.PlannedArrivalRoute[0].Name in iafInbounds:
|
|
|
+ delta = 100000.0
|
|
|
+ targetLevel = None
|
|
|
+ for level in iafInbounds[inbound.PlannedArrivalRoute[0].Name]:
|
|
|
+ difference = abs(level - inbound.PlannedArrivalRoute[0].Altitude)
|
|
|
+ if difference < delta:
|
|
|
+ delta = difference
|
|
|
+ targetLevel = level
|
|
|
+
|
|
|
+ if None == iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel]:
|
|
|
+ iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel] = Node
|
|
|
+ elif iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel].EstimatedIafTime < node.EstimatedIafTime:
|
|
|
+ iafInbounds[inbound.PlannedArrivalRoute[0].Name][targetLevel] = Node
|
|
|
+
|
|
|
+ return runwayInbounds, iafInbounds
|
|
|
|
|
|
def optimizationRelevantInbounds(self):
|
|
|
# no new inbounds
|