source: src/mlx/acft.py@ 917:803dc6bacfa5

Last change on this file since 917:803dc6bacfa5 was 917:803dc6bacfa5, checked in by István Váradi <ivaradi@…>, 5 years ago

Merged 0.39

File size: 50.0 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
[904]1151 elif bookedFlight.tailNumber=="HA-LCX":
1152 self.mtow = 100000
1153 self.mlw = 80000
1154 self.mzfw = 74000
1155
1156 self.flapSpeedLimits = { 15 : 227,
1157 28 : 194,
[905]1158 36 : 178,
[904]1159 45 : 162 }
[799]1160
[211]1161 def _appendLightsLoggers(self):
1162 """Append the loggers needed for the lights."""
1163 self._checkers.append(checks.AnticollisionLightsLogger())
1164 self._checkers.append(checks.LandingLightsLogger())
1165 self._checkers.append(checks.NavLightsLogger())
1166
1167 def _appendLightsCheckers(self):
1168 """Append the checkers needed for the lights."""
1169 self._checkers.append(checks.AntiCollisionLightsChecker())
[631]1170 self._checkers.append(checks.TupolevLandingLightsChecker())
[211]1171 self._checkers.append(checks.LandingLightsChecker())
1172 self._checkers.append(checks.NavLightsChecker())
1173
[539]1174#---------------------------------------------------------------------------------------
1175
1176class YK40(Aircraft):
1177 """Yakovlev Yak-40 aircraft.
1178
1179 The aircraft type-specific values in the aircraft state have the following
1180 structure:
1181 - fuel: left, right
1182 - n1: left, right
1183 - reverser: left, right"""
[861]1184 dow = 9400
1185
[539]1186 def __init__(self, flight):
1187 super(YK40, self).__init__(flight)
1188 self.mtow = 17200
1189 self.mlw = 16800
1190 self.mzfw = 12100
1191 self.gearSpeedLimit = 165
1192 self.flapSpeedLimits = { 20 : 165,
1193 35 : 135 }
1194
[644]1195 self.hasStrobeLight = False
1196
[539]1197 @property
1198 def speedInKnots(self):
1199 """Indicate if the speed is in knots."""
1200 return False
1201
1202 @property
[635]1203 def aglInFeet(self):
1204 """Indicate if AGL altituedes are in feet."""
1205 return False
1206
1207 @property
[539]1208 def derateType(self):
1209 """Get the derate type for this type."""
1210 return DERATE_TUPOLEV
1211
1212 def _appendLightsLoggers(self):
1213 """Append the loggers needed for the lights."""
1214 self._checkers.append(checks.AnticollisionLightsLogger())
1215 self._checkers.append(checks.LandingLightsLogger())
1216 self._checkers.append(checks.NavLightsLogger())
1217
1218 def _appendLightsCheckers(self):
1219 """Append the checkers needed for the lights."""
1220 self._checkers.append(checks.AntiCollisionLightsChecker())
1221 self._checkers.append(checks.LandingLightsChecker())
1222 self._checkers.append(checks.NavLightsChecker())
[403]1223
[7]1224#---------------------------------------------------------------------------------------
1225
[443]1226class B462(Aircraft):
1227 """British Aerospace BAe-146 aircraft.
1228
1229 The aircraft type-specific values in the aircraft state have the following
1230 structure:
1231 - fuel: left, centre, right
1232 - n1: left outer, left inner, right inner, right outer
1233 - reverser: empty (the plane has no reversers)"""
[861]1234 dow = 25706
1235
[443]1236 def __init__(self, flight):
1237 super(B462, self).__init__(flight)
1238 self.mtow = 43998
1239 self.mlw = 38599
1240 self.mzfw = 33792
1241 self.gearSpeedLimit = 210
1242 self.flapSpeedLimits = { 18 : 217,
1243 24 : 180,
1244 30 : 170,
1245 33 : 150 }
1246
[445]1247 @property
[512]1248 def derateType(self):
1249 """Get the derate type for this type."""
1250 return DERATE_B462
[445]1251
[443]1252#---------------------------------------------------------------------------------------
1253
[895]1254class IL62(Aircraft):
1255 """Ilyushin IL-62 aircraft.
1256
1257 The aircraft type-specific values in the aircraft state have the following
1258 structure:
1259 - fuel: left, centre, right
1260 - n1: left outer, left inner, right inner, right outer
1261 - reverser: empty (the plane has no reversers)"""
1262 dow = 69500
1263
1264 def __init__(self, flight):
1265 super(B462, self).__init__(flight)
1266 self.mtow = 165000
1267 self.mlw = 165000
1268 self.mzfw = 165000
1269 self.gearSpeedLimit = 210
1270 self.flapSpeedLimits = { 18 : 217,
1271 24 : 180,
1272 30 : 170,
1273 33 : 150 }
1274
1275 @property
1276 def derateType(self):
1277 """Get the derate type for this type."""
1278 return DERATE_NONE
1279
1280#---------------------------------------------------------------------------------------
1281
[274]1282mostFuelTanks = [const.FUELTANK_LEFT_TIP, const.FUELTANK_EXTERNAL1,
1283 const.FUELTANK_LEFT_AUX,
1284 const.FUELTANK_CENTRE,
1285 const.FUELTANK_RIGHT_AUX,
1286 const.FUELTANK_EXTERNAL2, const.FUELTANK_RIGHT_TIP]
[141]1287
1288#---------------------------------------------------------------------------------------
1289
[191]1290_classes = { const.AIRCRAFT_B736 : B736,
1291 const.AIRCRAFT_B737 : B737,
1292 const.AIRCRAFT_B738 : B738,
1293 const.AIRCRAFT_B738C : B738Charter,
[790]1294 const.AIRCRAFT_B732 : B732,
[191]1295 const.AIRCRAFT_B733 : B733,
1296 const.AIRCRAFT_B734 : B734,
1297 const.AIRCRAFT_B735 : B735,
1298 const.AIRCRAFT_DH8D : DH8D,
1299 const.AIRCRAFT_B762 : B762,
1300 const.AIRCRAFT_B763 : B763,
1301 const.AIRCRAFT_CRJ2 : CRJ2,
1302 const.AIRCRAFT_F70 : F70,
1303 const.AIRCRAFT_DC3 : DC3,
1304 const.AIRCRAFT_T134 : T134,
1305 const.AIRCRAFT_T154 : T154,
[443]1306 const.AIRCRAFT_YK40 : YK40,
[895]1307 const.AIRCRAFT_B462 : B462,
1308 const.AIRCRAFT_IL62 : IL62 }
[8]1309
1310#---------------------------------------------------------------------------------------
[197]1311
[862]1312def getClass(aircraftType):
1313 """Get the class representing the given aircraft types"""
1314 return _classes[aircraftType]
1315
1316#---------------------------------------------------------------------------------------
1317
[898]1318def setupTypes(aircraftTypes):
1319 """Setup the values in the given types using the info retrieved
1320 from the server."""
1321 for aircraftTypeInfo in aircraftTypes:
1322 clazz = getClass(aircraftTypeInfo.aircraftType)
1323
1324 clazz.dow = aircraftTypeInfo.dow
1325 clazz.dowCockpit = aircraftTypeInfo.dowCockpit
1326 clazz.dowCabin = aircraftTypeInfo.dowCabin
1327
1328#---------------------------------------------------------------------------------------
1329
[197]1330if __name__ == "__main__":
1331 value = SmoothedValue()
1332
1333 print "Adding 1, 12.0"
1334 value.add(1, 12.0)
1335 print value.get()
1336
1337 print "Adding 1, 15.0"
1338 value.add(1, 15.0)
1339 print value.get()
1340
1341 print "Adding 2, 18.0"
1342 value.add(2, 18.0)
1343 print value.get()
1344
1345 print "Adding 2, 20.0"
1346 value.add(2, 20.0)
1347 print value.get()
1348
1349 print "Adding 5, 22.0"
1350 value.add(5, 22.0)
1351 print value.get()
1352
1353 print "Adding 5, 25.0"
1354 value.add(5, 25.0)
1355 print value.get()
1356
1357 print "Adding 5, 29.0"
1358 value.add(5, 29.0)
1359 print value.get()
1360
1361 print "Adding 5, 21.0"
1362 value.add(5, 21.0)
1363 print value.get()
1364
1365 print "Adding 5, 26.0"
1366 value.add(5, 26.0)
1367 print value.get()
1368
1369 print "Adding 2, 30.0"
1370 value.add(2, 30.0)
1371 print value.get()
1372
1373 print "Adding 2, 55.0"
1374 value.add(2, 55.0)
1375 print value.get()
1376
1377#---------------------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.