source: src/mlx/flight.py@ 299:cb10e55ec9b7

Last change on this file since 299:cb10e55ec9b7 was 298:24c67ec5cdca, checked in by István Váradi <ivaradi@…>, 12 years ago

Documented the non-GUI modules

File size: 11.0 KB
Line 
1
2from soundsched import SoundScheduler, ChecklistScheduler
3
4import const
5import util
6
7import threading
8
9#---------------------------------------------------------------------------------------
10
11## @package mlx.flight
12#
13# The global flight state.
14#
15# This module defines a single class, \ref Flight, which represents the flight
16# in progress.
17
18#---------------------------------------------------------------------------------------
19
20class Flight(object):
21 """The object with the global flight state.
22
23 It is also the hub for the other main objects participating in the handling of
24 the flight."""
25 def __init__(self, logger, gui):
26 """Construct the flight."""
27 self._stage = None
28 self.logger = logger
29 self._gui = gui
30
31 gui.resetFlightStatus()
32
33 self._pilotHotkeyPressed = False
34 self._checklistHotkeyPressed = False
35
36 self.flareTimeFromFS = False
37
38 self.aircraftType = None
39 self.aircraft = None
40 self.simulator = None
41
42 self.blockTimeStart = None
43 self.flightTimeStart = None
44 self.flightTimeEnd = None
45 self.blockTimeEnd = None
46
47 self._lastDistanceTime = None
48 self._previousLatitude = None
49 self._previousLongitude = None
50 self.flownDistance = 0.0
51
52 self.startFuel = None
53 self.endFuel = None
54
55 self._endCondition = threading.Condition()
56
57 self._flareStart = None
58 self._flareStartFS = None
59
60 self._tdRate = None
61
62 self._soundScheduler = SoundScheduler(self)
63 self._checklistScheduler = ChecklistScheduler(self)
64
65 @property
66 def config(self):
67 """Get the configuration."""
68 return self._gui.config
69
70 @property
71 def stage(self):
72 """Get the flight stage."""
73 return self._stage
74
75 @property
76 def loggedIn(self):
77 """Indicate if the user has logged in properly."""
78 return self._gui.loggedIn
79
80 @property
81 def entranceExam(self):
82 """Get whether an entrance exam is being performed."""
83 return self._gui.entranceExam
84
85 @property
86 def bookedFlight(self):
87 """Get the booked flight."""
88 return self._gui.bookedFlight
89
90 @property
91 def cargoWeight(self):
92 """Get the cargo weight for the flight."""
93 return self._gui.cargoWeight
94
95 @property
96 def zfw(self):
97 """Get the Zero-Fuel Weight of the flight."""
98 return self._gui.zfw
99
100 @property
101 def filedCruiseAltitude(self):
102 """Get the filed cruise altitude."""
103 return self._gui.filedCruiseAltitude
104
105 @property
106 def cruiseAltitude(self):
107 """Get the cruise altitude of the flight."""
108 return self._gui.cruiseAltitude
109
110 @property
111 def route(self):
112 """Get the route of the flight."""
113 return self._gui.route
114
115 @property
116 def departureMETAR(self):
117 """Get the departure METAR of the flight."""
118 return self._gui.departureMETAR
119
120 @property
121 def arrivalMETAR(self):
122 """Get the arrival METAR of the flight."""
123 return self._gui.arrivalMETAR
124
125 @property
126 def departureRunway(self):
127 """Get the departure runway."""
128 return self._gui.departureRunway
129
130 @property
131 def sid(self):
132 """Get the SID followed."""
133 return self._gui.sid
134
135 @property
136 def v1(self):
137 """Get the V1 speed of the flight."""
138 return self._gui.v1
139
140 @property
141 def vr(self):
142 """Get the Vr speed of the flight."""
143 return self._gui.vr
144
145 @property
146 def v2(self):
147 """Get the V2 speed of the flight."""
148 return self._gui.v2
149
150 @property
151 def star(self):
152 """Get the STAR planned."""
153 return self._gui.star
154
155 @property
156 def transition(self):
157 """Get the transition planned."""
158 return self._gui.transition
159
160 @property
161 def approachType(self):
162 """Get the approach type."""
163 return self._gui.approachType
164
165 @property
166 def arrivalRunway(self):
167 """Get the arrival runway."""
168 return self._gui.arrivalRunway
169
170 @property
171 def vref(self):
172 """Get the VRef speed of the flight."""
173 return self._gui.vref
174
175 @property
176 def tdRate(self):
177 """Get the touchdown rate if known, None otherwise."""
178 return self._tdRate
179
180 @property
181 def flightType(self):
182 """Get the type of the flight."""
183 return self._gui.flightType
184
185 @property
186 def online(self):
187 """Get whether the flight was an online flight."""
188 return self._gui.online
189
190 @property
191 def comments(self):
192 """Get the comments made by the pilot."""
193 return self._gui.comments
194
195 @property
196 def flightDefects(self):
197 """Get the flight defects reported by the pilot."""
198 return self._gui.flightDefects
199
200 @property
201 def delayCodes(self):
202 """Get the delay codes."""
203 return self._gui.delayCodes
204
205 @property
206 def speedInKnots(self):
207 """Determine if the speeds for the flight are to be expressed in
208 knots."""
209 return self.aircraft.speedInKnots if self.aircraft is not None \
210 else True
211
212 def handleState(self, oldState, currentState):
213 """Handle a new state information."""
214 self._updateFlownDistance(currentState)
215
216 self.endFuel = currentState.totalFuel
217 if self.startFuel is None:
218 self.startFuel = self.endFuel
219
220 self._soundScheduler.schedule(currentState,
221 self._pilotHotkeyPressed)
222 self._pilotHotkeyPressed = False
223
224 if self._checklistHotkeyPressed:
225 self._checklistScheduler.hotkeyPressed()
226 self._checklistHotkeyPressed = False
227
228 def setStage(self, timestamp, stage):
229 """Set the flight stage.
230
231 Returns if the stage has really changed."""
232 if stage!=self._stage:
233 self._stage = stage
234 self._gui.setStage(stage)
235 self.logger.stage(timestamp, stage)
236 if stage==const.STAGE_PUSHANDTAXI:
237 self.blockTimeStart = timestamp
238 elif stage==const.STAGE_TAKEOFF:
239 self.flightTimeStart = timestamp
240 elif stage==const.STAGE_TAXIAFTERLAND:
241 self.flightTimeEnd = timestamp
242 elif stage==const.STAGE_PARKING:
243 self.blockTimeEnd = timestamp
244 elif stage==const.STAGE_END:
245 with self._endCondition:
246 self._endCondition.notify()
247 return True
248 else:
249 return False
250
251 def handleFault(self, faultID, timestamp, what, score):
252 """Handle the given fault.
253
254 faultID as a unique ID for the given kind of fault. If another fault of
255 this ID has been reported earlier, it will be reported again only if
256 the score is greater than last time. This ID can be, e.g. the checker
257 the report comes from."""
258 self.logger.fault(faultID, timestamp, what, score)
259 self._gui.setRating(self.logger.getRating())
260
261 def handleNoGo(self, faultID, timestamp, what, shortReason):
262 """Handle a No-Go fault."""
263 self.logger.noGo(faultID, timestamp, what)
264 self._gui.setNoGo(shortReason)
265
266 def flareStarted(self, flareStart, flareStartFS):
267 """Called when the flare time has started."""
268 self._flareStart = flareStart
269 self._flareStartFS = flareStartFS
270
271 def flareFinished(self, flareEnd, flareEndFS, tdRate):
272 """Called when the flare time has ended.
273
274 Return a tuple of the following items:
275 - a boolean indicating if FS time is used
276 - the flare time
277 """
278 self._tdRate = tdRate
279 if self.flareTimeFromFS:
280 return (True, flareEndFS - self._flareStartFS)
281 else:
282 return (False, flareEnd - self._flareStart)
283
284 def wait(self):
285 """Wait for the flight to end."""
286 with self._endCondition:
287 while self._stage!=const.STAGE_END:
288 self._endCondition.wait(1)
289
290 def getFleet(self, callback, force = False):
291 """Get the fleet and call the given callback."""
292 self._gui.getFleetAsync(callback = callback, force = force)
293
294 def pilotHotkeyPressed(self):
295 """Called when the pilot hotkey is pressed."""
296 self._pilotHotkeyPressed = True
297
298 def checklistHotkeyPressed(self):
299 """Called when the checklist hotkey is pressed."""
300 self._checklistHotkeyPressed = True
301
302 def speedFromKnots(self, knots):
303 """Convert the given speed value expressed in knots into the flight's
304 speed unit."""
305 return knots if self.speedInKnots else knots * const.KNOTSTOKMPH
306
307 def speedToKnots(self, speed):
308 """Convert the given speed expressed in the flight's speed unit into
309 knots."""
310 return speed if self.speedInKnots else speed * const.KMPHTOKNOTS
311
312 def getEnglishSpeedUnit(self):
313 """Get the English name of the speed unit used by the flight."""
314 return "knots" if self.speedInKnots else "km/h"
315
316 def getI18NSpeedUnit(self):
317 """Get the speed unit suffix for i18n message identifiers."""
318 return "_knots" if self.speedInKnots else "_kmph"
319
320 def logFuel(self, aircraftState):
321 """Log the amount of fuel"""
322 fuelStr = ""
323 for (tank, amount) in aircraftState.fuel:
324 if fuelStr: fuelStr += " - "
325 fuelStr += "%s=%.0f kg" % (const.fuelTank2logString(tank), amount)
326
327 self.logger.message(aircraftState.timestamp, "Fuel: " + fuelStr)
328 self.logger.message(aircraftState.timestamp,
329 "Total fuel: %.0f kg" % (aircraftState.totalFuel,))
330
331 def _updateFlownDistance(self, currentState):
332 """Update the flown distance."""
333 if not currentState.onTheGround:
334 updateData = False
335 if self._lastDistanceTime is None or \
336 self._previousLatitude is None or \
337 self._previousLongitude is None:
338 updateData = True
339 elif currentState.timestamp >= (self._lastDistanceTime + 30.0):
340 updateData = True
341 self.flownDistance += self._getDistance(currentState)
342
343 if updateData:
344 self._previousLatitude = currentState.latitude
345 self._previousLongitude = currentState.longitude
346 self._lastDistanceTime = currentState.timestamp
347 else:
348 if self._lastDistanceTime is not None and \
349 self._previousLatitude is not None and \
350 self._previousLongitude is not None:
351 self.flownDistance += self._getDistance(currentState)
352
353 self._lastDistanceTime = None
354
355 def _getDistance(self, currentState):
356 """Get the distance between the previous and the current state."""
357 return util.getDistCourse(self._previousLatitude, self._previousLongitude,
358 currentState.latitude, currentState.longitude)[0]
359
360#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.