2 Created on Feb 17, 2017 11 import pylib.ISToolsDataSorted
as itd
12 import subprocess
as subprocess
16 from scipy.interpolate
import interp1d
17 from pylib.pose
import norm, qlog, qexp, lla2ned, quat2eulerArray, meanOfQuatArray, qboxminus, qboxplus, qmult, qinv
25 for dev
in log.devices:
26 if 'debugArray' in dev.data.keys()
and 'GPS1Raw' in dev.data.keys():
27 dbg = dev.data[
'debugArray'][
'i']
28 counts = dev.data[
'GPS1Raw'][
'count'][dev.data[
'GPS1Raw'][
'type'] == 1]
29 total_obs_in_log = np.sum(counts)
30 obs_at_start = dbg[0, :]
31 obs_at_end = dbg[-1, :]
32 print(
"===================== Raw GPS Message Statistics ======================")
33 print(
"uINS - %d", dev.serialNumber)
34 print(
"recorded observations: %d, " % total_obs_in_log)
35 print(
"observations reported by firmware %d, " % obs_at_end[3])
38 for dev
in log.devices:
39 if 'gpsRtkNav' not in dev.data.keys()
or 'sysParams' not in dev.data.keys():
41 fix_status = dev.data[
'gpsRtkNav'][
'status'] & 0xFF00 == 0xC00
42 time_of_lost_fix = dev.data[
'gpsRtkNav'][
'towMs'][np.argmax(~fix_status)]
43 imu_temp_at_time_of_lost_fix = dev.data[
'sysParams'][
'imuTemp'][np.argmax(dev.data[
'sysParams'][
'towMs'] > time_of_lost_fix)]
44 baro_temp_at_time_of_lost_fix = dev.data[
'sysParams'][
'baroTemp'][np.argmax(dev.data[
'sysParams'][
'towMs'] > time_of_lost_fix)]
45 time_of_regain_fix = dev.data[
'gpsRtkNav'][
'towMs'][len(fix_status) - np.argmax(~fix_status[::-1]) - 1]
46 imu_temp_at_time_of_regain_fix = dev.data[
'sysParams'][
'imuTemp'][np.argmax(dev.data[
'sysParams'][
'towMs'] > time_of_regain_fix)]
47 baro_temp_at_time_of_regain_fix = dev.data[
'sysParams'][
'baroTemp'][np.argmax(dev.data[
'sysParams'][
'towMs'] > time_of_regain_fix)]
48 print (
"dev: {0} lost: IMU = {1}, baro = {2}, regain: IMU={3}, baro={4}".format(dev.data[
'devInfo'][
'serialNumber'][0], imu_temp_at_time_of_lost_fix,
49 baro_temp_at_time_of_lost_fix, imu_temp_at_time_of_regain_fix, baro_temp_at_time_of_regain_fix))
52 file = open(
"/home/superjax/Documents/inertial_sense/config.yaml",
'r') 53 config = yaml.load(file) 54 directory = config["directory"]
55 serials = config[
'serials']
57 numDev = len(log.devices)
59 np.set_printoptions(linewidth=200)
62 navMode = (log.devices[0].data[
'ins2'][
'iStatus'] & 0x1000)[-1]
65 print(
"\nComputing RMS Accuracies: (%d devices)" % (numDev))
68 data = [np.hstack((log.devices[i].data[
'ins2'][
'tow'][:,
None],
69 log.devices[i].data[
'ins2'][
'lla'],
70 log.devices[i].data[
'ins2'][
'uvw'],
71 log.devices[i].data[
'ins2'][
'q']))
for i
in range(numDev)]
74 for dev
in range(numDev):
75 if (np.diff(data[dev][:,0]) > 10.0).any():
76 print(
"large gaps in data for dev", dev,
"chopping off data before gap".format(dev))
77 idx = np.argmax(np.diff(data[dev][:,0])) + 1
78 data[dev] = data[dev][idx:,:]
80 min_time =
max([np.min(data[i][:,0])
for i
in range(numDev)])
81 max_time = min([np.max(data[i][:,0])
for i
in range(numDev)])
85 if log.devices[0].data[
'flashConfig'][
'RTKCfgBits'][-1] == 8:
87 time_of_fix_ms = [dev.data[
'gps1RtkCmpRel'][
'timeOfWeekMs'][np.argmax(dev.data[
'gps1RtkCmpRel'][
'arRatio'] > 3.0)] / 1000.0
for dev
in log.devices]
89 min_time =
max(time_of_fix_ms)
93 min_time = max_time - (max_time - min_time)/2.0
97 t = np.arange(1.0, max_time - min_time - 1.0, dt)
98 for i
in range(numDev):
100 data[i] = data[i][data[i][:, 0] > min_time]
101 data[i] = data[i][data[i][:, 0] < max_time]
104 data[i][:,0] -= min_time
107 fi = interp1d(data[i][:,0], data[i][:,1:].T, kind=
'cubic', fill_value=
'extrapolate', bounds_error=
False)
108 data[i] = np.hstack((t[:,
None], fi(t).T))
111 data[i][:,7:] /=
norm(data[i][:,7:], axis=1)[:,
None]
114 data = np.array(data)
118 refLla = data[0, int(round(len(t) / 2.0)), 1:4].copy()
119 for i
in range(numDev):
120 data[i, :, 1:4] =
lla2ned(refLla, data[i, :, 1:4])
123 means = np.empty((len(data[0]), 10))
124 means[:,:6] = np.mean(data[:,:,1:7], axis=0)
128 att_error = np.array([
qboxminus(data[dev,:, 7:], means[:, 6:])
for dev
in range(numDev)])
130 mount_bias = np.mean(att_error, axis=1)
138 att_error -= mount_bias[:,
None,:]
141 colors = [
'r', 'g', 'b', 'm']
144 plt.title(
"position error")
146 for n
in range(numDev):
147 plt.plot(data[n,:,0], data[n, :, m+1], color = colors[m])
148 plt.plot(data[0,:,0], means[:, m], linewidth=2, color = colors[m])
150 plt.title(
"velocity error")
152 for n
in range(numDev):
153 plt.plot(data[n,:,0], data[n, :, m+4], color = colors[m] )
154 plt.plot(data[0,:,0], means[:, m+3], linewidth=2, color = colors[m])
156 plt.title(
"attitude")
158 for n
in range(numDev):
159 plt.plot(data[n,:,0], data[n, :, m+7], color = colors[m])
160 plt.plot(data[0,:,0], means[:, m+6], linewidth=2, color = colors[m])
164 plt.subplot(3, 1, m +1)
165 for n
in range(numDev):
166 plt.plot(att_error[n, :, m])
170 RMS = np.empty((numDev, 9))
172 RMS[:,:6] = np.sqrt(np.mean(np.square(data[:, :, 1:7] - means[:,0:6]), axis=1))
174 RMS[:,6:] = np.sqrt(np.mean(np.square(att_error[:, :, :]), axis=1))
177 averageRMS = np.mean(RMS, axis=0)
179 print(
"average RMS = ", averageRMS)
182 RMS_euler = RMS[:,6:]
183 averageRMS_euler = averageRMS[6:]
184 mount_bias_euler = mount_bias
188 thresholds = np.array([0.2, 0.2, 0.2,
191 if navMode
or compassing:
194 thresholds[:6] = np.inf
196 thresholds[6:] *= DEG2RAD
200 specRatio = averageRMS / thresholds
202 filename = os.path.join(directory,
'RMS_report_new.txt');
203 f = open(filename,
'w')
204 f.write(
'***** Performance Analysis Report - %s *****\n' % (subdir))
206 f.write(
'Directory: %s\n' % (directory))
208 if navMode: mode =
"NAV" 209 if compassing: mode =
"DUAL GNSS" 216 '--------------------------------------------------- RMS Accuracy -------------------------------------------\n')
217 line = line +
'UVW[ (m/s) (m/s) (m/s) ], NED[ (m) (m) (m) ],' 219 f.write(
'-------------- RMS Accuracy --------------\n')
220 line = line +
' Att [ (deg) (deg) (deg) ]\n' 223 for n
in range(0, numDev):
224 devInfo = itd.cDevInfo(log.devices[n].data[
'devInfo'])
225 line =
'%2d SN%d ' % (n, devInfo.v[
'serialNumber'][-1])
227 line = line +
'[ %6.4f %6.4f %6.4f ], ' % ( RMS[n, 3], RMS[n, 4], RMS[n, 5])
228 line = line +
'[ %6.4f %6.4f %6.4f ], ' % ( RMS[n, 0], RMS[n, 1], RMS[n, 2])
229 line = line +
'[ %6.4f %6.4f %6.4f ]\n' % (RMS_euler[n, 0] * RAD2DEG, RMS_euler[n, 1] * RAD2DEG, RMS_euler[n, 2] * RAD2DEG)
234 f.write(
'------------------------------------------------------------------------------------------------------------\n')
235 line = line +
'[%7.4f %7.4f %7.4f ], ' % (averageRMS[3], averageRMS[4], averageRMS[5])
236 line = line +
'[%7.4f %7.4f %7.4f ], ' % (averageRMS[0], averageRMS[1], averageRMS[2])
238 f.write(
'------------------------------------------\n')
239 line = line +
'[%7.4f %7.4f %7.4f ]\n' % (averageRMS_euler[0] * RAD2DEG, averageRMS_euler[1] * RAD2DEG, averageRMS_euler[2] * RAD2DEG)
244 line = line +
'[%7.4f %7.4f %7.4f ], ' % (thresholds[3], thresholds[4], thresholds[5])
245 line = line +
'[%7.4f %7.4f %7.4f ], ' % (thresholds[0], thresholds[1], thresholds[2])
246 line = line +
'[%7.4f %7.4f %7.4f ]\n' % (thresholds[6] * RAD2DEG, thresholds[7] * RAD2DEG, thresholds[8] * RAD2DEG)
251 f.write(
'------------------------------------------------------------------------------------------------------------\n')
252 line = line +
'[%7.4f %7.4f %7.4f ], ' % (specRatio[3], specRatio[4], specRatio[5])
253 line = line +
'[%7.4f %7.4f %7.4f ], ' % (specRatio[0], specRatio[1], specRatio[2])
255 f.write(
'------------------------------------------\n')
256 line = line +
'[%7.4f %7.4f %7.4f ]\n' % (specRatio[6], specRatio[7], specRatio[8])
259 def pass_fail(ratio):
return 'FAIL' if ratio > 1.0
else 'PASS' 263 line = line +
'[ %s %s %s ], ' % (pass_fail(specRatio[3]),pass_fail(specRatio[4]),pass_fail(specRatio[5]))
264 line = line +
'[ %s %s %s ], ' % (pass_fail(specRatio[0]),pass_fail(specRatio[1]),pass_fail(specRatio[2]))
265 line = line +
'[ %s %s %s ]\n' % (pass_fail(specRatio[6]),pass_fail(specRatio[7]),pass_fail(specRatio[8]))
272 f.write(
'('+mode +
' mode)\n\n')
275 f.write(
'--------------- Angular Mounting Biases ----------------\n')
276 f.write(
'Device Euler Biases[ (deg) (deg) (deg) ]\n')
277 for n
in range(0, numDev):
278 devInfo = itd.cDevInfo(log.devices[n].data[
'devInfo'])
279 f.write(
'%2d SN%d [ %7.4f %7.4f %7.4f ]\n' % (
280 n, devInfo.v[
'serialNumber'][-1], mount_bias_euler[n, 0] * RAD2DEG, mount_bias_euler[n, 1] * RAD2DEG, mount_bias_euler[n, 2] * RAD2DEG))
285 '------------------------------------------- Device Info -------------------------------------------------\n')
286 for n
in range(0, numDev):
287 devInfo = itd.cDevInfo(log.devices[n].data[
'devInfo'])
288 hver = devInfo.v[
'hardwareVer'][-1]
289 cver = devInfo.v[
'commVer'][-1]
290 fver = devInfo.v[
'firmwareVer'][-1]
291 buld = devInfo.v[
'build'][-1]
292 repo = devInfo.v[
'repoRevision'][-1]
293 date = devInfo.v[
'buildDate'][-1]
294 time = devInfo.v[
'buildTime'][-1]
295 addi = devInfo.v[
'addInfo'][-1]
297 '%2d SN%d HW: %d.%d.%d.%d FW: %d.%d.%d.%d build %d repo %d Proto: %d.%d.%d.%d Date: %04d-%02d-%02d %02d:%02d:%02d %s\n' % (
298 n, devInfo.v[
'serialNumber'][-1],
299 hver[3], hver[2], hver[1], hver[0],
300 fver[3], fver[2], fver[1], fver[0], buld, repo,
301 cver[3], cver[2], cver[1], cver[0],
302 2000 + date[2], date[1], date[0],
303 time[3], time[2], time[1],
310 if 'win' in sys.platform:
311 subprocess.Popen([
"notepad.exe", filename])
312 if 'linux' in sys.platform:
313 subprocess.Popen([
'gedit', filename])
def checkRawDataDrop(log)
GeneratorWrapper< T > range(T const &start, T const &end, T const &step)
#define max(a, b)
Takes the maximal value of a and b.
def calcRMS(log, directory, subdir)