source: src/mlx/acft.py@ 339:ede634649e12

Last change on this file since 339:ede634649e12 was 338:eefffab45077, checked in by István Váradi <ivaradi@…>, 12 years ago

Added a delayed logging of the AP settings

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