source: src/mlx/acft.py@ 140:7f24ede5d214

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

Reworked fuel tank handling to be more indirect

File size: 30.2 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 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)
210
211 def prepareFlare(self):
212 """Called when it is detected that we will soon flare.
213
214 On the first call, it should start monitoring some parameters more
215 closely to determine flare time."""
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,))
230 self._logVRef()
231 self.flight.flareStarted(flareStart, flareStartFS)
232 fs.sendMessage(const.MESSAGETYPE_INFORMATION, "Flare-time", 3)
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,))
256
257 def cancelFlare(self):
258 """Cancel flare, if it has started."""
259 self.flight.simulator.cancelFlare()
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
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
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
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
323#---------------------------------------------------------------------------------------
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: left, centre, right
331 - n1: left, right
332 - reverser: left, right"""
333 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
334
335 def __init__(self, flight):
336 super(Boeing737, self).__init__(flight)
337 self._checkers.append(checks.ThrustChecker())
338
339 self.gearSpeedLimit = 270
340 self.flapSpeedLimits = { 1 : 260,
341 2 : 260,
342 5 : 250,
343 10 : 210,
344 15 : 200,
345 25 : 190,
346 30 : 175,
347 40 : 162 }
348
349 def logFuel(self, aircraftState):
350 """Log the amount of fuel"""
351 self.logger.message(aircraftState.timestamp,
352 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
353 (aircraftState.fuel[1], aircraftState.fuel[0],
354 aircraftState.fuel[2]))
355 self.logger.message(aircraftState.timestamp,
356 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
357
358#---------------------------------------------------------------------------------------
359
360class B736(Boeing737):
361 """Boeing 737-600 aircraft."""
362 def __init__(self, flight):
363 super(B736, self).__init__(flight)
364 self.dow = 38307
365 self.mtow = 58328
366 self.mlw = 54657
367 self.mzfw = 51482
368
369#---------------------------------------------------------------------------------------
370
371class B737(Boeing737):
372 """Boeing 737-700 aircraft."""
373 def __init__(self, flight):
374 super(B737, self).__init__(flight)
375 self.dow = 39250
376 self.mtow = 61410
377 self.mlw = 58059
378 self.mzfw = 54657
379
380#---------------------------------------------------------------------------------------
381
382class B738(Boeing737):
383 """Boeing 737-800 aircraft."""
384 def __init__(self, flight):
385 super(B738, self).__init__(flight)
386 self.dow = 42690
387 self.mtow = 71709
388 self.mlw = 65317
389 self.mzfw = 61688
390
391#---------------------------------------------------------------------------------------
392
393class B738Charter(B738):
394 """Boeing 737-800 aircraft used for charters."""
395 def __init__(self, flight):
396 super(B738Charter, self).__init__(flight)
397 self.mtow = 77791
398
399#---------------------------------------------------------------------------------------
400
401class B733(Boeing737):
402 """Boeing 737-300 aircraft."""
403 def __init__(self, flight):
404 super(B733, self).__init__(flight)
405 self.dow = 32700
406 self.mtow = 62820
407 self.mlw = 51700
408 self.mzfw = 48410
409
410#---------------------------------------------------------------------------------------
411
412class B734(Boeing737):
413 """Boeing 737-400 aircraft."""
414 def __init__(self, flight):
415 super(B734, self).__init__(flight)
416 self.dow = 33200
417 self.mtow = 68050
418 self.mlw = 56200
419 self.mzfw = 53100
420
421#---------------------------------------------------------------------------------------
422
423class B735(Boeing737):
424 """Boeing 737-500 aircraft."""
425 def __init__(self, flight):
426 super(B735, self).__init__(flight)
427 self.dow = 31300
428 self.mtow = 60550
429 self.mlw = 50000
430 self.mzfw = 46700
431
432#---------------------------------------------------------------------------------------
433
434class DH8D(Aircraft):
435 """Bombardier Dash-8 Q400 aircraft.
436
437 The aircraft type-specific values in the aircraft state have the following
438 structure:
439 - fuel: left, right
440 - n1: left, right
441 - reverser: left, right."""
442 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
443
444 def __init__(self, flight):
445 super(DH8D, self).__init__(flight)
446 self.dow = 17185
447 self.mtow = 29257
448 self.mlw = 28009
449 self.mzfw = 25855
450 self.gearSpeedLimit = 215
451 self.flapSpeedLimits = { 5 : 200,
452 10 : 181,
453 15 : 172,
454 35 : 158 }
455
456 def logFuel(self, aircraftState):
457 """Log the amount of fuel"""
458 self.logger.message(aircraftState.timestamp,
459 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
460 (aircraftState.fuel[1], aircraftState.fuel[0],
461 aircraftState.fuel[2]))
462 self.logger.message(aircraftState.timestamp,
463 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
464
465#---------------------------------------------------------------------------------------
466
467class Boeing767(Aircraft):
468 """Base class for the various aircraft in the Boeing 767 family.
469
470 The aircraft type-specific values in the aircraft state have the following
471 structure:
472 - fuel: left, centre, right
473 - n1: left, right
474 - reverser: left, right"""
475 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
476
477 def __init__(self, flight):
478 super(Boeing767, self).__init__(flight)
479 self._checkers.append(checks.ThrustChecker())
480 self.gearSpeedLimit = 270
481 self.flapSpeedLimits = { 1 : 255,
482 5 : 235,
483 10 : 215,
484 20 : 215,
485 25 : 185,
486 30 : 175 }
487
488 def logFuel(self, aircraftState):
489 """Log the amount of fuel"""
490 self.logger.message(aircraftState.timestamp,
491 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
492 (aircraftState.fuel[1], aircraftState.fuel[0],
493 aircraftState.fuel[2]))
494 self.logger.message(aircraftState.timestamp,
495 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
496
497#---------------------------------------------------------------------------------------
498
499class B762(Boeing767):
500 """Boeing 767-200 aircraft."""
501 def __init__(self, flight):
502 super(B762, self).__init__(flight)
503 self.dow = 84507
504 self.mtow = 175540
505 self.mlw = 126098
506 self.mzfw = 114758
507
508#---------------------------------------------------------------------------------------
509
510class B763(Boeing767):
511 """Boeing 767-300 aircraft."""
512 def __init__(self, flight):
513 super(B763, self).__init__(cflight)
514 self.dow = 91311
515 self.mtow = 181436
516 self.mlw = 137892
517 self.mzfw = 130635
518
519#---------------------------------------------------------------------------------------
520
521class CRJ2(Aircraft):
522 """Bombardier CRJ-200 aircraft.
523
524 The aircraft type-specific values in the aircraft state have the following
525 structure:
526 - fuel: left, centre, right
527 - n1: left, right
528 - reverser: left, right."""
529 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
530
531 def __init__(self, flight):
532 super(CRJ2, self).__init__(flight)
533 self._checkers.append(checks.ThrustChecker())
534 self.dow = 14549
535 self.mtow = 22995
536 self.mlw = 21319
537 self.mzfw = 19958
538 self.gearSpeedLimit = 240
539 self.flapSpeedLimits = { 8 : 260,
540 20 : 220,
541 30 : 190,
542 45 : 175 }
543
544 def logFuel(self, aircraftState):
545 """Log the amount of fuel"""
546 self.logger.message(aircraftState.timestamp,
547 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
548 (aircraftState.fuel[1], aircraftState.fuel[0],
549 aircraftState.fuel[2]))
550 self.logger.message(aircraftState.timestamp,
551 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
552
553#---------------------------------------------------------------------------------------
554
555class F70(Aircraft):
556 """Fokker 70 aircraft.
557
558 The aircraft type-specific values in the aircraft state have the following
559 structure:
560 - fuel: left, centre, right
561 - n1: left, right
562 - reverser: left, right."""
563 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_CENTRE, const.FUELTANK_RIGHT]
564
565 def __init__(self, flight):
566 super(F70, self).__init__(flight)
567 self._checkers.append(checks.ThrustChecker())
568 self.dow = 24283
569 self.mtow = 38100 # FIXME: differentiate by registration number,
570 # MTOW of HA-LMF: 41955
571 self.mlw = 36740
572 self.mzfw = 32655
573 self.gearSpeedLimit = 200
574 self.flapSpeedLimits = { 8 : 250,
575 15 : 220,
576 25 : 220,
577 42 : 180 }
578
579 def logFuel(self, aircraftState):
580 """Log the amount of fuel"""
581 self.logger.message(aircraftState.timestamp,
582 "Fuel: left=%.0f kg - centre=%.0f kg - right=%.0f kg" % \
583 (aircraftState.fuel[1], aircraftState.fuel[0],
584 aircraftState.fuel[2]))
585 self.logger.message(aircraftState.timestamp,
586 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
587
588#---------------------------------------------------------------------------------------
589
590class DC3(Aircraft):
591 """Lisunov Li-2 (DC-3) aircraft.
592
593 The aircraft type-specific values in the aircraft state have the following
594 structure:
595 - fuel: left aux, left, right, right aux
596 - rpm: left, right
597 - reverser: left, right."""
598 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
599 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
600
601 def __init__(self, flight):
602 super(DC3, self).__init__(flight)
603 self.dow = 8627
604 self.mtow = 11884
605 self.mlw = 11793
606 self.mzfw = 11780
607 self.gearSpeedLimit = 148
608 self.flapSpeedLimits = { 15 : 135,
609 30 : 99,
610 45 : 97 }
611
612 def _checkFlightEnd(self, aircraftState):
613 """Check if the end of the flight has arrived.
614
615 This implementation checks the RPM values to be 0."""
616 for rpm in aircraftState.rpm:
617 if rpm>0: return False
618 return True
619
620 def logFuel(self, aircraftState):
621 """Log the amount of fuel"""
622 self.logger.message(aircraftState.timestamp,
623 "Fuel: left aux=%.0f kg - left=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
624 (aircraftState.fuel[2], aircraftState.fuel[0],
625 aircraftState.fuel[1], aircraftState.fuel[3]))
626 self.logger.message(aircraftState.timestamp,
627 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
628
629#---------------------------------------------------------------------------------------
630
631class T134(Aircraft):
632 """Tupolev Tu-134 aircraft.
633
634 The aircraft type-specific values in the aircraft state have the following
635 structure:
636 - fuel: left tip, left aux, centre, right aux, right tip, external 1,
637 external 2
638 - n1: left, right
639 - reverser: left, right."""
640 fuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_LEFT_AUX,
641 const.FUELTANK_CENTRE,
642 const.FUELTANK_RIGHT_AUX, const.FUELTANK_RIGHT_TIP,
643 const.FUELTANK_EXTERNAL1, const.FUELTANK_EXTERNAL2]
644
645 def __init__(self, flight):
646 super(T134, self).__init__(flight)
647 self._checkers.append(checks.ThrustChecker())
648 self.dow = 29927
649 self.mtow = 47600
650 self.mlw = 43000
651 self.mzfw = 38500
652 self.gearSpeedLimit = 216
653 self.flapSpeedLimits = { 10 : 240,
654 20 : 216,
655 30 : 161 }
656
657 def logFuel(self, aircraftState):
658 """Log the amount of fuel"""
659 self.logger.message(aircraftState.timestamp,
660 "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" % \
661 (aircraftState.fuel[2], aircraftState.fuel[1],
662 aircraftState.fuel[0],
663 aircraftState.fuel[3], aircraftState.fuel[4],
664 aircraftState.fuel[5], aircraftState.fuel[6]))
665 self.logger.message(aircraftState.timestamp,
666 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
667
668#---------------------------------------------------------------------------------------
669
670class T154(Aircraft):
671 """Tupolev Tu-154 aircraft.
672
673 The aircraft type-specific values in the aircraft state have the following
674 structure:
675 - fuel: left aux, left, centre, centre 2, right, right aux
676 - n1: left, centre, right
677 - reverser: left, right"""
678 fuelTanks = [const.FUELTANK_LEFT_AUX, const.FUELTANK_LEFT,
679 const.FUELTANK_CENTRE, const.FUELTANK_CENTRE2,
680 const.FUELTANK_RIGHT, const.FUELTANK_RIGHT_AUX]
681 def __init__(self, flight):
682 super(T154, self).__init__(flight)
683 self._checkers.append(checks.ThrustChecker())
684 self.dow = 53259
685 self.mtow = 98000
686 self.mlw = 78000
687 self.mzfw = 72000
688 self.gearSpeedLimit = 216
689 self.flapSpeedLimits = { 15 : 227,
690 28 : 194,
691 45 : 162 }
692
693 def logFuel(self, aircraftState):
694 """Log the amount of fuel"""
695 self.logger.message(aircraftState.timestamp,
696 "Fuel: left aux=%.0f kg - left=%.0f kg - centre=%.0f kg - centre 2=%.0f kg - right=%.0f kg - right aux=%.0f kg" % \
697 (aircraftState.fuel[4], aircraftState.fuel[1],
698 aircraftState.fuel[0], aircraftState.fuel[3],
699 aircraftState.fuel[2], aircraftState.fuel[5]))
700 self.logger.message(aircraftState.timestamp,
701 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
702
703#---------------------------------------------------------------------------------------
704
705
706class YK40(Aircraft):
707 """Yakovlev Yak-40 aircraft.
708
709 The aircraft type-specific values in the aircraft state have the following
710 structure:
711 - fuel: left, right
712 - n1: left, right
713 - reverser: left, right"""
714 fuelTanks = [const.FUELTANK_LEFT, const.FUELTANK_RIGHT]
715
716 def __init__(self, flight):
717 super(YK40, self).__init__(flight)
718 self._checkers.append(checks.ThrustChecker())
719 self.dow = 9400
720 self.mtow = 17200
721 self.mlw = 16800
722 self.mzfw = 12100
723 self.gearSpeedLimit = 165
724 self.flapSpeedLimits = { 20 : 165,
725 35 : 135 }
726
727 def logFuel(self, aircraftState):
728 """Log the amount of fuel"""
729 self.logger.message(aircraftState.timestamp,
730 "Fuel: left=%.0f kg - right=%.0f kg" % \
731 (aircraftState.fuel[0], aircraftState.fuel[1]))
732 self.logger.message(aircraftState.timestamp,
733 "Total fuel: %.0f kg" % (sum(aircraftState.fuel),))
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.