source: src/mlx/acft.py@ 344:1374c29962a3

Last change on this file since 344:1374c29962a3 was 344:1374c29962a3, checked in by István Váradi <ivaradi@…>, 12 years ago

Added the speed checker for the strobeless planes (#143)

File size: 32.4 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()
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):
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 self._v1r2LineIndex = \
408 self.logger.message(self._aircraftState.timestamp, message)
409 else:
410 self.logger.updateLine(self._v1r2LineIndex, message)
411
412 def updateVRef(self):
413 """Update the Vref value from the flight, if the Vref value has already
414 been logged."""
415 if self._vrefLineIndex is not None:
416 self._logVRef()
417
418 def _logVRef(self):
419 """Log the Vref value either newly, or by updating the corresponding
420 line."""
421 message = "VRef speed calculated by the pilot: %s" % \
422 (self._speedToLog(self._flight.vref),)
423 if self._vrefLineIndex is None:
424 self._vrefLineIndex = \
425 self.logger.message(self._aircraftState.timestamp, message)
426 else:
427 self.logger.updateLine(self._vrefLineIndex, message)
428
429 def _fleetRetrieved(self, fleet):
430 """Callback for the fleet retrieval result."""
431 if fleet is not None:
432 gateList = ""
433 occupiedGateNumbers = fleet.getOccupiedGateNumbers()
434 for gateNumber in const.lhbpGateNumbers:
435 if gateNumber not in occupiedGateNumbers:
436 if gateList: gateList += ", "
437 gateList += gateNumber
438 fs.sendMessage(const.MESSAGETYPE_GATE_SYSTEM,
439 "Free gates: " + gateList, 20)
440
441
442 def _logRadios(self, aircraftState):
443 """Log the radios from the given aircraft state."""
444 flight = self._flight
445 logger = flight.logger
446
447 self._nav1Logger.forceLog(flight, logger, aircraftState)
448 self._nav2Logger.forceLog(flight, logger, aircraftState)
449 self._adf1Logger.forceLog(flight, logger, aircraftState)
450 self._adf2Logger.forceLog(flight, logger, aircraftState)
451
452#---------------------------------------------------------------------------------------
453
454class Boeing737(Aircraft):
455 """Base class for the various aircraft in the Boeing 737 family.
456
457 The aircraft type-specific values in the aircraft state have the following
458 structure:
459 - fuel: left, centre, right
460 - n1: left, right
461 - reverser: left, right"""
462 def __init__(self, flight):
463 super(Boeing737, self).__init__(flight)
464 self._checkers.append(checks.ThrustChecker())
465
466 self.gearSpeedLimit = 270
467 self.flapSpeedLimits = { 1 : 260,
468 2 : 260,
469 5 : 250,
470 10 : 210,
471 15 : 200,
472 25 : 190,
473 30 : 175,
474 40 : 162 }
475
476#---------------------------------------------------------------------------------------
477
478class B736(Boeing737):
479 """Boeing 737-600 aircraft."""
480 def __init__(self, flight):
481 super(B736, self).__init__(flight)
482 self.dow = 38307
483 self.mtow = 58328
484 self.mlw = 54657
485 self.mzfw = 51482
486
487#---------------------------------------------------------------------------------------
488
489class B737(Boeing737):
490 """Boeing 737-700 aircraft."""
491 def __init__(self, flight):
492 super(B737, self).__init__(flight)
493 self.dow = 39250
494 self.mtow = 61410
495 self.mlw = 58059
496 self.mzfw = 54657
497
498#---------------------------------------------------------------------------------------
499
500class B738(Boeing737):
501 """Boeing 737-800 aircraft."""
502 def __init__(self, flight):
503 super(B738, self).__init__(flight)
504 self.dow = 42690
505 self.mtow = 71709
506 self.mlw = 65317
507 self.mzfw = 61688
508
509#---------------------------------------------------------------------------------------
510
511class B738Charter(B738):
512 """Boeing 737-800 aircraft used for charters."""
513 def __init__(self, flight):
514 super(B738Charter, self).__init__(flight)
515 self.mtow = 77791
516
517#---------------------------------------------------------------------------------------
518
519class B733(Boeing737):
520 """Boeing 737-300 aircraft."""
521 def __init__(self, flight):
522 super(B733, self).__init__(flight)
523 self.dow = 32700
524 self.mtow = 62820
525 self.mlw = 51700
526 self.mzfw = 48410
527
528#---------------------------------------------------------------------------------------
529
530class B734(Boeing737):
531 """Boeing 737-400 aircraft."""
532 def __init__(self, flight):
533 super(B734, self).__init__(flight)
534 self.dow = 33200
535 self.mtow = 68050
536 self.mlw = 56200
537 self.mzfw = 53100
538
539#---------------------------------------------------------------------------------------
540
541class B735(Boeing737):
542 """Boeing 737-500 aircraft."""
543 def __init__(self, flight):
544 super(B735, self).__init__(flight)
545 self.dow = 31300
546 self.mtow = 60550
547 self.mlw = 50000
548 self.mzfw = 46700
549
550#---------------------------------------------------------------------------------------
551
552class DH8D(Aircraft):
553 """Bombardier Dash-8 Q400 aircraft.
554
555 The aircraft type-specific values in the aircraft state have the following
556 structure:
557 - fuel: left, right
558 - n1: left, right
559 - reverser: left, right."""
560
561 def __init__(self, flight):
562 super(DH8D, self).__init__(flight)
563 self.dow = 17185
564 self.mtow = 29257
565 self.mlw = 28009
566 self.mzfw = 25855
567 self.gearSpeedLimit = 215
568 self.flapSpeedLimits = { 5 : 200,
569 10 : 181,
570 15 : 172,
571 35 : 158 }
572
573#---------------------------------------------------------------------------------------
574
575class Boeing767(Aircraft):
576 """Base class for the various aircraft in the Boeing 767 family.
577
578 The aircraft type-specific values in the aircraft state have the following
579 structure:
580 - fuel: left, centre, right
581 - n1: left, right
582 - reverser: left, right"""
583
584 def __init__(self, flight):
585 super(Boeing767, self).__init__(flight)
586 self._checkers.append(checks.ThrustChecker())
587 self.gearSpeedLimit = 270
588 self.flapSpeedLimits = { 1 : 255,
589 5 : 235,
590 10 : 215,
591 20 : 215,
592 25 : 185,
593 30 : 175 }
594
595#---------------------------------------------------------------------------------------
596
597class B762(Boeing767):
598 """Boeing 767-200 aircraft."""
599 def __init__(self, flight):
600 super(B762, self).__init__(flight)
601 self.dow = 84507
602 self.mtow = 175540
603 self.mlw = 126098
604 self.mzfw = 114758
605
606#---------------------------------------------------------------------------------------
607
608class B763(Boeing767):
609 """Boeing 767-300 aircraft."""
610 def __init__(self, flight):
611 super(B763, self).__init__(flight)
612 self.dow = 91311
613 self.mtow = 181436
614 self.mlw = 137892
615 self.mzfw = 130635
616
617#---------------------------------------------------------------------------------------
618
619class CRJ2(Aircraft):
620 """Bombardier CRJ-200 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(CRJ2, self).__init__(flight)
629 self._checkers.append(checks.ThrustChecker())
630 self.dow = 14549
631 self.mtow = 22995
632 self.mlw = 21319
633 self.mzfw = 19958
634 self.gearSpeedLimit = 240
635 self.flapSpeedLimits = { 8 : 260,
636 20 : 220,
637 30 : 190,
638 45 : 175 }
639
640#---------------------------------------------------------------------------------------
641
642class F70(Aircraft):
643 """Fokker 70 aircraft.
644
645 The aircraft type-specific values in the aircraft state have the following
646 structure:
647 - fuel: left, centre, right
648 - n1: left, right
649 - reverser: left, right."""
650 def __init__(self, flight):
651 super(F70, self).__init__(flight)
652 self._checkers.append(checks.ThrustChecker())
653 self.dow = 24283
654 self.mtow = 38100 # FIXME: differentiate by registration number,
655 # MTOW of HA-LMF: 41955
656 self.mlw = 36740
657 self.mzfw = 32655
658 self.gearSpeedLimit = 200
659 self.flapSpeedLimits = { 8 : 250,
660 15 : 220,
661 25 : 220,
662 42 : 180 }
663
664#---------------------------------------------------------------------------------------
665
666class DC3(Aircraft):
667 """Lisunov Li-2 (DC-3) aircraft.
668
669 The aircraft type-specific values in the aircraft state have the following
670 structure:
671 - fuel: left aux, left, right, right aux
672 - rpm: left, right
673 - reverser: left, right."""
674 def __init__(self, flight):
675 super(DC3, self).__init__(flight)
676 self.dow = 8627
677 self.mtow = 11884
678 self.mlw = 11793
679 self.mzfw = 11780
680 self.gearSpeedLimit = 148
681 self.flapSpeedLimits = { 15 : 135,
682 30 : 99,
683 45 : 97 }
684
685 def _checkFlightEnd(self, aircraftState):
686 """Check if the end of the flight has arrived.
687
688 This implementation checks the RPM values to be 0."""
689 for rpm in aircraftState.rpm:
690 if rpm>0: return False
691 return True
692
693#---------------------------------------------------------------------------------------
694
695class T134(Aircraft):
696 """Tupolev Tu-134 aircraft.
697
698 The aircraft type-specific values in the aircraft state have the following
699 structure:
700 - fuel: left tip, left aux, centre, right aux, right tip, external 1,
701 external 2
702 - n1: left, right
703 - reverser: left, right."""
704 def __init__(self, flight):
705 super(T134, self).__init__(flight)
706 self._checkers.append(checks.ThrustChecker())
707 self.dow = 29500
708 self.mtow = 49000
709 self.mlw = 43000
710 self.mzfw = 38500
711 self.gearSpeedLimit = 216
712 self.flapSpeedLimits = { 10 : 450,
713 20 : 400,
714 30 : 300 }
715
716 @property
717 def speedInKnots(self):
718 """Indicate if the speed is in knots."""
719 return False
720
721 def _appendLightsLoggers(self):
722 """Append the loggers needed for the lights."""
723 self._checkers.append(checks.AnticollisionLightsLogger())
724 self._checkers.append(checks.LandingLightsLogger())
725 self._checkers.append(checks.NavLightsLogger())
726
727 def _appendLightsCheckers(self):
728 """Append the checkers needed for the lights."""
729 self._checkers.append(checks.TupolevAntiCollisionLightsChecker())
730 self._checkers.append(checks.LandingLightsChecker())
731 self._checkers.append(checks.NavLightsChecker())
732
733#---------------------------------------------------------------------------------------
734
735class T154(Aircraft):
736 """Tupolev Tu-154 aircraft.
737
738 The aircraft type-specific values in the aircraft state have the following
739 structure:
740 - fuel: left aux, left, centre, centre 2, right, right aux
741 - n1: left, centre, right
742 - reverser: left, right"""
743 def __init__(self, flight):
744 super(T154, self).__init__(flight)
745 self.dow = 53259
746 self.mtow = 98000
747 self.mlw = 78000
748 self.mzfw = 72000
749 self.gearSpeedLimit = 216
750 self.flapSpeedLimits = { 15 : 227,
751 28 : 194,
752 45 : 162 }
753
754 @property
755 def speedInKnots(self):
756 """Indicate if the speed is in knots."""
757 return False
758
759 def _appendLightsLoggers(self):
760 """Append the loggers needed for the lights."""
761 self._checkers.append(checks.AnticollisionLightsLogger())
762 self._checkers.append(checks.LandingLightsLogger())
763 self._checkers.append(checks.NavLightsLogger())
764
765 def _appendLightsCheckers(self):
766 """Append the checkers needed for the lights."""
767 self._checkers.append(checks.AntiCollisionLightsChecker())
768 self._checkers.append(checks.LandingLightsChecker())
769 self._checkers.append(checks.NavLightsChecker())
770
771#---------------------------------------------------------------------------------------
772
773
774class YK40(Aircraft):
775 """Yakovlev Yak-40 aircraft.
776
777 The aircraft type-specific values in the aircraft state have the following
778 structure:
779 - fuel: left, right
780 - n1: left, right
781 - reverser: left, right"""
782 def __init__(self, flight):
783 super(YK40, self).__init__(flight)
784 self._checkers.append(checks.ThrustChecker())
785 self.dow = 9400
786 self.mtow = 17200
787 self.mlw = 16800
788 self.mzfw = 12100
789 self.gearSpeedLimit = 165
790 self.flapSpeedLimits = { 20 : 165,
791 35 : 135 }
792
793 @property
794 def speedInKnots(self):
795 """Indicate if the speed is in knots."""
796 return False
797
798 def _appendLightsLoggers(self):
799 """Append the loggers needed for the lights."""
800 self._checkers.append(checks.AnticollisionLightsLogger())
801 self._checkers.append(checks.LandingLightsLogger())
802 self._checkers.append(checks.NavLightsLogger())
803
804 def _appendLightsCheckers(self):
805 """Append the checkers needed for the lights."""
806 self._checkers.append(checks.AntiCollisionLightsChecker())
807 self._checkers.append(checks.LandingLightsChecker())
808 self._checkers.append(checks.NavLightsChecker())
809
810#---------------------------------------------------------------------------------------
811
812mostFuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_EXTERNAL1,
813 const.FUELTANK_LEFT_AUX,
814 const.FUELTANK_CENTRE,
815 const.FUELTANK_RIGHT_AUX,
816 const.FUELTANK_EXTERNAL2, const.FUELTANK_RIGHT_TIP]
817
818#---------------------------------------------------------------------------------------
819
820_classes = { const.AIRCRAFT_B736 : B736,
821 const.AIRCRAFT_B737 : B737,
822 const.AIRCRAFT_B738 : B738,
823 const.AIRCRAFT_B738C : B738Charter,
824 const.AIRCRAFT_B733 : B733,
825 const.AIRCRAFT_B734 : B734,
826 const.AIRCRAFT_B735 : B735,
827 const.AIRCRAFT_DH8D : DH8D,
828 const.AIRCRAFT_B762 : B762,
829 const.AIRCRAFT_B763 : B763,
830 const.AIRCRAFT_CRJ2 : CRJ2,
831 const.AIRCRAFT_F70 : F70,
832 const.AIRCRAFT_DC3 : DC3,
833 const.AIRCRAFT_T134 : T134,
834 const.AIRCRAFT_T154 : T154,
835 const.AIRCRAFT_YK40 : YK40 }
836
837#---------------------------------------------------------------------------------------
838
839if __name__ == "__main__":
840 value = SmoothedValue()
841
842 print "Adding 1, 12.0"
843 value.add(1, 12.0)
844 print value.get()
845
846 print "Adding 1, 15.0"
847 value.add(1, 15.0)
848 print value.get()
849
850 print "Adding 2, 18.0"
851 value.add(2, 18.0)
852 print value.get()
853
854 print "Adding 2, 20.0"
855 value.add(2, 20.0)
856 print value.get()
857
858 print "Adding 5, 22.0"
859 value.add(5, 22.0)
860 print value.get()
861
862 print "Adding 5, 25.0"
863 value.add(5, 25.0)
864 print value.get()
865
866 print "Adding 5, 29.0"
867 value.add(5, 29.0)
868 print value.get()
869
870 print "Adding 5, 21.0"
871 value.add(5, 21.0)
872 print value.get()
873
874 print "Adding 5, 26.0"
875 value.add(5, 26.0)
876 print value.get()
877
878 print "Adding 2, 30.0"
879 value.add(2, 30.0)
880 print value.get()
881
882 print "Adding 2, 55.0"
883 value.add(2, 55.0)
884 print value.get()
885
886#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.