source: src/mlx/acft.py@ 320:cc7c3c84efa0

Last change on this file since 320:cc7c3c84efa0 was 317:26cd9b16bf92, checked in by István Váradi <ivaradi@…>, 12 years ago

Added the logging of the ADF frequencies

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