source: src/mlx/acft.py@ 332:9e73697f6981

Last change on this file since 332:9e73697f6981 was 331:79755718ab7d, checked in by István Váradi <ivaradi@…>, 12 years ago

#136 implemented fix

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