Changeset 8:85698811c70e for src/fsuipc.py
- Timestamp:
- 02/04/12 15:10:19 (12 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/fsuipc.py
r7 r8 341 341 via FSUIPC.""" 342 342 # The basic data that should be queried all the time once we are connected 343 normalData = [ (0x3d00, -256) ] 344 343 normalData = [ (0x0240, "H"), 344 (0x023e, "H"), 345 (0x023b, "b"), 346 (0x023c, "b"), 347 (0x023a, "b"), 348 (0x3d00, -256), 349 (0x3c00, -256) ] 350 345 351 def __init__(self, connectionListener, aircraft): 346 352 """Construct the simulator. … … 407 413 aircraft-specific values. 408 414 """ 409 self._setAircraftName(data[0]) 415 timestamp = calendar.timegm(time.struct_time([data[0], 416 1, 1, 0, 0, 0, -1, 1, 0])) 417 timestamp += data[1] * 24 * 3600 418 timestamp += data[2] * 3600 419 timestamp += data[3] * 60 420 timestamp += data[4] 421 422 createdNewModel = self._setAircraftName(timestamp, data[5], data[6]) 423 410 424 if self._monitoringRequested and not self._monitoring: 411 425 self._monitoring = True … … 416 430 self._stopNormal() 417 431 self._startDefaultNormal() 418 elif self._monitoring and self._aircraftModel is not None: 419 aircraftState = self._aircraftModel.getAircraftState(self._aircraft, data) 432 elif self._monitoring and self._aircraftModel is not None and \ 433 not createdNewModel: 434 aircraftState = self._aircraftModel.getAircraftState(self._aircraft, 435 timestamp, data) 420 436 self._aircraft.handleState(aircraftState) 421 437 422 def _setAircraftName(self, name):438 def _setAircraftName(self, timestamp, name, airPath): 423 439 """Set the name of the aicraft and if it is different from the 424 440 previous, create a new model for it. 425 441 426 If so, also notifty the aircraft about the change.""" 427 if name==self._aircraftName: 428 return 429 430 self._aircraftName = name 431 if self._aircraftModel is None or \ 432 not self._aircraftModel.doesHandle(name): 433 self._setAircraftModel(AircraftModel.create(self._aircraft, name)) 434 435 self._aircraft.modelChanged(self._aircraftName, 436 self._aircraftModel.name) 442 If so, also notifty the aircraft about the change. 443 444 Return if a new model was created.""" 445 aircraftName = (name, airPath) 446 if aircraftName==self._aircraftName: 447 return False 448 449 self._aircraftName = aircraftName 450 needNew = self._aircraftModel is None 451 needNew = needNew or\ 452 not self._aircraftModel.doesHandle(self._aircraft, aircraftName) 453 if not needNew: 454 specialModel = AircraftModel.findSpecial(self._aircraft, aircraftName) 455 needNew = specialModel is not None and \ 456 specialModel is not self._aircraftModel.__class__ 457 458 if needNew: 459 self._setAircraftModel(AircraftModel.create(self._aircraft, aircraftName)) 460 461 self._aircraft.modelChanged(timestamp, name, self._aircraftModel.name) 462 463 return needNew 437 464 438 465 def _setAircraftModel(self, model): … … 444 471 445 472 if self._monitoring: 446 self._ handler.clearPeriodic(self._normalRequestID)473 self._stopNormal() 447 474 self._startMonitoring() 448 475 … … 465 492 Aircraft models handle the data arriving from FSUIPC and turn it into an 466 493 object describing the aircraft's state.""" 467 monitoringData = [("year", 0x0240, "H"), 468 ("dayOfYear", 0x023e, "H"), 469 ("zuluHour", 0x023b, "b"), 470 ("zuluMinute", 0x023c, "b"), 471 ("seconds", 0x023a, "b"), 472 ("paused", 0x0264, "H"), 494 monitoringData = [("paused", 0x0264, "H"), 473 495 ("frozen", 0x3364, "H"), 474 496 ("replay", 0x0628, "d"), … … 484 506 ("groundSpeed", 0x02b4, "d"), 485 507 ("vs", 0x02c8, "d"), 508 ("radioAltitude", 0x31e4, "d"), 486 509 ("altitude", 0x0570, "l"), 487 510 ("gLoad", 0x11ba, "H"), … … 491 514 ("lights", 0x0d0c, "H"), 492 515 ("pitot", 0x029c, "b"), 516 ("parking", 0x0bc8, "H"), 493 517 ("noseGear", 0x0bec, "d"), 494 518 ("spoilersArmed", 0x0bcc, "d"), … … 496 520 ("altimeter", 0x0330, "H"), 497 521 ("nav1", 0x0350, "H"), 498 ("nav2", 0x0352, "H")] 499 500 genericModels = { const.AIRCRAFT.B736 : B737Model, 501 const.AIRCRAFT_B737 : B737Model, 502 const.AIRCRAFT_B738 : B737Model, 503 const.AIRCRAFT_B733 : B737Model, 504 const.AIRCRAFT_B734 : B737Model, 505 const.AIRCRAFT_B735 : B737Model, 506 const.AIRCRAFT_DH8D : DH8DModel, 507 const.AIRCRAFT_B762 : B767Model, 508 const.AIRCRAFT_B763 : B767Model, 509 const.AIRCRAFT_CRJ2 : B767Model, 510 const.AIRCRAFT_F79 : F70Model, 511 const.AIRCRAFT_DC3 : DC3Model, 512 const.AIRCRAFT_T134 : T134Model, 513 const.AIRCRAFT_T154 : T154Model, 514 const.AIRCRAFT_YK40 : YK40Model } 522 ("nav2", 0x0352, "H"), 523 ("squawk", 0x0354, "H")] 515 524 516 525 specialModels = [] … … 522 531 523 532 @staticmethod 533 def findSpecial(aircraft, aircraftName): 534 for specialModel in AircraftModel.specialModels: 535 if specialModel.doesHandle(aircraft, aircraftName): 536 return specialModel 537 return None 538 539 @staticmethod 524 540 def create(aircraft, aircraftName): 525 541 """Create the model for the given aircraft name, and notify the 526 542 aircraft about it.""" 527 for specialModel in AircraftModel.specialModels: 528 if specialModel.doesHandle(aircraft, aircraftName): 529 return specialModel(aircraft, aircraftName) 530 531 if aircraft.type in AircraftModel.genericModels: 532 return AircraftModel.genericModels[aircraft.type]() 543 specialModel = AircraftModel.findSpecial(aircraft, aircraftName) 544 if specialModel is not None: 545 return specialModel() 546 if aircraft.type in _genericModels: 547 return _genericModels[aircraft.type]() 533 548 else: 534 549 return GenericModel() 550 551 @staticmethod 552 def convertBCD(data, length): 553 """Convert a data item encoded as BCD into a string of the given number 554 of digits.""" 555 bcd = "" 556 for i in range(0, length): 557 digit = chr(ord('0') + (data&0x0f)) 558 data >>= 4 559 bcd = digit + bcd 560 return bcd 535 561 536 562 @staticmethod 537 563 def convertFrequency(data): 538 564 """Convert the given frequency data to a string.""" 539 frequency = "" 540 for i in range(0, 4): 541 digit = chr(ord('0') + (data&0x0f)) 542 data >>= 4 543 frequency = digit + frequency 544 if i==1: 545 frequency = "." + frequency 546 return "1" + frequency 565 bcd = AircraftModel.convertBCD(data, 4) 566 return "1" + bcd[0:2] + "." + bcd[2:4] 547 567 548 568 def __init__(self, flapsNotches): … … 557 577 return "FSUIPC/Generic" 558 578 559 def doesHandle(self, aircraft Name):579 def doesHandle(self, aircraft, aircraftName): 560 580 """Determine if the model handles the given aircraft name. 561 581 … … 568 588 dest.append((offset, type)) 569 589 if attrName is not None: 570 setattr(self, attrName, len(dest) )590 setattr(self, attrName, len(dest)-1) 571 591 572 592 def _addDataWithIndexMembers(self, dest, prefix, data): … … 586 606 def addMonitoringData(self, data): 587 607 """Add the model-specific monitoring data to the given array.""" 588 self. addDataWithIndexMembers(data, "_monidx_",589 AircraftModel.monitoringData)608 self._addDataWithIndexMembers(data, "_monidx_", 609 AircraftModel.monitoringData) 590 610 591 def getAircraftState(self, aircraft, data):611 def getAircraftState(self, aircraft, timestamp, data): 592 612 """Get an aircraft state object for the given monitoring data.""" 593 613 state = fs.AircraftState() 594 614 595 timestamp = calendar.timegm(time.struct_time([data[self._monidx_year],596 1, 1, 0, 0, 0, -1, 1, 0]))597 timestamp += data[self._monidx_dayOfYear] * 24 * 3600598 timestamp += data[self._monidx_zuluHour] * 3600599 timestamp += data[self._monidx_zuluMinute] * 60600 timestamp += data[self._monidx_seconds]601 615 state.timestamp = timestamp 602 616 … … 622 636 state.vs = data[self._monidx_vs]*60.0/const.FEETTOMETRES/256.0 623 637 638 state.radioAltitude = data[self._monidx_radioAltitude]/const.FEETTOMETRES/65536.0 624 639 state.altitude = data[self._monidx_altitude]/const.FEETTOMETRES/65536.0/65536.0 625 640 … … 655 670 state.pitotHeatOn = data[self._monidx_pitot]!=0 656 671 672 state.parking = data[self._monidx_parking]!=0 673 657 674 state.gearsDown = data[self._monidx_noseGear]==16383 658 675 … … 669 686 state.nav1 = AircraftModel.convertFrequency(data[self._monidx_nav1]) 670 687 state.nav2 = AircraftModel.convertFrequency(data[self._monidx_nav2]) 688 state.squawk = AircraftModel.convertBCD(data[self._monidx_squawk], 4) 671 689 672 690 return state … … 699 717 self._isN1 = isN1 700 718 719 def doesHandle(self, aircraft, aircraftName): 720 """Determine if the model handles the given aircraft name. 721 722 This implementation returns True.""" 723 return True 724 701 725 def addMonitoringData(self, data): 702 726 """Add the model-specific monitoring data to the given array.""" … … 716 740 self._addOffsetWithIndexMember(data, 0x088c + i * 0x98, "d") # throttle lever 717 741 718 def getAircraftState(self, aircraft, data):742 def getAircraftState(self, aircraft, timestamp, data): 719 743 """Get the aircraft state. 720 744 … … 722 746 the engine parameters.""" 723 747 state = super(GenericAircraftModel, self).getAircraftState(aircraft, 748 timestamp, 724 749 data) 725 750 … … 746 771 def __init__(self): 747 772 """Construct the model.""" 748 super(Generic AircraftModel, self).773 super(GenericModel, self). \ 749 774 __init__(flapsNotches = [0, 10, 20, 30], 750 775 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 762 787 def __init__(self): 763 788 """Construct the model.""" 764 super( GenericAircraftModel, self).789 super(B737Model, self). \ 765 790 __init__(flapsNotches = [0, 1, 2, 5, 10, 15, 25, 30, 40], 766 791 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 771 796 """Get the name for this aircraft model.""" 772 797 return "FSUIPC/Generic Boeing 737" 798 799 #------------------------------------------------------------------------------ 800 801 class PMDGBoeing737NGModel(B737Model): 802 """A model handler for the PMDG Boeing 737NG model.""" 803 @staticmethod 804 def doesHandle(aircraft, (name, airPath)): 805 """Determine if this model handler handles the aircraft with the given 806 name.""" 807 return aircraft.type in [const.AIRCRAFT_B736, 808 const.AIRCRAFT_B737, 809 const.AIRCRAFT_B738] and \ 810 (name.find("PMDG")!=-1 or airPath.find("PMDG")!=-1) and \ 811 (name.find("737")!=-1 or airPath.find("737")!=-1) and \ 812 (name.find("600")!=-1 or airPath.find("600")!=-1 or \ 813 name.find("700")!=-1 or airPath.find("700")!=-1 or \ 814 name.find("800")!=-1 or airPath.find("800")!=-1 or \ 815 name.find("900")!=-1 or airPath.find("900")!=-1) 816 817 @property 818 def name(self): 819 """Get the name for this aircraft model.""" 820 return "FSUIPC/PMDG Boeing 737NG" 821 822 def addMonitoringData(self, data): 823 """Add the model-specific monitoring data to the given array.""" 824 super(PMDGBoeing737NGModel, self).addMonitoringData(data) 825 826 self._addOffsetWithIndexMember(data, 0x6202, "b", "_pmdgidx_switches") 827 828 def getAircraftState(self, aircraft, timestamp, data): 829 """Get the aircraft state. 830 831 Get it from the parent, and then check some PMDG-specific stuff.""" 832 state = super(PMDGBoeing737NGModel, self).getAircraftState(aircraft, 833 timestamp, 834 data) 835 if data[self._pmdgidx_switches]&0x01==0x01: 836 state.altimeter = 1013.25 837 838 return state 773 839 774 840 #------------------------------------------------------------------------------ … … 778 844 def __init__(self): 779 845 """Construct the model.""" 780 super( GenericAircraftModel, self).846 super(B767Model, self). \ 781 847 __init__(flapsNotches = [0, 1, 5, 15, 20, 25, 30], 782 848 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 794 860 def __init__(self): 795 861 """Construct the model.""" 796 super( GenericAircraftModel, self).862 super(DH8DModel, self). \ 797 863 __init__(flapsNotches = [0, 5, 10, 15, 35], 798 864 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 810 876 def __init__(self): 811 877 """Construct the model.""" 812 super( GenericAircraftModel, self).878 super(CRJ2Model, self). \ 813 879 __init__(flapsNotches = [0, 8, 20, 30, 45], 814 880 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 826 892 def __init__(self): 827 893 """Construct the model.""" 828 super( GenericAircraftModel, self).894 super(F70Model, self). \ 829 895 __init__(flapsNotches = [0, 8, 15, 25, 42], 830 896 fuelInfo = [0x0b74, 0x0b7c, 0xb94], … … 842 908 def __init__(self): 843 909 """Construct the model.""" 844 super( GenericAircraftModel, self).910 super(DC3Model, self). \ 845 911 __init__(flapsNotches = [0, 15, 30, 45], 846 912 fuelInfo = [0x0b7c, 0x0b84, 0x0b94, 0x0b9c], … … 858 924 def __init__(self): 859 925 """Construct the model.""" 860 super( GenericAircraftModel, self).926 super(T134Model, self). \ 861 927 __init__(flapsNotches = [0, 10, 20, 30], 862 928 fuelInfo = [0x0b74, … … 877 943 def __init__(self): 878 944 """Construct the model.""" 879 super( GenericAircraftModel, self).945 super(T154Model, self). \ 880 946 __init__(flapsNotches = [0, 15, 28, 45], 881 947 fuelInfo = [0x0b74, 0x0b7c, 0x0b94, 882 0x1244, 0x0b84, 0x0b9c] 948 0x1244, 0x0b84, 0x0b9c], 883 949 numEngines = 3) 884 950 … … 888 954 return "FSUIPC/Generic Tupolev Tu-154" 889 955 890 def getAircraftState(self, aircraft, data):956 def getAircraftState(self, aircraft, timestamp, data): 891 957 """Get an aircraft state object for the given monitoring data. 892 958 893 959 This removes the reverser value for the middle engine.""" 894 state = super(T154Model, self).getAircraftState(aircraft, data)960 state = super(T154Model, self).getAircraftState(aircraft, timestamp, data) 895 961 del state.reverser[1] 896 962 return state … … 902 968 def __init__(self): 903 969 """Construct the model.""" 904 super( GenericAircraftModel, self).970 super(YK40Model, self). \ 905 971 __init__(flapsNotches = [0, 20, 35], 906 fuelInfo = [0x0b7c, 0x0b94] 972 fuelInfo = [0x0b7c, 0x0b94], 907 973 numEngines = 2) 908 974 … … 914 980 #------------------------------------------------------------------------------ 915 981 982 _genericModels = { const.AIRCRAFT_B736 : B737Model, 983 const.AIRCRAFT_B737 : B737Model, 984 const.AIRCRAFT_B738 : B737Model, 985 const.AIRCRAFT_B733 : B737Model, 986 const.AIRCRAFT_B734 : B737Model, 987 const.AIRCRAFT_B735 : B737Model, 988 const.AIRCRAFT_DH8D : DH8DModel, 989 const.AIRCRAFT_B762 : B767Model, 990 const.AIRCRAFT_B763 : B767Model, 991 const.AIRCRAFT_CRJ2 : B767Model, 992 const.AIRCRAFT_F70 : F70Model, 993 const.AIRCRAFT_DC3 : DC3Model, 994 const.AIRCRAFT_T134 : T134Model, 995 const.AIRCRAFT_T154 : T154Model, 996 const.AIRCRAFT_YK40 : YK40Model } 997 998 #------------------------------------------------------------------------------ 999 1000 AircraftModel.registerSpecial(PMDGBoeing737NGModel) 1001 1002 #------------------------------------------------------------------------------ 1003
Note:
See TracChangeset
for help on using the changeset viewer.