source: src/mlx/acft.py@ 139:839016dcd0d1

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

Implemented ACARS sending

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