Changeset 5:90eade9afbcb
- Timestamp:
- 01/31/12 18:01:43 (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/acft.py
r4 r5 49 49 50 50 if self._aircraftState is None or \ 51 self._aircraftState.onTheGround != aircraftState.onTheGround: 52 print "Aircraft.handleState: %s: onTheGround=%d" % \ 53 (timeStr, aircraftState.onTheGround) 54 55 if self._aircraftState is None or \ 51 56 self._aircraftState.grossWeight != aircraftState.grossWeight: 52 57 print "Aircraft.handleState: %s: grossWeight=%f" % \ … … 74 79 75 80 if self._aircraftState is None or \ 81 self._aircraftState.groundSpeed != aircraftState.groundSpeed: 82 print "Aircraft.handleState: %s: groundSpeed=%f" % \ 83 (timeStr, aircraftState.groundSpeed) 84 85 if self._aircraftState is None or \ 76 86 self._aircraftState.vs != aircraftState.vs: 77 87 print "Aircraft.handleState: %s: vs=%f" % \ … … 82 92 print "Aircraft.handleState: %s: altitude=%f" % \ 83 93 (timeStr, aircraftState.altitude) 94 95 if self._aircraftState is None or \ 96 self._aircraftState.gLoad != aircraftState.gLoad: 97 print "Aircraft.handleState: %s: gLoad=%f" % \ 98 (timeStr, aircraftState.gLoad) 84 99 85 100 if self._aircraftState is None or \ … … 133 148 (timeStr, aircraftState.spoilersExtension) 134 149 150 if self._aircraftState is None or \ 151 self._aircraftState.altimeter != aircraftState.altimeter: 152 print "Aircraft.handleState: %s: altimeter=%f" % \ 153 (timeStr, aircraftState.altimeter) 154 155 if self._aircraftState is None or \ 156 self._aircraftState.nav1 != aircraftState.nav1: 157 print "Aircraft.handleState: %s: nav1=%s" % \ 158 (timeStr, aircraftState.nav1) 159 160 if self._aircraftState is None or \ 161 self._aircraftState.nav2 != aircraftState.nav2: 162 print "Aircraft.handleState: %s: nav2=%s" % \ 163 (timeStr, aircraftState.nav2) 164 135 165 self._aircraftState = aircraftState 136 166 -
src/fs.py
r4 r5 25 25 #------------------------------------------------------------------------------- 26 26 27 def createSimulator(type, connectionListener ):27 def createSimulator(type, connectionListener, aircraft): 28 28 """Create a simulator instance for the given simulator type with the given 29 29 connection listener. … … 34 34 assert type==const.TYPE_MSFS9, "Only MS Flight Simulator 2004 is supported" 35 35 import fsuipc 36 return fsuipc.Simulator(connectionListener )36 return fsuipc.Simulator(connectionListener, aircraft) 37 37 38 38 #------------------------------------------------------------------------------- … … 60 60 negative means bank right (float) 61 61 - ias: the indicated airspeed in knots (float) 62 - groundSpeed: the ground speed (float) 62 63 - vs: the vertical speed in feet/minutes (float) 63 64 - altitude: the altitude of the aircraft in feet (float) 65 - gLoad: G-load (float) 64 66 - flapsSet: the selected degrees of the flaps (float) 65 67 - flaps: the actual degrees of the flaps (float) 68 - fuelWeight[]: the fuel weights in the different tanks in kgs (array of 69 floats of as many items as the number fuel tanks) 66 70 - n1[]: the N1 values of the turbine engines (array of floats 67 71 of as many items as the number of engines, present only for aircraft with … … 83 87 - spoilersExtension: the percentage of how much the spoiler is extended 84 88 (float) 89 - altimeter: the altimeter setting in hPa (float) 90 - nav1: the frequency of the NAV1 radio in MHz (string) 91 - nav2: the frequency of the NAV1 radio in MHz (string) 85 92 86 93 FIXME: needed when taxiing only: 87 94 - zfw: the Zero Fuel Weight in klograms (float) 95 - payload weight 88 96 89 97 FIXME: needed for touchdown only: … … 91 99 - ambientWindSpeed: the ambient wind speed around the aircraft in knowns (float) 92 100 - tdRate: the touchdown rate calculated by FSUIPC (float) 101 102 FIXME: needed rarely: 103 - latitude, longitude 104 - transporter 105 - visibility 93 106 """ 94 107 -
src/fsuipc.py
r4 r5 340 340 """The simulator class representing the interface to the flight simulator 341 341 via FSUIPC.""" 342 def __init__(self, connectionListener): 343 """Construct the simulator.""" 344 self._handler = Handler(connectionListener) 345 self._handler.start() 346 self._aircraft = None 347 self._aircraftName = None 348 self._aircraftModel = None 349 self._monitoringRequestID = None 350 351 def connect(self): 352 """Initiate a connection to the simulator.""" 353 self._handler.connect() 354 355 def startMonitoring(self, aircraft): 356 """Start the periodic monitoring of the aircraft and pass the resulting 357 state to the given aircraft object periodically. 342 # The basic data that should be queried all the time once we are connected 343 normalData = [ (0x3d00, -256) ] 344 345 def __init__(self, connectionListener, aircraft): 346 """Construct the simulator. 358 347 359 348 The aircraft object passed must provide the following members: … … 362 351 the aircraft has changed. 363 352 - handleState(aircraftState): handle the given state.""" 364 assert self._aircraft is None365 366 353 self._aircraft = aircraft 367 self._startMonitoring() 354 355 self._handler = Handler(connectionListener) 356 self._handler.start() 357 358 self._normalRequestID = None 359 360 self._monitoringRequested = False 361 self._monitoring = False 362 363 self._aircraftName = None 364 self._aircraftModel = None 365 366 def connect(self): 367 """Initiate a connection to the simulator.""" 368 self._handler.connect() 369 self._startDefaultNormal() 370 371 def startMonitoring(self): 372 """Start the periodic monitoring of the aircraft and pass the resulting 373 state to the aircraft object periodically.""" 374 assert not self._monitoringRequested 375 self._monitoringRequested = True 368 376 369 377 def stopMonitoring(self): 370 378 """Stop the periodic monitoring of the aircraft.""" 371 self._aircraft = None 379 assert self._monitoringRequested 380 self._monitoringRequested = False 372 381 373 382 def disconnect(self): 374 383 """Disconnect from the simulator.""" 384 assert not self._monitoringRequested 385 386 self._stopNormal() 375 387 self._handler.disconnect() 376 388 377 def _startMonitoring(self): 378 """The internal call to start monitoring.""" 379 self._handler.requestRead([(0x3d00, -256)], self._monitoringStartCallback) 380 381 def _monitoringStartCallback(self, data, extra): 382 """Callback for the data read when the monitoring has started. 383 384 The following data items are expected: 385 - the name of the aircraft 389 def _startDefaultNormal(self): 390 """Start the default normal periodic request.""" 391 assert self._normalRequestID is None 392 self._normalRequestID = self._handler.requestPeriodicRead(1.0, 393 Simulator.normalData, 394 self._handleNormal) 395 396 def _stopNormal(self): 397 """Stop the normal period request.""" 398 assert self._normalRequestID is not None 399 self._handler.clearPeriodic(self._normalRequestID) 400 self._normalRequestID = None 401 402 def _handleNormal(self, data, extra): 403 """Handle the reply to the normal request. 404 405 At the beginning the result consists the data for normalData. When 406 monitoring is started, it contains the result also for the 407 aircraft-specific values. 386 408 """ 387 if self._aircraft is None: 388 return 389 elif data is None: 409 self._setAircraftName(data[0]) 410 if self._monitoringRequested and not self._monitoring: 411 self._monitoring = True 412 self._stopNormal() 390 413 self._startMonitoring() 391 else: 392 self._setAircraftName(data[0]) 414 elif self._monitoring and not self._monitoringRequested: 415 self._monitoring = False 416 self._stopNormal() 417 self._startDefaultNormal() 418 elif self._monitoring and self._aircraftModel is not None: 419 aircraftState = self._aircraftModel.getAircraftState(self._aircraft, data) 420 self._aircraft.handleState(aircraftState) 393 421 394 422 def _setAircraftName(self, name): … … 415 443 self._aircraftModel = model 416 444 417 if self._monitoringRequestID is not None: 418 self._handler.clearPeriodic(self._monitoringRequestID) 419 420 self._monitoringRequestID = \ 421 self._handler.requestPeriodicRead(1.0, 422 model.getMonitoringData(), 423 self._handleMonitoringData) 424 425 def _handleMonitoringData(self, data, extra): 426 """Handle the monitoring data.""" 427 if self._aircraft is None: 428 self._handler.clearPeriodic(self._monitoringRequestID) 429 return 430 431 self._setAircraftName(data[0]) 432 aircraftState = self._aircraftModel.getAircraftState(self._aircraft, data) 433 self._aircraft.handleState(aircraftState) 445 if self._monitoring: 446 self._handler.clearPeriodic(self._normalRequestID) 447 self._startMonitoring() 448 449 def _startMonitoring(self): 450 """Start monitoring with the current aircraft model.""" 451 assert self._monitoring 452 453 data = Simulator.normalData[:] 454 self._aircraftModel.addMonitoringData(data) 455 456 self._normalRequestID = \ 457 self._handler.requestPeriodicRead(1.0, data, 458 self._handleNormal) 434 459 435 460 #------------------------------------------------------------------------------ … … 440 465 Aircraft models handle the data arriving from FSUIPC and turn it into an 441 466 object describing the aircraft's state.""" 442 monitoringData = [("aircraftName", 0x3d00, -256), 443 ("year", 0x0240, "H"), 467 monitoringData = [("year", 0x0240, "H"), 444 468 ("dayOfYear", 0x023e, "H"), 445 469 ("zuluHour", 0x023b, "b"), … … 448 472 ("paused", 0x0264, "H"), 449 473 ("frozen", 0x3364, "H"), 474 ("replay", 0x0628, "d"), 450 475 ("slew", 0x05dc, "H"), 451 476 ("overspeed", 0x036d, "b"), … … 457 482 ("bank", 0x057c, "d"), 458 483 ("ias", 0x02bc, "d"), 484 ("groundSpeed", 0x02b4, "d"), 459 485 ("vs", 0x02c8, "d"), 460 486 ("altitude", 0x0570, "l"), 487 ("gLoad", 0x11ba, "H"), 461 488 ("flapsControl", 0x0bdc, "d"), 462 489 ("flapsLeft", 0x0be0, "d"), … … 466 493 ("noseGear", 0x0bec, "d"), 467 494 ("spoilersArmed", 0x0bcc, "d"), 468 ("spoilers", 0x0bd0, "d")] 495 ("spoilers", 0x0bd0, "d"), 496 ("altimeter", 0x0330, "H"), 497 ("nav1", 0x0350, "H"), 498 ("nav2", 0x0352, "H")] 469 499 470 500 @staticmethod … … 473 503 aircraft about it.""" 474 504 return AircraftModel([0, 10, 20, 30]) 505 506 @staticmethod 507 def convertFrequency(data): 508 """Convert the given frequency data to a string.""" 509 frequency = "" 510 for i in range(0, 4): 511 digit = chr(ord('0') + (data&0x0f)) 512 data >>= 4 513 frequency = digit + frequency 514 if i==1: 515 frequency = "." + frequency 516 return "1" + frequency 475 517 476 518 def __init__(self, flapsNotches): … … 508 550 index += 1 509 551 510 def getMonitoringData(self):552 def addMonitoringData(self, data): 511 553 """Get the data specification for monitoring. 512 554 513 The first item should always be the aircraft name (0x3d00, -256).""" 514 data = [] 555 Add the model-specific monitoring data to the given array.""" 515 556 self.addDataWithIndexMembers(data, "_monidx_", 516 557 AircraftModel.monitoringData) 517 return data518 558 519 559 def getAircraftState(self, aircraft, data): … … 530 570 531 571 state.paused = data[self._monidx_paused]!=0 or \ 532 data[self._monidx_frozen]!=0 572 data[self._monidx_frozen]!=0 or \ 573 data[self._monidx_replay]!=0 533 574 state.trickMode = data[self._monidx_slew]!=0 534 575 … … 546 587 547 588 state.ias = data[self._monidx_ias]/128.0 589 state.groundSpeed = data[self._monidx_groundSpeed]* 3600.0/65536.0/1852.0 548 590 state.vs = data[self._monidx_vs]*60.0*3.28984/256.0 549 591 550 592 state.altitude = data[self._monidx_altitude]*3.28084/65536.0/65536.0 593 594 state.gLoad = data[self._monidx_gLoad] / 625.0 551 595 552 596 numNotchesM1 = len(self._flapsNotches) - 1 … … 572 616 lights = data[self._monidx_lights] 573 617 574 state.navLightsOn = (lights %0x01) != 0575 state.antiCollisionLightsOn = (lights %0x02) != 0576 state.landingLightsOn = (lights %0x04) != 0577 state.strobeLightsOn = (lights %0x10) != 0618 state.navLightsOn = (lights&0x01) != 0 619 state.antiCollisionLightsOn = (lights&0x02) != 0 620 state.landingLightsOn = (lights&0x04) != 0 621 state.strobeLightsOn = (lights&0x10) != 0 578 622 579 623 state.pitotHeatOn = data[self._monidx_pitot]!=0 … … 588 632 else: 589 633 state.spoilersExtension = (spoilers - 4800) * 100.0 / (16383 - 4800) 634 635 state.altimeter = data[self._monidx_altimeter] / 16.0 636 637 state.nav1 = AircraftModel.convertFrequency(data[self._monidx_nav1]) 638 state.nav2 = AircraftModel.convertFrequency(data[self._monidx_nav2]) 590 639 591 640 return state 641 642 #------------------------------------------------------------------------------ 643 -
src/test.py
r4 r5 9 9 print data 10 10 11 class ConnectionListener(fs.ConnectionListener):12 def __init__(self):13 self._simulator = None14 self._monitoring = False11 def main(): 12 simulator = fs.createSimulator(const.TYPE_MSFS9, fs.ConnectionListener(), 13 acft.Aircraft(const.AIRCRAFT_B737)) 14 simulator.connect() 15 15 16 def connected(self, fsType, descriptor): 17 print "fs.ConnectionListener.connected, fsType:", fsType, ", descriptor:", descriptor 18 if not self._monitoring: 19 self._simulator.startMonitoring(acft.Aircraft(const.AIRCRAFT_B737)) 20 21 def main(): 22 connectionListener = ConnectionListener() 23 simulator = fs.createSimulator(const.TYPE_MSFS9, connectionListener) 24 connectionListener._simulator = simulator 25 simulator.connect() 16 time.sleep(10) 17 simulator.startMonitoring() 26 18 27 19 while True: 28 20 time.sleep(1000) 21 simulator.stopMonitoring() 22 simulator.disconnect() 23 24 time.sleep(5) 29 25 30 26 if __name__ == "__main__":
Note:
See TracChangeset
for help on using the changeset viewer.