source: src/mlx/acft.py@ 335:db900a4a0930

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

#139: added a checker for thev transponder state

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