source: src/mlx/acft.py@ 295:7340a9356485

Last change on this file since 295:7340a9356485 was 274:b866c39279e8, checked in by István Váradi <ivaradi@…>, 12 years ago

Reworked fuel handling so that the model can tell what tanks there are

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