source: src/mlx/fs.py@ 138:bc4d9d192a7b

Last change on this file since 138:bc4d9d192a7b was 134:9ce031d5d4a9, checked in by István Váradi <ivaradi@…>, 13 years ago

Most of the remaining messages are implemented

File size: 8.6 KB
Line 
1# Module for generic flight-simulator interfaces
2
3#-------------------------------------------------------------------------------
4
5import const
6from sound import startSound
7
8import fsuipc
9import threading
10import time
11
12#-------------------------------------------------------------------------------
13
14class ConnectionListener(object):
15 """Base class for listeners on connections to the flight simulator."""
16 def connected(self, fsType, descriptor):
17 """Called when a connection has been established to the flight
18 simulator of the given type."""
19 print "fs.ConnectionListener.connected, fsType:", fsType, ", descriptor:", descriptor
20
21 def connectionFailed(self):
22 """Called when the connection could not be established."""
23 print "fs.ConnectionListener.connectionFailed"
24
25 def disconnected(self):
26 """Called when a connection to the flight simulator has been broken."""
27 print "fs.ConnectionListener.disconnected"
28
29#-------------------------------------------------------------------------------
30
31class SimulatorException(Exception):
32 """Exception thrown by the simulator interface for communication failure."""
33
34#-------------------------------------------------------------------------------
35
36def createSimulator(type, connectionListener):
37 """Create a simulator instance for the given simulator type with the given
38 connection listener.
39
40 The returned object should provide the following members:
41 FIXME: add info
42 """
43 assert type in [const.SIM_MSFS9, const.SIM_MSFSX], \
44 "Only MS Flight Simulator 2004 and X are supported"
45 return fsuipc.Simulator(connectionListener, connectAttempts = 3)
46
47#-------------------------------------------------------------------------------
48
49class MessageThread(threading.Thread):
50 """Thread to handle messages."""
51 def __init__(self, config, simulator):
52 """Initialize the message thread with the given configuration and
53 simulator."""
54 super(MessageThread, self).__init__()
55
56 self._config = config
57 self._simulator = simulator
58
59 self._requestCondition = threading.Condition()
60 self._messages = []
61 self._nextMessageTime = None
62 self._toQuit = False
63
64 self.daemon = True
65
66 def add(self, messageType, text, duration):
67 """Add the given message to the requested messages."""
68 with self._requestCondition:
69 self._messages.append((messageType, text, duration))
70 self._requestCondition.notify()
71
72 def quit(self):
73 """Quit the thread."""
74 with self._requestCondition:
75 self._toQuit = True
76 self._requestCondition.notifty()
77 self.join()
78
79 def run(self):
80 """Perform the thread's operation."""
81 while True:
82 (messageType, text, duration) = (None, None, None)
83 with self._requestCondition:
84 now = time.time()
85 while not self._toQuit and \
86 ((self._nextMessageTime is not None and \
87 self._nextMessageTime>now) or \
88 not self._messages):
89 self._requestCondition.wait(1)
90 now = time.time()
91
92 if self._toQuit: return
93 if self._nextMessageTime is None or \
94 self._nextMessageTime<=now:
95 self._nextMessageTime = None
96
97 if self._messages:
98 (messageType, text, duration) = self._messages[0]
99 del self._messages[0]
100
101 if text is not None:
102 self._sendMessage(messageType, text, duration)
103
104 def _sendMessage(self, messageType, text, duration):
105 """Send the message and setup the next message time."""
106 messageLevel = self._config.getMessageTypeLevel(messageType)
107 if messageLevel==const.MESSAGELEVEL_SOUND or \
108 messageLevel==const.MESSAGELEVEL_BOTH:
109 startSound(const.SOUND_DING)
110 if (messageLevel==const.MESSAGELEVEL_FS or \
111 messageLevel==const.MESSAGELEVEL_BOTH):
112 self._simulator.sendMessage("[MLX] " + text, duration = duration)
113 self._nextMessageTime = time.time() + duration
114
115#-------------------------------------------------------------------------------
116
117_messageThread = None
118
119#-------------------------------------------------------------------------------
120
121def setupMessageSending(config, simulator):
122 """Setup message sending with the given config and simulator."""
123 global _messageThread
124 if _messageThread is not None:
125 _messageThread.quit()
126 _messageThread = MessageThread(config, simulator)
127 _messageThread.start()
128
129#-------------------------------------------------------------------------------
130
131def sendMessage(messageType, text, duration = 3):
132 """Send the given message of the given type into the simulator and/or play
133 a corresponding sound."""
134 global _messageThread
135 if _messageThread is not None:
136 _messageThread.add(messageType, text, duration)
137
138#-------------------------------------------------------------------------------
139
140class AircraftState(object):
141 """Base class for the aircraft state produced by the aircraft model based
142 on readings from the simulator.
143
144 The following data members should be provided at least:
145 - timestamp: the simulator time of the measurement in seconds since the
146 epoch (float)
147 - latitude (in degrees, North is positive)
148 - longitude (in degrees, East is positive)
149 - paused: a boolean indicating if the flight simulator is paused for
150 whatever reason (it could be a pause mode, or a menu, a dialog, or a
151 replay, etc.)
152 - trickMode: a boolean indicating if some "trick" mode (e.g. "SLEW" in
153 MSFS) is activated
154 - overspeed: a boolean indicating if the aircraft is in overspeed
155 - stalled: a boolean indicating if the aircraft is stalled
156 - onTheGround: a boolean indicating if the aircraft is on the ground
157 - zfw: the zero-fuel weight in kilograms (float)
158 - grossWeight: the gross weight in kilograms (float)
159 - heading: the heading of the aircraft in degrees (float)
160 - pitch: the pitch of the aircraft in degrees. Positive means pitch down,
161 negative means pitch up (float)
162 - bank: the bank of the aircraft in degrees. Positive means bank left,
163 negative means bank right (float)
164 - ias: the indicated airspeed in knots (float)
165 - mach: the airspeed in mach (float)
166 - groundSpeed: the ground speed (float)
167 - vs: the vertical speed in feet/minutes (float)
168 - radioAltitude: the radio altitude of the aircraft in feet (float)
169 - altitude: the altitude of the aircraft in feet (float)
170 - gLoad: G-load (float)
171 - flapsSet: the selected degrees of the flaps (float)
172 - flaps: the actual degrees of the flaps (float)
173 - fuelWeight[]: the fuel weights in the different tanks in kgs (array of
174 floats of as many items as the number fuel tanks)
175 - n1[]: the N1 values of the turbine engines (array of floats
176 of as many items as the number of engines, present only for aircraft with
177 turbines)
178 - rpm[]: the RPM values of the piston engines (array of floats
179 of as many items as the number of engines, present only for aircraft with
180 pistons)
181 - reverser[]: an array of booleans indicating if the thrust reversers are
182 activated on any of the engines. The number of items equals to the number
183 of engines with a reverser.
184 - navLightsOn: a boolean indicating if the navigation lights are on
185 - antiCollisionLightsOn: a boolean indicating if the anti-collision lights are on
186 - strobeLightsOn: a boolean indicating if the strobe lights are on
187 - landingLightsOn: a boolean indicating if the landing lights are on
188 - pitotHeatOn: a boolean indicating if the pitot heat is on
189 - parking: a boolean indicating if the parking brake is set
190 - gearsDown: a boolean indicating if the gears are down
191 - spoilersArmed: a boolean indicating if the spoilers have been armed for
192 automatic deployment
193 - spoilersExtension: the percentage of how much the spoiler is extended
194 (float)
195 - altimeter: the altimeter setting in hPa (float)
196 - nav1: the frequency of the NAV1 radio in MHz (string)
197 - nav2: the frequency of the NAV1 radio in MHz (string)
198 - squawk: the transponder code (string)
199 - windSpeed: the speed of the wind at the aircraft in knots (float)
200 - windDirection: the direction of the wind at the aircraft in degrees (float)
201 - visibility: the visibility in metres (float)
202
203 FIXME: needed when taxiing only:
204 - payload weight
205
206 FIXME: needed rarely:
207 - latitude, longitude
208 - transporter
209 - visibility
210 """
211
Note: See TracBrowser for help on using the repository browser.