source: src/mlx/acft.py@ 899:ec5238c77005

Last change on this file since 899:ec5238c77005 was 899:ec5238c77005, checked in by István Váradi <ivaradi@…>, 6 years ago

Cockpit and cabin crew weight is included in DOW, extra people are calulcated with specific weights, and passenger weight is set to 84 kgs (re #332)

File size: 49.6 KB
RevLine 
[298]1
2import const
[619]3import gates
[298]4import checks
5import fs
[384]6from i18n import xstr
[298]7import util
8
9import sys
10import time
11import traceback
12
13from collections import deque
14
15#---------------------------------------------------------------------------------------
16
[297]17## @package mlx.acft
18#
19# The simulator-independent aircraft classes.
20#
21# This module contains the aircraft classes that contain some general data
22# about each aircraft type in the MAVA Fleet. The base class, \ref Aircraft
23# also implements some parts of the logging and traces some data. The classes
24# are also responsible for creating the \ref mlx.checks "checkers". Most of
25# them are created by the \ref Aircraft class' constructor, but there can be
26# type-specific differences. For example the lights are different for different
27# types, so there is a \ref Aircraft._appendLightsLoggers "function" which can
28# be reimplemented in child classes, if needed. This class maintains also the
29# \ref SmoothedValue "smoothed values" of the IAS and the VS and set these
30# values in the \ref mlx.fs.AircraftState "aircraft state" when it is received
31# from the simulator.
[4]32
33#---------------------------------------------------------------------------------------
34
[512]35# Derate type: no derate possible
36DERATE_NONE = 0
37
38# Derate type: Boeing, i.e. a percentage value.
39# For logging, the percentage value is expected as a string (i.e. whatever the
40# pilot enters into the text field).
41DERATE_BOEING = 1
42
43# Derate type: EPR, i.e. an EPR value.
44# For logging, the EPR value is expected as a string (i.e. whatever the pilot
45# enters into the text field).
46DERATE_EPR = 2
47
48# Derate type: Tupolev, i.e. nominal or takeoff
49# For logging, one of the DERATE_TUPOLEV_xxx values are expected.
50DERATE_TUPOLEV = 3
51
52# Tupolev derate value: nominal
53DERATE_TUPOLEV_NOMINAL = 1
54
55# Tupolev derate value: takeoff
56DERATE_TUPOLEV_TAKEOFF = 2
57
58# Derate type: BAe-146, i.e. enabled or not
59# For logging, a boolean is expected.
60DERATE_B462 = 4
61
62#---------------------------------------------------------------------------------------
63
[197]64class SmoothedValue(object):
65 """A smoothed value."""
66 def __init__(self):
67 """Construct the value."""
68 self._deque = deque()
69 self._sum = 0
70
71 def add(self, length, value):
72 """Add the given value and smooth with the given length."""
73 dequeLength = len(self._deque)
74 while dequeLength>=length:
75 self._sum -= self._deque.popleft()
76 dequeLength -= 1
77
78 self._sum += value
79 self._deque.append(value)
80
81 def get(self):
82 """Get the average."""
83 return self._sum / len(self._deque)
[331]84
[4]85#---------------------------------------------------------------------------------------
86
[709]87class SimBriefData(object):
88 """Data to be used when creating SimBrief briefings."""
89 def __init__(self, climbProfiles, cruiseProfiles, descentProfiles):
90 """Construct the SimBrief data with the given profiles."""
91 self.climbProfiles = climbProfiles
92 self.cruiseProfiles = cruiseProfiles
93 self.descentProfiles = descentProfiles
94
95#---------------------------------------------------------------------------------------
96
[4]97class Aircraft(object):
98 """Base class for aircraft."""
[898]99 dowCockpit = 2
100 dowCabin = 3
101
[8]102 @staticmethod
[798]103 def create(flight, bookedFlight):
[8]104 """Create an aircraft instance for the type in the given flight."""
[798]105 acft = _classes[flight.aircraftType](flight)
106 acft.setBookedFlight(bookedFlight)
107 return acft
[8]108
[592]109 def __init__(self, flight, minLandingFuel = None,
110 recommendedLandingFuel = None):
[4]111 """Construct the aircraft for the given type."""
[8]112 self._flight = flight
[591]113 self._minLandingFuel = minLandingFuel
[592]114 self._recommendedLandingFuel = recommendedLandingFuel
[369]115
116 self._name = None
117 self._modelName = None
118
[4]119 self._aircraftState = None
[331]120
[9]121 self._maxVS = -10000.0
122 self._minVS = 10000.0
[4]123
[101]124 self._v1r2LineIndex = None
[384]125 self._derateLineID = None
[391]126 self._takeoffAntiIceLineID = None
[96]127 self._vrefLineIndex = None
[391]128 self._landingAntiIceLineID = None
[96]129
[899]130 self.cockpitCrewWeight = 85.0
131 self.cabinCrewWeight = 75.0
132 self.humanWeight = 84.0
[117]133
[598]134 self.initialClimbSpeedAltitude = 1500
135 self.reverseMinSpeed = 50
[360]136
[644]137 self.hasStrobeLight = True
138
[611]139 self.maxTakeOffPitch = 15.0
140 self.maxTouchDownPitch = 15.0
[624]141 self.brakeCoolTime = 10.0
[611]142
[709]143 self.simBriefData = None
144
[8]145 self._checkers = []
146
[197]147 config = flight.config
[11]148 # Loggers
149
[8]150 self._checkers.append(checks.StageChecker())
[9]151 self._checkers.append(checks.TakeOffLogger())
[8]152
153 self._checkers.append(checks.AltimeterLogger())
[321]154
[366]155 self._ilsLogger = checks.ILSLogger()
156 self._checkers.append(self._ilsLogger)
[321]157 self._nav1Logger = checks.NAV1Logger()
158 self._checkers.append(self._nav1Logger)
159 self._nav2Logger = checks.NAV2Logger()
160 self._checkers.append(self._nav2Logger)
161
162 self._adf1Logger = checks.ADF1Logger()
163 self._checkers.append(self._adf1Logger)
164 self._adf2Logger = checks.ADF2Logger()
165 self._checkers.append(self._adf2Logger)
[331]166
[8]167 self._checkers.append(checks.SquawkLogger())
168
[211]169 self._appendLightsLoggers()
[8]170
171 self._checkers.append(checks.FlapsLogger())
172
173 self._checkers.append(checks.GearsLogger())
[601]174 self._checkers.append(checks.InitialClimbSpeedLogger())
[9]175 self._checkers.append(checks.CruiseSpeedLogger())
[10]176 self._checkers.append(checks.SpoilerLogger())
[338]177 self._checkers.append(checks.APLogger())
[9]178
[197]179 if config.isMessageTypeFS(const.MESSAGETYPE_VISIBILITY):
[134]180 self._checkers.append(checks.VisibilityChecker())
181
[139]182 # FIXME: we should have a central data model object, and not collect
183 # the data from the GUI. However, some pieces of data (e.g. V-speeds,
184 # etc. that is entered into the GUI) *should* be a part of the GUI and
185 # queried from it, so the model should have a reference to the GUI as
186 # well and access such data via the GUI!
[215]187 if config.onlineACARS and flight.loggedIn and not flight.entranceExam:
[139]188 self._checkers.append(checks.ACARSSender(flight._gui))
189
[11]190 # Fault checkers
[211]191
192 self._appendLightsCheckers()
[11]193
[335]194 self._checkers.append(checks.TransponderChecker())
195
[11]196 self._checkers.append(checks.BankChecker())
197
198 self._checkers.append(checks.FlapsRetractChecker())
199 self._checkers.append(checks.FlapsSpeedLimitChecker())
200
201 self._checkers.append(checks.GearsDownChecker())
202 self._checkers.append(checks.GearSpeedLimitChecker())
203
204 self._checkers.append(checks.GLoadChecker())
205
206 self._checkers.append(checks.MLWChecker())
207 self._checkers.append(checks.MTOWChecker())
208 self._checkers.append(checks.MZFWChecker())
209 self._checkers.append(checks.PayloadChecker())
210
[539]211 self._checkers.append(checks.SpeedChecker())
[11]212 self._checkers.append(checks.VSChecker())
[197]213
[447]214 timeout = 30.0 + config.realIASSmoothingLength - 1
[622]215 self._checkers.append(checks.OverspeedChecker(faultTimeout = timeout))
[331]216
[11]217 self._checkers.append(checks.StallChecker())
218
219 self._checkers.append(checks.PitotChecker())
[331]220
[598]221 self._checkers.append(checks.ReverserLogger())
[11]222 self._checkers.append(checks.ReverserChecker())
223
[273]224 if flight.aircraftType is not None and config.enableApproachCallouts:
225 approachCallouts = flight.config.getApproachCallouts(flight.aircraftType)
226 if approachCallouts:
227 self._checkers.append(checks.ApproachCalloutsPlayer(approachCallouts))
228
[197]229 self._smoothedIAS = SmoothedValue()
230 self._smoothedVS = SmoothedValue()
231
[4]232 @property
233 def type(self):
234 """Get the type of the aircraft."""
[8]235 return self._flight.aircraftType
236
237 @property
238 def flight(self):
239 """Get the flight the aircraft belongs to."""
240 return self._flight
[4]241
[8]242 @property
[592]243 def minLandingFuel(self):
244 """Get the minimum acceptable amount of the landing fuel."""
245 return self._minLandingFuel
246
247 @property
248 def recommendedLandingFuel(self):
249 """Get the recommended amount of the landing fuel."""
250 return self._recommendedLandingFuel
251
252 @property
[8]253 def logger(self):
254 """Get the logger to use for the aircraft."""
255 return self._flight.logger
256
[139]257 @property
258 def state(self):
259 """Get the current aircraft state."""
260 return self._aircraftState
[241]261
262 @property
263 def speedInKnots(self):
264 """Indicate if the speed is in knots.
265
266 This default implementation returns True."""
267 return True
[304]268
269 @property
[635]270 def aglInFeet(self):
271 """Indicate if AGL altitudes are to be logged in feet.
272
273 This default implementation returns True."""
274 return True
275
276 @property
[304]277 def timestamp(self):
278 """Get the timestamp of the current state."""
279 return None if self._aircraftState is None \
280 else self._aircraftState.timestamp
[331]281
[384]282 @property
[512]283 def derateType(self):
284 """Get the derate type for this aircraft.
285
286 This default implementation returns DERATE_NONE."""
287 return DERATE_NONE
[384]288
[798]289 def setBookedFlight(self, bookedFlight):
290 """Update the aircraft based on the booked flight data (e.g. tail number).
291
292 This default implementation does nothing."""
293
[512]294 def getDerateLine(self, value):
295 """Get the log line for the given derate value.
296
297 It uses the the derate type and produces the standard message for
298 each. This children need not override it, although they can."""
299 dt = self.derateType
[384]300
[512]301 if dt==DERATE_BOEING:
302 return "Derate calculated by the pilot: %s %%" % \
303 ("-" if value is None else value,)
304 elif dt==DERATE_EPR:
305 return "EPR calculated by the pilot: %s" % \
306 ("-" if value is None else value,)
307 elif dt==DERATE_TUPOLEV:
308 return "Thrust setting calculated by the pilot: %s" % \
309 ("-" if value is None else
310 "nominal" if value==DERATE_TUPOLEV_NOMINAL else "takeoff",)
311 elif dt==DERATE_B462:
312 return "Derate setting: %s" % \
313 ("-" if value is None else "enabled" if value else "disabled",)
314 elif dt!=DERATE_NONE:
315 print "mlx.acft.getDerateLine: invalid derate type: " + dt
[384]316
317 return None
318
[11]319 def getFlapsSpeedLimit(self, flaps):
320 """Get the speed limit for the given flaps setting."""
321 return self.flapSpeedLimits[flaps] if flaps in self.flapSpeedLimits \
322 else None
323
[8]324 def modelChanged(self, timestamp, aircraftName, modelName):
[4]325 """Called when the simulator's aircraft changes."""
[369]326 self._name = aircraftName
327 self._modelName = modelName
328 if self._flight.stage is not None:
329 self._logNameAndModel(timestamp)
[4]330
331 def handleState(self, aircraftState):
[197]332 """Called when the state of the aircraft changes.
333
334 This is the function that the simulator calls directly with the new
335 state."""
[274]336 try:
337 config = self._flight.config
[197]338
[274]339 self._smoothedIAS.add(config.realIASSmoothingLength, aircraftState.ias)
340 aircraftState.smoothedIAS = self._smoothedIAS.get()
341
342 self._smoothedVS.add(config.realVSSmoothingLength, aircraftState.vs)
343 aircraftState.smoothedVS = self._smoothedVS.get()
[197]344
[274]345 for checker in self._checkers:
346 try:
347 checker.check(self._flight, self, self._flight.logger,
348 self._aircraftState, aircraftState)
349 except:
350 print >> sys.stderr, "Checker", checker, "failed"
351 traceback.print_exc()
[7]352
[274]353 self._flight.handleState(self._aircraftState, aircraftState)
[89]354
[274]355 self._maxVS = max(self._maxVS, aircraftState.vs)
356 self._minVS = min(self._minVS, aircraftState.vs)
357 except:
358 print >> sys.stderr, "Failed to handle the state"
359 traceback.print_exc()
360 finally:
361 self._aircraftState = aircraftState
[331]362
[8]363 def setStage(self, aircraftState, newStage):
364 """Set the given stage as the new one and do whatever should be
365 done."""
[369]366 if newStage==const.STAGE_BOARDING:
367 self._logNameAndModel(aircraftState.timestamp)
368
[624]369 oldStage = self._flight.stage
370
[9]371 if self._flight.setStage(aircraftState.timestamp, newStage):
372 if newStage==const.STAGE_PUSHANDTAXI:
373 self.logger.message(aircraftState.timestamp, "Block time start")
[274]374 self._flight.logFuel(aircraftState)
[331]375 self.logger.message(aircraftState.timestamp,
[313]376 "ZFW: %.2f kg" % (aircraftState.zfw))
[134]377 flight = self._flight
378 if flight.v1 is None or flight.vr is None or flight.v2 is None:
379 fs.sendMessage(const.MESSAGETYPE_HELP,
380 "Don't forget to set the takeoff V-speeds!",
381 5)
[9]382 elif newStage==const.STAGE_TAKEOFF:
[624]383 if oldStage == const.STAGE_RTO and self._flight.hasRTO:
384 rtoState = self._flight.rtoState
385 if (aircraftState.timestamp - rtoState.timestamp) < \
386 (self.brakeCoolTime * 60.0):
387 self.logger.fault("brakeCoolTime",
388 aircraftState.timestamp,
389 "Did not cool the brakes for at least %.f minutes after the RTO" % (self.brakeCoolTime,),
390 15.0)
[241]391 self.logger.message(aircraftState.timestamp,
392 "Flight time start")
[331]393 self.logger.message(aircraftState.timestamp,
[9]394 "Takeoff weight: %.0f kg, MTOW: %.0f kg" % \
395 (aircraftState.grossWeight, self.mtow))
[409]396 self._logQNH(aircraftState)
[9]397 self.logger.message(aircraftState.timestamp,
[333]398 "Wind %03.0f/%.0f" % \
[331]399 (aircraftState.windDirection,
[9]400 aircraftState.windSpeed))
[321]401 self._logRadios(aircraftState)
[345]402 self._logV1R2(aircraftState)
[384]403 self._logDerate(aircraftState)
[391]404 self._logTakeoffAntiIce(aircraftState)
[321]405 elif newStage==const.STAGE_DESCENT or newStage==const.STAGE_LANDING:
406 self._logRadios(aircraftState)
[409]407 if newStage==const.STAGE_LANDING:
408 self._logQNH(aircraftState)
[634]409 elif newStage==const.STAGE_GOAROUND:
410 from logger import Logger
411 self._flight.handleFault("goaround",
412 aircraftState.timestamp,
413 "Go-around detected, please, explain!",
414 Logger.NO_SCORE)
[9]415 elif newStage==const.STAGE_TAXIAFTERLAND:
[184]416 flight = self._flight
417 bookedFlight = flight.bookedFlight
418 config = flight.config
[136]419 if config.onlineGateSystem and \
[215]420 flight.loggedIn and \
[184]421 not flight.entranceExam and \
[136]422 bookedFlight.arrivalICAO=="LHBP" and \
423 config.isMessageTypeFS(const.MESSAGETYPE_GATE_SYSTEM):
[134]424 self._flight.getFleet(callback = self._fleetRetrieved,
425 force = True)
[9]426 self.logger.message(aircraftState.timestamp, "Flight time end")
[274]427 self._flight.logFuel(aircraftState)
[591]428 if self._minLandingFuel is not None and \
429 aircraftState.totalFuel<self._minLandingFuel:
[597]430 self._flight.handleFault(self.__class__,
431 aircraftState.timestamp,
432 "The amount of the landing fuel is less than the minimum for this type: %ukgs (possible NO GO!)" %
433 (self._minLandingFuel,), 0)
[9]434 self.logger.message(aircraftState.timestamp,
435 "Landing weight: %.0f kg, MLW: %.0f" % \
436 (aircraftState.grossWeight, self.mlw))
437 self.logger.message(aircraftState.timestamp,
438 "Vertical speed range: %.0f..%.0f feet/min" % \
[12]439 (self._minVS, self._maxVS))
[359]440 # elif newStage==const.STAGE_PARKING:
441 # self.logger.message(aircraftState.timestamp, "Block time end")
[89]442 elif newStage==const.STAGE_END:
443 flightLength = self._flight.flightTimeEnd - self._flight.flightTimeStart
[359]444 self.logger.message(aircraftState.timestamp, "Block time end")
[89]445 self.logger.message(aircraftState.timestamp,
446 "Flight time: " +
447 util.getTimeIntervalString(flightLength))
448 self.logger.message(aircraftState.timestamp,
449 "Flown distance: %.2f NM" % \
[331]450 (self._flight.flownDistance,))
[89]451 blockLength = self._flight.blockTimeEnd - self._flight.blockTimeStart
452 self.logger.message(aircraftState.timestamp,
453 "Block time: " +
454 util.getTimeIntervalString(blockLength))
[8]455
[9]456 def prepareFlare(self):
457 """Called when it is detected that we will soon flare.
[8]458
459 On the first call, it should start monitoring some parameters more
460 closely to determine flare time."""
[9]461 self.flight.simulator.startFlare()
462
[331]463 def flareStarted(self, windSpeed, windDirection, visibility,
[9]464 flareStart, flareStartFS):
465 """Called when the flare has started."""
466 self.logger.message(self._aircraftState.timestamp, "The flare has begun")
467 self.logger.message(self._aircraftState.timestamp,
[333]468 "Wind %03.0f/%.0f" % \
[9]469 (windDirection, windSpeed))
470 self.logger.message(self._aircraftState.timestamp,
471 "Visibility: %.0f metres" % (visibility,))
[409]472 self._logQNH(self._aircraftState)
[101]473 self._logVRef()
[391]474 self._logLandingAntiIce(self._aircraftState)
[9]475 self.flight.flareStarted(flareStart, flareStartFS)
[134]476 fs.sendMessage(const.MESSAGETYPE_INFORMATION, "Flare-time", 3)
[331]477
[9]478 def flareFinished(self, flareEnd, flareEndFS, tdRate, tdRateCalculatedByFS,
479 ias, pitch, bank, heading):
480 """Called when the flare has finished."""
481 (flareTimeFromFS, flareTime) = self.flight.flareFinished(flareEnd,
[170]482 flareEndFS,
483 tdRate)
[9]484 self.logger.message(self._aircraftState.timestamp,
[153]485 "Flaretime: %.3f (from %s)" % \
[331]486 (flareTime,
[9]487 "the simulator" if flareTimeFromFS else "real time",))
488 self.logger.message(self._aircraftState.timestamp,
489 "Touchdown rate: %.0f feet/min" % (tdRate,))
490 self.logger.message(self._aircraftState.timestamp,
491 "Touchdown rate was calculated by the %s" % \
492 ("simulator" if tdRateCalculatedByFS else "logger",))
[241]493 flight = self._flight
[9]494 self.logger.message(self._aircraftState.timestamp,
[241]495 "Touchdown speed: %.0f %s" % \
496 (flight.speedFromKnots(ias),
497 flight.getEnglishSpeedUnit()))
[9]498 self.logger.message(self._aircraftState.timestamp,
499 "Touchdown pitch: %.1f degrees" % (pitch,))
500 self.logger.message(self._aircraftState.timestamp,
501 "Touchdown bank: %.1f degrees" % (bank,))
502 self.logger.message(self._aircraftState.timestamp,
503 "Touchdown heading: %03.0f degrees" % (heading,))
[331]504 self.logger.message(self._aircraftState.timestamp,
[340]505 "CG: %.1f%%" % \
[271]506 (self._aircraftState.cog*100.0,))
[8]507
[611]508 if abs(pitch)>self.maxTouchDownPitch:
509 self._flight.handleNoGo("TDPitch", self._aircraftState.timestamp,
510 "Touchdown pitch higher than aircraft maximum (%.2f)" % \
511 (self.maxTouchDownPitch,),
512 "TD TAILSTRIKE NO GO")
513
[8]514 def cancelFlare(self):
515 """Cancel flare, if it has started."""
[9]516 self.flight.simulator.cancelFlare()
[8]517
518 def checkFlightEnd(self, aircraftState):
519 """Check if the end of the flight has arrived.
520
521 This default implementation checks the N1 values, but for
522 piston-powered aircraft you need to check the RPMs."""
523 for n1 in aircraftState.n1:
524 if n1>=0.5: return False
525 return True
526
[101]527 def updateV1R2(self):
528 """Update the V1, Vr and V2 values from the flight, if the these values
529 have already been logged."""
530 if self._v1r2LineIndex is not None:
531 self._logV1R2()
532
[384]533 def updateDerate(self):
534 """Update the derate value from the flight, if the these values
535 have already been logged."""
536 if self._derateLineID is not None:
537 self._logDerate()
538
[391]539 def updateTakeoffAntiIce(self):
540 """Update the take-off anti-ice setting."""
541 if self._takeoffAntiIceLineID is not None:
542 self._logTakeoffAntiIce()
543
[211]544 def _appendLightsLoggers(self):
545 """Append the loggers needed for the lights.
546
547 This default implementation adds the loggers for the anti-collision
548 lights, the landing lights, the strobe lights and the NAV lights."""
549 self._checkers.append(checks.AnticollisionLightsLogger())
550 self._checkers.append(checks.LandingLightsLogger())
551 self._checkers.append(checks.StrobeLightsLogger())
552 self._checkers.append(checks.NavLightsLogger())
553
554 def _appendLightsCheckers(self):
555 """Append the checkers needed for the lights.
556
557 This default implementation adds the checkers for the anti-collision
558 lights, the landing lights, the strobe lights and the NAV lights."""
559 self._checkers.append(checks.AntiCollisionLightsChecker())
560 self._checkers.append(checks.LandingLightsChecker())
561 self._checkers.append(checks.NavLightsChecker())
562 self._checkers.append(checks.StrobeLightsChecker())
563
[241]564 def _speedToLog(self, speed):
565 """Convert the given speed (being either None or expressed in the
566 flight's speed unit into a string."""
567 if speed is None:
568 return "-"
569 else:
570 return str(speed) + " " + self._flight.getEnglishSpeedUnit()
571
[345]572 def _logV1R2(self, state = None):
[101]573 """Log the V1, Vr and V2 value either newly, or by updating the
574 corresponding line."""
[526]575 message = "Calc. TO speeds: V1: %s, VR: %s, V2: %s" % \
[241]576 (self._speedToLog(self._flight.v1),
577 self._speedToLog(self._flight.vr),
578 self._speedToLog(self._flight.v2))
[101]579
580 if self._v1r2LineIndex is None:
[345]581 if state is None:
582 state = self._aircraftState
[101]583 self._v1r2LineIndex = \
[345]584 self.logger.message(state.timestamp, message)
[101]585 else:
586 self.logger.updateLine(self._v1r2LineIndex, message)
587
[384]588 def _logDerate(self, state = None):
589 """Log the derate values either newly or by updating the corresponding
590 line."""
[512]591 dt = self.derateType
592 if dt==DERATE_NONE:
[384]593 return
594
[512]595 message = self.getDerateLine(self._flight.derate)
596 if message is not None:
597 if self._derateLineID is None:
598 if state is None:
599 state = self._aircraftState
600 self._derateLineID = \
601 self.logger.message(state.timestamp, message)
602 else:
603 self.logger.updateLine(self._derateLineID, message)
[384]604
[391]605 def _logTakeoffAntiIce(self, state = None):
606 """Log the take-off anti-ice setting either newly or by updating the
607 corresponding line."""
608 antiIceOn = self._flight.takeoffAntiIceOn
609 if state is not None:
610 antiIceOn = antiIceOn or state.antiIceOn is True
611 self._flight.takeoffAntiIceOn = antiIceOn
612
613 message = "Anti-ice was turned %s" % \
614 ("ON" if antiIceOn else "OFF")
615
616 if self._takeoffAntiIceLineID is None:
617 if state is None:
618 state = self._aircraftState
619 self._takeoffAntiIceLineID = \
620 self.logger.message(state.timestamp, message)
621 else:
622 self.logger.updateLine(self._takeoffAntiIceLineID, message)
623
[96]624 def updateVRef(self):
625 """Update the Vref value from the flight, if the Vref value has already
626 been logged."""
627 if self._vrefLineIndex is not None:
628 self._logVRef()
629
630 def _logVRef(self):
631 """Log the Vref value either newly, or by updating the corresponding
632 line."""
633 message = "VRef speed calculated by the pilot: %s" % \
[241]634 (self._speedToLog(self._flight.vref),)
[96]635 if self._vrefLineIndex is None:
636 self._vrefLineIndex = \
637 self.logger.message(self._aircraftState.timestamp, message)
638 else:
639 self.logger.updateLine(self._vrefLineIndex, message)
640
[391]641 def updateLandingAntiIce(self):
642 """Update the landing anti-ice setting."""
643 if self._landingAntiIceLineID is not None:
644 self._logLandingAntiIce()
645
646 def _logLandingAntiIce(self, state = None):
647 """Log the landing anti-ice setting either newly or by updating the
648 corresponding line."""
649 antiIceOn = self._flight.landingAntiIceOn
650 if state is not None:
651 antiIceOn = antiIceOn or state.antiIceOn is True
652 self._flight.landingAntiIceOn = antiIceOn
653
654 message = "Anti-ice was turned %s" % \
655 ("ON" if antiIceOn else "OFF")
656
657 if self._landingAntiIceLineID is None:
658 if state is None:
659 state = self._aircraftState
660 self._landingAntiIceLineID = \
661 self.logger.message(state.timestamp, message)
662 else:
663 self.logger.updateLine(self._landingAntiIceLineID, message)
664
[134]665 def _fleetRetrieved(self, fleet):
666 """Callback for the fleet retrieval result."""
667 if fleet is not None:
668 gateList = ""
669 occupiedGateNumbers = fleet.getOccupiedGateNumbers()
[619]670 for gate in gates.lhbpGates.gates:
671 if gate.isAvailable(gates.lhbpGates, occupiedGateNumbers):
[134]672 if gateList: gateList += ", "
[619]673 gateList += gate.number
[134]674 fs.sendMessage(const.MESSAGETYPE_GATE_SYSTEM,
675 "Free gates: " + gateList, 20)
[331]676
[134]677
[321]678 def _logRadios(self, aircraftState):
679 """Log the radios from the given aircraft state."""
680 flight = self._flight
681 logger = flight.logger
682
[366]683 self._ilsLogger.forceLog(flight, logger, aircraftState)
[321]684 self._nav1Logger.forceLog(flight, logger, aircraftState)
685 self._nav2Logger.forceLog(flight, logger, aircraftState)
[329]686 self._adf1Logger.forceLog(flight, logger, aircraftState)
687 self._adf2Logger.forceLog(flight, logger, aircraftState)
[321]688
[409]689 def _logQNH(self, aircraftState):
690 """Log the current QNH along with the altimeter setting."""
691 self.logger.message(aircraftState.timestamp,
692 "QNH: %.2f hPa, altimeter: %.2f hPa" % \
693 (aircraftState.qnh, aircraftState.altimeter))
694
[369]695 def _logNameAndModel(self, timestamp):
696 """Log the aircraft's name and model with taking the timestamp from the
697 given state."""
698 self._flight.logger.message(timestamp,
699 "Aircraft: name='%s', model='%s'" % \
700 (self._name, self._modelName))
701
[4]702#---------------------------------------------------------------------------------------
[7]703
704class Boeing737(Aircraft):
705 """Base class for the various aircraft in the Boeing 737 family.
706
707 The aircraft type-specific values in the aircraft state have the following
708 structure:
[140]709 - fuel: left, centre, right
[7]710 - n1: left, right
[331]711 - reverser: left, right"""
[592]712 def __init__(self, flight, minLandingFuel = 2500,
713 recommendedLandingFuel = 3500):
714 super(Boeing737, self).__init__(flight,
715 minLandingFuel = minLandingFuel,
716 recommendedLandingFuel =
717 recommendedLandingFuel)
[95]718
[9]719 self.gearSpeedLimit = 270
720 self.flapSpeedLimits = { 1 : 260,
721 2 : 260,
722 5 : 250,
723 10 : 210,
724 15 : 200,
725 25 : 190,
726 30 : 175,
727 40 : 162 }
[7]728
[384]729 @property
[512]730 def derateType(self):
731 """Get the derate type for this type."""
732 return DERATE_BOEING
[384]733
[7]734#---------------------------------------------------------------------------------------
735
736class B736(Boeing737):
737 """Boeing 737-600 aircraft."""
[861]738 dow = 38307
739
[8]740 def __init__(self, flight):
741 super(B736, self).__init__(flight)
[9]742 self.mtow = 58328
743 self.mlw = 54657
744 self.mzfw = 51482
[611]745 self.maxTakeOffPitch = 16.2
746 self.maxTouchDownPitch = 14.7
[709]747 self.simBriefData = SimBriefData(["250/280/78"],
748 ["CI", "M75", "M78", "M79", "M80", "LRC"],
749 ["78/280/250"])
[7]750
751#---------------------------------------------------------------------------------------
752
753class B737(Boeing737):
754 """Boeing 737-700 aircraft."""
[861]755 dow = 39250
756
[8]757 def __init__(self, flight):
758 super(B737, self).__init__(flight)
[9]759 self.mtow = 61410
760 self.mlw = 58059
761 self.mzfw = 54657
[611]762 self.maxTakeOffPitch = 14.7
763 self.maxTouchDownPitch = 13.2
[709]764 self.simBriefData = SimBriefData(["250/280/78"],
765 ["CI", "M75", "M78", "M79", "M80", "LRC"],
766 ["78/280/250", "78/250/250"])
[7]767
768#---------------------------------------------------------------------------------------
769
770class B738(Boeing737):
771 """Boeing 737-800 aircraft."""
[861]772 dow = 42690
773
[8]774 def __init__(self, flight):
775 super(B738, self).__init__(flight)
[797]776 self.mtow = 71791
[9]777 self.mlw = 65317
778 self.mzfw = 61688
[611]779 self.maxTakeOffPitch = 11
780 self.maxTouchDownPitch = 9.5
[709]781 self.simBriefData = SimBriefData(["250/280/78"],
782 ["CI", "M76", "M78", "M79", "M80", "LRC"],
783 ["78/280/250", "78/250/250"])
[9]784
785#---------------------------------------------------------------------------------------
786
787class B738Charter(B738):
788 """Boeing 737-800 aircraft used for charters."""
789 def __init__(self, flight):
790 super(B738Charter, self).__init__(flight)
791 self.mtow = 77791
[709]792 self.simBriefData = SimBriefData(["AUTO"],
793 ["280/M74"],
794 ["AUTO"])
[7]795
796#---------------------------------------------------------------------------------------
797
[591]798class Boeing737CL(Boeing737):
799 """Base class for the various aircraft in the Boeing 737 Classic family."""
800 def __init__(self, flight):
[592]801 super(Boeing737CL, self).__init__(flight, minLandingFuel = 3500,
802 recommendedLandingFuel = None)
[591]803
804#---------------------------------------------------------------------------------------
805
[790]806class B732(Boeing737CL):
807 """Boeing 737-200 aircraft."""
[861]808 dow = 27646
809
[790]810 def __init__(self, flight):
811 super(B732, self).__init__(flight)
[796]812 self.mtow = 52390
813 self.mlw = 46720
814 self.mzfw = 43091
815 self.maxTakeOffPitch = 15.5
816 self.maxTouchDownPitch = 15.5
[790]817
818#---------------------------------------------------------------------------------------
819
[591]820class B733(Boeing737CL):
[7]821 """Boeing 737-300 aircraft."""
[861]822 dow = 32900
823
[8]824 def __init__(self, flight):
825 super(B733, self).__init__(flight)
[797]826 self.mtow = 56472
827 self.mlw = 51710
828 self.mzfw = 47625
[611]829 self.maxTakeOffPitch = 13.4
830 self.maxTouchDownPitch = 12.0
[7]831
832#---------------------------------------------------------------------------------------
833
[591]834class B734(Boeing737CL):
[7]835 """Boeing 737-400 aircraft."""
[898]836 dow = 35100
837
[8]838 def __init__(self, flight):
839 super(B734, self).__init__(flight)
[797]840 self.mtow = 62822
841 self.mlw = 54885
842 self.mzfw = 51256
[611]843 self.maxTakeOffPitch = 11.4
844 self.maxTouchDownPitch = 10
[7]845
846#---------------------------------------------------------------------------------------
847
[591]848class B735(Boeing737CL):
[7]849 """Boeing 737-500 aircraft."""
[861]850 dow = 31900
851
[8]852 def __init__(self, flight):
853 super(B735, self).__init__(flight)
[797]854 self.mtow = 62823
855 self.mlw = 49895
856 self.mzfw = 46720
[611]857 self.maxTakeOffPitch = 14.7
858 self.maxTouchDownPitch = 13.2
[7]859
860#---------------------------------------------------------------------------------------
861
862class DH8D(Aircraft):
863 """Bombardier Dash-8 Q400 aircraft.
864
865 The aircraft type-specific values in the aircraft state have the following
866 structure:
[140]867 - fuel: left, right
[7]868 - n1: left, right
869 - reverser: left, right."""
[861]870 dow = 18508
[140]871
[8]872 def __init__(self, flight):
[591]873 super(DH8D, self).__init__(flight, minLandingFuel = 2000)
[797]874 self.mtow = 29574
875 self.mlw = 28123
876 self.mzfw = 26308
[9]877 self.gearSpeedLimit = 215
878 self.flapSpeedLimits = { 5 : 200,
879 10 : 181,
880 15 : 172,
881 35 : 158 }
[611]882 self.maxTakeOffPitch = 8.0
883 self.maxTouchDownPitch = 7.0
[709]884 self.simBriefData = SimBriefData(["I-900", "II-900", "III-900",
885 "I-850", "II-850", "III-850"],
886 ["MCR", "ISC", "LRC", "HSC"],
887 ["I-850", "II-850", "III-850"])
[9]888
[7]889#---------------------------------------------------------------------------------------
890
891class Boeing767(Aircraft):
892 """Base class for the various aircraft in the Boeing 767 family.
893
894 The aircraft type-specific values in the aircraft state have the following
895 structure:
[140]896 - fuel: left, centre, right
[7]897 - n1: left, right
898 - reverser: left, right"""
[140]899
[612]900 def __init__(self, flight, minLandingFuel = 7000):
[591]901 super(Boeing767, self).__init__(flight, minLandingFuel = minLandingFuel)
[9]902 self.gearSpeedLimit = 270
903 self.flapSpeedLimits = { 1 : 255,
904 5 : 235,
905 10 : 215,
906 20 : 215,
907 25 : 185,
908 30 : 175 }
[7]909
[384]910 @property
[512]911 def derateType(self):
912 """Get the derate type for this type."""
913 return DERATE_BOEING
[384]914
[7]915#---------------------------------------------------------------------------------------
916
917class B762(Boeing767):
918 """Boeing 767-200 aircraft."""
[861]919 dow = 84507
920
[8]921 def __init__(self, flight):
922 super(B762, self).__init__(flight)
[797]923 self.mtow = 159210
[9]924 self.mlw = 126098
925 self.mzfw = 114758
[611]926 self.maxTakeOffPitch = 13.1
927 self.maxTouchDownPitch = 11.6
[7]928
929#---------------------------------------------------------------------------------------
930
931class B763(Boeing767):
932 """Boeing 767-300 aircraft."""
[861]933 dow = 91311
934
[8]935 def __init__(self, flight):
[331]936 super(B763, self).__init__(flight)
[9]937 self.mtow = 181436
938 self.mlw = 137892
[797]939 self.mzfw = 114758
[611]940 self.maxTakeOffPitch = 9.6
941 self.maxTouchDownPitch = 8.1
[709]942 self.simBriefData = SimBriefData(["250/290/78"],
943 ["CI", "M76", "M78", "M80", "M82", "M84", "LRC"],
944 ["78/290/250"])
[7]945
[799]946 def setBookedFlight(self, bookedFlight):
947 """Update the aircraft based on the booked flight data (e.g. tail number)."""
948 if bookedFlight.tailNumber=="HA-LHD":
949 self.mtow = 159210
950 self.mlw = 126098
951
[7]952#---------------------------------------------------------------------------------------
953
954class CRJ2(Aircraft):
955 """Bombardier CRJ-200 aircraft.
956
957 The aircraft type-specific values in the aircraft state have the following
958 structure:
[140]959 - fuel: left, centre, right
[7]960 - n1: left, right
961 - reverser: left, right."""
[861]962 dow = 14549
963
[8]964 def __init__(self, flight):
[591]965 super(CRJ2, self).__init__(flight, minLandingFuel = 1000)
[9]966 self.mtow = 22995
967 self.mlw = 21319
968 self.mzfw = 19958
969 self.gearSpeedLimit = 240
970 self.flapSpeedLimits = { 8 : 260,
971 20 : 220,
972 30 : 190,
973 45 : 175 }
[611]974 self.maxTakeOffPitch = 18.0
975 self.maxTouchDownPitch = 18.0
[709]976 self.simBriefData = SimBriefData(["250/70", "290/74"],
977 ["CI", "LRC", "M70", "M72", "M74", "M77", "M80"],
978 ["74/290/250", "77/320/250"])
[7]979
980#---------------------------------------------------------------------------------------
981
982class F70(Aircraft):
983 """Fokker 70 aircraft.
984
985 The aircraft type-specific values in the aircraft state have the following
986 structure:
[140]987 - fuel: left, centre, right
[7]988 - n1: left, right
989 - reverser: left, right."""
[861]990 dow = 24283
991
[8]992 def __init__(self, flight):
[591]993 super(F70, self).__init__(flight, minLandingFuel = 1900)
[9]994 self.mtow = 38100 # FIXME: differentiate by registration number,
995 # MTOW of HA-LMF: 41955
996 self.mlw = 36740
997 self.mzfw = 32655
998 self.gearSpeedLimit = 200
999 self.flapSpeedLimits = { 8 : 250,
1000 15 : 220,
1001 25 : 220,
1002 42 : 180 }
[360]1003 self.reverseMinSpeed = 50
[611]1004 self.maxTakeOffPitch = 16.0
1005 self.maxTouchDownPitch = 16.0
[7]1006
[384]1007 @property
[512]1008 def derateType(self):
1009 """Get the derate type for this type."""
1010 return DERATE_EPR
[384]1011
[7]1012#---------------------------------------------------------------------------------------
1013
1014class DC3(Aircraft):
1015 """Lisunov Li-2 (DC-3) aircraft.
1016
1017 The aircraft type-specific values in the aircraft state have the following
1018 structure:
[140]1019 - fuel: left aux, left, right, right aux
[7]1020 - rpm: left, right
1021 - reverser: left, right."""
[861]1022 dow = 8627
1023
[8]1024 def __init__(self, flight):
1025 super(DC3, self).__init__(flight)
[9]1026 self.mtow = 11884
1027 self.mlw = 11793
1028 self.mzfw = 11780
1029 self.gearSpeedLimit = 148
1030 self.flapSpeedLimits = { 15 : 135,
1031 30 : 99,
1032 45 : 97 }
[8]1033
1034 def _checkFlightEnd(self, aircraftState):
1035 """Check if the end of the flight has arrived.
1036
1037 This implementation checks the RPM values to be 0."""
1038 for rpm in aircraftState.rpm:
[29]1039 if rpm>0: return False
1040 return True
[7]1041
1042#---------------------------------------------------------------------------------------
1043
1044class T134(Aircraft):
1045 """Tupolev Tu-134 aircraft.
1046
1047 The aircraft type-specific values in the aircraft state have the following
1048 structure:
[140]1049 - fuel: left tip, left aux, centre, right aux, right tip, external 1,
[7]1050 external 2
1051 - n1: left, right
1052 - reverser: left, right."""
[861]1053 dow = 29500
1054
[8]1055 def __init__(self, flight):
[591]1056 super(T134, self).__init__(flight, minLandingFuel = 3000)
[210]1057 self.mtow = 49000
[9]1058 self.mlw = 43000
1059 self.mzfw = 38500
1060 self.gearSpeedLimit = 216
[210]1061 self.flapSpeedLimits = { 10 : 450,
1062 20 : 400,
1063 30 : 300 }
[360]1064 self.reverseMinSpeed = 50
[7]1065
[644]1066 self.hasStrobeLight = False
1067
[611]1068 self.maxTakeOffPitch = 16.0
1069 self.maxTouchDownPitch = 16.0
1070
[241]1071 @property
[512]1072 def derateType(self):
1073 """Get the derate type for this type."""
1074 return DERATE_TUPOLEV
[384]1075
1076 @property
[241]1077 def speedInKnots(self):
1078 """Indicate if the speed is in knots."""
1079 return False
[331]1080
[635]1081 @property
1082 def aglInFeet(self):
1083 """Indicate if AGL altituedes are in feet."""
1084 return False
1085
[211]1086 def _appendLightsLoggers(self):
1087 """Append the loggers needed for the lights."""
1088 self._checkers.append(checks.AnticollisionLightsLogger())
1089 self._checkers.append(checks.LandingLightsLogger())
1090 self._checkers.append(checks.NavLightsLogger())
1091
1092 def _appendLightsCheckers(self):
1093 """Append the checkers needed for the lights."""
1094 self._checkers.append(checks.TupolevAntiCollisionLightsChecker())
[631]1095 self._checkers.append(checks.TupolevLandingLightsChecker())
[211]1096 self._checkers.append(checks.LandingLightsChecker())
1097 self._checkers.append(checks.NavLightsChecker())
1098
[7]1099#---------------------------------------------------------------------------------------
1100
1101class T154(Aircraft):
1102 """Tupolev Tu-154 aircraft.
1103
1104 The aircraft type-specific values in the aircraft state have the following
1105 structure:
[140]1106 - fuel: left aux, left, centre, centre 2, right, right aux
[7]1107 - n1: left, centre, right
1108 - reverser: left, right"""
[888]1109 dow = 53259
[861]1110
[8]1111 def __init__(self, flight):
[591]1112 super(T154, self).__init__(flight, minLandingFuel = 5000)
[9]1113 self.mtow = 98000
1114 self.mlw = 78000
1115 self.mzfw = 72000
1116 self.gearSpeedLimit = 216
1117 self.flapSpeedLimits = { 15 : 227,
1118 28 : 194,
1119 45 : 162 }
[360]1120 self.reverseMinSpeed = 50
[9]1121
[644]1122 self.hasStrobeLight = False
1123
[611]1124 self.maxTakeOffPitch = 16.0
1125 self.maxTouchDownPitch = 16.0
[709]1126 self.simBriefData = SimBriefData(["AUTO"],
1127 ["300/M80"],
1128 ["AUTO"])
[611]1129
[241]1130 @property
1131 def speedInKnots(self):
1132 """Indicate if the speed is in knots."""
1133 return False
[331]1134
[384]1135 @property
[635]1136 def aglInFeet(self):
1137 """Indicate if AGL altituedes are in feet."""
1138 return False
1139
1140 @property
[512]1141 def derateType(self):
1142 """Get the derate type for this type."""
1143 return DERATE_TUPOLEV
[384]1144
[799]1145 def setBookedFlight(self, bookedFlight):
1146 """Update the aircraft based on the booked flight data (e.g. tail number)."""
1147 if bookedFlight.tailNumber in ["HA-LCM", "HA-LCN", "HA-LCO", "HA-LCP",
1148 "HA-LCR", "HA-LCU", "HA-LCV"]:
1149 self.mtow = 100000
1150 self.mlw = 80000
1151
[211]1152 def _appendLightsLoggers(self):
1153 """Append the loggers needed for the lights."""
1154 self._checkers.append(checks.AnticollisionLightsLogger())
1155 self._checkers.append(checks.LandingLightsLogger())
1156 self._checkers.append(checks.NavLightsLogger())
1157
1158 def _appendLightsCheckers(self):
1159 """Append the checkers needed for the lights."""
1160 self._checkers.append(checks.AntiCollisionLightsChecker())
[631]1161 self._checkers.append(checks.TupolevLandingLightsChecker())
[211]1162 self._checkers.append(checks.LandingLightsChecker())
1163 self._checkers.append(checks.NavLightsChecker())
1164
[539]1165#---------------------------------------------------------------------------------------
1166
1167class YK40(Aircraft):
1168 """Yakovlev Yak-40 aircraft.
1169
1170 The aircraft type-specific values in the aircraft state have the following
1171 structure:
1172 - fuel: left, right
1173 - n1: left, right
1174 - reverser: left, right"""
[861]1175 dow = 9400
1176
[539]1177 def __init__(self, flight):
1178 super(YK40, self).__init__(flight)
1179 self.mtow = 17200
1180 self.mlw = 16800
1181 self.mzfw = 12100
1182 self.gearSpeedLimit = 165
1183 self.flapSpeedLimits = { 20 : 165,
1184 35 : 135 }
1185
[644]1186 self.hasStrobeLight = False
1187
[539]1188 @property
1189 def speedInKnots(self):
1190 """Indicate if the speed is in knots."""
1191 return False
1192
1193 @property
[635]1194 def aglInFeet(self):
1195 """Indicate if AGL altituedes are in feet."""
1196 return False
1197
1198 @property
[539]1199 def derateType(self):
1200 """Get the derate type for this type."""
1201 return DERATE_TUPOLEV
1202
1203 def _appendLightsLoggers(self):
1204 """Append the loggers needed for the lights."""
1205 self._checkers.append(checks.AnticollisionLightsLogger())
1206 self._checkers.append(checks.LandingLightsLogger())
1207 self._checkers.append(checks.NavLightsLogger())
1208
1209 def _appendLightsCheckers(self):
1210 """Append the checkers needed for the lights."""
1211 self._checkers.append(checks.AntiCollisionLightsChecker())
1212 self._checkers.append(checks.LandingLightsChecker())
1213 self._checkers.append(checks.NavLightsChecker())
[403]1214
[7]1215#---------------------------------------------------------------------------------------
1216
[443]1217class B462(Aircraft):
1218 """British Aerospace BAe-146 aircraft.
1219
1220 The aircraft type-specific values in the aircraft state have the following
1221 structure:
1222 - fuel: left, centre, right
1223 - n1: left outer, left inner, right inner, right outer
1224 - reverser: empty (the plane has no reversers)"""
[861]1225 dow = 25706
1226
[443]1227 def __init__(self, flight):
1228 super(B462, self).__init__(flight)
1229 self.mtow = 43998
1230 self.mlw = 38599
1231 self.mzfw = 33792
1232 self.gearSpeedLimit = 210
1233 self.flapSpeedLimits = { 18 : 217,
1234 24 : 180,
1235 30 : 170,
1236 33 : 150 }
1237
[445]1238 @property
[512]1239 def derateType(self):
1240 """Get the derate type for this type."""
1241 return DERATE_B462
[445]1242
[443]1243#---------------------------------------------------------------------------------------
1244
[895]1245class IL62(Aircraft):
1246 """Ilyushin IL-62 aircraft.
1247
1248 The aircraft type-specific values in the aircraft state have the following
1249 structure:
1250 - fuel: left, centre, right
1251 - n1: left outer, left inner, right inner, right outer
1252 - reverser: empty (the plane has no reversers)"""
1253 dow = 69500
1254
1255 def __init__(self, flight):
1256 super(B462, self).__init__(flight)
1257 self.mtow = 165000
1258 self.mlw = 165000
1259 self.mzfw = 165000
1260 self.gearSpeedLimit = 210
1261 self.flapSpeedLimits = { 18 : 217,
1262 24 : 180,
1263 30 : 170,
1264 33 : 150 }
1265
1266 @property
1267 def derateType(self):
1268 """Get the derate type for this type."""
1269 return DERATE_NONE
1270
1271#---------------------------------------------------------------------------------------
1272
[274]1273mostFuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_EXTERNAL1,
1274 const.FUELTANK_LEFT_AUX,
1275 const.FUELTANK_CENTRE,
1276 const.FUELTANK_RIGHT_AUX,
1277 const.FUELTANK_EXTERNAL2, const.FUELTANK_RIGHT_TIP]
[141]1278
1279#---------------------------------------------------------------------------------------
1280
[191]1281_classes = { const.AIRCRAFT_B736 : B736,
1282 const.AIRCRAFT_B737 : B737,
1283 const.AIRCRAFT_B738 : B738,
1284 const.AIRCRAFT_B738C : B738Charter,
[790]1285 const.AIRCRAFT_B732 : B732,
[191]1286 const.AIRCRAFT_B733 : B733,
1287 const.AIRCRAFT_B734 : B734,
1288 const.AIRCRAFT_B735 : B735,
1289 const.AIRCRAFT_DH8D : DH8D,
1290 const.AIRCRAFT_B762 : B762,
1291 const.AIRCRAFT_B763 : B763,
1292 const.AIRCRAFT_CRJ2 : CRJ2,
1293 const.AIRCRAFT_F70 : F70,
1294 const.AIRCRAFT_DC3 : DC3,
1295 const.AIRCRAFT_T134 : T134,
1296 const.AIRCRAFT_T154 : T154,
[443]1297 const.AIRCRAFT_YK40 : YK40,
[895]1298 const.AIRCRAFT_B462 : B462,
1299 const.AIRCRAFT_IL62 : IL62 }
[8]1300
1301#---------------------------------------------------------------------------------------
[197]1302
[862]1303def getClass(aircraftType):
1304 """Get the class representing the given aircraft types"""
1305 return _classes[aircraftType]
1306
1307#---------------------------------------------------------------------------------------
1308
[898]1309def setupTypes(aircraftTypes):
1310 """Setup the values in the given types using the info retrieved
1311 from the server."""
1312 for aircraftTypeInfo in aircraftTypes:
1313 clazz = getClass(aircraftTypeInfo.aircraftType)
1314
1315 clazz.dow = aircraftTypeInfo.dow
1316 clazz.dowCockpit = aircraftTypeInfo.dowCockpit
1317 clazz.dowCabin = aircraftTypeInfo.dowCabin
1318
1319#---------------------------------------------------------------------------------------
1320
[197]1321if __name__ == "__main__":
1322 value = SmoothedValue()
1323
1324 print "Adding 1, 12.0"
1325 value.add(1, 12.0)
1326 print value.get()
1327
1328 print "Adding 1, 15.0"
1329 value.add(1, 15.0)
1330 print value.get()
1331
1332 print "Adding 2, 18.0"
1333 value.add(2, 18.0)
1334 print value.get()
1335
1336 print "Adding 2, 20.0"
1337 value.add(2, 20.0)
1338 print value.get()
1339
1340 print "Adding 5, 22.0"
1341 value.add(5, 22.0)
1342 print value.get()
1343
1344 print "Adding 5, 25.0"
1345 value.add(5, 25.0)
1346 print value.get()
1347
1348 print "Adding 5, 29.0"
1349 value.add(5, 29.0)
1350 print value.get()
1351
1352 print "Adding 5, 21.0"
1353 value.add(5, 21.0)
1354 print value.get()
1355
1356 print "Adding 5, 26.0"
1357 value.add(5, 26.0)
1358 print value.get()
1359
1360 print "Adding 2, 30.0"
1361 value.add(2, 30.0)
1362 print value.get()
1363
1364 print "Adding 2, 55.0"
1365 value.add(2, 55.0)
1366 print value.get()
1367
1368#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.