source: src/mlx/fs.py@ 295:7340a9356485

Last change on this file since 295:7340a9356485 was 295:7340a9356485, checked in by István Váradi <ivaradi@…>, 12 years ago

Documented the fs module and changed some settings

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