source: src/mlx/acft.py@ 170:7cda0cc74e19

Last change on this file since 170:7cda0cc74e19 was 170:7cda0cc74e19, checked in by István Váradi <ivaradi@…>, 12 years ago

The background sounds play back properly

File size: 29.9 KB
Line 
1# Module for the simulator-independent aircraft classes
2
3#---------------------------------------------------------------------------------------
4
5import const
6import checks
7import fs
8import util
9
10import sys
11import time
12import traceback
13
14#---------------------------------------------------------------------------------------
15
16class Aircraft(object):
17 """Base class for aircraft."""
18 @staticmethod
19 def create(flight):
20 """Create an aircraft instance for the type in the given flight."""
21 return _classes[flight.aircraftType](flight)
22
23 def __init__(self, flight):
24 """Construct the aircraft for the given type."""
25 self._flight = flight
26 self._aircraftState = None
27
28 self._maxVS = -10000.0
29 self._minVS = 10000.0
30
31 self._v1r2LineIndex = None
32 self._vrefLineIndex = None
33
34 self.humanWeight = 82.0
35
36 self._checkers = []
37
38 # Loggers
39
40 self._checkers.append(checks.StageChecker())
41 self._checkers.append(checks.TakeOffLogger())
42
43 self._checkers.append(checks.AltimeterLogger())
44
45 self._checkers.append(checks.NAV1Logger())
46 self._checkers.append(checks.NAV2Logger())
47 self._checkers.append(checks.SquawkLogger())
48
49 self._checkers.append(checks.AnticollisionLightsLogger())
50 self._checkers.append(checks.LandingLightsLogger())
51 self._checkers.append(checks.StrobeLightsLogger())
52 self._checkers.append(checks.NavLightsLogger())
53
54 self._checkers.append(checks.FlapsLogger())
55
56 self._checkers.append(checks.GearsLogger())
57 self._checkers.append(checks.CruiseSpeedLogger())
58 self._checkers.append(checks.SpoilerLogger())
59
60 if flight.config.isMessageTypeFS(const.MESSAGETYPE_VISIBILITY):
61 self._checkers.append(checks.VisibilityChecker())
62
63 # FIXME: we should have a central data model object, and not collect
64 # the data from the GUI. However, some pieces of data (e.g. V-speeds,
65 # etc. that is entered into the GUI) *should* be a part of the GUI and
66 # queried from it, so the model should have a reference to the GUI as
67 # well and access such data via the GUI!
68 if flight.config.onlineACARS:
69 self._checkers.append(checks.ACARSSender(flight._gui))
70
71 # Fault checkers
72
73 self._checkers.append(checks.AntiCollisionLightsChecker())
74 self._checkers.append(checks.LandingLightsChecker())
75 self._checkers.append(checks.NavLightsChecker())
76 self._checkers.append(checks.StrobeLightsChecker())
77
78 self._checkers.append(checks.BankChecker())
79
80 self._checkers.append(checks.FlapsRetractChecker())
81 self._checkers.append(checks.FlapsSpeedLimitChecker())
82
83 self._checkers.append(checks.GearsDownChecker())
84 self._checkers.append(checks.GearSpeedLimitChecker())
85
86 self._checkers.append(checks.GLoadChecker())
87
88 self._checkers.append(checks.MLWChecker())
89 self._checkers.append(checks.MTOWChecker())
90 self._checkers.append(checks.MZFWChecker())
91 self._checkers.append(checks.PayloadChecker())
92
93 self._checkers.append(checks.SpeedChecker())
94 self._checkers.append(checks.VSChecker())
95 self._checkers.append(checks.OverspeedChecker())
96 self._checkers.append(checks.StallChecker())
97
98 self._checkers.append(checks.PitotChecker())
99
100 self._checkers.append(checks.ReverserChecker())
101
102 @property
103 def type(self):
104 """Get the type of the aircraft."""
105 return self._flight.aircraftType
106
107 @property
108 def flight(self):
109 """Get the flight the aircraft belongs to."""
110 return self._flight
111
112 @property
113 def logger(self):
114 """Get the logger to use for the aircraft."""
115 return self._flight.logger
116
117 @property
118 def state(self):
119 """Get the current aircraft state."""
120 return self._aircraftState
121
122 def getFlapsSpeedLimit(self, flaps):
123 """Get the speed limit for the given flaps setting."""
124 return self.flapSpeedLimits[flaps] if flaps in self.flapSpeedLimits \
125 else None
126
127 def modelChanged(self, timestamp, aircraftName, modelName):
128 """Called when the simulator's aircraft changes."""
129 self._flight.logger.message(timestamp,
130 "Aircraft: name='%s', model='%s'" % \
131 (aircraftName, modelName))
132
133 def handleState(self, aircraftState):
134 """Called when the state of the aircraft changes."""
135 for checker in self._checkers:
136 try:
137 checker.check(self._flight, self, self._flight.logger,
138 self._aircraftState, aircraftState)
139 except:
140 print >> sys.stderr, "Checker", checker, "failed"
141 traceback.print_exc()
142
143 self._flight.handleState(self._aircraftState, aircraftState)
144
145 self._maxVS = max(self._maxVS, aircraftState.vs)
146 self._minVS = min(self._minVS, aircraftState.vs)
147
148 self._aircraftState = aircraftState
149
150 def setStage(self, aircraftState, newStage):
151 """Set the given stage as the new one and do whatever should be
152 done."""
153 if self._flight.setStage(aircraftState.timestamp, newStage):
154 if newStage==const.STAGE_PUSHANDTAXI:
155 self.logger.message(aircraftState.timestamp, "Block time start")
156 self.logFuel(aircraftState)
157 self.logger.message(aircraftState.timestamp,
158 "Zero-fuel weight: %.0f kg" % (aircraftState.zfw))
159 flight = self._flight
160 if flight.v1 is None or flight.vr is None or flight.v2 is None:
161 fs.sendMessage(const.MESSAGETYPE_HELP,
162 "Don't forget to set the takeoff V-speeds!",
163 5)
164 elif newStage==const.STAGE_TAKEOFF:
165 self.logger.message(aircraftState.timestamp, "Flight time start")
166 self.logger.message(aircraftState.timestamp,
167 "Takeoff weight: %.0f kg, MTOW: %.0f kg" % \
168 (aircraftState.grossWeight, self.mtow))
169 self.logger.message(aircraftState.timestamp,
170 "Wind %03.0f degrees at %.0f knots" % \
171 (aircraftState.windDirection,
172 aircraftState.windSpeed))
173 self._logV1R2()
174 elif newStage==const.STAGE_TAXIAFTERLAND:
175 bookedFlight = self._flight.bookedFlight
176 config = self._flight.config
177 if config.onlineGateSystem and \
178 bookedFlight.arrivalICAO=="LHBP" and \
179 config.isMessageTypeFS(const.MESSAGETYPE_GATE_SYSTEM):
180 self._flight.getFleet(callback = self._fleetRetrieved,
181 force = True)
182 self.logger.message(aircraftState.timestamp, "Flight time end")
183 self.logFuel(aircraftState)
184 self.logger.message(aircraftState.timestamp,
185 "Landing weight: %.0f kg, MLW: %.0f" % \
186 (aircraftState.grossWeight, self.mlw))
187 self.logger.message(aircraftState.timestamp,
188 "Vertical speed range: %.0f..%.0f feet/min" % \
189 (self._minVS, self._maxVS))
190 elif newStage==const.STAGE_PARKING:
191 self.logger.message(aircraftState.timestamp, "Block time end")
192 elif newStage==const.STAGE_END:
193 flightLength = self._flight.flightTimeEnd - self._flight.flightTimeStart
194 self.logger.message(aircraftState.timestamp,
195 "Flight time: " +
196 util.getTimeIntervalString(flightLength))
197 self.logger.message(aircraftState.timestamp,
198 "Flown distance: %.2f NM" % \
199 (self._flight.flownDistance,))
200 blockLength = self._flight.blockTimeEnd - self._flight.blockTimeStart
201 self.logger.message(aircraftState.timestamp,
202 "Block time: " +
203 util.getTimeIntervalString(blockLength))
204
205 def prepareFlare(self):
206 """Called when it is detected that we will soon flare.
207
208 On the first call, it should start monitoring some parameters more
209 closely to determine flare time."""
210 self.flight.simulator.startFlare()
211
212 def flareStarted(self, windSpeed, windDirection, visibility,
213 flareStart, flareStartFS):
214 """Called when the flare has started."""
215 self.logger.message(self._aircraftState.timestamp, "The flare has begun")
216 self.logger.message(self._aircraftState.timestamp,
217 "Wind %03.0f degrees at %.0f knots" % \
218 (windDirection, windSpeed))
219 self.logger.message(self._aircraftState.timestamp,
220 "Visibility: %.0f metres" % (visibility,))
221 self.logger.message(self._aircraftState.timestamp,
222 "Altimeter setting: %.0f hPa" % \
223 (self._aircraftState.altimeter,))
224 self._logVRef()
225 self.flight.flareStarted(flareStart, flareStartFS)
226 fs.sendMessage(const.MESSAGETYPE_INFORMATION, "Flare-time", 3)
227
228 def flareFinished(self, flareEnd, flareEndFS, tdRate, tdRateCalculatedByFS,
229 ias, pitch, bank, heading):
230 """Called when the flare has finished."""
231 (flareTimeFromFS, flareTime) = self.flight.flareFinished(flareEnd,
232 flareEndFS,
233 tdRate)
234 self.logger.message(self._aircraftState.timestamp,
235 "Flaretime: %.3f (from %s)" % \
236 (flareTime,
237 "the simulator" if flareTimeFromFS else "real time",))
238 self.logger.message(self._aircraftState.timestamp,
239 "Touchdown rate: %.0f feet/min" % (tdRate,))
240 self.logger.message(self._aircraftState.timestamp,
241 "Touchdown rate was calculated by the %s" % \
242 ("simulator" if tdRateCalculatedByFS else "logger",))
243 self.logger.message(self._aircraftState.timestamp,
244 "Touchdown speed: %.0f knots" % (ias,))
245 self.logger.message(self._aircraftState.timestamp,
246 "Touchdown pitch: %.1f degrees" % (pitch,))
247 self.logger.message(self._aircraftState.timestamp,
248 "Touchdown bank: %.1f degrees" % (bank,))
249 self.logger.message(self._aircraftState.timestamp,
250 "Touchdown heading: %03.0f degrees" % (heading,))
251
252 def cancelFlare(self):
253 """Cancel flare, if it has started."""
254 self.flight.simulator.cancelFlare()
255
256 def checkFlightEnd(self, aircraftState):
257 """Check if the end of the flight has arrived.
258
259 This default implementation checks the N1 values, but for
260 piston-powered aircraft you need to check the RPMs."""
261 for n1 in aircraftState.n1:
262 if n1>=0.5: return False
263 return True
264
265 def updateV1R2(self):
266 """Update the V1, Vr and V2 values from the flight, if the these values
267 have already been logged."""
268 if self._v1r2LineIndex is not None:
269 self._logV1R2()
270
271 def _logV1R2(self):
272 """Log the V1, Vr and V2 value either newly, or by updating the
273 corresponding line."""
274 message = "Speeds calculated by the pilot: V1: %s, VR: %s, V2: %s" % \
275 ("-" if self._flight.v1 is None
276 else str(self._flight.v1),
277 "-" if self._flight.vr is None
278 else str(self._flight.vr),
279 "-" if self._flight.v2 is None
280 else str(self._flight.v2))
281
282 if self._v1r2LineIndex is None:
283 self._v1r2LineIndex = \
284 self.logger.message(self._aircraftState.timestamp, message)
285 else:
286 self.logger.updateLine(self._v1r2LineIndex, message)
287
288 def updateVRef(self):
289 """Update the Vref value from the flight, if the Vref value has already
290 been logged."""
291 if self._vrefLineIndex is not None:
292 self._logVRef()
293
294 def _logVRef(self):
295 """Log the Vref value either newly, or by updating the corresponding
296 line."""
297 message = "VRef speed calculated by the pilot: %s" % \
298 ("-" if self._flight.vref is None else str(self._flight.vref))
299 if self._vrefLineIndex is None:
300 self._vrefLineIndex = \
301 self.logger.message(self._aircraftState.timestamp, message)
302 else:
303 self.logger.updateLine(self._vrefLineIndex, message)
304
305 def _fleetRetrieved(self, fleet):
306 """Callback for the fleet retrieval result."""
307 if fleet is not None:
308 gateList = ""
309 occupiedGateNumbers = fleet.getOccupiedGateNumbers()
310 for gateNumber in const.lhbpGateNumbers:
311 if gateNumber not in occupiedGateNumbers:
312 if gateList: gateList += ", "
313 gateList += gateNumber
314 fs.sendMessage(const.MESSAGETYPE_GATE_SYSTEM,
315 "Free gates: " + gateList, 20)
316
317
318#---------------------------------------------------------------------------------------
319
320class Boeing737(Aircraft):
321 """Base class for the various aircraft in the Boeing 737 family.
322
323 The aircraft type-specific values in the aircraft state have the following
324 structure:
325 - fuel: left, centre, right
326 - n1: left, right
327 - reverser: left, right"""
328 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
329
330 def __init__(self, flight):
331 super(Boeing737, self).__init__(flight)
332 self._checkers.append(checks.ThrustChecker())
333
334 self.gearSpeedLimit = 270
335 self.flapSpeedLimits = { 1 : 260,
336 2 : 260,
337 5 : 250,
338 10 : 210,
339 15 : 200,
340 25 : 190,
341 30 : 175,
342 40 : 162 }
343
344 def logFuel(self, aircraftState):
345 """Log the amount of fuel"""
346 self.logger.message(aircraftState.timestamp,
347 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
348 (aircraftState.fuel[0], aircraftState.fuel[1],
349 aircraftState.fuel[2]))
350 self.logger.message(aircraftState.timestamp,
351 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
352
353#---------------------------------------------------------------------------------------
354
355class B736(Boeing737):
356 """Boeing 737-600 aircraft."""
357 def __init__(self, flight):
358 super(B736, self).__init__(flight)
359 self.dow = 38307
360 self.mtow = 58328
361 self.mlw = 54657
362 self.mzfw = 51482
363
364#---------------------------------------------------------------------------------------
365
366class B737(Boeing737):
367 """Boeing 737-700 aircraft."""
368 def __init__(self, flight):
369 super(B737, self).__init__(flight)
370 self.dow = 39250
371 self.mtow = 61410
372 self.mlw = 58059
373 self.mzfw = 54657
374
375#---------------------------------------------------------------------------------------
376
377class B738(Boeing737):
378 """Boeing 737-800 aircraft."""
379 def __init__(self, flight):
380 super(B738, self).__init__(flight)
381 self.dow = 42690
382 self.mtow = 71709
383 self.mlw = 65317
384 self.mzfw = 61688
385
386#---------------------------------------------------------------------------------------
387
388class B738Charter(B738):
389 """Boeing 737-800 aircraft used for charters."""
390 def __init__(self, flight):
391 super(B738Charter, self).__init__(flight)
392 self.mtow = 77791
393
394#---------------------------------------------------------------------------------------
395
396class B733(Boeing737):
397 """Boeing 737-300 aircraft."""
398 def __init__(self, flight):
399 super(B733, self).__init__(flight)
400 self.dow = 32700
401 self.mtow = 62820
402 self.mlw = 51700
403 self.mzfw = 48410
404
405#---------------------------------------------------------------------------------------
406
407class B734(Boeing737):
408 """Boeing 737-400 aircraft."""
409 def __init__(self, flight):
410 super(B734, self).__init__(flight)
411 self.dow = 33200
412 self.mtow = 68050
413 self.mlw = 56200
414 self.mzfw = 53100
415
416#---------------------------------------------------------------------------------------
417
418class B735(Boeing737):
419 """Boeing 737-500 aircraft."""
420 def __init__(self, flight):
421 super(B735, self).__init__(flight)
422 self.dow = 31300
423 self.mtow = 60550
424 self.mlw = 50000
425 self.mzfw = 46700
426
427#---------------------------------------------------------------------------------------
428
429class DH8D(Aircraft):
430 """Bombardier Dash-8 Q400 aircraft.
431
432 The aircraft type-specific values in the aircraft state have the following
433 structure:
434 - fuel: left, right
435 - n1: left, right
436 - reverser: left, right."""
437 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
438
439 def __init__(self, flight):
440 super(DH8D, self).__init__(flight)
441 self.dow = 17185
442 self.mtow = 29257
443 self.mlw = 28009
444 self.mzfw = 25855
445 self.gearSpeedLimit = 215
446 self.flapSpeedLimits = { 5 : 200,
447 10 : 181,
448 15 : 172,
449 35 : 158 }
450
451 def logFuel(self, aircraftState):
452 """Log the amount of fuel"""
453 self.logger.message(aircraftState.timestamp,
454 "Fuel: left=%.0f kg - right=%.0f kg" % \
455 (aircraftState.fuel[0], aircraftState.fuel[1]))
456 self.logger.message(aircraftState.timestamp,
457 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
458
459#---------------------------------------------------------------------------------------
460
461class Boeing767(Aircraft):
462 """Base class for the various aircraft in the Boeing 767 family.
463
464 The aircraft type-specific values in the aircraft state have the following
465 structure:
466 - fuel: left, centre, right
467 - n1: left, right
468 - reverser: left, right"""
469 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
470
471 def __init__(self, flight):
472 super(Boeing767, self).__init__(flight)
473 self._checkers.append(checks.ThrustChecker())
474 self.gearSpeedLimit = 270
475 self.flapSpeedLimits = { 1 : 255,
476 5 : 235,
477 10 : 215,
478 20 : 215,
479 25 : 185,
480 30 : 175 }
481
482 def logFuel(self, aircraftState):
483 """Log the amount of fuel"""
484 self.logger.message(aircraftState.timestamp,
485 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
486 (aircraftState.fuel[0], aircraftState.fuel[1],
487 aircraftState.fuel[2]))
488 self.logger.message(aircraftState.timestamp,
489 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
490
491#---------------------------------------------------------------------------------------
492
493class B762(Boeing767):
494 """Boeing 767-200 aircraft."""
495 def __init__(self, flight):
496 super(B762, self).__init__(flight)
497 self.dow = 84507
498 self.mtow = 175540
499 self.mlw = 126098
500 self.mzfw = 114758
501
502#---------------------------------------------------------------------------------------
503
504class B763(Boeing767):
505 """Boeing 767-300 aircraft."""
506 def __init__(self, flight):
507 super(B763, self).__init__(cflight)
508 self.dow = 91311
509 self.mtow = 181436
510 self.mlw = 137892
511 self.mzfw = 130635
512
513#---------------------------------------------------------------------------------------
514
515class CRJ2(Aircraft):
516 """Bombardier CRJ-200 aircraft.
517
518 The aircraft type-specific values in the aircraft state have the following
519 structure:
520 - fuel: left, centre, right
521 - n1: left, right
522 - reverser: left, right."""
523 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
524
525 def __init__(self, flight):
526 super(CRJ2, self).__init__(flight)
527 self._checkers.append(checks.ThrustChecker())
528 self.dow = 14549
529 self.mtow = 22995
530 self.mlw = 21319
531 self.mzfw = 19958
532 self.gearSpeedLimit = 240
533 self.flapSpeedLimits = { 8 : 260,
534 20 : 220,
535 30 : 190,
536 45 : 175 }
537
538 def logFuel(self, aircraftState):
539 """Log the amount of fuel"""
540 self.logger.message(aircraftState.timestamp,
541 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
542 (aircraftState.fuel[0], aircraftState.fuel[1],
543 aircraftState.fuel[2]))
544 self.logger.message(aircraftState.timestamp,
545 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
546
547#---------------------------------------------------------------------------------------
548
549class F70(Aircraft):
550 """Fokker 70 aircraft.
551
552 The aircraft type-specific values in the aircraft state have the following
553 structure:
554 - fuel: left, centre, right
555 - n1: left, right
556 - reverser: left, right."""
557 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
558
559 def __init__(self, flight):
560 super(F70, self).__init__(flight)
561 self._checkers.append(checks.ThrustChecker())
562 self.dow = 24283
563 self.mtow = 38100 # FIXME: differentiate by registration number,
564 # MTOW of HA-LMF: 41955
565 self.mlw = 36740
566 self.mzfw = 32655
567 self.gearSpeedLimit = 200
568 self.flapSpeedLimits = { 8 : 250,
569 15 : 220,
570 25 : 220,
571 42 : 180 }
572
573 def logFuel(self, aircraftState):
574 """Log the amount of fuel"""
575 self.logger.message(aircraftState.timestamp,
576 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
577 (aircraftState.fuel[0], aircraftState.fuel[1],
578 aircraftState.fuel[2]))
579 self.logger.message(aircraftState.timestamp,
580 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
581
582#---------------------------------------------------------------------------------------
583
584class DC3(Aircraft):
585 """Lisunov Li-2 (DC-3) aircraft.
586
587 The aircraft type-specific values in the aircraft state have the following
588 structure:
589 - fuel: left aux, left, right, right aux
590 - rpm: left, right
591 - reverser: left, right."""
592 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
593 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
594
595 def __init__(self, flight):
596 super(DC3, self).__init__(flight)
597 self.dow = 8627
598 self.mtow = 11884
599 self.mlw = 11793
600 self.mzfw = 11780
601 self.gearSpeedLimit = 148
602 self.flapSpeedLimits = { 15 : 135,
603 30 : 99,
604 45 : 97 }
605
606 def _checkFlightEnd(self, aircraftState):
607 """Check if the end of the flight has arrived.
608
609 This implementation checks the RPM values to be 0."""
610 for rpm in aircraftState.rpm:
611 if rpm>0: return False
612 return True
613
614 def logFuel(self, aircraftState):
615 """Log the amount of fuel"""
616 self.logger.message(aircraftState.timestamp,
617 "Fuel: left aux=%.0f kg - left=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
618 (aircraftState.fuel[0], aircraftState.fuel[1],
619 aircraftState.fuel[2], aircraftState.fuel[3]))
620 self.logger.message(aircraftState.timestamp,
621 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
622
623#---------------------------------------------------------------------------------------
624
625class T134(Aircraft):
626 """Tupolev Tu-134 aircraft.
627
628 The aircraft type-specific values in the aircraft state have the following
629 structure:
630 - fuel: left tip, left aux, centre, right aux, right tip, external 1,
631 external 2
632 - n1: left, right
633 - reverser: left, right."""
634 fuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_LEFT_AUX,
635 const.FUELTANK_CENTRE,
636 const.FUELTANK_RIGHT_AUX, const.FUELTANK_RIGHT_TIP,
637 const.FUELTANK_EXTERNAL1, const.FUELTANK_EXTERNAL2]
638
639 def __init__(self, flight):
640 super(T134, self).__init__(flight)
641 self._checkers.append(checks.ThrustChecker())
642 self.dow = 29927
643 self.mtow = 47600
644 self.mlw = 43000
645 self.mzfw = 38500
646 self.gearSpeedLimit = 216
647 self.flapSpeedLimits = { 10 : 240,
648 20 : 216,
649 30 : 161 }
650
651 def logFuel(self, aircraftState):
652 """Log the amount of fuel"""
653 self.logger.message(aircraftState.timestamp,
654 "Fuel: left aux=%.0f kg - left tip=%.0f kg - centre= %.0f kg - right tip=%.0f kg - right aux=%.0f kg - external 1=%.0f kg - external 2=%.0f kg" % \
655 (aircraftState.fuel[1], aircraftState.fuel[0],
656 aircraftState.fuel[2],
657 aircraftState.fuel[4], aircraftState.fuel[3],
658 aircraftState.fuel[5], aircraftState.fuel[6]))
659 self.logger.message(aircraftState.timestamp,
660 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
661
662#---------------------------------------------------------------------------------------
663
664class T154(Aircraft):
665 """Tupolev Tu-154 aircraft.
666
667 The aircraft type-specific values in the aircraft state have the following
668 structure:
669 - fuel: left aux, left, centre, centre 2, right, right aux
670 - n1: left, centre, right
671 - reverser: left, right"""
672 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
673 const.FUELTANK_CENTRE, const.FUELTANK_CENTRE2,
674 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
675 def __init__(self, flight):
676 super(T154, self).__init__(flight)
677 self._checkers.append(checks.ThrustChecker())
678 self.dow = 53259
679 self.mtow = 98000
680 self.mlw = 78000
681 self.mzfw = 72000
682 self.gearSpeedLimit = 216
683 self.flapSpeedLimits = { 15 : 227,
684 28 : 194,
685 45 : 162 }
686
687 def logFuel(self, aircraftState):
688 """Log the amount of fuel"""
689 self.logger.message(aircraftState.timestamp,
690 "Fuel: left aux=%.0f kg - left=%.0f kg - centre=%.0f kg - centre 2=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
691 (aircraftState.fuel[0], aircraftState.fuel[1],
692 aircraftState.fuel[2], aircraftState.fuel[3],
693 aircraftState.fuel[4], aircraftState.fuel[5]))
694 self.logger.message(aircraftState.timestamp,
695 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
696
697#---------------------------------------------------------------------------------------
698
699
700class YK40(Aircraft):
701 """Yakovlev Yak-40 aircraft.
702
703 The aircraft type-specific values in the aircraft state have the following
704 structure:
705 - fuel: left, right
706 - n1: left, right
707 - reverser: left, right"""
708 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
709
710 def __init__(self, flight):
711 super(YK40, self).__init__(flight)
712 self._checkers.append(checks.ThrustChecker())
713 self.dow = 9400
714 self.mtow = 17200
715 self.mlw = 16800
716 self.mzfw = 12100
717 self.gearSpeedLimit = 165
718 self.flapSpeedLimits = { 20 : 165,
719 35 : 135 }
720
721 def logFuel(self, aircraftState):
722 """Log the amount of fuel"""
723 self.logger.message(aircraftState.timestamp,
724 "Fuel: left=%.0f kg - right=%.0f kg" % \
725 (aircraftState.fuel[0], aircraftState.fuel[1]))
726 self.logger.message(aircraftState.timestamp,
727 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
728
729#---------------------------------------------------------------------------------------
730
731MostFuelTankAircraft = T134
732
733#---------------------------------------------------------------------------------------
734
735_classes = { const.AIRCRAFT_B736 : B736,
736 const.AIRCRAFT_B737 : B737,
737 const.AIRCRAFT_B738 : B738,
738 const.AIRCRAFT_B733 : B733,
739 const.AIRCRAFT_B734 : B734,
740 const.AIRCRAFT_B735 : B735,
741 const.AIRCRAFT_DH8D : DH8D,
742 const.AIRCRAFT_B762 : B762,
743 const.AIRCRAFT_B763 : B763,
744 const.AIRCRAFT_CRJ2 : CRJ2,
745 const.AIRCRAFT_F70 : F70,
746 const.AIRCRAFT_DC3 : DC3,
747 const.AIRCRAFT_T134 : T134,
748 const.AIRCRAFT_T154 : T154,
749 const.AIRCRAFT_YK40 : YK40 }
750
751#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.