source: src/mlx/gates.py

python3
Last change on this file was 1158:7fea55a5d04c, checked in by István Váradi <ivaradi@…>, 3 weeks ago

Updated the taxi-through properties of the gates based on the airport data (re #386).

File size: 11.8 KB
RevLine 
[619]1#--------------------------------------------------------------------------------------
2
3## @package mlx.gates
4#
5# The module to handle the LHBP gate information.
6#
7
8#--------------------------------------------------------------------------------------
9
10class Gate(object):
11 """Information about a gate."""
12 def __init__(self, number, terminal, type,
[1154]13 availableFn = None, taxiThrough = False,
14 maxSpan = 0.0, maxLength = 0.0):
[619]15 """Construct the gate with the given information.
16
17 number is the gate's number as a string (as it can contain letters).
18 terminal is the terminal the gate belongs to (not used currently).
19 type is the gate's type: G for gate, S for stand.
20 availableFn is a function that can determine if the gate is available based on
21 the statuses of other gates. Its arguments are:
22 - a collection of the gates, and
23 - a set of occupied gate numbers."""
[1154]24 self.number = number
25 self.terminal = terminal
26 self.type = type
[619]27 self._availableFn = availableFn
[1154]28 self.taxiThrough = taxiThrough
29 self.maxSpan = maxSpan
30 self.maxLength = maxLength
[619]31
[1154]32 def isAvailable(self, plane, gates, occupiedGateNumbers):
33 """Determine if this gate is available for the given plane and the
34 given the set of gates and occupied gate numbers."""
35 if self.number in occupiedGateNumbers:
[619]36 return False
[1154]37 if self._availableFn is None or \
38 self._availableFn(gates, occupiedGateNumbers):
39 return plane is None or \
[1155]40 ((self.maxSpan<0.1 or plane.wingSpan <= self.maxSpan) and
[1156]41 (self.maxLength<0.1 or plane.fuselageLength <= self.maxLength) and
42 (not plane.hasStairs or self.type!="G"))
[1154]43 else:
44 return False
[619]45
46#--------------------------------------------------------------------------------------
47
48class Gates(object):
49 """A collection of gates."""
50 # Display info type: a gate (number)
51 DISPLAY_GATE=1
52
53 # Display info type: a space
54 DISPLAY_SPACE=2
55
56 # Display info type: a new column
57 DISPLAY_NEW_COLUMN=3
58
59 def __init__(self):
60 """Construct the gate collection."""
61 self._gates = []
62 self._displayInfos = []
63 self._numColumns = 1
64 self._numRows = 0
65 self._numRowsInColumn = 0
66
67 @property
68 def gates(self):
69 """Get an iterator over the gates."""
70 return iter(self._gates)
71
72 @property
73 def displayInfos(self):
74 """Get an iterator over the display info tuples.
75
76 Each tuple consists of
77 - a type (one of the DISPLAY_XXX constants), and
78 - an additional data (the gate for DISPLAY_GATE, None for others)."""
79 return iter(self._displayInfos)
80
81 @property
82 def numRows(self):
83 """Get the number of rows."""
84 return self._numRows
85
86 @property
87 def numColumns(self):
88 """Get the number of columns."""
89 return self._numColumns
90
91 def add(self, gate):
92 """Add a gate to the collection."""
93 self._gates.append(gate)
94 self._displayInfos.append((Gates.DISPLAY_GATE, gate))
95 self._addRow()
96
[1105]97 def find(self, gateNumber):
98 """Find a gate by its number."""
99 for gate in self._gates:
100 if gate.number == gateNumber:
101 return gate
102
[619]103 def addSpace(self):
104 """Add a space between subsequent gates."""
105 self._displayInfos.append((Gates.DISPLAY_SPACE, None))
106 self._addRow()
107
108 def addNewColumn(self):
109 """Start a new column of gates."""
110 self._displayInfos.append((Gates.DISPLAY_NEW_COLUMN, None))
111 self._numRowsInColumn = 0
112 self._numColumns += 1
113
[1154]114 def merge(self, otherGates):
115 """Merge the information from the given gate list (retrieved from the
116 MAVA server) into this gate list."""
117 for otherGate in otherGates.gates:
118 gate = self.find(otherGate.number)
119 if gate is None:
120 print("Received data for gate %s, but it does not exist locally!" %
121 (otherGate.number,))
122 else:
123 if gate.terminal != otherGate.terminal:
124 print("The terminal for gate %s is received as: %s" %
125 (gate.number, otherGate.terminal))
126 gate.terminal = otherGate.terminal
127 if gate.type != otherGate.type:
128 print("The type for gate %s is received as: %s" %
129 (gate.number, otherGate.type))
130 gate.type = otherGate.type
131
132 gate.maxSpan = otherGate.maxSpan
133 gate.maxLength = otherGate.maxLength
134
135 for gate in self.gates:
136 if gate.maxSpan==0.0 or gate.maxLength==0.0:
137 print("Gate %s has no maximal dimensions from the database" %
138 (gate.number,))
139
[619]140 def _addRow(self):
141 """Add a new row."""
142 self._numRowsInColumn += 1
143 if self._numRowsInColumn > self._numRows:
144 self._numRows = self._numRowsInColumn
145
146#--------------------------------------------------------------------------------------
147
148def availableIf(occupiedGateNumbers, othersAvailable = []):
149 """Determine if a gate is available.
150
151 othersAvailable is a list of numbers of gates, that must be available so
152 that the one we are considering is available."""
153 for otherNumber in othersAvailable:
154 if otherNumber in occupiedGateNumbers:
155 return False
156 return True
157
158#--------------------------------------------------------------------------------------
159
[1151]160def getAvailableIf(othersAvailable = []):
[619]161 """Get a function that determines if a gate is available based on the
162 statuses of other gates."""
163 return lambda gates, occupiedGateNumbers: availableIf(occupiedGateNumbers,
164 othersAvailable =
165 othersAvailable)
166
167#--------------------------------------------------------------------------------------
168
169# The gates at LHBP
170lhbpGates = Gates()
171
[1158]172lhbpGates.add(Gate("R101", "1", "S", taxiThrough = True))
[1151]173lhbpGates.add(Gate("R102", "1", "S"))
174lhbpGates.add(Gate("R103", "1", "S"))
175lhbpGates.add(Gate("R104", "1", "S",
176 availableFn = getAvailableIf(othersAvailable = ["R105"])))
177lhbpGates.add(Gate("R105", "1", "S",
178 availableFn = getAvailableIf(othersAvailable = ["R104", "R106"])))
179lhbpGates.add(Gate("R106", "1", "S",
180 availableFn = getAvailableIf(othersAvailable = ["R105", "R108"])))
181lhbpGates.add(Gate("R107", "1", "S",
182 availableFn = getAvailableIf(othersAvailable = ["R108"])))
183lhbpGates.add(Gate("R108", "1", "S",
184 availableFn = getAvailableIf(othersAvailable = ["R106", "R107"])))
185
[619]186lhbpGates.addSpace()
[1151]187lhbpGates.add(Gate("R110", "1", "S",
188 availableFn = getAvailableIf(othersAvailable = ["R111"])))
189lhbpGates.add(Gate("R111", "1", "S",
190 availableFn = getAvailableIf(othersAvailable = ["R110", "R112"])))
191lhbpGates.add(Gate("R112", "1", "S",
192 availableFn = getAvailableIf(othersAvailable = ["R111"])))
193lhbpGates.add(Gate("R113", "1", "S",
194 availableFn = getAvailableIf(othersAvailable = ["R112", "R114"])))
195lhbpGates.add(Gate("R114", "1", "S",
196 availableFn = getAvailableIf(othersAvailable = ["R113"])))
197lhbpGates.add(Gate("R115", "1", "S"))
198lhbpGates.add(Gate("R116", "1", "S",
[1158]199 availableFn = getAvailableIf(othersAvailable = ["R117"]),
200 taxiThrough = True))
[1151]201lhbpGates.add(Gate("R117", "1", "S",
202 availableFn = getAvailableIf(othersAvailable = ["R116", "R117A"])))
203lhbpGates.add(Gate("R117A", "1", "S",
204 availableFn = getAvailableIf(othersAvailable = ["R116", "R117"])))
205lhbpGates.addNewColumn()
206
207lhbpGates.add(Gate("G150", "1", "S"))
208lhbpGates.add(Gate("G151", "1", "S"))
209lhbpGates.add(Gate("G152", "1", "S"))
210lhbpGates.add(Gate("G153", "1", "S"))
211lhbpGates.add(Gate("G154", "1", "S"))
212lhbpGates.add(Gate("G155", "1", "S"))
213
214lhbpGates.addSpace()
[1158]215lhbpGates.add(Gate("G170", "1", "S", taxiThrough = True))
216lhbpGates.add(Gate("G171", "1", "S", taxiThrough = True))
217lhbpGates.add(Gate("G172", "1", "S", taxiThrough = True))
[1151]218lhbpGates.addNewColumn()
[619]219
220lhbpGates.add(Gate("31", "2B", "G"))
221lhbpGates.add(Gate("32", "2B", "G"))
222lhbpGates.add(Gate("33", "2B", "G"))
[1151]223lhbpGates.add(Gate("34", "2B", "G",
224 availableFn = getAvailableIf(othersAvailable = ["34L", "34R"])))
225lhbpGates.add(Gate("34L", "2B", "G",
226 availableFn = getAvailableIf(othersAvailable = ["34", "34R"])))
227lhbpGates.add(Gate("34R", "2B", "G",
228 availableFn = getAvailableIf(othersAvailable = ["34L", "34"])))
229lhbpGates.add(Gate("35", "2B", "G",
230 availableFn = getAvailableIf(othersAvailable = ["35L", "35R"])))
231lhbpGates.add(Gate("35L", "2B", "G",
232 availableFn = getAvailableIf(othersAvailable = ["35", "35R"])))
233lhbpGates.add(Gate("35R", "2B", "G",
234 availableFn = getAvailableIf(othersAvailable = ["35L", "35"])))
235lhbpGates.add(Gate("36", "2B", "G",
236 availableFn = getAvailableIf(othersAvailable = ["36L", "36R"])))
237lhbpGates.add(Gate("36L", "2B", "G",
238 availableFn = getAvailableIf(othersAvailable = ["36", "36R"])))
239lhbpGates.add(Gate("36R", "2B", "G",
240 availableFn = getAvailableIf(othersAvailable = ["36L", "36"])))
241lhbpGates.addSpace()
[619]242
243lhbpGates.add(Gate("37", "2B", "G"))
244lhbpGates.add(Gate("38", "2B", "G"))
[1151]245lhbpGates.add(Gate("39", "2B", "G",
246 availableFn = getAvailableIf(othersAvailable = ["37L", "37R"])))
247lhbpGates.add(Gate("39L", "2B", "G",
248 availableFn = getAvailableIf(othersAvailable = ["37", "37R"])))
249lhbpGates.add(Gate("39R", "2B", "G",
250 availableFn = getAvailableIf(othersAvailable = ["37L", "37"])))
251lhbpGates.addNewColumn()
[619]252
253lhbpGates.add(Gate("42", "2A", "G"))
254lhbpGates.add(Gate("43", "2A", "G"))
255lhbpGates.add(Gate("44", "2A", "G"))
256lhbpGates.add(Gate("45", "2A", "G"))
[1151]257lhbpGates.addSpace()
[619]258
259lhbpGates.add(Gate("R210", "2A", "S",
[1151]260 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
[1105]261 taxiThrough = True))
[619]262lhbpGates.add(Gate("R211", "2A", "S",
[1151]263 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
[1105]264 taxiThrough = True))
[619]265lhbpGates.add(Gate("R212", "2A", "S",
[1151]266 availableFn = getAvailableIf(othersAvailable = ["R212A"]),
[1105]267 taxiThrough = True))
[619]268lhbpGates.add(Gate("R212A", "2A", "S",
[1151]269 availableFn = getAvailableIf(othersAvailable = ["R210", "R211", "R212"]),
[1105]270 taxiThrough = True))
[619]271lhbpGates.addSpace()
272
273lhbpGates.add(Gate("R220", "2B", "S"))
274lhbpGates.add(Gate("R221", "2B", "S"))
275lhbpGates.add(Gate("R222", "2B", "S"))
276lhbpGates.add(Gate("R223", "2B", "S"))
277lhbpGates.addSpace()
278
[1151]279lhbpGates.add(Gate("R224", "2A", "S"))
[619]280lhbpGates.add(Gate("R225", "2A", "S"))
281lhbpGates.add(Gate("R226", "2A", "S"))
282lhbpGates.add(Gate("R227", "2A", "S"))
283lhbpGates.addNewColumn()
284
285lhbpGates.add(Gate("R270", "2A", "S"))
286lhbpGates.add(Gate("R271", "2A", "S"))
287lhbpGates.add(Gate("R272", "2A", "S"))
[1151]288lhbpGates.add(Gate("R273", "2A", "S"))
[619]289lhbpGates.add(Gate("R274", "2A", "S"))
290lhbpGates.add(Gate("R275", "2A", "S"))
291lhbpGates.add(Gate("R276", "2A", "S"))
292lhbpGates.add(Gate("R277", "2A", "S"))
293lhbpGates.add(Gate("R278", "2A", "S",
[1151]294 availableFn = getAvailableIf(othersAvailable = ["R278A"]),
[1105]295 taxiThrough = True))
[619]296lhbpGates.add(Gate("R278A", "2A", "S",
[1158]297 availableFn = getAvailableIf(othersAvailable = ["R278", "R279"])))
[619]298lhbpGates.add(Gate("R279", "2A", "S",
[1151]299 availableFn = getAvailableIf(othersAvailable = ["R278A"]),
[1105]300 taxiThrough = True))
Note: See TracBrowser for help on using the repository browser.