source: src/pyuipc_emu.py@ 21:0b447152d28b

Last change on this file since 21:0b447152d28b was 3:ca35ec2b9cc4, checked in by István Váradi <ivaradi@…>, 13 years ago

The FSUIPC data collection framework works

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