source: src/mlx/flight.py@ 279:192aeea89424

Last change on this file since 279:192aeea89424 was 274:b866c39279e8, checked in by István Váradi <ivaradi@…>, 12 years ago

Reworked fuel handling so that the model can tell what tanks there are

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