source: src/mlx/fs.py@ 298:24c67ec5cdca

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

Documented the non-GUI modules

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