Changeset 54:6b4af8182384


Ignore:
Timestamp:
04/02/12 15:31:11 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
hg-Phase:
(<MercurialRepository 1 'hg:/home/ivaradi/mlx/hg' '/'>, 'public')
Message:

It is now possible to write the values.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/mlx/pyuipc_sim.py

    r53 r54  
    88import socket
    99import time
     10import calendar
    1011import sys
    1112import struct
     
    140141
    141142    @staticmethod
    142     def _convertFrequency(frequency):
     143    def _readFrequency(frequency):
    143144        """Convert the given frequency into BCD."""
    144         return Values._convertBCD(int(frequency*100.0))
     145        return Values._readBCD(int(frequency*100.0))
    145146
    146147    @staticmethod
    147     def _convertBCD(value):
     148    def _readBCD(value):
    148149        """Convert the given value into BCD format."""
    149150        bcd = (value/1000) % 10
     
    154155        bcd <<= 4
    155156        bcd |= value % 10
     157        return bcd
     158       
     159    @staticmethod
     160    def _writeFrequency(value):
     161        """Convert the given value into a frequency."""
     162        return (Values._writeBCD(value) + 10000) / 100.0
     163
     164    @staticmethod
     165    def _writeBCD(value):
     166        """Convert the given BCD value into a real value."""
     167        bcd = (value>>24) & 0xf
     168        bcd *= 10
     169        bcd += (value>>16) & 0xf
     170        bcd *= 10
     171        bcd += (value>>8) & 0xf
     172        bcd *= 10
     173        bcd += (value>>0) & 0xf
     174
    156175        return bcd
    157176       
     
    254273            return int(self.altimeter * 16.0)
    255274        elif offset==0x0350:       # NAV1
    256             return Values._convertFrequency(self.nav1)
     275            return Values._readFrequency(self.nav1)
    257276        elif offset==0x0352:       # NAV2
    258             return Values._convertFrequency(self.nav2)
     277            return Values._readFrequency(self.nav2)
    259278        elif offset==0x0354:       # Squawk
    260             return Values._convertBCD(self.squawk)
    261         elif offset==0x0366:       # Stalled
    262             return 1 if self.stalled else 0
     279            return Values._readBCD(self.squawk)
     280        elif offset==0x0366:       # On the ground
     281            return 1 if self.onTheGround else 0
    263282        elif offset==0x036c:       # Stalled
    264283            return 1 if self.stalled else 0
     
    392411            print "Unhandled offset: %04x" % (offset,)
    393412            raise FSUIPCException(ERR_DATA)
     413
     414    def write(self, offset, value):
     415        """Write the value at the given offset."""
     416        try:
     417            return self._write(offset, value)
     418        except Exception, e:
     419            print "failed to write offset %04x: %s" % (offset, str(e))
     420            raise FSUIPCException(ERR_DATA)
     421
     422    def _write(self, offset, value):
     423        """Write the given value at the given offset."""
     424        if offset==0x023a:         # Second of time
     425            self._updateTimeOffset(5, value)
     426        elif offset==0x023b:       # Hour of Zulu time
     427            self._updateTimeOffset(3, value)
     428        elif offset==0x023c:       # Minute of Zulu time
     429            self._updateTimeOffset(4, value)
     430        elif offset==0x023e:       # Day number in the year
     431            self._updateTimeOffset(7, value)
     432        elif offset==0x0240:       # Year in FS
     433            self._updateTimeOffset(0, value)
     434        elif offset==0x0264:       # Paused
     435            self.paused = value!=0
     436        elif offset==0x029c:       # Pitot
     437            self.pitot = value!=0
     438        elif offset==0x02b4:       # Ground speed
     439            # FIXME: calculate TAS using the heading and the wind, and
     440            # then IAS based on the altitude
     441            self.ias = value * 3600.0 / 65536.0 / 1852.0
     442        elif offset==0x02bc:       # IAS
     443            self.ias = value / 128.0
     444        elif offset==0x02c8:       # VS
     445            self.vs = value * 60.0 / const.FEETTOMETRES / 256.0
     446        elif offset==0x0330:       # Altimeter
     447            self.altimeter = value / 16.0
     448        elif offset==0x0350:       # NAV1
     449            self.nav1 = Values._writeFrequency(value)
     450        elif offset==0x0352:       # NAV2
     451            self.nav2 = Values._writeFrequency(value)
     452        elif offset==0x0354:       # Squawk
     453            self.squawk = Values._writeBCD(value)
     454        elif offset==0x0366:       # Stalled
     455            self.onTheGround = value!=0
     456        elif offset==0x036c:       # Stalled
     457            self.stalled = value!=0
     458        elif offset==0x036d:       # Overspeed
     459            self.overspeed = value!=0
     460        elif offset==0x0570:       # Altitude
     461            self.altitude = value / const.FEETTOMETRES / 65536.0 / 65536.0
     462        elif offset==0x0578:       # Pitch
     463            self.pitch = value * 360.0 / 65536.0 / 65536.0
     464        elif offset==0x057c:       # Bank
     465            self.bank = value * 360.0 / 65536.0 / 65536.0
     466        elif offset==0x0580:       # Heading
     467            self.heading = value * 360.0 / 65536.0 / 65536.0
     468        elif offset==0x05dc:       # Slew
     469            self.slew = value!=0
     470        elif offset==0x0628:       # Replay
     471            self.replay = value!=0
     472        elif offset==0x088c:       # Engine #1 throttle
     473            self._setThrottle(self.ENGINE_1, value)
     474        elif offset==0x0924:       # Engine #2 throttle
     475            self._setThrottle(self.ENGINE_2, value)
     476        elif offset==0x09bc:       # Engine #3 throttle
     477            self._setThrottle(self.ENGINE_3, value)
     478        elif offset==0x0af4:       # Fuel weight
     479            self.fuelWeight = value / 256.0
     480        elif offset==0x0b74:       # Centre tank level
     481            self._setFuelLevel(self.FUEL_CENTRE, value)
     482        elif offset==0x0b78:       # Centre tank capacity
     483            self._setFuelCapacity(self.FUEL_CENTRE, value)
     484        elif offset==0x0b7c:       # Left tank level
     485            self._setFuelLevel(self.FUEL_LEFT, value)
     486        elif offset==0x0b80:       # Left tank capacity
     487            self._setFuelCapacity(self.FUEL_LEFT, value)
     488        elif offset==0x0b84:       # Left aux tank level
     489            self._setFuelLevel(self.FUEL_LEFT_AUX, value)
     490        elif offset==0x0b88:       # Left aux tank capacity
     491            self._setFuelCapacity(self.FUEL_LEFT_AUX, value)
     492        elif offset==0x0b8c:       # Left tip tank level
     493            self._setFuelLevel(self.FUEL_LEFT_TIP, value)
     494        elif offset==0x0b90:       # Left tip tank capacity
     495            self._setFuelCapacity(self.FUEL_LEFT_TIP, value)
     496        elif offset==0x0b94:       # Right aux tank level
     497            self._setFuelLevel(self.FUEL_RIGHT, value)
     498        elif offset==0x0b98:       # Right aux tank capacity
     499            self._setFuelCapacity(self.FUEL_RIGHT, value)
     500        elif offset==0x0b9c:       # Right tank level
     501            self._setFuelLevel(self.FUEL_RIGHT_AUX, value)
     502        elif offset==0x0ba0:       # Right tank capacity
     503            self._setFuelCapacity(self.FUEL_RIGHT_AUX, value)
     504        elif offset==0x0ba4:       # Right tip tank level
     505            self._setFuelLevel(self.FUEL_RIGHT_TIP, value)
     506        elif offset==0x0ba8:       # Right tip tank capacity
     507            self._setFuelCapacity(self.FUEL_RIGHT_TIP, value)
     508        elif offset==0x0bc8:       # Parking
     509            self.parking = value!=0
     510        elif offset==0x0bcc:       # Spoilers armed
     511            self.spoilersArmed = value!=0
     512        elif offset==0x0bd0:       # Spoilers
     513            self.spoilters = 0 if value==0 \
     514                             else (value - 4800) / (16383 - 4800)
     515        elif offset==0x0bdc:       # Flaps control
     516            numNotchesM1 = len(self.flapsNotches) - 1
     517            flapsIncrement = 16383.0 / numNotchesM1
     518            index = value / flapsIncrement
     519            if index>=numNotchesM1:
     520                self.flapsControl = self.flapsNotches[-1]
     521            else:
     522                self.flapsControl = self.flapsNotches[index]
     523                self.flapsControl += value * \
     524                    (self.flapsNotches[index+1] - self.flapsNotches[index]) / \
     525                    flapsIncrement
     526        elif offset==0x0be0 or offset==0x0be4:    # Flaps left and  right
     527            self.flaps = value * self.flapsNotches[-1] / 16383.0
     528        elif offset==0x0bec:       # Nose gear
     529            self.noseGear = value / 16383.0
     530        elif offset==0x0d0c:       # Lights
     531            self.navLightsOn = (lights&0x01)!=0
     532            self.antiCollisionLightsOn = (lights&0x02)!=0
     533            self.landingLightsOn = (lights&0x04)!=0
     534            self.strobeLightsOn = (lights&0x10)!=0
     535        elif offset==0x0e90:       # Wind speed
     536            self.windSpeed = value
     537        elif offset==0x0e92:       # Wind direction
     538            self.windDirection = value * 360.0 / 65536.0
     539        elif offset==0x11ba:       # G-Load
     540            self.gLoad = value / 625.0
     541        elif offset==0x11c6:       # Mach
     542            # FIXME: calculate IAS using the altitude and QNH
     543            self.ias = value / 0.05 / 20480
     544        elif offset==0x1244:       # Centre 2 tank level
     545            self._setFuelLevel(self.FUEL_CENTRE_2, value)
     546        elif offset==0x1248:       # Centre 2 tank capacity
     547            self._setFuelCapacity(self.FUEL_CENTRE_2, value)
     548        elif offset==0x1254:       # External 1 tank level
     549            self._setFuelLevel(self.FUEL_EXTERNAL_1, value)
     550        elif offset==0x1258:       # External 1 tank capacity
     551            self._setFuelCapacity(self.FUEL_EXTERNAL_1, value)
     552        elif offset==0x125c:       # External 2 tank level
     553            self._setFuelLevel(self.FUEL_EXTERNAL_2, value)
     554        elif offset==0x1260:       # External 2 tank capacity
     555            self._setFuelCapacity(self.FUEL_EXTERNAL_2, value)
     556        elif offset==0x2000:       # Engine #1 N1
     557            self.n1[self.ENGINE_1] = value
     558        elif offset==0x2100:       # Engine #2 N1
     559            self.n1[self.ENGINE_2] = value
     560        elif offset==0x2200:       # Engine #3 N1
     561            self.n1[self.ENGINE_3] = value
     562        elif offset==0x30c0:       # Grossweight
     563            raise FSUIPCException(ERR_DATA)
     564        elif offset==0x31e4:       # Radio altitude
     565            raise FSUIPCException(ERR_DATA)
     566        elif offset==0x3364:       # Frozen
     567            self.frozen = value!=0
     568        elif offset==0x3bfc:       # ZFW
     569            self.zfw = value * const.LBSTOKG / 256.0
     570            print "ZFW:", self.zfw
     571        elif offset==0x3c00:       # Path of the current AIR file
     572            self.airPath = value
     573        elif offset==0x3d00:       # Name of the current aircraft
     574            self.aircraftName = value
     575        else:
     576            print "Unhandled offset: %04x" % (offset,)
     577            raise FSUIPCException(ERR_DATA)
    394578       
    395579    def _readUTC(self):
     
    402586        """Get the fuel level for the fuel tank with the given
    403587        index."""
    404         # FIXME: check if the constants are correct
    405588        return 0 if self.fuelCapacities[index]==0.0 else \
    406             int(self.fuelWeights[index] * 65536.0 / self.fuelCapacities[index])
     589            int(self.fuelWeights[index] * 65536.0 * 128.0 / self.fuelCapacities[index])
    407590   
    408591    def _getFuelCapacity(self, index):
    409592        """Get the capacity of the fuel tank with the given index."""
    410         # FIXME: check if the constants are correct
    411         return int(self.fuelCapacities[index] * const.KGSTOLB * 128.0 /
    412                    self.fuelWeight)
     593        return int(self.fuelCapacities[index] * const.KGSTOLB  / self.fuelWeight)
    413594
    414595    def _getThrottle(self, index):
    415596        """Get the throttle value for the given index."""
    416597        return int(self.throttles[index] * 16383.0)
     598
     599    def _updateTimeOffset(self, index, value):
     600        """Update the time offset if the value in the tm structure is replaced
     601        by the given value."""
     602        tm = self._readUTC()
     603        tm1 = tm[:index] + (value,) + tm[(index+1):]
     604        self._timeOffset += calendar.timegm(tm1) - calendar.timegm(tm)
    417605   
     606    def _setThrottle(self, index, value):
     607        """Set the throttle value for the given index."""
     608        self.throttles[index] = value / 16383.0
     609
     610    def _setFuelLevel(self, index, value):
     611        """Set the fuel level for the fuel tank with the given index."""
     612        self.fuelWeights[index] = self.fuelCapacities[index] * float(value) / \
     613                                  65536.0 / 128.0
     614   
     615    def _setFuelCapacity(self, index, value):
     616        """Set the capacity of the fuel tank with the given index."""
     617        self.fuelCapacities[index] = value * self.fuelWeight * const.LBSTOKG
     618
     619
    418620#------------------------------------------------------------------------------
    419621
     
    437639    """Read the given data."""
    438640    return [values.read(offset) for (offset, type) in data]
     641           
     642#------------------------------------------------------------------------------
     643
     644def write(data):
     645    """Write the given data."""
     646    for (offset, type, value) in data:
     647        values.write(offset, value)
    439648           
    440649#------------------------------------------------------------------------------
     
    526735    def read(self, data):
    527736        """Read the given data."""
    528         data = cPickle.dumps((CALL_READ, [data]))
     737        return self._call(CALL_READ, data)
     738
     739    def write(self, data):
     740        """Write the given data."""
     741        return self._call(CALL_WRITE, data)
     742
     743    def _call(self, command, data):
     744        """Perform a call with the given command and data."""
     745        data = cPickle.dumps((command, [data]))
    529746        self._socket.send(struct.pack("I", len(data)) + data)
    530747        (length,) = struct.unpack("I", self._socket.recv(4))
     
    534751            return result
    535752        else:
    536             raise result
     753            raise result       
    537754
    538755#------------------------------------------------------------------------------
     
    594811if __name__ == "__main__":
    595812    client = Client("127.0.0.1")
    596     print client.read([(0x3bfc, "d")])
     813    # print client.write([(0x3bfc, "d", 1000 * 256.0 * const.KGSTOLB)])
     814    # print client.read([(0x3bfc, "d")])
     815    print client.write([(0x023c, "d", 30)])
     816    print client.read([(0x023c, "d")])
    597817else:
    598818    server = Server()
Note: See TracChangeset for help on using the changeset viewer.