Ignore:
Timestamp:
02/05/12 13:42:53 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Flare calculations are handled and added some other printouts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/fsuipc.py

    r8 r9  
    2222class Handler(threading.Thread):
    2323    """The thread to handle the FSUIPC requests."""
     24    @staticmethod
     25    def fsuipc2VS(data):
     26        """Convert the given vertical speed data read from FSUIPC into feet/min."""
     27        return data*60.0/const.FEETTOMETRES/256.0
     28
     29    @staticmethod
     30    def fsuipc2radioAltitude(data):
     31        """Convert the given radio altitude data read from FSUIPC into feet."""
     32        return data/const.FEETTOMETRES/65536.0
     33
     34    @staticmethod
     35    def fsuipc2Degrees(data):
     36        """Convert the given data into degrees."""
     37        return data * 360.0 / 65536.0 / 65536.0
     38
     39    @staticmethod
     40    def fsuipc2PositiveDegrees(data):
     41        """Convert the given data into positive degrees."""
     42        degrees = Handler.fsuipc2Degrees(data)
     43        if degrees<0.0: degrees += 360.0
     44        return degrees
     45
     46    @staticmethod
     47    def fsuipc2IAS(data):
     48        """Convert the given data into indicated airspeed."""
     49        return data / 128.0
     50
    2451    @staticmethod
    2552    def _callSafe(fun):
     
    341368    via FSUIPC."""
    342369    # The basic data that should be queried all the time once we are connected
    343     normalData = [ (0x0240, "H"),
    344                    (0x023e, "H"),
    345                    (0x023b, "b"),
    346                    (0x023c, "b"),
    347                    (0x023a, "b"),
    348                    (0x3d00, -256),
    349                    (0x3c00, -256) ]
    350    
     370    normalData = [ (0x0240, "H"),            # Year
     371                   (0x023e, "H"),            # Number of day in year
     372                   (0x023b, "b"),            # UTC hour
     373                   (0x023c, "b"),            # UTC minute
     374                   (0x023a, "b"),            # seconds
     375                   (0x3d00, -256),           # The name of the current aircraft
     376                   (0x3c00, -256) ]          # The path of the current AIR file
     377
     378    flareData1 = [ (0x023a, "b"),            # Seconds of time
     379                   (0x31e4, "d"),            # Radio altitude
     380                   (0x02c8, "d") ]           # Vertical speed
     381                   
     382    flareStartData = [ (0x0e90, "H"),        # Ambient wind speed
     383                       (0x0e92, "H"),        # Ambient wind direction
     384                       (0x0e8a, "H") ]       # Visibility
     385                       
     386    flareData2 = [ (0x023a, "b"),            # Seconds of time
     387                   (0x0366, "H"),            # On the ground
     388                   (0x02c8, "d"),            # Vertical speed
     389                   (0x030c, "d"),            # Touch-down rate
     390                   (0x02bc, "d"),            # IAS
     391                   (0x0578, "d"),            # Pitch
     392                   (0x057c, "d"),            # Bank
     393                   (0x0580, "d") ]           # Heading
     394
    351395    def __init__(self, connectionListener, aircraft):
    352396        """Construct the simulator.
     
    356400        - modelChanged(aircraftName, modelName): called when the model handling
    357401        the aircraft has changed.
    358         - handleState(aircraftState): handle the given state."""
     402        - handleState(aircraftState): handle the given state.
     403        - flareStarted(windSpeed, windDirection, visibility, flareStart,
     404                       flareStartFS): called when the flare has
     405          started. windSpeed is in knots, windDirection is in degrees and
     406          visibility is in metres. flareStart and flareStartFS are two time
     407          values expressed in seconds that can be used to calculate the flare
     408          time.
     409       - flareFinished(flareEnd, flareEndFS, tdRate, tdRateCalculatedByFS,
     410                       ias, pitch, bank, heading): called when the flare has
     411         finished, i.e. the aircraft is on the ground. flareEnd and flareEndFS
     412         are the two time values corresponding to the touchdown time. tdRate is
     413         the touch-down rate, tdRateCalculatedBySim indicates if the data comes
     414         from the simulator or was calculated by the adapter. The other data
     415         are self-explanatory and expressed in their 'natural' units."""
    359416        self._aircraft = aircraft
    360417
     
    370427        self._aircraftModel = None
    371428
     429        self._flareRequestID = None
     430        self._flareRates = []
     431        self._flareStart = None
     432        self._flareStartFS = None
     433       
    372434    def connect(self):
    373435        """Initiate a connection to the simulator."""
     
    385447        assert self._monitoringRequested
    386448        self._monitoringRequested = False
     449
     450    def startFlare(self):
     451        """Start monitoring the flare time.
     452
     453        At present it is assumed to be called from the FSUIPC thread, hence no
     454        protection."""
     455        #self._aircraft.logger.debug("startFlare")
     456        if self._flareRequestID is None:
     457            self._flareRates = []
     458            self._flareRequestID = self._handler.requestPeriodicRead(0.1,
     459                                                                     Simulator.flareData1,
     460                                                                     self._handleFlare1)
     461
     462    def cancelFlare(self):
     463        """Cancel monitoring the flare time.
     464
     465        At present it is assumed to be called from the FSUIPC thread, hence no
     466        protection."""
     467        if self._flareRequestID is not None:
     468            self._handler.clearPeriodic(self._flareRequestID)
     469            self._flareRequestID = None
    387470
    388471    def disconnect(self):
     
    485568                                              self._handleNormal)
    486569
     570    def _addFlareRate(self, data):
     571        """Append a flare rate to the list of last rates."""
     572        if len(self._flareRates)>=3:
     573            del self._flareRates[0]
     574        self._flareRates.append(Handler.fsuipc2VS(data))
     575
     576    def _handleFlare1(self, data, normal):
     577        """Handle the first stage of flare monitoring."""
     578        #self._aircraft.logger.debug("handleFlare1: " + str(data))
     579        if Handler.fsuipc2radioAltitude(data[1])<=50.0:
     580            self._flareStart = time.time()
     581            self._flareStartFS = data[0]
     582            self._handler.clearPeriodic(self._flareRequestID)
     583            self._flareRequestID = \
     584                self._handler.requestPeriodicRead(0.1,
     585                                                  Simulator.flareData2,
     586                                                  self._handleFlare2)
     587            self._handler.requestRead(Simulator.flareStartData,
     588                                      self._handleFlareStart)
     589               
     590        self._addFlareRate(data[2])
     591
     592    def _handleFlareStart(self, data, extra):
     593        """Handle the data need to notify the aircraft about the starting of
     594        the flare."""
     595        #self._aircraft.logger.debug("handleFlareStart: " + str(data))
     596        if data is not None:
     597            windDirection = data[1]*360.0/65536.0
     598            if windDirection<0.0: windDirection += 360.0
     599            self._aircraft.flareStarted(data[0], windDirection,
     600                                        data[2]*1609.344/100.0,
     601                                        self._flareStart, self._flareStartFS)
     602
     603    def _handleFlare2(self, data, normal):
     604        """Handle the first stage of flare monitoring."""
     605        #self._aircraft.logger.debug("handleFlare2: " + str(data))
     606        if data[1]!=0:
     607            flareEnd = time.time()
     608            self._handler.clearPeriodic(self._flareRequestID)
     609            self._flareRequestID = None
     610
     611            flareEndFS = data[0]
     612            if flareEndFS<self._flareStartFS:
     613                flareEndFS += 60
     614
     615            tdRate = Handler.fsuipc2VS(data[3])
     616            tdRateCalculatedByFS = True
     617            if tdRate==0 or tdRate>1000.0 or tdRate<-1000.0:
     618                tdRate = min(self._flareRates)
     619                tdRateCalculatedByFS = False
     620
     621            self._aircraft.flareFinished(flareEnd, flareEndFS,
     622                                         tdRate, tdRateCalculatedByFS,
     623                                         Handler.fsuipc2IAS(data[4]),
     624                                         Handler.fsuipc2Degrees(data[5]),
     625                                         Handler.fsuipc2Degrees(data[6]),
     626                                         Handler.fsuipc2PositiveDegrees(data[7]))
     627        else:
     628            self._addFlareRate(data[2])
     629                                                 
    487630#------------------------------------------------------------------------------
    488631
     
    499642                      ("stalled", 0x036c, "b"),
    500643                      ("onTheGround", 0x0366, "H"),
     644                      ("zfw", 0x3bfc, "d"),
    501645                      ("grossWeight", 0x30c0, "f"),
    502646                      ("heading", 0x0580, "d"),
     
    504648                      ("bank", 0x057c, "d"),
    505649                      ("ias", 0x02bc, "d"),
     650                      ("mach", 0x11c6, "H"),
    506651                      ("groundSpeed", 0x02b4, "d"),
    507652                      ("vs", 0x02c8, "d"),
     
    521666                      ("nav1", 0x0350, "H"),
    522667                      ("nav2", 0x0352, "H"),
    523                       ("squawk", 0x0354, "H")]
     668                      ("squawk", 0x0354, "H"),
     669                      ("windSpeed", 0x0e90, "H"),
     670                      ("windDirection", 0x0e92, "H")]
     671
    524672
    525673    specialModels = []
     
    624772        state.onTheGround = data[self._monidx_onTheGround]!=0
    625773
     774        state.zfw = data[self._monidx_zfw] * const.LBSTOKG / 256.0
    626775        state.grossWeight = data[self._monidx_grossWeight] * const.LBSTOKG
    627776       
    628         state.heading = data[self._monidx_heading]*360.0/65536.0/65536.0
    629         if state.heading<0.0: state.heading += 360.0
    630 
    631         state.pitch = data[self._monidx_pitch]*360.0/65536.0/65536.0
    632         state.bank = data[self._monidx_bank]*360.0/65536.0/65536.0
    633 
    634         state.ias = data[self._monidx_ias]/128.0
     777        state.heading = Handler.fsuipc2PositiveDegrees(data[self._monidx_heading])
     778
     779        state.pitch = Handler.fsuipc2Degrees(data[self._monidx_pitch])
     780        state.bank = Handler.fsuipc2Degrees(data[self._monidx_bank])
     781
     782        state.ias = Handler.fsuipc2IAS(data[self._monidx_ias])
     783        state.mach = data[self._monidx_mach] / 20480.0
    635784        state.groundSpeed = data[self._monidx_groundSpeed]* 3600.0/65536.0/1852.0
    636         state.vs = data[self._monidx_vs]*60.0/const.FEETTOMETRES/256.0
    637 
    638         state.radioAltitude = data[self._monidx_radioAltitude]/const.FEETTOMETRES/65536.0
     785        state.vs = Handler.fsuipc2VS(data[self._monidx_vs])
     786
     787        state.radioAltitude = \
     788            Handler.fsuipc2radioAltitude(data[self._monidx_radioAltitude])
    639789        state.altitude = data[self._monidx_altitude]/const.FEETTOMETRES/65536.0/65536.0
    640790
     
    687837        state.nav2 = AircraftModel.convertFrequency(data[self._monidx_nav2])
    688838        state.squawk = AircraftModel.convertBCD(data[self._monidx_squawk], 4)
     839
     840        state.windSpeed = data[self._monidx_windSpeed]
     841        state.windDirection = data[self._monidx_windDirection]*360.0/65536.0
     842        if state.windDirection<0.0: state.windDirection += 360.0
    689843       
    690844        return state
Note: See TracChangeset for help on using the changeset viewer.