source: src/mlx/acft.py@ 298:24c67ec5cdca

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

Documented the non-GUI modules

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