Changeset 52:09c8dec95072 for src/mlx
- Timestamp:
- 04/01/12 09:58:25 (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src/mlx
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/acft.py
r29 r52 462 462 The aircraft type-specific values in the aircraft state have the following 463 463 structure: 464 - fuel: left, right, left aux, right a ix464 - fuel: left, right, left aux, right aux 465 465 - rpm: left, right 466 466 - reverser: left, right.""" -
src/mlx/const.py
r51 r52 10 10 # The ratio between lbs and kg 11 11 LBSTOKG=0.4536 12 13 # The ratio between kgs and lbs 14 KGSTOLB=1/LBSTOKG 12 15 13 16 # The ratio between feet and metre -
src/mlx/pyuipc_sim.py
r51 r52 1 1 # Simulator for the pyuipc module 2 2 #------------------------------------------------------------------------------ 3 4 import const 3 5 4 6 import time … … 87 89 #------------------------------------------------------------------------------ 88 90 91 class Values(object): 92 """The values that can be read from 'FSUIPC'.""" 93 # Fuel data index: centre tank 94 FUEL_CENTRE = 0 95 96 # Fuel data index: left main tank 97 FUEL_LEFT = 1 98 99 # Fuel data index: right main tank 100 FUEL_RIGHT = 2 101 102 # Fuel data index: left aux tank 103 FUEL_LEFT_AUX = 3 104 105 # Fuel data index: right aux tank 106 FUEL_RIGHT_AUX = 4 107 108 # Fuel data index: left tip tank 109 FUEL_LEFT_TIP = 5 110 111 # Fuel data index: right tip tank 112 FUEL_RIGHT_AUX = 6 113 114 # Fuel data index: external 1 tank 115 FUEL_EXTERNAL_1 = 7 116 117 # Fuel data index: external 2 tank 118 FUEL_EXTERNAL_2 = 8 119 120 # Fuel data index: centre 2 tank 121 FUEL_CENTRE_2 = 9 122 123 # The number of fuel tank entries 124 NUM_FUEL = FUEL_CENTRE_2 + 1 125 126 # Engine index: engine #1 127 ENGINE_1 = 0 128 129 # Engine index: engine #2 130 ENGINE_2 = 1 131 132 # Engine index: engine #3 133 ENGINE_3 = 2 134 135 @staticmethod 136 def _convertFrequency(frequency): 137 """Convert the given frequency into BCD.""" 138 return Values._convertBCD(int(frequency-100.0)*100) 139 140 @staticmethod 141 def _convertBCD(value): 142 """Convert the given value into BCD format.""" 143 bcd = (value/1000) % 10 144 bcd <<= 4 145 bcd |= (value/100) & 10 146 bcd <<= 4 147 bcd |= (value/10) % 10 148 bcd <<= 4 149 bcd |= value % 10 150 return bcd 151 152 def __init__(self): 153 """Construct the values with defaults.""" 154 self._timeOffset = 0 155 self.airPath = "C:\\Program Files\\Microsoft Games\\" \ 156 "FS9\\Aircraft\\Cessna\\cessna172.air" 157 self.aircraftName = "Cessna 172SP" 158 self.flapsNotches = [0, 1, 2, 5, 10, 15, 25, 30, 40] 159 self.fuelCapacities = [10000.0, 5000.0, 5000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 160 161 self.paused = False 162 self.frozen = False 163 self.replay = False 164 self.slew = False 165 self.overspeed = False 166 self.stalled = False 167 self.onTheGround = True 168 169 self.zfw = 50000.0 170 171 self.fuelWeights = [0.0, 3000.0, 3000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] 172 # FIXME: check for realistic values 173 self.fuelWeight = 3.5 174 175 self.heading = 220.0 176 self.pitch = 0.0 177 self.bank = 0.0 178 179 self.ias = 0.0 180 self.vs = 0.0 181 182 self.radioAltitude = None 183 self.altitude = 513.0 184 185 self.gLoad = 1.0 186 187 self.flapsControl = 0.0 188 self.flaps = 0.0 189 190 self.navLightsOn = True 191 self.antiCollisionLightsOn = False 192 self.landingLightsOn = False 193 self.strobeLightsOn = False 194 195 self.pitot = False 196 self.parking = True 197 198 self.noseGear = 1.0 199 200 self.spoilersArmed = False 201 self.spoilers = 0.0 202 203 self.altimeter = 1013.0 204 205 self.nav1 = 117.3 206 self.nav2 = 109.5 207 self.squawk = 2200 208 209 self.windSpeed = 8.0 210 self.windDirection = 300.0 211 212 self.n1 = [0.0, 0.0, 0.0] 213 self.throttles = [0.0, 0.0, 0.0] 214 215 def read(self, offset): 216 """Read the value at the given offset.""" 217 try: 218 return self._read(offset) 219 except Exception, e: 220 print "failed to read offset %04x: %s" % (offset, str(e)) 221 raise FSUIPCException(ERR_DATA) 222 223 def _read(self, offset): 224 """Read the value at the given offset.""" 225 if offset==0x023a: # Second of time 226 return self._readUTC().tm_sec 227 elif offset==0x023b: # Hour of Zulu time 228 return self._readUTC().tm_hour 229 elif offset==0x023c: # Minute of Zulu time 230 return self._readUTC().tm_min 231 elif offset==0x023e: # Day number on year 232 return self._readUTC().tm_yday 233 elif offset==0x0240: # Year in FS 234 return self._readUTC().tm_year 235 elif offset==0x0264: # Paused 236 return 1 if self.paused else 0 237 elif offset==0x029c: # Pitot 238 return 1 if self.pitot else 0 239 elif offset==0x02b4: # Ground speed 240 # FIXME: calculate TAS first, then from the heading and 241 # wind the GS 242 return int(self.ias * 65536.0 * 1852.0 / 3600.0) 243 elif offset==0x02bc: # IAS 244 return int(self.ias * 128.0) 245 elif offset==0x02c8: # VS 246 return int(self.vs * const.FEETTOMETRES * 256.0 / 60.0) 247 elif offset==0x0330: # Altimeter 248 return int(self.altimeter * 16.0) 249 elif offset==0x0350: # NAV1 250 return Values._convertFrequency(self.nav1) 251 elif offset==0x0352: # NAV2 252 return Values._convertFrequency(self.nav2) 253 elif offset==0x0354: # Squawk 254 return Values._convertBCD(self.squawk) 255 elif offset==0x0366: # Stalled 256 return 1 if self.stalled else 0 257 elif offset==0x036c: # Stalled 258 return 1 if self.stalled else 0 259 elif offset==0x036d: # Overspeed 260 return 1 if self.overspeed else 0 261 elif offset==0x0570: # Altitude 262 return long(self.altitude * const.FEETTOMETRES * 65536.0 * 65536.0) 263 elif offset==0x0578: # Pitch 264 return int(self.pitch * 65536.0 * 65536.0 / 360.0) 265 elif offset==0x057c: # Bank 266 return int(self.bank * 65536.0 * 65536.0 / 360.0) 267 elif offset==0x0580: # Heading 268 return int(self.heading * 65536.0 * 65536.0 / 360.0) 269 elif offset==0x05dc: # Slew 270 return 1 if self.slew else 0 271 elif offset==0x0628: # Replay 272 return 1 if self.replay else 0 273 elif offset==0x088c: # Engine #1 throttle 274 return self._getThrottle(self.ENGINE_1) 275 elif offset==0x0924: # Engine #2 throttle 276 return self._getThrottle(self.ENGINE_2) 277 elif offset==0x09bc: # Engine #3 throttle 278 return self._getThrottle(self.ENGINE_3) 279 elif offset==0x0af4: # Fuel weight 280 return int(self.fuelWeight * 256.0) 281 elif offset==0x0b74: # Centre tank level 282 return self._getFuelLevel(self.FUEL_CENTRE) 283 elif offset==0x0b78: # Centre tank capacity 284 return self._getFuelCapacity(self.FUEL_CENTRE) 285 elif offset==0x0b7c: # Left tank level 286 return self._getFuelLevel(self.FUEL_LEFT) 287 elif offset==0x0b80: # Left tank capacity 288 return self._getFuelCapacity(self.FUEL_LEFT) 289 elif offset==0x0b84: # Left aux tank level 290 return self._getFuelLevel(self.FUEL_LEFT_AUX) 291 elif offset==0x0b88: # Left aux tank capacity 292 return self._getFuelCapacity(self.FUEL_LEFT_AUX) 293 elif offset==0x0b8c: # Left tip tank level 294 return self._getFuelLevel(self.FUEL_LEFT_TIP) 295 elif offset==0x0b90: # Left tip tank capacity 296 return self._getFuelCapacity(self.FUEL_LEFT_TIP) 297 elif offset==0x0b94: # Right aux tank level 298 return self._getFuelLevel(self.FUEL_RIGHT_AUX) 299 elif offset==0x0b98: # Right aux tank capacity 300 return self._getFuelCapacity(self.FUEL_RIGHT_AUX) 301 elif offset==0x0b9c: # Right tank level 302 return self._getFuelLevel(self.FUEL_RIGHT) 303 elif offset==0x0ba0: # Right tank capacity 304 return self._getFuelCapacity(self.FUEL_RIGHT) 305 elif offset==0x0ba4: # Right tip tank level 306 return self._getFuelLevel(self.FUEL_RIGHT_TIP) 307 elif offset==0x0ba8: # Right tip tank capacity 308 return self._getFuelCapacity(self.FUEL_RIGHT_TIP) 309 elif offset==0x0bc8: # Parking 310 return 1 if self.parking else 0 311 elif offset==0x0bcc: # Spoilers armed 312 return 1 if self.spoilersArmed else 0 313 elif offset==0x0bd0: # Spoilers 314 return 0 if self.spoilers == 0 \ 315 else int(self.spoilers * (16383 - 4800) + 4800) 316 elif offset==0x0bdc: # Flaps control 317 numNotchesM1 = len(self.flapsNotches) - 1 318 flapsIncrement = 16383.0 / numNotchesM1 319 index = 0 320 while index<numNotchesM1 and \ 321 self.flapsControl<self.flapsNotches[index]: 322 index += 1 323 324 if index==numNotchesM1: 325 return 16383 326 else: 327 return int((self.flapsControl-self.flapsNotches[index]) * \ 328 flapsIncrement / \ 329 (self.flapsNotches[index+1] - self.flapsNotches[index])) 330 elif offset==0x0be0 or offset==0x0be4: # Flaps left and right 331 return self.flaps * 16383.0 / self.flapsNotches[-1] 332 elif offset==0x0bec: # Nose gear 333 return int(self.noseGear * 16383.0) 334 elif offset==0x0d0c: # Lights 335 lights = 0 336 if self.navLightsOn: lights |= 0x01 337 if self.antiCollisionLightsOn: lights |= 0x02 338 if self.landingLightsOn: lights |= 0x04 339 if self.strobeLightsOn: lights |= 0x10 340 return lights 341 elif offset==0x0e90: # Wind speed 342 return int(self.windSpeed) 343 elif offset==0x0e92: # Wind direction 344 return int(self.windDirection * 65536.0 / 360.0) 345 elif offset==0x11ba: # G-Load 346 return int(self.gLoad * 625.0) 347 elif offset==0x11c6: # Mach 348 # FIXME: calculate from IAS, altitude and QNH 349 return int(self.ias * 0.05 * 20480.) 350 elif offset==0x1244: # Centre 2 tank level 351 return self._getFuelLevel(self.FUEL_CENTRE_2) 352 elif offset==0x1248: # Centre 2 tank capacity 353 return self._getFuelCapacity(self.FUEL_CENTRE_2) 354 elif offset==0x1254: # External 1 tank level 355 return self._getFuelLevel(self.FUEL_EXTERNAL_1) 356 elif offset==0x1258: # External 1 tank capacity 357 return self._getFuelCapacity(self.FUEL_EXTERNAL_1) 358 elif offset==0x125c: # External 2 tank level 359 return self._getFuelLevel(self.FUEL_EXTERNAL_2) 360 elif offset==0x1260: # External 2 tank capacity 361 return self._getFuelCapacity(self.FUEL_EXTERNAL_2) 362 elif offset==0x2000: # Engine #1 N1 363 return self.n1[self.ENGINE_1] 364 elif offset==0x2100: # Engine #2 N1 365 return self.n1[self.ENGINE_2] 366 elif offset==0x2200: # Engine #3 N1 367 return self.n1[self.ENGINE_3] 368 elif offset==0x30c0: # Grossweight 369 return (self.zfw + sum(self.fuelWeights)) * const.KGSTOLB 370 elif offset==0x31e4: # Radio altitude 371 # FIXME: if self.radioAltitude is None, calculate from the 372 # altitude with some, perhaps random, ground altitude 373 # value 374 radioAltitude = (self.altitude - 517) \ 375 if self.radioAltitude is None else self.radioAltitude 376 return (radioAltitude * const.FEETTOMETRES * 65536.0) 377 elif offset==0x3364: # Frozen 378 return 1 if self.frozen else 0 379 elif offset==0x3bfc: # ZFW 380 return int(self.zfw) * 256.0 * const.KGSTOLB 381 elif offset==0x3c00: # Path of the current AIR file 382 return self.airPath 383 elif offset==0x3d00: # Name of the current aircraft 384 return self.aircraftName 385 else: 386 print "Unhandled offset: %04x" % (offset,) 387 raise FSUIPCException(ERR_DATA) 388 389 def _readUTC(self): 390 """Read the UTC time. 391 392 The current offset is added to it.""" 393 return time.gmtime(time.time() + self._timeOffset) 394 395 def _getFuelLevel(self, index): 396 """Get the fuel level for the fuel tank with the given 397 index.""" 398 # FIXME: check if the constants are correct 399 return 0 if self.fuelCapacities[index]==0.0 else \ 400 int(self.fuelWeights[index] * 65536.0 / self.fuelCapacities[index]) 401 402 def _getFuelCapacity(self, index): 403 """Get the capacity of the fuel tank with the given index.""" 404 # FIXME: check if the constants are correct 405 return int(self.fuelCapacities[index] * const.KGSTOLB * 128.0 / 406 self.fuelWeight) 407 408 def _getThrottle(self, index): 409 """Get the throttle value for the given index.""" 410 return int(self.throttles[index] * 16383.0) 411 412 #------------------------------------------------------------------------------ 413 414 values = Values() 415 416 #------------------------------------------------------------------------------ 417 89 418 def open(request): 90 419 """Open the connection.""" … … 101 430 def read(data): 102 431 """Read the given data.""" 103 result = [] 104 for (offset, type) in data: 105 if offset==0x023a: # Second of time 106 result.append(time.gmtime().tm_sec) 107 elif offset==0x023b: # Hour of Zulu time 108 result.append(time.gmtime().tm_hour) 109 elif offset==0x023c: # Minute of Zulu time 110 result.append(time.gmtime().tm_min) 111 elif offset==0x023e: # Day number on year 112 result.append(time.gmtime().tm_yday) 113 elif offset==0x0240: # Year in FS 114 result.append(time.gmtime().tm_year) 115 elif offset==0x3c00: # Path of the current AIR file 116 result.append("c:\\Program Files\\Microsoft Games\\FS9\\Aircraft\\kutya") 117 elif offset==0x3d00: # Name of the current aircraft 118 result.append("Cessna 172") 119 else: 120 print "Unhandled offset: %04x" % (offset,) 121 raise FSUIPCException(ERR_DATA) 122 return result 432 return [values.read(offset) for (offset, type) in data] 123 433 124 434 #------------------------------------------------------------------------------
Note:
See TracChangeset
for help on using the changeset viewer.