Changeset 11:433f7e61f9f3


Ignore:
Timestamp:
02/08/12 16:28:21 (13 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Added the checks

Files:
7 edited

Legend:

Unmodified
Added
Removed
  • TODO

    r10 r11  
    22
    33- Test:
     4   - Check how pitot heat works on the Dash-8
  • src/acft.py

    r10 r11  
    2727        self._checkers = []
    2828
     29        # Loggers
     30
    2931        self._checkers.append(checks.StageChecker())
    3032        self._checkers.append(checks.TakeOffLogger())
     
    4749        self._checkers.append(checks.SpoilerLogger())
    4850
     51        # Fault checkers
     52       
     53        self._checkers.append(checks.AntiCollisionLightsChecker())
     54        self._checkers.append(checks.LandingLightsChecker())
     55        self._checkers.append(checks.NavLightsChecker())
     56        self._checkers.append(checks.StrobeLightsChecker())
     57
     58        self._checkers.append(checks.BankChecker())
     59
     60        self._checkers.append(checks.FlapsRetractChecker())
     61        self._checkers.append(checks.FlapsSpeedLimitChecker())
     62
     63        self._checkers.append(checks.GearsDownChecker())
     64        self._checkers.append(checks.GearSpeedLimitChecker())
     65
     66        self._checkers.append(checks.GLoadChecker())
     67
     68        self._checkers.append(checks.MLWChecker())
     69        self._checkers.append(checks.MTOWChecker())
     70        self._checkers.append(checks.MZFWChecker())
     71        self._checkers.append(checks.PayloadChecker())
     72
     73        self._checkers.append(checks.SpeedChecker())
     74        self._checkers.append(checks.VSChecker())
     75        self._checkers.append(checks.OverspeedChecker())
     76        self._checkers.append(checks.StallChecker())
     77
     78        self._checkers.append(checks.PitotChecker())
     79       
     80        self._checkers.append(checks.ThrustChecker())
     81        self._checkers.append(checks.ReverserChecker())
     82
    4983    @property
    5084    def type(self):
     
    6195        """Get the logger to use for the aircraft."""
    6296        return self._flight.logger
     97
     98    def getFlapsSpeedLimit(self, flaps):
     99        """Get the speed limit for the given flaps setting."""
     100        return self.flapSpeedLimits[flaps] if flaps in self.flapSpeedLimits \
     101               else None
    63102
    64103    def modelChanged(self, timestamp, aircraftName, modelName):
  • src/checks.py

    r10 r11  
    365365
    366366#---------------------------------------------------------------------------------------
     367
     368class FaultChecker(StateChecker):
     369    """Base class for checkers that look for faults."""
     370    @staticmethod
     371    def _appendDuring(flight, message):
     372        """Append a 'during XXX' test to the given message, depending on the
     373        flight stage."""
     374        stageStr = const.stage2string(flight.stage)
     375        return message if stageStr is None \
     376               else (message + " during " + stageStr.upper())
     377
     378    @staticmethod
     379    def _getLinearScore(minFaultValue, maxFaultValue, minScore, maxScore,
     380                        value):
     381        """Get the score for a faulty value where the score is calculated
     382        linearly within a certain range."""
     383        if value<minFaultValue:
     384            return 0
     385        elif value>maxFaultValue:
     386            return maxScore
     387        else:
     388            return minScore + (maxScore-minScore) * (value-minFaultValue) / \
     389                   (maxFaultValue - minFaultValue)
     390
     391#---------------------------------------------------------------------------------------
     392
     393class SimpleFaultChecker(FaultChecker):
     394    """Base class for fault checkers that check for a single occurence of a
     395    faulty condition.
     396
     397    Child classes should implement the following functions:
     398    - isCondition(self, flight, aircraft, oldState, state): should return whether the
     399    condition holds
     400    - logFault(self, flight, aircraft, logger, oldState, state): log the fault
     401    via the logger."""
     402    def check(self, flight, aircraft, logger, oldState, state):
     403        """Perform the check."""
     404        if self.isCondition(flight, aircraft, oldState, state):
     405            self.logFault(flight, aircraft, logger, oldState, state)
     406
     407#---------------------------------------------------------------------------------------
     408
     409class PatientFaultChecker(FaultChecker):
     410    """A fault checker that does not decides on a fault when the condition
     411    arises immediately, but can wait some time.
     412
     413    Child classes should implement the following functions:
     414    - isCondition(self, flight, aircraft, oldState, state): should return whether the
     415    condition holds
     416    - logFault(self, flight, aircraft, logger, oldState, state): log the fault
     417    via the logger
     418    """
     419    def __init__(self, timeout = 2.0):
     420        """Construct the fault checker with the given timeout."""
     421        self._timeout = timeout
     422        self._faultStarted = None
     423
     424    def getTimeout(self, flight, aircraft, oldState, state):
     425        """Get the timeout.
     426
     427        This default implementation returns the timeout given in the
     428        constructor, but child classes might want to enforce a different
     429        policy."""
     430        return self._timeout
     431
     432    def check(self, flight, aircraft, logger, oldState, state):
     433        """Perform the check."""
     434        if self.isCondition(flight, aircraft, oldState, state):
     435            if self._faultStarted is None:
     436                self._faultStarted = state.timestamp
     437            timeout = self.getTimeout(flight, aircraft, oldState, state)
     438            if state.timestamp>=(self._faultStarted + timeout):
     439                self.logFault(flight, aircraft, logger, oldState, state)
     440                self._faulted = True
     441                self._faultStarted = state.timestamp
     442        else:
     443            self._faultStarted = None
     444               
     445#---------------------------------------------------------------------------------------
     446
     447class AntiCollisionLightsChecker(PatientFaultChecker):
     448    """Check for the anti-collision light being off at high N1 values."""
     449    def isCondition(self, flight, aircraft, oldState, state):
     450        """Check if the fault condition holds."""
     451        return (flight.stage!=const.STAGE_PARKING or \
     452                not flight.options.fs2Crew) and \
     453                not state.antiCollisionLightsOn and \
     454                max(state.n1)>5
     455
     456    def logFault(self, flight, aircraft, logger, oldState, state):
     457        """Log the fault."""
     458        logger.fault(AntiCollisionLightChecker, state.timestamp,
     459                     FaultChecker._appendDuring(flight, "Anti-collision lights were off"),
     460                     1)
     461
     462#---------------------------------------------------------------------------------------
     463
     464class BankChecker(SimpleFaultChecker):
     465    """Check for the anti-collision light being off at high N1 values."""
     466    def isCondition(self, flight, aircraft, oldState, state):
     467        """Check if the fault condition holds."""
     468        if flight.stage==const.STAGE_CRUISE:
     469            bankLimit = 30
     470        elif flight.stage in [const.STAGE_TAKEOFF, const.STAGE_CLIMB,
     471                              const.STAGE_DESCENT, const.STAGE_LANDING]:
     472            bankLimit = 35
     473        else:
     474            return False
     475
     476        return state.bank>bankLimit or state.bank<-bankLimit
     477
     478    def logFault(self, flight, aircraft, logger, oldState, state):
     479        """Log the fault."""
     480        logger.fault(BankChecker, state.timestamp,
     481                     FaultChecker._appendDuring(flight, "Bank too steep"),
     482                     2)
     483
     484#---------------------------------------------------------------------------------------
     485
     486class FlapsRetractChecker(SimpleFaultChecker):
     487    """Check if the flaps are not retracted too early."""
     488    def isCondition(self, flight, aircraft, oldState, state):
     489        """Check if the fault condition holds.
     490
     491        FIXME: check if this really is the intention (FlapsRetractedMistake.java)"""
     492        if (flight.stage==const.STAGE_TAKEOFF and not state.onTheGround) or \
     493           (flight.stage==const.STAGE_LANDING and state.onTheGround):
     494            if self._timeStart is None:
     495                self._timeStart = state.timestamp
     496
     497            if state.flapsSet==0 and state.timestamp<=(self._timeStart+2.0):
     498                return True
     499        return False
     500
     501    def logFault(self, flight, aircraft, logger, oldState, state):
     502        """Log the fault."""
     503        logger.fault(FlapsRetractChecker, state.timestamp,
     504                     FaultChecker._appendDuring(flight, "Flaps retracted"),
     505                     20)
     506
     507#---------------------------------------------------------------------------------------
     508
     509class FlapsSpeedLimitChecker(SimpleFaultChecker):
     510    """Check if the flaps are extended only at the right speeds."""
     511    def isCondition(self, flight, aircraft, oldState, state):
     512        """Check if the fault condition holds."""
     513        speedLimit = aircraft.getFlapsSpeedLimit(state.flapsSet)
     514        return speedLimit is not None and state.ias>speedLimit
     515
     516    def logFault(self, flight, aircraft, logger, oldState, state):
     517        """Log the fault."""
     518        logger.fault(FlapsSpeedLimitChecker, state.timestamp,
     519                     FaultChecker._appendDuring(flight, "Flap speed limit fault"),
     520                     5)
     521
     522#---------------------------------------------------------------------------------------
     523
     524class GearsDownChecker(SimpleFaultChecker):
     525    """Check if the gears are down at low altitudes."""
     526    def isCondition(self, flight, aircraft, oldState, state):
     527        """Check if the fault condition holds."""
     528        return state.radioAltitude<10 and not state.gearsDown and \
     529               flight.stage!=const.STAGE_TAKEOFF
     530
     531    def logFault(self, flight, aircraft, logger, oldState, state):
     532        """Log the fault."""
     533        logger.noGo(GearsDownChecker, state.timestamp,
     534                    "Gears not down at %.0f feet radio altitude" % \
     535                    (state.radioAltitude,),
     536                    "GEAR DOWN NO GO")
     537
     538#---------------------------------------------------------------------------------------
     539
     540class GearSpeedLimitChecker(PatientFaultChecker):
     541    """Check if the gears not down at too high a speed."""
     542    def isCondition(self, flight, aircraft, oldState, state):
     543        """Check if the fault condition holds."""
     544        return state.gearsDown and state.ias>gearSpeedLimit
     545
     546    def logFault(self, flight, aircraft, logger, oldState, state):
     547        """Log the fault."""
     548        logger.fault(GearSpeedLinmitChecker, state.timestamp,
     549                     FaultChecker._appendDuring(flight, "Gear speed limit fault"),
     550                     5)
     551
     552#---------------------------------------------------------------------------------------
     553
     554class GLoadChecker(SimpleFaultChecker):
     555    """Check if the G-load does not exceed 2 except during flare."""
     556    def isCondition(self, flight, aircraft, oldState, state):
     557        """Check if the fault condition holds."""
     558        return state.gLoad>2.0 and (flight.stage!=const.STAGE_LANDING or \
     559                                    state.radioAltitude>=50)
     560               
     561    def logFault(self, flight, aircraft, logger, oldState, state):
     562        """Log the fault."""
     563        logger.fault(GLoadChecker, state.timestamp,
     564                     "G-load was %.2f" % (state.gLoad,),
     565                     10)
     566
     567#---------------------------------------------------------------------------------------
     568
     569class LandingLightsChecker(PatientFaultChecker):
     570    """Check if the landing lights are used properly."""
     571    def getTimeout(self, flight, aircraft, oldState, state):
     572        """Get the timeout.
     573
     574        It is the default timeout except for landing and takeoff."""
     575        return 0.0 if flight.stage in [const.STAGE_TAKEOFF,
     576                                       const.STAGE_LANDING] else self._timeout
     577
     578    def isCondition(self, flight, aircraft, oldState, state):
     579        """Check if the fault condition holds."""
     580        return (flight.stage==const.STAGE_BOARDING and \
     581                state.landingLightsOn and state.onTheGround) or \
     582               (flight.stage==const.STAGE_TAKEOFF and \
     583                not state.landingLightsOn and not state.onTheGround) or \
     584               (flight.stage in [const.STAGE_CLIMB, const.STAGE_CRUISE,
     585                                 const.STAGE_DESCENT] and \
     586                state.landingLightsOn and state.altitude>12500) or \
     587               (flight.stage==const.STAGE_LANDING and \
     588                not state.landingLightsOn and state.onTheGround) or \
     589               (flight.stage==const.STAGE_PARKING and \
     590                state.landingLightsOn and state.onTheGround)
     591               
     592    def logFault(self, flight, aircraft, logger, oldState, state):
     593        """Log the fault."""
     594        score = 0 if flight.stage==const.STAGE_LANDING else 1
     595        message = "Landing lights were %s" % (("on" if state.landingLightsOn else "off"),)
     596        logger.fault(LandingLightsChecker, state.timestamp,
     597                     FaultChecker._appendDuring(flight, message),
     598                     score)       
     599
     600#---------------------------------------------------------------------------------------
     601
     602class WeightChecker(PatientFaultChecker):
     603    """Base class for checkers that check that some limit is not exceeded."""
     604    def __init__(self, name):
     605        """Construct the checker."""
     606        super(WeightChecker, self).__init__(timeout = 5.0)
     607        self._name = name
     608
     609    def isCondition(self, flight, aircraft, oldState, state):
     610        """Check if the fault condition holds."""
     611        if flight.entranceExam:
     612            return False
     613
     614        limit = self.getLimit(flight, aircraft, state)
     615        if limit is not None:
     616            if flight.options.compensation is not None:
     617                limit += flight.options.compensation
     618            return state.grossWeight>mlw
     619
     620        return False
     621
     622    def logFault(self, flight, aircraft, logger, oldState, state):
     623        """Log the fault."""
     624        logger.noGo(self.__class__, state.timestamp,
     625                    "%s exceeded: %.0f kg" % (self._name, state.grossWeight),
     626                    "%s NO GO" % (self._name,))
     627
     628#---------------------------------------------------------------------------------------
     629
     630class MLWChecker(WeightChecker):
     631    """Checks if the MLW is not exceeded on landing."""
     632    def __init__(self):
     633        """Construct the checker."""
     634        super(MLWChecker, self).__init__("MLW")
     635
     636    def getLimit(flight, aircraft, state):
     637        """Get the limit if we are in the right state."""
     638        return aircraft.mlw if flight.stage==const.STAGE_LANDING and \
     639                               state.onTheGround else None
     640
     641#---------------------------------------------------------------------------------------
     642
     643class MTOWChecker(WeightChecker):
     644    """Checks if the MTOW is not exceeded on landing."""
     645    def __init__(self):
     646        """Construct the checker."""
     647        super(MTOWChecker, self).__init__("MTOW")
     648
     649    def getLimit(flight, aircraft, state):
     650        """Get the limit if we are in the right state."""
     651        return aircraft.mtow if flight.stage==const.STAGE_TAKEOFF else None
     652
     653#---------------------------------------------------------------------------------------
     654
     655class MZFWChecker(WeightChecker):
     656    """Checks if the MTOW is not exceeded on landing."""
     657    def __init__(self):
     658        """Construct the checker."""
     659        super(MZFWChecker, self).__init__("MZFW")
     660
     661    def getLimit(flight, aircraft, state):
     662        """Get the limit if we are in the right state."""
     663        return aircraft.mzfw
     664
     665#---------------------------------------------------------------------------------------
     666
     667class NavLightsChecker(PatientFaultChecker):
     668    """Check if the navigational lights are used properly."""
     669    def isCondition(self, flight, aircraft, oldState, state):
     670        """Check if the fault condition holds."""
     671        return flight.stage!=const.STAGE_BOARDING and \
     672               flight.stage!=const.STAGE_PARKING and \
     673               not state.navLightsOn
     674               
     675    def logFault(self, flight, aircraft, logger, oldState, state):
     676        """Log the fault."""
     677        logger.fault(NavLightsChecker, state.timestamp,
     678                     FaultChecker._appendDuring(flight, "Navigation lights were off"),
     679                     1)       
     680
     681#---------------------------------------------------------------------------------------
     682
     683class OverspeedChecker(PatientFaultChecker):
     684    """Check if Vne has been exceeded."""
     685    def __init__(self):
     686        """Construct the checker."""
     687        super(OverspeedChecker, self).__init__(timeout = 5.0)
     688
     689    def isCondition(self, flight, aircraft, oldState, state):
     690        """Check if the fault condition holds."""
     691        return state.overspeed
     692               
     693    def logFault(self, flight, aircraft, logger, oldState, state):
     694        """Log the fault."""
     695        logger.fault(OverspeedChecker, state.timestamp,
     696                     FaultChecker._appendDuring(flight, "Overspeed"),
     697                     20)       
     698
     699#---------------------------------------------------------------------------------------
     700
     701class PayloadChecker(SimpleFaultChecker):
     702    """Check if the payload matches the specification."""
     703    TOLERANCE=550
     704   
     705    def isCondition(self, flight, aircraft, oldState, state):
     706        """Check if the fault condition holds."""
     707        return flight.stage==const.STAGE_PUSHANDTAXI and \
     708               (state.zfw < (flight.zfw - PayloadChecker.TOLERANCE) or \
     709                state.zfw > (flight.zfw + PayloadChecker.TOLERANCE))
     710               
     711    def logFault(self, flight, aircraft, logger, oldState, state):
     712        """Log the fault."""
     713        logger.noGo(PayloadChecker, state.timestamp,
     714                    "ZFW difference is more than %d kgs" % (PayloadChecker.TOLERANCE,),
     715                    "ZFW NO GO")
     716
     717#---------------------------------------------------------------------------------------
     718
     719class PitotChecker(PatientFaultChecker):
     720    """Check if pitot heat is on."""
     721    def __init__(self):
     722        """Construct the checker."""
     723        super(PitotChecker, self).__init__(timeout = 3.0)
     724
     725    def isCondition(self, flight, aircraft, oldState, state):
     726        """Check if the fault condition holds."""
     727        return state.groundSpeed>80 and not current.pitotHeatOn
     728               
     729    def logFault(self, flight, aircraft, logger, oldState, state):
     730        """Log the fault."""
     731        score = 2 if flight.stage in [const.STAGE_TAKEOFF, const.STAGE_CLIMB,
     732                                      const.STAGE_CRUISE, const.STAGE_DESCENT,
     733                                      const.STAGE_LANDING] else 0
     734        logger.fault(PitotChecker, state.timestamp,
     735                     FaultChecker._appendDuring(flight, "Pitot heat was off"),
     736                     score)       
     737
     738#---------------------------------------------------------------------------------------
     739
     740class ReverserChecker(SimpleFaultChecker):
     741    """Check if the reverser is not used below 60 knots."""
     742    def isCondition(self, flight, aircraft, oldState, state):
     743        """Check if the fault condition holds."""
     744        return flight.stage in [const.STAGE_DESCENT, const.STAGE_LANDING,
     745                                const.STAGE_TAXIAFTERLAND] and \
     746            state.groundSpeed<80 and max(state.reverser)
     747                           
     748    def logFault(self, flight, aircraft, logger, oldState, state):
     749        """Log the fault."""
     750        logger.fault(ReverserChecker, state.timestamp,
     751                     FaultChecker._appendDuring(flight, "Reverser used below 60 knots"),
     752                     15)       
     753
     754#---------------------------------------------------------------------------------------
     755
     756class SpeedChecker(SimpleFaultChecker):
     757    """Check if the speed is in the prescribed limits."""
     758    def isCondition(self, flight, aircraft, oldState, state):
     759        """Check if the fault condition holds."""
     760        return flight.stage in [const.STAGE_PUSHANDTAXI,
     761                                const.STAGE_TAXIAFTERLAND] and \
     762            state.groundSpeed>50
     763                           
     764    def logFault(self, flight, aircraft, logger, oldState, state):
     765        """Log the fault."""
     766        logger.fault(SpeedChecker, state.timestamp,
     767                     FaultChecker._appendDuring(flight, "Reverser used below 60 knots"),
     768                     FaultChecker._getLinearScore(50, 80, 10, 15, state.groundSpeed))
     769
     770#---------------------------------------------------------------------------------------
     771
     772class StallChecker(PatientFaultChecker):
     773    """Check if stall occured."""
     774    def isCondition(self, flight, aircraft, oldState, state):
     775        """Check if the fault condition holds."""
     776        return flight.stage in [const.STAGE_TAKEOFF, const.STAGE_CLIMB,
     777                                const.STAGE_CRUISE, const.STAGE_DESCENT,
     778                                const.STAGE_LANDING] and state.stalled
     779               
     780    def logFault(self, flight, aircraft, logger, oldState, state):
     781        """Log the fault."""
     782        score = 40 if flight.stage in [const.STAGE_TAKEOFF,
     783                                       const.STAGE_LANDING] else 30
     784        logger.fault(StallChecker, state.timestamp,
     785                     FaultChecker._appendDuring(flight, "Stalled"),
     786                     score)       
     787
     788#---------------------------------------------------------------------------------------
     789
     790class StrobeLightsChecker(PatientFaultChecker):
     791    """Check if the strobe lights are used properly."""
     792    def isCondition(self, flight, aircraft, oldState, state):
     793        """Check if the fault condition holds."""
     794        return (flight.stage==const.STAGE_BOARDING and \
     795                state.strobeLightsOn and state.onTheGround) or \
     796               (flight.stage==const.STAGE_TAKEOFF and \
     797                not state.strobeLightsOn and not state.gearsDown) or \
     798               (flight.stage in [const.STAGE_CLIMB, const.STAGE_CRUISE,
     799                                 const.STAGE_DESCENT] and \
     800                not state.strobeLightsOn and not state.onTheGround) or \
     801               (flight.stage==const.STAGE_PARKING and \
     802                state.strobeLightsOn and state.onTheGround)
     803               
     804    def logFault(self, flight, aircraft, logger, oldState, state):
     805        """Log the fault."""
     806        message = "Strobe lights were %s" % (("on" if state.strobeLightsOn else "off"),)
     807        logger.fault(StrobeLightsChecker, state.timestamp,
     808                     FaultChecker._appendDuring(flight, message),
     809                     1)       
     810
     811#---------------------------------------------------------------------------------------
     812
     813class ThrustChecker(SimpleFaultChecker):
     814    """Check if the thrust setting is not too high during takeoff.
     815
     816    FIXME: is this really so general, for all aircraft?"""
     817    def isCondition(self, flight, aircraft, oldState, state):
     818        """Check if the fault condition holds."""
     819        return flight.stage==const.STAGE_TAKEOFF and max(state.n1)>97
     820               
     821    def logFault(self, flight, aircraft, logger, oldState, state):
     822        """Log the fault."""
     823        logger.fault(LandingLightsChecker, state.timestamp,
     824                     FaultChecker._appendDuring(flight, "Thrust setting was too high (>97%)"),
     825                     FaultChecker._getLinearScore(97, 110, 0, 10, max(state.n1)))
     826
     827#---------------------------------------------------------------------------------------
     828
     829class VSChecker(SimpleFaultChecker):
     830    """Check if the vertical speed is not too low at certain altitudes"""
     831    BELOW10000 = -5000
     832    BELOW5000 = -2500
     833    BELOW2500 = -1500
     834    BELOW500 = -1000
     835    TOLERANCE = 1.2
     836
     837    def isCondition(self, flight, aircraft, oldState, state):
     838        """Check if the fault condition holds."""
     839        vs = state.vs
     840        altitude = state.altitude
     841        return vs < -8000 or vs > 8000 or \
     842               (altitude<500 and vs < (VSChecker.BELOW500 *
     843                                       VSCHECKER.TOLERANCE)) or \
     844               (altitude<2500 and vs < (VSChecker.BELOW2500 *
     845                                        VSCHECKER.TOLERANCE)) or \
     846               (altitude<5000 and vs < (VSChecker.BELOW5000 *
     847                                        VSCHECKER.TOLERANCE)) or \
     848               (altitude<10000 and vs < (VSChecker.BELOW10000 *
     849                                         VSCHECKER.TOLERANCE))
     850               
     851    def logFault(self, flight, aircraft, logger, oldState, state):
     852        """Log the fault."""
     853        vs = state.vs
     854
     855        message = "Vertical speed was %.0f feet/min" % (vs,)
     856        if vs>-8000 and vs<8000:
     857            message += " at %.0f feet (exceeds company limit)" % (state.altitude,)
     858
     859        score = 10 if vs<-8000 or vs>8000 else 0
     860
     861        logger.fault(VSChecker, state.timestamp,
     862                     FaultChecker._appendDuring(flight, message),
     863                     score)
     864
     865#---------------------------------------------------------------------------------------
  • src/const.py

    r8 r11  
    107107# Flight stage: end
    108108STAGE_END = 12
     109
     110#-------------------------------------------------------------------------------
     111
     112_stageStrings = { STAGE_BOARDING : "boarding",
     113                  STAGE_PUSHANDTAXI : "pushback and taxi",
     114                  STAGE_TAKEOFF : "takeoff",
     115                  STAGE_RTO : "RTO",
     116                  STAGE_CLIMB : "climb",
     117                  STAGE_CRUISE : "cruise",
     118                  STAGE_DESCENT : "descent",
     119                  STAGE_LANDING : "landing",
     120                  STAGE_TAXIAFTERLAND : "taxi",
     121                  STAGE_PARKING : "parking",
     122                  STAGE_GOAROUND : "go-around",
     123                  STAGE_END : "end" }
     124
     125def stage2string(stage):
     126    """Convert the given stage to a lower-case string."""
     127    return _stageStrings[stage] if stage in _stageStrings else None
     128       
     129   
  • src/flight.py

    r9 r11  
    66
    77import threading
     8
     9#---------------------------------------------------------------------------------------
     10
     11class Options(object):
     12    """Various configuration options."""
     13    def __init__(self):
     14        """Construct the object with default values."""
     15        self.fs2Crew = False
     16        self.compensation = None       
    817
    918#---------------------------------------------------------------------------------------
     
    1827        self._stage = None
    1928        self.logger = logger
     29
    2030        self.cruiseAltitude = None
    2131        self.flareTimeFromFS = False
     32        self.entranceExam = False
     33        self.zfw = 50000
     34
     35        self.options = Options()
     36
    2237        self.aircraftType = None
    2338        self.aircraft = None
  • src/fs.py

    r9 r11  
    7979    - reverser[]: an array of booleans indicating if the thrust reversers are
    8080    activated on any of the engines. The number of items equals to the number
    81     of engines.
     81    of engines with a reverser.
    8282    - navLightsOn: a boolean indicating if the navigation lights are on
    8383    - antiCollisionLightsOn: a boolean indicating if the anti-collision lights are on
  • src/logger.py

    r9 r11  
    1212class Logger(object):
    1313    """The class with the interface to log the various events."""
     14    # FIXME: shall we use const.stage2string() instead?
    1415    _stages = { const.STAGE_BOARDING : "Boarding",
    1516                const.STAGE_PUSHANDTAXI : "Pushback and Taxi",
     
    2526                const.STAGE_END : "End" }
    2627
     28    _noGoScore = 10000
     29
    2730    def __init__(self, output = sys.stdout):
    2831        """Construct the logger."""
    29         self._score = 100.0
     32        self._faults = {}
    3033        self._output = output
    3134
     
    5154        self.message(timestamp, "--- %s ---" % (s,))
    5255       
    53     def fault(self, timestamp, what, score):
    54         """Report a fault."""
    55         self._score -= score
    56         self.message(timestamp, "%s (%f)" % (what, score))
     56    def fault(self, faultID, timestamp, what, score):
     57        """Report a fault.
    5758
    58     def noGo(self, timestamp, what):
     59        faultID as a unique ID for the given kind of fault. If another fault of
     60        this ID has been reported earlier, it will be reported again only if
     61        the score is greater than last time. This ID can be, e.g. the checker
     62        the report comes from."""
     63        if faultID in self._faults:
     64            if score<=self._faults[faultID]:
     65                return
     66        self._faults[faultID] = score
     67        if score==Logger._noGoScore:
     68            self.message(timestamp, "%s (NO GO)" % (what))
     69        else:
     70            self.message(timestamp, "%s (%f)" % (what, score))
     71
     72    def noGo(self, faultID, timestamp, what, shortReason):
    5973        """Report a No-Go fault."""
    60         self._score = -1
    61         self.message(timestamp, "%s (NO GO)" % (what,))
     74        self.fault(faultID, timestamp, what, Logger._noGoScore)
    6275
    6376#--------------------------------------------------------------------------------------
Note: See TracChangeset for help on using the changeset viewer.