source: src/mlx/acft.py@ 348:50659419e5d8

Last change on this file since 348:50659419e5d8 was 345:a62373a28d90, checked in by István Váradi <ivaradi@…>, 12 years ago

Implemented the new, more flexible way of storing the log during flight (#143)

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