source: src/mlx/pyuipc_emu.py@ 800:709f86ab4573

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

Documented the non-GUI modules

File size: 8.5 KB
Line 
1
2import time
3
4#------------------------------------------------------------------------------
5
6## @package mlx.pyuipc_emu
7#
8# A very simple PyUIPC emulator.
9#
10# This is not used currently.
11
12#------------------------------------------------------------------------------
13
14## The ratio between kg and lbs
15KGTOLBS=1/0.4536
16
17## Feet to metres
18FEETTOMETRES=0.3048
19
20#------------------------------------------------------------------------------
21
22def interpolate_proportion(proportion, value0, value1):
23 """
24 Interpolate between value0 and value1 using the given proportion.
25 """
26 return value0 + (value1-value0)*1.0*proportion
27
28#------------------------------------------------------------------------------
29
30def interpolate(point0, point, point1, value0, value1):
31 """
32 Interpolate linearly between the given points for the given
33 values.
34 """
35 if point0==point1:
36 if point>=point1: return value1
37 else: return value0
38 else:
39 return interpolate_proportion((point-point0)*1.0/(point1-point0),
40 value0, value1)
41
42#------------------------------------------------------------------------------
43
44## Version constants
45SIM_ANY=0
46SIM_FS98=1
47SIM_FS2K=2
48SIM_CFS2=3
49SIM_CFS1=4
50SIM_FLY=5
51SIM_FS2K2=6
52SIM_FS2K4=7
53
54#------------------------------------------------------------------------------
55
56## Error constants
57ERR_OK=0
58ERR_OPEN=1
59ERR_NOFS=2
60ERR_REGMSG=3
61ERR_ATOM=4
62ERR_MAP=5
63ERR_VIEW=6
64ERR_VERSION=7
65ERR_WRONGFS=8
66ERR_NOTOPEN=9
67ERR_NODATA=10
68ERR_TIMEOUT=11
69ERR_SENDMSG=12
70ERR_DATA=13
71ERR_RUNNING=14
72ERR_SIZE=15
73
74#------------------------------------------------------------------------------
75
76## The version of FSUIPC
77fsuipc_version=0x0401
78lib_version=0x0302
79fs_version=SIM_FS2K4
80
81#------------------------------------------------------------------------------
82
83class FSUIPCException(Exception):
84 """
85 FSUIPC exception class. It contains a member variable named
86 errorCode. The string is a text describing the error.
87 """
88
89 errors=["OK",
90 "Attempt to Open when already Open",
91 "Cannot link to FSUIPC or WideClient",
92 "Failed to Register common message with Windows",
93 "Failed to create Atom for mapping filename",
94 "Failed to create a file mapping object",
95 "Failed to open a view to the file map",
96 "Incorrect version of FSUIPC, or not FSUIPC",
97 "Sim is not version requested",
98 "Call cannot execute, link not Open",
99 "Call cannot execute: no requests accumulated",
100 "IPC timed out all retries",
101 "IPC sendmessage failed all retries",
102 "IPC request contains bad data",
103 "Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC",
104 "Read or Write request cannot be added, memory for Process is full"]
105
106 def __init__(self, errorCode):
107 """
108 Construct the exception
109 """
110 if errorCode<len(self.errors):
111 self.errorString = self.errors[errorCode]
112 else:
113 self.errorString = "Unknown error"
114 Exception.__init__(self, self.errorString)
115 self.errorCode = errorCode
116
117 def __str__(self):
118 """
119 Convert the excption to string
120 """
121 return "FSUIPC error: %d (%s)" % (self.errorCode, self.errorString)
122
123#------------------------------------------------------------------------------
124
125open_count=0
126read_count=0
127
128#------------------------------------------------------------------------------
129
130def open(request):
131 """
132 Open the connection.
133 """
134
135 global open_count, read_count
136
137 open_count += 1
138 if open_count<5:
139 raise FSUIPCException(open_count+2)
140 elif open_count==5:
141 return True
142 else:
143 raise FSUIPCException(ERR_OPEN)
144
145#------------------------------------------------------------------------------
146
147def prepare_data(pattern, forRead = True):
148 """
149 Prepate the given pattern for reading and/or writing
150 """
151 return pattern
152
153#------------------------------------------------------------------------------
154
155flight=None
156schedule_points=None
157
158#------------------------------------------------------------------------------
159
160def set_flight(f):
161 """
162 Set the flight to use for providing the data
163 """
164
165 global flight, schedule_points, read_count
166
167 flight=f
168 schedule_points=flight.get_schedule_points()
169 read_count = 0
170
171#------------------------------------------------------------------------------
172
173fuel_weight=4.5
174centre_tank_capacity=12900
175side_tank_capacity=3900
176
177def read(data):
178 """
179 Read the given data.
180 """
181
182 global open_count, read_count
183 if open_count<5:
184 raise FSUIPCException(ERR_NOTOPEN)
185
186 global flight, schedule_points
187
188 tm=time.gmtime()
189
190 if read_count<=10:
191 latitude = 0
192 longitude = 0
193 altitude = 0
194 tas = 0
195 vs = 0.0
196 fuel_flow = 0.0
197 fuel_remaining = 1000
198 ground_altitude = 0
199 else:
200 dist = read_count - 10
201
202 latitude = 0
203 longitude = 0
204 altitude = dist*20
205 tas = 100+dist*20
206 vs = dist*100.0
207 fuel_flow = 3.0
208 fuel_remaining = 1000 - dist*2
209
210 ground_altitude = 0
211
212 results=[]
213 for (offset, type) in data:
214 if offset==0x02b8: # True airspeed (128*knots)
215 results.append(int(tas*128))
216 elif offset==0x02c8: # Vertical speed (256*m/s)
217 results.append(int(vs / 60.0 * 0.3048 * 256))
218 elif offset==0x0560: # Latitude
219 results.append(long(latitude*10001750.0*65536.0*65536.0/90.0))
220 elif offset==0x0568: # Longitude
221 results.append(long(longitude*65536.9*65536.0*65536.0*65536.0/360.0))
222 elif offset==0x0570: # Aircraft altitude in metres (fractional part)
223 results.append(long( (altitude*0.3048*65536*65536)%(65536*65536)))
224 elif offset==0x0574: # Aircraft altitude in metres (whole part)
225 results.append(int(altitude*.3048))
226 elif offset==0x0918 or \
227 offset==0x09b0: # Engine 1 and 2 fuel flow (pounds per hour)
228 results.append(fuel_flow*KGTOLBS/2.0)
229 elif offset==0x0a48 or \
230 offset==0x0ae0: # Engine 3 and 4 fuel flow (pounds per hour)
231 results.append(0.0)
232 elif offset==0x0aec: # Number of engines
233 results.append(2)
234 elif offset==0x0af4: # Fuel weight (pounds per gallon)
235 results.append(int(round(fuel_weight * 256)))
236 elif offset==0x0b74: # Centre tank level (%*128*65536)
237 centre_fuel = fuel_remaining - 2*side_tank_capacity
238 if centre_fuel<0: centre_fuel = 0.0
239 results.append(long(round(centre_fuel/centre_tank_capacity*128.0*65536.0)))
240 elif offset==0x0b78: # Centre tank capacity (gallons)
241 results.append(long(round(centre_tank_capacity*KGTOLBS/fuel_weight)))
242 elif offset==0x0b7c or \
243 offset==0x0b94: # Left and right main tank level (%*128*65536)
244 fuel = fuel_remaining/2
245 if fuel>side_tank_capacity: fuel = side_tank_capacity
246 results.append(long(round(fuel/side_tank_capacity*128.0*65536.0)))
247 elif offset==0x0b80 or \
248 offset==0x0b98: # Left and right main tank capacity (gallons)
249 results.append(long(round(side_tank_capacity*KGTOLBS/fuel_weight)))
250 elif offset in [0x0b84, 0x0b88, 0x0b8c, 0x0b90,
251 0x0b9c, 0x0ba0, 0x0ba4, 0x0ba8,
252 0x1244, 0x1248, 0x124c, 0x1250,
253 0x1254, 0x1258, 0x125c, 0x1260]:
254 # Other tank capacities and levels
255 results.append(long(0))
256 elif offset==0x023a: # Second of time
257 results.append(int(tm[5]))
258 elif offset==0x023b: # Hour of UTC time
259 results.append(int(tm[3]))
260 elif offset==0x023c: # Minute of UTC time
261 results.append(int(tm[4]))
262 elif offset==0x023e: # Day number in year
263 results.append(int(tm[7]))
264 elif offset==0x0240: # Year
265 results.append(int(tm[0]))
266 elif offset==0x0020: # Ground altitude (metres*256)
267 results.append(int(round(ground_altitude*FEETTOMETRES*256.0)))
268 else:
269 raise FSUIPCException(ERR_DATA)
270
271 read_count += 1
272
273 return results
274
275
276#------------------------------------------------------------------------------
277
278def close():
279 """
280 Close the connection
281 """
282 global open_count
283 open_count = 0
284
285#------------------------------------------------------------------------------
286
Note: See TracBrowser for help on using the repository browser.