source: src/mlx/acft.py@ 184:0a000ef19c3a

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

Added support for the entrance exam

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