source: src/mlx/acft.py@ 169:eccafedbf55c

Last change on this file since 169:eccafedbf55c was 153:f53ca1f24fcc, checked in by István Váradi <ivaradi@…>, 11 years ago

Changed the way the flare-time is logged

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 self.logger.message(self._aircraftState.timestamp,
234 "Flaretime: %.3f (from %s)" % \
235 (flareTime,
236 "the simulator" if flareTimeFromFS else "real time",))
237 self.logger.message(self._aircraftState.timestamp,
238 "Touchdown rate: %.0f feet/min" % (tdRate,))
239 self.logger.message(self._aircraftState.timestamp,
240 "Touchdown rate was calculated by the %s" % \
241 ("simulator" if tdRateCalculatedByFS else "logger",))
242 self.logger.message(self._aircraftState.timestamp,
243 "Touchdown speed: %.0f knots" % (ias,))
244 self.logger.message(self._aircraftState.timestamp,
245 "Touchdown pitch: %.1f degrees" % (pitch,))
246 self.logger.message(self._aircraftState.timestamp,
247 "Touchdown bank: %.1f degrees" % (bank,))
248 self.logger.message(self._aircraftState.timestamp,
249 "Touchdown heading: %03.0f degrees" % (heading,))
250
251 def cancelFlare(self):
252 """Cancel flare, if it has started."""
253 self.flight.simulator.cancelFlare()
254
255 def checkFlightEnd(self, aircraftState):
256 """Check if the end of the flight has arrived.
257
258 This default implementation checks the N1 values, but for
259 piston-powered aircraft you need to check the RPMs."""
260 for n1 in aircraftState.n1:
261 if n1>=0.5: return False
262 return True
263
264 def updateV1R2(self):
265 """Update the V1, Vr and V2 values from the flight, if the these values
266 have already been logged."""
267 if self._v1r2LineIndex is not None:
268 self._logV1R2()
269
270 def _logV1R2(self):
271 """Log the V1, Vr and V2 value either newly, or by updating the
272 corresponding line."""
273 message = "Speeds calculated by the pilot: V1: %s, VR: %s, V2: %s" % \
274 ("-" if self._flight.v1 is None
275 else str(self._flight.v1),
276 "-" if self._flight.vr is None
277 else str(self._flight.vr),
278 "-" if self._flight.v2 is None
279 else str(self._flight.v2))
280
281 if self._v1r2LineIndex is None:
282 self._v1r2LineIndex = \
283 self.logger.message(self._aircraftState.timestamp, message)
284 else:
285 self.logger.updateLine(self._v1r2LineIndex, message)
286
287 def updateVRef(self):
288 """Update the Vref value from the flight, if the Vref value has already
289 been logged."""
290 if self._vrefLineIndex is not None:
291 self._logVRef()
292
293 def _logVRef(self):
294 """Log the Vref value either newly, or by updating the corresponding
295 line."""
296 message = "VRef speed calculated by the pilot: %s" % \
297 ("-" if self._flight.vref is None else str(self._flight.vref))
298 if self._vrefLineIndex is None:
299 self._vrefLineIndex = \
300 self.logger.message(self._aircraftState.timestamp, message)
301 else:
302 self.logger.updateLine(self._vrefLineIndex, message)
303
304 def _fleetRetrieved(self, fleet):
305 """Callback for the fleet retrieval result."""
306 if fleet is not None:
307 gateList = ""
308 occupiedGateNumbers = fleet.getOccupiedGateNumbers()
309 for gateNumber in const.lhbpGateNumbers:
310 if gateNumber not in occupiedGateNumbers:
311 if gateList: gateList += ", "
312 gateList += gateNumber
313 fs.sendMessage(const.MESSAGETYPE_GATE_SYSTEM,
314 "Free gates: " + gateList, 20)
315
316
317#---------------------------------------------------------------------------------------
318
319class Boeing737(Aircraft):
320 """Base class for the various aircraft in the Boeing 737 family.
321
322 The aircraft type-specific values in the aircraft state have the following
323 structure:
324 - fuel: left, centre, right
325 - n1: left, right
326 - reverser: left, right"""
327 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
328
329 def __init__(self, flight):
330 super(Boeing737, self).__init__(flight)
331 self._checkers.append(checks.ThrustChecker())
332
333 self.gearSpeedLimit = 270
334 self.flapSpeedLimits = { 1 : 260,
335 2 : 260,
336 5 : 250,
337 10 : 210,
338 15 : 200,
339 25 : 190,
340 30 : 175,
341 40 : 162 }
342
343 def logFuel(self, aircraftState):
344 """Log the amount of fuel"""
345 self.logger.message(aircraftState.timestamp,
346 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
347 (aircraftState.fuel[0], aircraftState.fuel[1],
348 aircraftState.fuel[2]))
349 self.logger.message(aircraftState.timestamp,
350 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
351
352#---------------------------------------------------------------------------------------
353
354class B736(Boeing737):
355 """Boeing 737-600 aircraft."""
356 def __init__(self, flight):
357 super(B736, self).__init__(flight)
358 self.dow = 38307
359 self.mtow = 58328
360 self.mlw = 54657
361 self.mzfw = 51482
362
363#---------------------------------------------------------------------------------------
364
365class B737(Boeing737):
366 """Boeing 737-700 aircraft."""
367 def __init__(self, flight):
368 super(B737, self).__init__(flight)
369 self.dow = 39250
370 self.mtow = 61410
371 self.mlw = 58059
372 self.mzfw = 54657
373
374#---------------------------------------------------------------------------------------
375
376class B738(Boeing737):
377 """Boeing 737-800 aircraft."""
378 def __init__(self, flight):
379 super(B738, self).__init__(flight)
380 self.dow = 42690
381 self.mtow = 71709
382 self.mlw = 65317
383 self.mzfw = 61688
384
385#---------------------------------------------------------------------------------------
386
387class B738Charter(B738):
388 """Boeing 737-800 aircraft used for charters."""
389 def __init__(self, flight):
390 super(B738Charter, self).__init__(flight)
391 self.mtow = 77791
392
393#---------------------------------------------------------------------------------------
394
395class B733(Boeing737):
396 """Boeing 737-300 aircraft."""
397 def __init__(self, flight):
398 super(B733, self).__init__(flight)
399 self.dow = 32700
400 self.mtow = 62820
401 self.mlw = 51700
402 self.mzfw = 48410
403
404#---------------------------------------------------------------------------------------
405
406class B734(Boeing737):
407 """Boeing 737-400 aircraft."""
408 def __init__(self, flight):
409 super(B734, self).__init__(flight)
410 self.dow = 33200
411 self.mtow = 68050
412 self.mlw = 56200
413 self.mzfw = 53100
414
415#---------------------------------------------------------------------------------------
416
417class B735(Boeing737):
418 """Boeing 737-500 aircraft."""
419 def __init__(self, flight):
420 super(B735, self).__init__(flight)
421 self.dow = 31300
422 self.mtow = 60550
423 self.mlw = 50000
424 self.mzfw = 46700
425
426#---------------------------------------------------------------------------------------
427
428class DH8D(Aircraft):
429 """Bombardier Dash-8 Q400 aircraft.
430
431 The aircraft type-specific values in the aircraft state have the following
432 structure:
433 - fuel: left, right
434 - n1: left, right
435 - reverser: left, right."""
436 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
437
438 def __init__(self, flight):
439 super(DH8D, self).__init__(flight)
440 self.dow = 17185
441 self.mtow = 29257
442 self.mlw = 28009
443 self.mzfw = 25855
444 self.gearSpeedLimit = 215
445 self.flapSpeedLimits = { 5 : 200,
446 10 : 181,
447 15 : 172,
448 35 : 158 }
449
450 def logFuel(self, aircraftState):
451 """Log the amount of fuel"""
452 self.logger.message(aircraftState.timestamp,
453 "Fuel: left=%.0f kg - right=%.0f kg" % \
454 (aircraftState.fuel[0], aircraftState.fuel[1]))
455 self.logger.message(aircraftState.timestamp,
456 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
457
458#---------------------------------------------------------------------------------------
459
460class Boeing767(Aircraft):
461 """Base class for the various aircraft in the Boeing 767 family.
462
463 The aircraft type-specific values in the aircraft state have the following
464 structure:
465 - fuel: left, centre, right
466 - n1: left, right
467 - reverser: left, right"""
468 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
469
470 def __init__(self, flight):
471 super(Boeing767, self).__init__(flight)
472 self._checkers.append(checks.ThrustChecker())
473 self.gearSpeedLimit = 270
474 self.flapSpeedLimits = { 1 : 255,
475 5 : 235,
476 10 : 215,
477 20 : 215,
478 25 : 185,
479 30 : 175 }
480
481 def logFuel(self, aircraftState):
482 """Log the amount of fuel"""
483 self.logger.message(aircraftState.timestamp,
484 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
485 (aircraftState.fuel[0], aircraftState.fuel[1],
486 aircraftState.fuel[2]))
487 self.logger.message(aircraftState.timestamp,
488 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
489
490#---------------------------------------------------------------------------------------
491
492class B762(Boeing767):
493 """Boeing 767-200 aircraft."""
494 def __init__(self, flight):
495 super(B762, self).__init__(flight)
496 self.dow = 84507
497 self.mtow = 175540
498 self.mlw = 126098
499 self.mzfw = 114758
500
501#---------------------------------------------------------------------------------------
502
503class B763(Boeing767):
504 """Boeing 767-300 aircraft."""
505 def __init__(self, flight):
506 super(B763, self).__init__(cflight)
507 self.dow = 91311
508 self.mtow = 181436
509 self.mlw = 137892
510 self.mzfw = 130635
511
512#---------------------------------------------------------------------------------------
513
514class CRJ2(Aircraft):
515 """Bombardier CRJ-200 aircraft.
516
517 The aircraft type-specific values in the aircraft state have the following
518 structure:
519 - fuel: left, centre, right
520 - n1: left, right
521 - reverser: left, right."""
522 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
523
524 def __init__(self, flight):
525 super(CRJ2, self).__init__(flight)
526 self._checkers.append(checks.ThrustChecker())
527 self.dow = 14549
528 self.mtow = 22995
529 self.mlw = 21319
530 self.mzfw = 19958
531 self.gearSpeedLimit = 240
532 self.flapSpeedLimits = { 8 : 260,
533 20 : 220,
534 30 : 190,
535 45 : 175 }
536
537 def logFuel(self, aircraftState):
538 """Log the amount of fuel"""
539 self.logger.message(aircraftState.timestamp,
540 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
541 (aircraftState.fuel[0], aircraftState.fuel[1],
542 aircraftState.fuel[2]))
543 self.logger.message(aircraftState.timestamp,
544 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
545
546#---------------------------------------------------------------------------------------
547
548class F70(Aircraft):
549 """Fokker 70 aircraft.
550
551 The aircraft type-specific values in the aircraft state have the following
552 structure:
553 - fuel: left, centre, right
554 - n1: left, right
555 - reverser: left, right."""
556 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
557
558 def __init__(self, flight):
559 super(F70, self).__init__(flight)
560 self._checkers.append(checks.ThrustChecker())
561 self.dow = 24283
562 self.mtow = 38100 # FIXME: differentiate by registration number,
563 # MTOW of HA-LMF: 41955
564 self.mlw = 36740
565 self.mzfw = 32655
566 self.gearSpeedLimit = 200
567 self.flapSpeedLimits = { 8 : 250,
568 15 : 220,
569 25 : 220,
570 42 : 180 }
571
572 def logFuel(self, aircraftState):
573 """Log the amount of fuel"""
574 self.logger.message(aircraftState.timestamp,
575 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
576 (aircraftState.fuel[0], aircraftState.fuel[1],
577 aircraftState.fuel[2]))
578 self.logger.message(aircraftState.timestamp,
579 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
580
581#---------------------------------------------------------------------------------------
582
583class DC3(Aircraft):
584 """Lisunov Li-2 (DC-3) aircraft.
585
586 The aircraft type-specific values in the aircraft state have the following
587 structure:
588 - fuel: left aux, left, right, right aux
589 - rpm: left, right
590 - reverser: left, right."""
591 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
592 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
593
594 def __init__(self, flight):
595 super(DC3, self).__init__(flight)
596 self.dow = 8627
597 self.mtow = 11884
598 self.mlw = 11793
599 self.mzfw = 11780
600 self.gearSpeedLimit = 148
601 self.flapSpeedLimits = { 15 : 135,
602 30 : 99,
603 45 : 97 }
604
605 def _checkFlightEnd(self, aircraftState):
606 """Check if the end of the flight has arrived.
607
608 This implementation checks the RPM values to be 0."""
609 for rpm in aircraftState.rpm:
610 if rpm>0: return False
611 return True
612
613 def logFuel(self, aircraftState):
614 """Log the amount of fuel"""
615 self.logger.message(aircraftState.timestamp,
616 "Fuel: left aux=%.0f kg - left=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
617 (aircraftState.fuel[0], aircraftState.fuel[1],
618 aircraftState.fuel[2], aircraftState.fuel[3]))
619 self.logger.message(aircraftState.timestamp,
620 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
621
622#---------------------------------------------------------------------------------------
623
624class T134(Aircraft):
625 """Tupolev Tu-134 aircraft.
626
627 The aircraft type-specific values in the aircraft state have the following
628 structure:
629 - fuel: left tip, left aux, centre, right aux, right tip, external 1,
630 external 2
631 - n1: left, right
632 - reverser: left, right."""
633 fuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_LEFT_AUX,
634 const.FUELTANK_CENTRE,
635 const.FUELTANK_RIGHT_AUX, const.FUELTANK_RIGHT_TIP,
636 const.FUELTANK_EXTERNAL1, const.FUELTANK_EXTERNAL2]
637
638 def __init__(self, flight):
639 super(T134, self).__init__(flight)
640 self._checkers.append(checks.ThrustChecker())
641 self.dow = 29927
642 self.mtow = 47600
643 self.mlw = 43000
644 self.mzfw = 38500
645 self.gearSpeedLimit = 216
646 self.flapSpeedLimits = { 10 : 240,
647 20 : 216,
648 30 : 161 }
649
650 def logFuel(self, aircraftState):
651 """Log the amount of fuel"""
652 self.logger.message(aircraftState.timestamp,
653 "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" % \
654 (aircraftState.fuel[1], aircraftState.fuel[0],
655 aircraftState.fuel[2],
656 aircraftState.fuel[4], aircraftState.fuel[3],
657 aircraftState.fuel[5], aircraftState.fuel[6]))
658 self.logger.message(aircraftState.timestamp,
659 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
660
661#---------------------------------------------------------------------------------------
662
663class T154(Aircraft):
664 """Tupolev Tu-154 aircraft.
665
666 The aircraft type-specific values in the aircraft state have the following
667 structure:
668 - fuel: left aux, left, centre, centre 2, right, right aux
669 - n1: left, centre, right
670 - reverser: left, right"""
671 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
672 const.FUELTANK_CENTRE, const.FUELTANK_CENTRE2,
673 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
674 def __init__(self, flight):
675 super(T154, self).__init__(flight)
676 self._checkers.append(checks.ThrustChecker())
677 self.dow = 53259
678 self.mtow = 98000
679 self.mlw = 78000
680 self.mzfw = 72000
681 self.gearSpeedLimit = 216
682 self.flapSpeedLimits = { 15 : 227,
683 28 : 194,
684 45 : 162 }
685
686 def logFuel(self, aircraftState):
687 """Log the amount of fuel"""
688 self.logger.message(aircraftState.timestamp,
689 "Fuel: left aux=%.0f kg - left=%.0f kg - centre=%.0f kg - centre 2=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
690 (aircraftState.fuel[0], aircraftState.fuel[1],
691 aircraftState.fuel[2], aircraftState.fuel[3],
692 aircraftState.fuel[4], aircraftState.fuel[5]))
693 self.logger.message(aircraftState.timestamp,
694 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
695
696#---------------------------------------------------------------------------------------
697
698
699class YK40(Aircraft):
700 """Yakovlev Yak-40 aircraft.
701
702 The aircraft type-specific values in the aircraft state have the following
703 structure:
704 - fuel: left, right
705 - n1: left, right
706 - reverser: left, right"""
707 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
708
709 def __init__(self, flight):
710 super(YK40, self).__init__(flight)
711 self._checkers.append(checks.ThrustChecker())
712 self.dow = 9400
713 self.mtow = 17200
714 self.mlw = 16800
715 self.mzfw = 12100
716 self.gearSpeedLimit = 165
717 self.flapSpeedLimits = { 20 : 165,
718 35 : 135 }
719
720 def logFuel(self, aircraftState):
721 """Log the amount of fuel"""
722 self.logger.message(aircraftState.timestamp,
723 "Fuel: left=%.0f kg - right=%.0f kg" % \
724 (aircraftState.fuel[0], aircraftState.fuel[1]))
725 self.logger.message(aircraftState.timestamp,
726 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
727
728#---------------------------------------------------------------------------------------
729
730MostFuelTankAircraft = T134
731
732#---------------------------------------------------------------------------------------
733
734_classes = { const.AIRCRAFT_B736 : B736,
735 const.AIRCRAFT_B737 : B737,
736 const.AIRCRAFT_B738 : B738,
737 const.AIRCRAFT_B733 : B733,
738 const.AIRCRAFT_B734 : B734,
739 const.AIRCRAFT_B735 : B735,
740 const.AIRCRAFT_DH8D : DH8D,
741 const.AIRCRAFT_B762 : B762,
742 const.AIRCRAFT_B763 : B763,
743 const.AIRCRAFT_CRJ2 : CRJ2,
744 const.AIRCRAFT_F70 : F70,
745 const.AIRCRAFT_DC3 : DC3,
746 const.AIRCRAFT_T134 : T134,
747 const.AIRCRAFT_T154 : T154,
748 const.AIRCRAFT_YK40 : YK40 }
749
750#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.