7 import pylib.pose
as ps
8 import pylib.ISToolsDataSorted
as itd
9 import pylib.filterTools
as ft
10 import pylib.plotTools
as plotTools
11 import matplotlib.pyplot
as plt
15 import time
as systime
16 from pylib.ISToolsDataSorted
import cObj, refLla, getTimeFromTowMs, getTimeFromTow
17 from pylib
import pose
34 if key
in log.data.keys():
35 d = dataClass(log.data[key])
41 def IsLoggerPlot( pe, log, tru=None, startFigure=None, referencePlot=False, saveFigs=False, saveFigsDirectory='', numDevs=None ):
51 serialNumbers.append(log.data[
'devInfo'][
'serialNumber'][0])
53 print (
"something is wrong")
55 def saveFigures(filename, f=None, fig=None):
62 fsize = fig.get_size_inches()
64 fig.set_size_inches(20,20)
65 fig.savefig(os.path.join(saveFigsDirectory,filename), bbox_inches=
'tight')
66 fig.set_size_inches(fsize)
69 return key
in pe
and pe[key]
72 pt.timeIsUtc = pe[
'showUtcTime']
76 print(
"=============== IsLoggerPlot() - datalog keys ===============")
77 for key
in log.data.keys():
79 print(key, log.data[key].dtype.names)
85 if not key
in log.data.keys():
87 if not key
in log.data.keys():
89 if not key
in log.data.keys():
90 print(
"INS data not found!!!")
92 print(
"==============================================================")
97 itd.setGpsWeek( ins.v[
'week'] )
99 gps1Pos =
log2Data( log, itd.cGPS,
'gps1Pos' )
101 gps1Ubx =
log2Data( log, itd.cGPS,
'gps1UbxPos' )
102 gps1RtkPos =
log2Data( log, itd.cGPS,
'gps1RtkPos' )
103 gps1Raw =
log2Data( log, itd.cGPSRaw,
'GPS1Raw')
104 gps2Raw =
log2Data( log, itd.cGPSRaw,
'GPS2Raw')
105 gpsBaseRaw =
log2Data( log, itd.cGPSRaw,
'GPSBaseRaw')
106 imu1 =
log2Data( log, itd.cIMU,
'imu1' )
107 dimu =
log2Data( log, itd.cIMU,
'dualImu' )
108 dimu =
log2Data( log, itd.cIMU,
'preintegratedImu' )
109 mag1 =
log2Data( log, itd.cIMU,
'magnetometer1' )
110 mag2 =
log2Data( log, itd.cIMU,
'magnetometer2' )
111 magInfo =
log2Data( log, itd.cSIMPLE,
'inl2MagObs')
112 varInfo =
log2Data( log, itd.cSIMPLE,
'inl2Variance')
113 baro =
log2Data( log, itd.cIMU,
'barometer' )
117 gmt1 = systime.gmtime( ins.time[0] - systime.timezone )
118 gmt2 = systime.gmtime( ins.time[-1] - systime.timezone )
119 dgmt = systime.gmtime( ins.time[-1] - ins.time[0] )
120 print(
" INS: %d-%d-%d %d:%d:%d - %d:%d:%d (%d:%d:%d)" % (gmt1.tm_year, gmt1.tm_mon, gmt1.tm_mday,
121 gmt1.tm_hour, gmt1.tm_min, gmt1.tm_sec,
122 gmt2.tm_hour, gmt2.tm_min, gmt2.tm_sec,
123 dgmt.tm_hour, dgmt.tm_min, dgmt.tm_sec))
125 gmt1 = systime.gmtime( imu1.time[0] - systime.timezone )
126 gmt2 = systime.gmtime( imu1.time[-1] - systime.timezone )
127 dgmt = systime.gmtime( imu1.time[-1] - imu1.time[0] )
128 print(
" IMU: %d-%d-%d %d:%d:%d - %d:%d:%d (%d:%d:%d)" % (gmt1.tm_year, gmt1.tm_mon, gmt1.tm_mday,
129 gmt1.tm_hour, gmt1.tm_min, gmt1.tm_sec,
130 gmt2.tm_hour, gmt2.tm_min, gmt2.tm_sec,
131 dgmt.tm_hour, dgmt.tm_min, dgmt.tm_sec))
133 gmt1 = systime.gmtime( gps1Pos.time[0] - systime.timezone )
134 gmt2 = systime.gmtime( gps1Pos.time[-1] - systime.timezone )
135 dgmt = systime.gmtime( gps1Pos.time[-1] - gps1Pos.time[0] )
136 print(
" GPS: %d-%d-%d %d:%d:%d - %d:%d:%d (%d:%d:%d)" % (gmt1.tm_year, gmt1.tm_mon, gmt1.tm_mday,
137 gmt1.tm_hour, gmt1.tm_min, gmt1.tm_sec,
138 gmt2.tm_hour, gmt2.tm_min, gmt2.tm_sec,
139 dgmt.tm_hour, dgmt.tm_min, dgmt.tm_sec))
141 sysp =
log2Data( log, itd.cSysParams,
'sysParams' )
142 sysp =
log2Data( log, itd.cSysParams,
'ins2' )
144 sysp =
log2Data( log, itd.cSysParams,
'sysParams' )
145 ires =
log2Data( log, itd.cInsRes,
'insResources')
146 info =
log2Data( log, itd.cDevInfo,
'devInfo')
149 print(
'Index:', log.index,
' Device S/N: ',info.v[
'serialNumber'][-1])
150 hver = info.v[
'hardwareVer'][-1]
151 cver = info.v[
'commVer'][-1]
152 fver = info.v[
'firmwareVer'][-1]
153 print(
' Hardware: %d.%d.%d.%d Com: %d.%d.%d.%d Firmware: %d.%d.%d.%d b%d r%d' %( hver[0], hver[1], hver[2], hver[3], cver[0], cver[1], cver[2], cver[3], fver[0], fver[1], fver[2], fver[3], info.v[
'build'][-1], info.v[
'repoRevision'][-1] ))
155 print(
'Index:', log.index)
157 if 'debugArray' in log.data.keys():
159 dbg =
log2Data( log, itd.cSIMPLE,
'debugArray')
160 dbg.time = dbg.v[
'i'][:,0]*0.001
166 biasPqr = np.r_[ 0.0, 0.44, -0.15 ]*DEG2RAD
167 biasAcc = np.r_[ -0.038, 0.085, 0.065 ]
168 rot = np.r_[ 0.32, 0.18, 0.5 ]*DEG2RAD
170 rImu = itd.cRIMU(tru.data[
'IMU'])
171 rGps = itd.cRGPS(tru.data[
'GPS'])
172 rIns = itd.cRINS(tru.data[
'INS'])
174 print(
"RINS keys:", rIns.v.dtype.names)
175 print(
"RIMU keys:", rImu.v.dtype.names)
176 print(
"RGPS keys:", rGps.v.dtype.names)
200 np.set_printoptions(threshold=
'nan')
205 if pt.timeIsUtc == 0:
206 startTow = ins.time[0]
207 ins.time = ins.time - startTow
209 meanTowOffset = np.mean(gps1Pos.v[
'towOffset'])
212 gps1Pos.time = gps1Pos.time - startTow
214 gps1Ubx.time = gps1Ubx.time - startTow
216 gps1RtkPos.time = gps1RtkPos.time - startTow
219 sysp.time = sysp.time - startTow
220 if ires
and 'time' in ires.v:
221 ires.time = ires.time - startTow
224 imu1.time = imu1.time + meanTowOffset - startTow
226 imu1.time = imu1.time - imu1.time[0]
230 dimu.time = dimu.time + meanTowOffset - startTow
232 dimu.time = dimu.time - dimu.time[0]
235 mag1.time = mag1.time + meanTowOffset - startTow
237 mag2.time = mag2.time + meanTowOffset - startTow
239 baro.time = baro.time + meanTowOffset - startTow
242 rIns.v[
'tow'] = rIns.v[
'tow'] - startTow
243 rImu.v[
'time'] = rImu.v[
'time'] - startTow
244 rGps.v[
'tow'] = rGps.v[
'tow'] - startTow
247 dbg.time = dbg.time - startTow
249 if 'ekfStates' in log.data:
251 log.data[
'ekfStates'][
'time'] = log.data[
'ekfStates'][
'time'] + meanTowOffset - startTow
253 log.data[
'ekfStates'][
'time'] = log.data[
'ekfStates'][
'time'] - log.data[
'ekfStates'][
'time'][0]
256 if 'ned' in ins.v.dtype.names:
257 ins.v[
'ned'] = ins.v[
'ned'] - ins.v[
'ned'][0,:]
263 if 'eulerErr' in ins.v.dtype.names
and rIns:
265 start = np.shape(ins.time)[0]/2
266 print(
" ========== STATISTICS ========== ")
269 insEuler = ins.v[
'eulerErr'][start:,:]
270 rIns.offset = np.r_[np.mean(insEuler[:,0]),
271 np.mean(insEuler[:,1]),
272 np.mean(insEuler[:,2])]
273 eulerErr = np.c_[insEuler[:,0] - rIns.offset[0],
274 insEuler[:,1] - rIns.offset[1],
275 insEuler[:,2] - rIns.offset[2]]
276 ins.eulerErrRms = np.sqrt( np.r_[np.mean(eulerErr[:,0]**2),
277 np.mean(eulerErr[:,1]**2),
278 np.mean(eulerErr[:,2]**2)] )
279 print(
"Euler Angles (deg):")
280 print(
" Offset from Truth: \t", rIns.offset*RAD2DEG)
281 print(
" RMS Accuracy: \t", ins.eulerErrRms*RAD2DEG)
285 uvwErr = ins.v[
'uvwErr'][start:,:]
286 ins.uvwErrRms = np.sqrt( np.r_[np.mean(uvwErr[:,0]**2),
287 np.mean(uvwErr[:,1]**2),
288 np.mean(uvwErr[:,2]**2)] )
289 print(
"UVW RMS Accuracy (m/s): \t", ins.uvwErrRms)
293 nedErr = ins.v[
'nedErr'][start:,:]
294 ins.nedErrRms = np.sqrt( np.r_[np.mean(nedErr[:,0]**2),
295 np.mean(nedErr[:,1]**2),
296 np.mean(nedErr[:,2]**2)] )
297 print(
"NED RMS Accuracy (m): \t", ins.nedErrRms)
299 if peCheck(
'rawGPSStats'):
301 print(
"GPS 1 Corrupt Data Count", gps1Raw.corruptCount,
"/", len(gps1Raw.count))
303 print(
"GPS 2 Corrupt Data Count", gps2Raw.corruptCount,
"/", len(gps2Raw.count))
304 if gpsBaseRaw
is not 0:
305 print(
"GPS Base Corrupt Data Count", gpsBaseRaw.corruptCount,
"/", len(gpsBaseRaw.count))
312 refColor =
'r' rtkColor = 'c' 324 if startFigure!=
None:
328 IsLoggerPlot.serialNumbers += [log.serialNumber]
330 pt.setPreTitle(
"%s__%s" % (os.path.basename(saveFigsDirectory), log.serialNumber))
337 if not 'sysParams' in log.data.keys():
338 print(
"Unable to plot sysParams (because it's not there)")
340 sysP = log.data[
'sysParams']
341 time = (sysP[
'towMs'] - sysP[
'towMs'][0])/1000.0
342 fig, ax = pt.subplots(f, 2,
'Temperature')
343 pt.subplotSingle(ax[0],
getTimeFromTowMs(sysP[
'towMs']), sysP[
'imuTemp'], title=
'Temperature: IMU')
344 pt.subplotSingle(ax[1],
getTimeFromTowMs(sysP[
'towMs']), sysP[
'baroTemp'], title=
'Temperature: Baro')
345 saveFigures(
'Temperature', f)
351 if peCheck(
'debugArray_i'):
354 print(
"Unable to print debug array - messages missing")
356 fig, ax = pt.subplots(f, 1,
'debugArray_i', sharex=
True)
358 pt.subplotSingle(ax, dbg.time, dbg.v[
'i'][:,j], title=
'i', options={
'label': j})
360 saveFigures(
'debugArray_i.svg', f)
361 if peCheck(
'debugArray_f')
and dbg:
364 print(
"Unable to print debug array - messages missing")
366 fig, ax = pt.subplots(f, 1,
'debugArray_f', sharex=
True)
368 pt.subplotSingle(ax, dbg.time, dbg.v[
'f'][:,j], title=
'f', options={
'label': j})
370 saveFigures(
'debugArray_f.svg', f)
371 if peCheck(
'debugArray_lf')
and dbg:
374 print(
"Unable to print debug array - messages missing")
376 fig, ax = pt.subplots(f, 1,
'debugArray_lf', sharex=
True)
378 pt.subplotSingle(ax, dbg.time, dbg.v[
'lf'][:,j], title =
'lf', options={
'label': j})
380 saveFigures(
'debugArray_lf.svg', f)
385 def inliers(data, m=4):
386 d = np.abs(data - np.median(data))
388 s = d / mdev
if mdev
else 0.
391 def plotSNR(raw_gps, f, name):
394 print(
"unable to plot " + name +
"SNR because data is missing")
396 satellites = np.unique(raw_gps.obs[
'sat'])
397 fig, ax = pt.subplots(f, len(satellites),
'raw' + name +
'SNR', sharex=
True)
399 for i, sat
in enumerate(satellites):
400 valid_indexes = (raw_gps.obs[
'sat'] == sat)
401 pt.subplotSingle(ax[i], raw_gps.obstime[valid_indexes].astype(datetime.datetime), raw_gps.obs[
'sat'][valid_indexes], title=
"sat " + str(sat), options=
'x')
402 saveFigures(
'raw' + name +
'SNR.svg', f)
405 def plotPrange(raw_gps, f, name):
408 print(
"unable to plot " + name +
"Prange because data is missing")
410 satellites = np.unique(raw_gps.obs[
'sat'])
411 fig, ax = pt.subplots(f, len(satellites),
'raw' + name +
'Prange', sharex=
True)
413 for i, sat
in enumerate(satellites):
414 valid_indexes = raw_gps.obs[
'sat'] == sat
416 pt.subplotSingle(ax[i], raw_gps.obstime[valid_indexes].astype(datetime.datetime), raw_gps.obs[
'P'][valid_indexes], title=
"sat " + str(sat), options=
'x')
419 saveFigures(
'raw' + name +
'Prange.svg', f)
422 def plotCPhase(raw_gps, f, name):
425 print(
"unable to plot " + name +
"Cphase because data is missing")
427 satellites = np.unique(raw_gps.obs[
'sat'])
428 fig, ax = pt.subplots(f, len(satellites),
'raw' + name +
'CarrierPhase', sharex=
True)
430 for i, sat
in enumerate(satellites):
431 valid_indexes = (raw_gps.obs[
'sat'] == sat) & (raw_gps.obs[
'L'] != 0)
433 pt.subplotSingle(ax[i], raw_gps.obstime[valid_indexes].astype(datetime.datetime), raw_gps.obs[
'L'][valid_indexes],
434 title=
"sat " + str(sat), options=
'x')
436 print(
"problem plotting cphase")
437 saveFigures(
'raw' + name +
'CarrierPhase.svg', f)
440 if peCheck(
'rawBaseGpsSNR')
and gpsBaseRaw:
441 f = plotSNR(gpsBaseRaw, f,
'BaseRaw')
443 if peCheck(
'rawBaseGpsPrange')
and gpsBaseRaw:
444 f = plotPrange(gpsBaseRaw, f,
'BaseRaw')
446 if peCheck(
'rawBaseCarrierPhase')
and gpsBaseRaw:
447 f = plotCPhase(gpsBaseRaw, f,
'BaseRaw')
452 if peCheck(
'rawGps1SNR')
and gps1Raw:
453 f = plotSNR(gps1Raw, f,
'Gps1Raw')
455 if peCheck(
'rawGps1Prange')
and gps1Raw:
456 f = plotPrange(gps1Raw, f,
'Gps1Raw')
458 if peCheck(
'rawGps1CarrierPhase')
and gps1Raw:
459 f = plotCPhase(gps1Raw, f,
'Gps1Raw')
464 if peCheck(
'rawGps2SNR')
and gps2Raw:
465 f = plotSNR(gps2Raw, f,
'GPS2Raw')
467 if peCheck(
'rawGps2Prange')
and gps2Raw:
468 f = plotPrange(gps2Raw, f,
'GPS2Raw')
470 if peCheck(
'rawGps2CarrierPhase')
and gps2Raw:
471 f = plotCPhase(gps2Raw, f,
'GPS2Raw')
475 if peCheck(
'compassingAngle'):
477 if 'gps1RtkCmpRel' not in log.data.keys():
478 print(
"no gps1RtkCmpRel, cannot plot compassingAngle")
481 fig, ax = pt.subplots(f, 2,
'Heading', sharex=
True)
483 rtkRel = log.data[
'gps1RtkCmpRel']
485 pt.subplotSingle(ax[0],
getTimeFromTowMs(rtkRel[
'timeOfWeekMs']), rtkRel[
'headingToBase'] * RAD2DEG, title=
"RTK")
486 pt.subplotSingle(ax[1],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:, 2] * RAD2DEG, title=
"INS")
487 saveFigures(
'compassingAngle.svg', f)
491 if peCheck(
'vectorToBase'):
494 if 'gps1RtkCmpRel' not in log.data.keys():
495 print(
"no gps1RtkCmpRel, cannot plot vectorToBase")
498 fig, ax = pt.subplots(f, 4,
'vectorToBase', sharex=
True)
500 rtkRel = log.data[
'gps1RtkCmpRel']
518 cmap = matplotlib.cm.get_cmap(
'Spectral')
519 colors = [cmap(i/numDevs)
for i
in range(numDevs)]
521 titles = [
"North",
"East",
"Down"]
523 pt.subplotSingle(ax[i], time, rtkRel[
'vectorToBase'][:,i],title=titles[i], ylabel=
'm')
528 ax[0].legend([str(ser)
for ser
in serialNumbers])
530 pt.subplotSingle(ax[3], time, rtkRel[
'distanceToBase']
531 , title=
"DistanceToBase", ylabel=
'm')
535 saveFigures(
'vectorToBase.svg', f)
539 if peCheck(
'compassingCircle'):
541 if 'gps1RtkCmpRel' not in log.data.keys():
542 print(
"no RTK_Rel, cannot plot compassingCircle")
546 rtkRel = log.data[
'gps1RtkCmpRel']
548 vec2basefix = rtkRel[
'vectorToBase'].copy()
549 vec2basefloat = rtkRel[
'vectorToBase'].copy()
550 vec2basesingle = rtkRel[
'vectorToBase'].copy()
552 vec2basefix[rtkRel[
'arRatio'] < 3.0, :] = np.nan
553 vec2basefloat[(rtkRel[
'arRatio'] < 0.0) | (rtkRel[
'arRatio'] > 3.0), :] = np.nan
554 vec2basesingle[rtkRel[
'arRatio'] > 0.001, :] = np.nan
556 fig, ax = pt.subplots(f, 2,
'compassingCircle', numCols=2)
557 pt.subplotSingle(ax[0,0], vec2basefix[:, 0], vec2basefix[:, 1], options=
'm')
558 pt.subplotSingle(ax[0,0], vec2basefloat[:, 0], vec2basefloat[:, 1], options=
'b')
559 pt.subplotSingle(ax[0,0], vec2basesingle[:, 0], vec2basesingle[:, 1], options=
'g')
564 pt.subplotSingle(ax[1,0], vec2basefix[:, 1], vec2basefix[:, 2], options=
'm')
565 pt.subplotSingle(ax[1,0], vec2basefloat[:, 1], vec2basefloat[:, 2], options=
'b')
566 pt.subplotSingle(ax[1,0], vec2basesingle[:, 1], vec2basesingle[:, 2], options=
'g')
571 pt.subplotSingle(ax[0,1], vec2basefix[:, 0], vec2basefix[:, 2], options=
'm')
572 pt.subplotSingle(ax[0,1], vec2basefloat[:, 0], vec2basefloat[:, 2], options=
'b')
573 pt.subplotSingle(ax[0,1], vec2basesingle[:, 0], vec2basesingle[:, 2], options=
'g')
577 ax[0,1].legend([
'fix',
'float',
'single'])
579 saveFigures(
'compassingCircle.svg', f)
581 if peCheck(
'compassingCircle3d'):
583 if 'gps1RtkCmpRel' not in log.data.keys():
584 print(
"no RTK_Rel, cannot plot compassingCircle")
586 vec2basefix = rtkRel[
'vectorToBase'].copy()
587 vec2basefloat = rtkRel[
'vectorToBase'].copy()
588 vec2basesingle = rtkRel[
'vectorToBase'].copy()
590 vec2basefix[rtkRel[
'arRatio'] < 3.0, :] = np.nan
591 vec2basefloat[(rtkRel[
'arRatio'] < 0.0) | (rtkRel[
'arRatio'] > 3.0), :] = np.nan
592 vec2basesingle[rtkRel[
'arRatio'] > 0.001, :] = np.nan
594 fig, ax = pt.plot3D(f,
'compassingCircle3d')
595 ax.plot(vec2basefix[:, 0], vec2basefix[:, 1], vec2basefix[:,2],
'm')
596 ax.plot(vec2basefloat[:, 0], vec2basefloat[:, 1], vec2basefloat[:,2],
'b')
597 ax.plot(vec2basesingle[:, 0], vec2basesingle[:, 1], vec2basesingle[:,2],
'g')
598 ax.legend([
'fix',
'float',
'single'])
600 saveFigures(
'compassingCircle3d.svg', f)
602 u, v = np.mgrid[0:2 * np.pi:180j, 0:np.pi:180j]
603 x = np.cos(u) * np.sin(v)
604 y = np.sin(u) * np.sin(v)
606 ax.plot_wireframe(x, y, z, color=
"k", alpha=0.1, linewidth=1.0)
610 if peCheck(
'googleEarth'):
613 if pe[
'googleEarth'] == 2:
616 altMode=
"clampToGround" 620 kmlfile = itd.lla2kml(ins.time, ins.v[
'lla'], log.serialNumber, log.directory +
"/" +
"LOG_"+log.serialNumber+
"ins.kml", timeStep=tStep, altitudeMode=altMode )
621 os.startfile( kmlfile )
624 kmlfile = itd.lla2kml(gps1Pos.time, gps1Pos.v[
'lla'], log.serialNumber, log.directory +
"/" +
"LOG_"+log.serialNumber+
"gps1Pos.kml", timeStep=tStep, altitudeMode=altMode, color=simplekml.Color.red )
625 os.startfile( kmlfile )
628 kmlfile = itd.lla2kml(rIns.v[
'time'], rIns.v[
'lla'], tru.serialNumber, log.directory +
"/" +
"LOG_"+tru.serialNumber+
"refIns.kml", timeStep=tStep, altitudeMode=altMode, color=simplekml.Color.black )
629 os.startfile( kmlfile )
631 if pe[
'googleEarth'] == 2:
639 pt.labels(
'IMU Time',
'ms')
641 fig, ax = pt.subplots(f,1,
"IMU time")
642 timeCnt = len(dimu.time)
645 for i
in range(0,timeCnt):
647 dimuTime.append(np.float64(dimu.time[i]).item())
649 pt.subplotSingle(ax, counter, dimu.v[
'time'])
650 plt.ylim( -1, 10000 )
655 pt.labels(
'UVW',
'm/s')
658 pt.plot3Axes(f, rIns.v[
'time'], rIns.uvw, options=rInsColor)
660 pt.plot3Axes(f,
getTimeFromTow(ins.v[
'tow']), ins.v[
'uvw'], options=insColor)
664 if peCheck(
'uvwDot'):
668 pt.plot3Axes(f, rIns.v[
'time'], ft.smooth(ft.derivative(rIns.v[
'time'], rIns.uvw, delta=2), delta=10), options=rInsColor)
670 pt.plot3Axes(f, ires.time, ft.smooth(ires.v[
'x_dot.uvw'], delta=20),
'UVW Dot',
'm/s^2', options=insColor)
674 saveFigures(
'uvw.svg', f)
676 if peCheck(
'uvwErr')
and 'uvwErr' in ins.v.dtype.names:
678 pt.plot3Axes(f,
getTimeFromTow(ins.v[
'tow']), ins.v[
'uvwErr'],
'UVW Error from Truth INS',
'm/s', options=errColor)
684 f += 1; legend = [str(ser)
for ser
in serialNumbers]
685 fig, ax = pt.subplots(f,3,
"Attitude", sharex=
True)
688 pt.subplotSingle(ax[0], rIns.v[
'time'], rIns.v[
'euler'][:,0]*RAD2DEG, options=rInsColor)
691 pt.subplotSingle(ax[0],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,0]*RAD2DEG,
'Roll',
'deg', options=insColor)
693 pt.subplotSingle(ax[0],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,0]*RAD2DEG,
'Roll',
'deg')
696 pt.subplotSingle(ax[1], rIns.v[
'time'], rIns.v[
'euler'][:,1]*RAD2DEG, options=rInsColor)
699 pt.subplotSingle(ax[1],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,1]*RAD2DEG,
'Pitch',
'deg', options=insColor)
701 pt.subplotSingle(ax[1],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,1]*RAD2DEG,
'Pitch',
'deg')
704 pt.subplotSingle(ax[2], rIns.v[
'time'], rIns.v[
'euler'][:,2]*RAD2DEG, options=rInsColor)
708 pt.subplotSingle(ax[2],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,2]*RAD2DEG,
'Yaw',
'deg', options=insColor)
710 pt.subplotSingle(ax[2],
getTimeFromTow(ins.v[
'tow']), ins.v[
'euler'][:,2]*RAD2DEG,
'Yaw',
'deg')
716 if gps1Pos
and np.fabs(np.mean(
getTimeFromTow(ins.v[
'tow'])) - np.mean(gps1Pos.time)) < 1000:
717 pt.subplotSingle(ax[2], gps1Pos.time, gps1Pos.v[
'course']*RAD2DEG, options=refColor)
722 saveFigures(
'attINS.svg', f)
727 if peCheck(
'magNISThreshold'):
729 fig, ax = pt.subplots(f,1,
'magNISThreshold')
731 pt.subplotSingle(ax,magInfo.v[
'towMs'], magInfo.v[
'nis'] ,
'nis' )
732 pt.subplotSingle(ax,magInfo.v[
'towMs'], magInfo.v[
'nis_threshold'] ,
'nis_threshold' )
736 if peCheck(
'variance'):
738 fig, ax = pt.subplots(f,3,
'Variance', sharex=
True)
739 pt.labels(
'INL2 Position Variance')
740 pt.subplotSingle(ax[0],varInfo.v[
'towMs'], varInfo.v[
'PxyxNED'][:,0] ,
'INS Px N (NED)' )
741 pt.subplotSingle(ax[1],varInfo.v[
'towMs'], varInfo.v[
'PxyxNED'][:,1] ,
'INS Py E (NED)' )
742 pt.subplotSingle(ax[2],varInfo.v[
'towMs'], varInfo.v[
'PxyxNED'][:,2] ,
'INS Pz D (NED)' )
745 fig, ax = pt.subplots(f,3,
'Vel Variance', sharex=
True)
746 pt.labels(
'INL2 Velocity Variance')
747 pt.subplotSingle(ax[0],varInfo.v[
'towMs'], varInfo.v[
'PvelNED'][:,0] ,
'INS Pvx N (NED)' )
748 pt.subplotSingle(ax[1],varInfo.v[
'towMs'], varInfo.v[
'PvelNED'][:,1] ,
'INS Pvy E (NED)' )
749 pt.subplotSingle(ax[2],varInfo.v[
'towMs'], varInfo.v[
'PvelNED'][:,2] ,
'INS Pvz D (NED)' )
752 fig, ax = pt.subplots(f,3,
'Att Variance', sharex=
True)
753 pt.labels(
'INL2 Attitude Variance')
754 pt.subplotSingle(ax[0],varInfo.v[
'towMs'], varInfo.v[
'PattNED'][:,0] ,
'INS Pwx (NED)' )
755 pt.subplotSingle(ax[1],varInfo.v[
'towMs'], varInfo.v[
'PattNED'][:,1] ,
'INS Pwy (NED)' )
756 pt.subplotSingle(ax[2],varInfo.v[
'towMs'], varInfo.v[
'PattNED'][:,2] ,
'INS Pwz (NED)' )
759 fig, ax = pt.subplots(f,3,
'A Bias Variance', sharex=
True)
760 pt.labels(
'INL2 A Bias Variance')
761 pt.subplotSingle(ax[0],varInfo.v[
'towMs'], varInfo.v[
'PABias'][:,0] ,
'INS PA Bias x' )
762 pt.subplotSingle(ax[1],varInfo.v[
'towMs'], varInfo.v[
'PABias'][:,1] ,
'INS PA Bias y' )
763 pt.subplotSingle(ax[2],varInfo.v[
'towMs'], varInfo.v[
'PABias'][:,2] ,
'INS PA Bias z' )
766 fig, ax = pt.subplots(f,3,
'W Bias Variance', sharex=
True)
767 pt.labels(
'INL2 W Bias Variance')
768 pt.subplotSingle(ax[0],varInfo.v[
'towMs'], varInfo.v[
'PWBias'][:,0] ,
'INS PW Bias x' )
769 pt.subplotSingle(ax[1],varInfo.v[
'towMs'], varInfo.v[
'PWBias'][:,1] ,
'INS PW Bias y' )
770 pt.subplotSingle(ax[2],varInfo.v[
'towMs'], varInfo.v[
'PWBias'][:,2] ,
'INS PW Bias z' )
773 fig, ax = pt.subplots(f,1,
'Baro Bias Variance', sharex=
True)
774 pt.labels(
'INL2 Baro Bias Variance')
775 pt.subplotSingle(ax,varInfo.v[
'towMs'], varInfo.v[
'PBaroBias'] ,
'Baro Bias' )
778 fig, ax = pt.subplots(f,1,
'Declination Variance', sharex=
True)
779 pt.labels(
'INL2 Declination Variance')
780 pt.subplotSingle(ax,varInfo.v[
'towMs'], varInfo.v[
'PDeclination'] ,
'Declination' )
785 if peCheck(
'gpsVel'):
786 pt.labels(
'GPS Vel NED',
'm/s')
789 pt.plot3Axes(f, rIns.v[
'time'], rIns.v[
'nedDot'], options=rInsColor )
792 pt.plot3Axes(f, gps1Vel.time, gps1Vel.v[
'velNed'], options=refColor )
793 legend += [
'GPS.velNed']
794 gps1Pos.nedDot = ft.derivative(gps1Pos.time, gps1Pos.ned, delta=2)
798 saveFigures(
'gpsVel.svg', f)
802 if peCheck(
'ekfStatesMagField')
and 'ekfStates' in log.data.keys():
804 fig, ax = pt.subplots(f,2,
'ekfStatesMagField', sharex=
True)
805 pt.subplotSingle(ax[0], log.data[
'ekfStates'][
'time'], log.data[
'ekfStates'][
'magInc']*RAD2DEG,
'EKF States - Mag Inclination',
'deg', options=insColor )
806 pt.subplotSingle(ax[1], log.data[
'ekfStates'][
'time'], log.data[
'ekfStates'][
'magDec']*RAD2DEG,
'EKF States - Mag Declination',
'deg', options=insColor )
808 saveFigures(
'ekfStatesMagField.svg', fig=fig)
812 if peCheck(
'velNED'):
813 pt.labels(
'Vel NED',
'm/s')
818 pt.plot3Axes(f, rIns.v[
'time'], rIns.v[
'nedDot'], options=rInsColor )
821 pt.plot3Axes(f, gps1Pos.time, gps1Pos.v[
'ned'], options=refColor )
823 pt.plot3Axes(f, ins.time, ins.velNed(), options=insColor )
828 if peCheck(
'velNedDot'):
832 gps1Pos.nedVelDot = ft.derivative(gps1Pos.time, gps1Pos.v[
'ned'], delta)
833 ins.nedVelDot = ft.derivative(ins.time, ins.v[
'vel'], delta)
834 ins.nedVelDot = ft.lpfNoDelay(ins.nedVelDot, cornerFreqHz=20, time=ins.time)
837 pt.plot3Axes(f, rIns.v[
'time'], rIns.nedDotDot, options=rInsColor )
839 pt.plot3Axes(f, ins.time, ins.nedVelDot )
841 pt.plot3Axes(f, gps1Pos.time, gps1Pos.nedVelDot,
'NED Vel Dot',
'm/s^2', options=refColor )
842 legend += [
'gps1Pos']
845 saveFigures(
'velNED.svg', f)
850 if peCheck(
'ecef')
and gps1Pos:
852 fig, ax = pt.subplots(f,3,
'ECEF', sharex=
True)
857 pt.subplotSingle(ax[0], instime, ins.ecef()[:,0],
'X',
'm', options=insColor)
858 pt.subplotSingle(ax[0], gpstime, gps1Pos.v[
'ecef'][:,0], options=refColor )
860 pt.subplotSingle(ax[1], instime, ins.ecef()[:,1],
'Y',
'm', options=insColor )
861 pt.subplotSingle(ax[1], gpstime, gps1Pos.v[
'ecef'][:,1], options=refColor )
864 pt.subplotSingle(ax[2], instime, ins.ecef()[:,2], options=insColor )
866 pt.subplotSingle(ax[2], gpstime, gps1Pos.v[
'ecef'][:,2], options=refColor )
870 saveFigures(
'ecef.svg', f)
874 if peCheck(
'lla')
and gps1Pos
and hasattr(gps1Pos,
'pos'):
876 fig, ax = pt.subplots(f,3,
'LLA', sharex=
True)
878 pt.subplotSingle(ax[0], rIns.v[
'time'], rIns.v[
'lla'][:,0], options=rInsColor )
882 pt.subplotSingle(ax[0], instime, ins.v[
'lla'][:,0],
'Latitude',
'deg', options=insColor)
883 pt.subplotSingle(ax[0], gpstime, gps1Pos.v[
'lla'][:,0], options=refColor )
886 pt.subplotSingle(ax[1], rIns.v[
'time'], rIns.v[
'lla'][:,1], options=rInsColor )
888 pt.subplotSingle(ax[1], instime, ins.v[
'lla'][:,1],
'Longitude',
'deg', options=insColor )
889 pt.subplotSingle(ax[1], gpstime, gps1Pos.v[
'lla'][:,1], options=refColor )
892 pt.subplotSingle(ax[2], rIns.v[
'time'], rIns.v[
'lla'][:,2], options=rInsColor )
895 pt.labels(
'Elipsoid Alt',
'm')
896 pt.subplotSingle(ax[2], instime, ins.v[
'lla'][:,2], options=insColor )
898 pt.subplotSingle(ax[2], gpstime, gps1Pos.v[
'lla'][:,2], options=refColor )
901 pt.subplotSingle(ax[2], baro.time, baro.v[
'mslBar'], options=
'm' )
905 saveFigures(
'lla.svg', f)
909 if peCheck(
'nedErr')
and 'nedErr' in ins.v.dtype.names:
911 pt.plot3Axes(f, ins.time, ins.v[
'nedErr'],
'NED Error from Truth INS',
'm' )
919 fig, ax = pt.subplots(f,3,
'NED', sharex=
True)
934 if 'gps1UbxPos' in log.data.keys():
942 if 'gps1RtkPos' in log.data.keys():
953 pt.subplotSingle(ax[0], instime, ins.ned()[:,0], options=insColor, title=
"North", ylabel=
'm')
956 pt.subplotSingle(ax[0], gpstime, gps1Pos.ned[:,0], options=refColor)
957 legend += [
'gps1Pos']
959 pt.subplotSingle(ax[0], ubxtime, gps1Ubx.ned[:,0], options=ubxColor)
960 legend += [
'gps1Ubx']
962 pt.subplotSingle(ax[0], rtktime, gps1RtkPos.ned[:,0], options=rtkColor)
963 legend += [
'gps1RtkPos']
969 pt.subplotSingle(ax[1], instime, ins.ned()[:,1], options=insColor, title=
"East", ylabel=
'm')
972 pt.subplotSingle(ax[1], gpstime, gps1Pos.ned[:,1], options=refColor)
973 legend += [
'gps1Pos']
975 pt.subplotSingle(ax[1], ubxtime, gps1Ubx.ned[:,1], options=ubxColor)
976 legend += [
'gps1Ubx']
978 pt.subplotSingle(ax[1], rtktime, gps1RtkPos.ned[:,1], options=rtkColor)
979 legend += [
'gps1RtkPos']
985 pt.subplotSingle(ax[2], instime, ins.ned()[:,2], options=insColor, title=
"Down", ylabel=
'm')
988 pt.subplotSingle(ax[2], gpstime, gps1Pos.ned[:,2], options=refColor)
989 legend += [
'gps1Pos']
991 pt.subplotSingle(ax[2], ubxtime, gps1Ubx.ned[:,2], options=ubxColor)
992 legend += [
'gps1Ubx']
994 pt.subplotSingle(ax[2], rtktime, gps1RtkPos.ned[:,2], options=rtkColor)
995 legend += [
'gps1RtkPos']
1007 saveFigures(
'ned.svg', f)
1011 if peCheck(
'nedMap'):
1018 fig, ax = pt.subplots(f,1,
'NED Map')
1019 pt.subplotSingle(ax, ins.ned()[:,1], ins.ned()[:,0], options=insColor, title=
"North East Map")
1022 pt.subplotSingle(ax, gps1Pos.ned[:,1], gps1Pos.ned[:,0], options=refColor)
1023 legend += [
'gps1Pos']
1026 saveFigures(
'nedMap.svg', f)
1030 if peCheck(
'nedMapRtk'):
1034 fig, ax = pt.subplots(f,1,
'RTK NED Map')
1036 pt.subplotSingle(ax, gps1RtkPos.ned[:,1], gps1RtkPos.ned[:,0], options=insColor)
1039 pt.subplotSingle(ax, gps1Ubx.ned[:,1], gps1Ubx.ned[:,0], options=refColor)
1040 legend += [
'gps1Ubx']
1042 pt.labels(
'RTK NED Map',
'm')
1044 saveFigures(
'nedMapRtk.png', f)
1081 if peCheck(
'nve')
and not peCheck(
'showUtcTime'):
1083 fig, ax = pt.subplots(f,1,
'NVE')
1085 pt.subplotSingle(ax, ins.v[
'lla'][:,1], ins.v[
'lla'][:,0], options=insColor, title=
"Lat Lon Map")
1088 pt.subplotSingle(ax, gps1Pos.v[
'lla'][:,1], gps1Pos.v[
'lla'][:,0], options=refColor)
1089 legend += [
'gps1Pos']
1091 saveFigures(
'LatLonMap.svg', f)
1095 if peCheck(
'nedDot'):
1100 ins.nedDot = ft.derivative(ins.time, ins.ned(), delta, title=
"NED dot")
1102 gps1Pos.nedDot = ft.derivative(gps1Pos.time, gps1Pos.ned, delta)
1104 rIns.nedDot = ft.derivative(rIns.v[
'time'], rIns.ned, delta)
1105 pt.plot3Axes(f, rIns.v[
'time'], rIns.nedDot, options=rInsColor )
1108 pt.plot3Axes(f, ins.time, ins.velNED )
1111 pt.plot3Axes(f, gps1Pos.time, gps1Pos.nedDot,
'NED Dot',
'm/s', options=refColor )
1112 legend += [
'gps1Pos']
1115 if peCheck(
'staticBiasAttEst'):
1117 [ imu1.accAtt, imu1.accBias] = ps.acc2AttAndBias( imu1.fltAcc())
1119 [rImu.accAtt, rImu.accBias] = ps.acc2AttAndBias(rImu.fltAcc())
1120 pt.plot3Axes(f, rImu.v[
'time'], rImu.accBias, options=rInsColor)
1121 legend += [
'RefIMU'];
1122 pt.plot3Axes(f, imu1.time, imu1.accBias,
'IMU Accel Bias',
'm/s^2' )
1128 pt.plot3Axes(f, rImu.v[
'time'], rImu.accAtt*RAD2DEG, options=rInsColor)
1129 legend += [
'RefIMU'];
1130 pt.plot3Axes(f, imu1.time, imu1.accAtt*RAD2DEG,
'Attitude from Gravity',
'deg')
1136 if peCheck(
'altitude'):
1138 fig, ax = pt.subplots(f,1,
'Altitude')
1139 pt.labels(
'Altitude',
'm')
1141 pt.subplotSingle(ax, ins.time, ins.v[
'lla'][:,2], options=insColor )
1144 pt.subplotSingle(ax, baro.time, baro.v[
'mslBar'], options=
'g' )
1145 legend += [
'Baro MSL']
1147 pt.subplotSingle(ax, gps1Pos.time - gps1Pos.time[0], gps1Pos.v[
'lla'][:,2], options=refColor )
1148 legend += [
'GPS ellipsoid']
1149 pt.subplotSingle(ax, gps1Pos.time - gps1Pos.time[0], gps1Pos.v[
'hMSL'], options=
'm' )
1150 legend += [
'GPS geoid/MSL']
1159 imu[0].pqr = dimu.i[0].pqr
1160 imu[1].pqr = dimu.i[1].pqr
1161 imu[0].acc = dimu.i[0].acc
1162 imu[1].acc = dimu.i[1].acc
1164 if peCheck(
'sensorXLim'):
1165 xlim = pe[
'sensorXLim']
1169 if peCheck(
'sensorPqr'):
1171 if peCheck(
'sensorSeparate'):
1172 pt.labels(
'Sensors: PQR1',
'deg/s')
1174 pt.labels(
'Sensors: PQR',
'deg/s')
1175 if pe[
'sensorPqr'] != 1:
1176 freq = pe[
'sensorPqr']
1177 imu[0].pqr = ft.lpfNoDelay(imu[0].pqr, freq, time=dimu.time)
1178 imu[1].pqr = ft.lpfNoDelay(imu[1].pqr, freq, time=dimu.time)
1181 pt.plot3Axes(f, rImu.v[
'time'], RAD2DEG * rImu.flt.pqr, options=rInsColor )
1184 i = len(dimu.time)/2
1187 if peCheck(
'sensorPqrSpan'):
1188 yspan = pe[
'sensorPqrSpan']
1189 pt.plot3Axes(f, dimu.time, imu[0].pqr * RAD2DEG, xlim=xlim )
1190 pt.plot3setYspan(f, yspan)
1192 if peCheck(
'sensorSeparate'):
1193 plt.legend(legend); f += 1; legend = []
1194 pt.labels(
'Sensors: PQR2',
'deg/s')
1195 pt.plot3Axes(f, dimu.time, imu[1].pqr * RAD2DEG, xlim=xlim)
1196 pt.plot3setYspan(f, yspan)
1200 saveFigures(
'sensorPqr.svg', f)
1202 g_imu1BiasPqr = np.mean(imu[0].pqr * RAD2DEG, axis=0)
1203 g_imu2BiasPqr = np.mean(imu[1].pqr * RAD2DEG, axis=0)
1207 if peCheck(
'sensorAcc'):
1209 offset = [0.0,0.0,0.0]
1211 if peCheck(
'sensorSeparate'):
1212 pt.labels(
'Sensors: Accel1',
'm/s^2')
1214 pt.labels(
'Sensors: Accel',
'm/s^2')
1215 if pe[
'sensorAcc'] != 1:
1216 freq = pe[
'sensorAcc']
1217 imu[0].acc = ft.lpfNoDelay(imu[0].acc, freq, time=dimu.time)
1218 imu[1].acc = ft.lpfNoDelay(imu[1].acc, freq, time=dimu.time)
1221 pt.plot3Axes(f, rImu.v[
'time'], rImu.flt.acc+offset, options=rInsColor )
1222 legend += [
'Truth'];
1225 if peCheck(
'sensorAccSpan'):
1226 yspan = pe[
'sensorAccSpan']
1227 pt.plot3Axes(f, dimu.time, imu[0].acc+offset, xlim=xlim )
1228 pt.plot3setYspan(f, yspan)
1230 if peCheck(
'sensorSeparate'):
1231 plt.legend(legend); f += 1; legend = []
1232 pt.labels(
'Sensors: Accel2',
'm/s^2')
1233 pt.plot3Axes(f, dimu.time, imu[1].acc+offset, xlim=xlim )
1234 pt.plot3setYspan(f, yspan)
1238 saveFigures(
'sensorAccel.svg', f)
1240 g_imu1BiasAcc = np.mean(imu[0].acc, axis=0)
1241 g_imu2BiasAcc = np.mean(imu[1].acc, axis=0)
1245 if peCheck(
'fftPqr'):
1247 fig, ax = pt.subplots(f,3,
'FFT PQR')
1248 ax[0].set_title(
"FFT: PQR")
1250 N = np.shape(imu[0].pqr[:,0])[0]
1251 T = np.mean(dimu.time[1:] - dimu.time[0:-1])
1253 pqrFftX = np.linspace(0.0, 1.0/(2.0*T), N/2)
1255 for i
in range(0,3):
1256 pqrFftY = 2.0/N * np.abs(np.fft.fft(imu[0].pqr[:,i])[:N//2])
1257 ax[i].set_xlabel(
'Freq (Hz)')
1258 ax[i].set_ylim([-0.1*ylim,ylim])
1259 pt.subplotSingle(ax[i], pqrFftX, pqrFftY )
1261 ax[0].set_ylabel(
'P')
1262 ax[1].set_ylabel(
'Q')
1263 ax[2].set_ylabel(
'R') 1264 saveFigures('fftPqr.svg', f)
1269 if peCheck(
'fftAcc'):
1271 fig, ax = pt.subplots(f,3,
'FFT Accel')
1272 ax[0].set_title(
'FFT: Accel')
1274 N = np.shape(imu[0].acc[:,0])[0]
1275 T = np.mean(dimu.time[1:] - dimu.time[0:-1])
1277 accFftX = np.linspace(0.0, 1.0/(2.0*T), N/2)
1279 for i
in range(0,3):
1280 accFftY = 2.0/N * np.abs(np.fft.fft(imu[0].acc[:,i])[:N//2])
1281 ax[i].set_xlabel(
'Freq (Hz)')
1282 ax[i].set_ylim([-0.1*ylim,ylim])
1283 pt.subplotSingle(ax[i], accFftX, accFftY )
1285 ax[0].set_ylabel(
'X')
1286 ax[1].set_ylabel(
'Y')
1287 ax[2].set_ylabel(
'Z')
1289 saveFigures(
'fftAcc.svg', f)
1294 if peCheck(
'sensorMag'):
1296 pt.labels(
'Sensors: Mag',
'gauss')
1297 if pe[
'sensorMag'] > 1:
1298 mag_1 = ft.smooth(mag1.v[
'mag'][:,:], pe[
'sensorMag'])
1299 mag_2 = ft.smooth(mag2.v[
'mag'][:,:], pe[
'sensorMag'])
1301 mag_1 = mag1.v[
'mag'][:,:]
1302 mag_2 = mag2.v[
'mag'][:,:]
1304 pt.plot3Axes(f, mag1.v[
'time'], mag_1 )
1305 pt.plot3Axes(f, mag2.v[
'time'], mag_2 )
1306 legend += [
'mag 1',
'mag 2']
1309 saveFigures(
'sensorMagnetometer.svg', f)
1313 if peCheck(
'sensorMag'):
1315 if peCheck(
'sensorSeparate'):
1316 pt.labels(
'Sensors: Mag1',
'gauss')
1318 pt.labels(
'Sensors: Mag',
'gauss')
1319 mag[0].time = mag1.time
1320 mag[0].mag = mag1.v[
'mag'][:,:]
1321 mag[1].time = mag2.time
1322 mag[1].mag = mag2.v[
'mag'][:,:]
1324 if pe[
'sensorMag'] != 1:
1325 freq = pe[
'sensorAcc']
1326 mag[0].mag = ft.lpfNoDelay(mag[0].mag, freq, time=mag[0].time)
1327 mag[1].mag = ft.lpfNoDelay(mag[1].mag, freq, time=mag[1].time)
1329 pt.plot3Axes(f, mag[0].time, mag[0].mag, xlim=xlim )
1331 if peCheck(
'sensorSeparate'):
1332 plt.legend(legend); f += 1; legend = []
1333 pt.labels(
'Sensors: Mag2',
'gauss')
1334 pt.plot3Axes(f, mag[1].time, mag[1].mag, xlim=xlim )
1338 saveFigures(
'sensorMag.svg', f)
1342 if peCheck(
'sensorBar'):
1344 fig, ax = pt.subplots(f,1,
'Sensor Baro')
1346 pt.labels(
'Barometer MSL',
'm')
1347 pt.subplotSingle(ax, baro.time, baro.v[
'mslBar'] )
1348 legend += [
'mslBar']
1350 pt.subplotSingle(ax, rIns.v[
'time'], rIns.v[
'lla'][:,2], options=rInsColor )
1352 if pe[
'sensorBar'] == 2:
1353 pt.subplotSingle(ax, gps1Pos.time, gps1Pos.v[
'lla'][:,2], options=refColor )
1357 saveFigures(
'baroMsl.svg', f)
1361 if peCheck(
'sensorIs1PqrVsTemp')
or \
1362 peCheck(
'sensorIs1AccVsTemp')
or \
1363 peCheck(
'sensorIs1Pqr')
or \
1364 peCheck(
'sensorIs1Acc')
or \
1365 peCheck(
'sensorIs1Mag'):
1369 mpu[0].temp = log.data[
'sensorsIs1'][
'mpu'][:,0][
'temp']
1370 mpu[1].temp = log.data[
'sensorsIs1'][
'mpu'][:,1][
'temp']
1372 mpuTime = np.arange(0.0, np.shape(mpu[0].temp)[0])*dt
1376 if peCheck(
'sensorIs1PqrVsTemp'):
1378 pt.labels(
'SensorsIS1: PQR vs Temperature',
'deg/s')
1379 mpu[0].pqr = log.data[
'sensorsIs1'][
'mpu'][:,0][
'pqr']
1380 mpu[1].pqr = log.data[
'sensorsIs1'][
'mpu'][:,1][
'pqr']
1381 if pe[
'sensorIs1PqrVsTemp'] != 1:
1382 freq = pe[
'sensorIs1PqrVsTemp']
1383 mpu[0].pqr = ft.lpfNoDelay(mpu[0].pqr, freq, dt=dt)
1384 mpu[1].pqr = ft.lpfNoDelay(mpu[1].pqr, freq, dt=dt)
1385 pt.plot3Axes(f, mpu[0].temp, mpu[0].pqr*RAD2DEG, xlabel=
"temp (C)" )
1386 pt.plot3Axes(f, mpu[1].temp, mpu[1].pqr*RAD2DEG, xlabel=
"temp (C)" )
1387 legend += [
'mpu1',
'mpu2']
1390 if peCheck(
'sensorIs1Pqr'):
1391 mpu[0].pqr = log.data[
'sensorsIs1'][
'mpu'][:,0][
'pqr']
1392 mpu[1].pqr = log.data[
'sensorsIs1'][
'mpu'][:,1][
'pqr']
1393 if pe[
'sensorIs1Pqr'] != 1:
1394 freq = pe[
'sensorIs1Pqr']
1395 mpu[0].pqr = ft.lpfNoDelay(mpu[0].pqr, freq, dt=dt)
1396 mpu[1].pqr = ft.lpfNoDelay(mpu[1].pqr, freq, dt=dt)
1398 for m
in range(0,2):
1399 if m==0
or peCheck(
'sensorSeparate'):
1401 fig, ax = pt.subplots(f,4,
'SensorsIS1: PQR & Temp vs Time', sharex=
True)
1402 legend += [
'mpu%d' % (m+1)]
1403 pt.subplotSingle(ax[0], mpuTime, mpu[m].pqr[:,0]*RAD2DEG,
'P',
'deg/s' )
1404 pt.subplotSingle(ax[1], mpuTime, mpu[m].pqr[:,1]*RAD2DEG,
'Q',
'deg/s' )
1405 pt.subplotSingle(ax[2], mpuTime, mpu[m].pqr[:,2]*RAD2DEG,
'R', 'deg/s' ) pt.subplotSingle(ax[3], mpuTime, mpu[m].temp,
'Temp',
'C' )
1406 ax[0].legend(legend)
1410 if peCheck(
'sensorIs1AccVsTemp'):
1412 pt.labels(
'SensorsIS1: Accel vs Temperature',
'm/s^2')
1413 mpu[0].acc = log.data[
'sensorsIs1'][
'mpu'][:,0][
'acc']
1414 mpu[1].acc = log.data[
'sensorsIs1'][
'mpu'][:,1][
'acc']
1415 if pe[
'sensorIs1AccVsTemp'] != 1:
1416 freq = pe[
'sensorIs1AccVsTemp']
1417 mpu[0].acc = ft.lpfNoDelay(mpu[0].acc, freq, dt=dt)
1418 mpu[1].acc = ft.lpfNoDelay(mpu[1].acc, freq, dt=dt)
1419 pt.plot3Axes(f, mpu[0].temp, mpu[0].acc, xlabel=
"temp (C)" )
1420 pt.plot3Axes(f, mpu[1].temp, mpu[1].acc, xlabel=
"temp (C)" )
1421 legend += [
'mpu1',
'mpu2']
1424 if peCheck(
'sensorIs1Acc'):
1425 mpu[0].acc = log.data[
'sensorsIs1'][
'mpu'][:,0][
'acc']
1426 mpu[1].acc = log.data[
'sensorsIs1'][
'mpu'][:,1][
'acc']
1427 if pe[
'sensorIs1Acc'] != 1:
1428 freq = pe[
'sensorIs1Acc']
1429 mpu[0].acc = ft.lpfNoDelay(mpu[0].acc, freq, dt=dt)
1430 mpu[1].acc = ft.lpfNoDelay(mpu[1].acc, freq, dt=dt)
1432 for m
in range(0,2):
1433 if m==0
or peCheck(
'sensorSeparate'):
1435 fig, ax = pt.subplots(f,4,
'SensorsIS1: PQR & Temp vs Time', sharex=
True)
1436 legend += [
"mpu%d"%(m+1)]
1437 pt.subplotSingle(ax[0], mpuTime, mpu[m].acc[:,0],
'Accel X',
'm/s^2' )
1438 pt.subplotSingle(ax[1], mpuTime, mpu[m].acc[:,1],
'Accel Y',
'm/s^2' )
1439 pt.subplotSingle(ax[2], mpuTime, mpu[m].acc[:,2],
'Accel Z',
'm/s^2' )
1440 pt.subplotSingle(ax[3], mpuTime, mpu[m].temp,
'Temp',
'C' )
1441 ax[0].legend(legend)
1445 if peCheck(
'sensorIs1Mag'):
1447 pt.labels(
'SensorsIS1: Mag vs Temperature',
'gauss')
1448 lgd = [
'mpu1',
'mpu2']
1449 mpu[0].mag = log.data[
'sensorsIs1'][
'mpu'][:,0][
'mag']
1450 mpu[1].mag = log.data[
'sensorsIs1'][
'mpu'][:,1][
'mag']
1451 if pe[
'sensorIs1Mag'] != 1:
1452 freq = pe[
'sensorMag']
1453 mpu[0].mag = ft.smooth(mpu[0].mag, pe[
'sensorIs1Mag'])
1454 mpu[1].mag = ft.smooth(mpu[1].mag, pe[
'sensorIs1Mag'])
1455 pt.plot3Axes(f, mpu[0].temp, mpu[0].mag, xlabel=
"temp (C)" )
1456 pt.plot3Axes(f, mpu[1].temp, mpu[1].mag, xlabel=
"temp (C)" )
1463 if peCheck(
'gpsStats'):
1465 if 'gps1Pos' not in log.data.keys():
1466 print(
"unable to print gpsStats, because we are missing data")
1468 fig, ax = pt.subplots(f,3,
'GPS Stats', sharex=
True)
1470 gpsPos = log.data[
'gps1Pos']
1473 pt.subplotSingle(ax[0], time, gpsPos[
'status'] & 0xFF,
'Satellites Used in Solution',
'' )
1474 pt.subplotSingle(ax[1], time, gpsPos[
'pDop'],
'Accuracy',
'm', options=
'm' )
1476 pt.subplotSingle(ax[1], time, gpsPos[
'hAcc'],
'Accuracy',
'm', options=
'r' ) legend += ['Hor']
1477 pt.subplotSingle(ax[1], time, gpsPos[
'vAcc'], options=
'b' )
1479 if 'gps1RtkPos' in log.data.keys():
1481 pt.subplotSingle(ax[1], rtktime, log.data[
'gps1RtkPos'][
'vAcc'], options=rtkColor)
1482 legend += [
'rtkHor']
1483 ax[1].legend(legend)
1485 pt.subplotSingle(ax[2], time, gpsPos[
'cnoMean'],
'CNO',
'dBHz', options=
'b' )
1487 ax[2].legend(legend)
1489 saveFigures(
'gpsStats.svg', f)
1491 if gps1Ubx
and peCheck(
'gps1Stats'):
1493 fig, ax = pt.subplots(f,3,
'GPS1 Stats', sharex=
True)
1495 pt.subplotSingle(ax[0], gps1Ubx.time, gps1Ubx.satsUsed,
'Satellites Used in Solution',
'' )
1496 pt.subplotSingle(ax[1], gps1Ubx.time, gps1Ubx.v[
'pDop'],
'Accuracy',
'm', options=
'm' )
1498 pt.subplotSingle(ax[1], gps1Ubx.time, gps1Ubx.v[
'hAcc'],
'Accuracy',
'm', options=
'r' ) 1500 pt.subplotSingle(ax[1], gps1Ubx.time, gps1Ubx.v[
'vAcc'], options=
'b' )
1502 ax[1].legend(legend)
1503 pt.subplotSingle(ax[2], gps1Ubx.time, gps1Ubx.v[
'cno'],
'CNO',
'dBHz', options=
'r' ) 1505 pt.subplotSingle(ax[2], gps1Ubx.time, gps1Ubx.v[
'cnoMean'],
'CNO',
'dBHz', options=
'b' )
1507 ax[2].legend(legend)
1509 saveFigures(
'gps1Stats.svg', f)
1513 if peCheck(
'rtkStats'):
1514 f += 1; legend = [str(ser)
for ser
in serialNumbers]
1515 if 'gps1Pos' not in log.data
or 'gps1RtkPosRel' not in log.data:
1516 print(
"Unable to plot rtkStats - data missing")
1519 if 'gps1RktMisc' in log.data.keys():
1525 fig, ax = pt.subplots(f,n_plots,
'RTK Stats', sharex=
True)
1528 compassing = log.data[
'gps1Pos'][
'status'][10] & 0x00400000
1530 fixType = log.data[
'gps1Pos'][
'status'] >> 8 & 0xFF
1531 pt.subplotSingle(ax[0], time, fixType,
'GPS Fix Type: 2=2D, 3=3D, 10=Single, 11=Float, 12=Fix',
'' )
1532 ax[0].legend(legend)
1537 fixType = log.data[
'gps1RtkPosRel'][
'arRatio'].copy()
1539 pt.subplotSingle(ax[0], time, fixType,
'GPS Fix Type: 2=2D, 3=3D, 10=Single, 11=Float, 12=Fix',
'' )
1541 if 'gps1RtkPosRel' in log.data.keys():
1542 disttobase = log.data[
'gps1RtkPosRel'][
'distanceToBase']
1543 disttobase[disttobase > 100000] = np.nan
1544 pt.subplotSingle(ax[1], time, log.data[
'gps1RtkPosRel'][
'differentialAge'],
'RTK: Age of Differential',
's' )
1545 pt.subplotSingle(ax[2], time, log.data[
'gps1RtkPosRel'][
'arRatio'],
'RTK: AR Ratio',
'num' )
1546 pt.subplotSingle(ax[3], time, disttobase,
'Distance to Base',
'm' )
1549 if 'gps1RtkPosMisc' in log.data.keys():
1551 pt.subplotSingle(ax[n_plot], rtkMiscTime, log.data[
'gps1RtkPosMisc'][
'cycleSlipCount'],
'RTK: Slip Counter',
' ' )
1579 saveFigures(
'rtkStats.svg', f)
1584 if peCheck(
'iStatus')
and ins:
1586 fig, ax = pt.subplots(f,1,
'INS Status')
1589 pt.labels(
'INS Status')
1593 iStatus = ins.iStatus()
1599 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.coarse.att, options=
'b' )
1600 p1 = ax.get_xlim()[0] + 0.02*(ax.get_xlim()[1] - ax.get_xlim()[0])
1601 ax.text(p1, -cnt*1.5,
'Att Coarse')
1603 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.good.att, options=
'b' )
1604 ax.text(p1, -cnt*1.5,
'Att Good')
1606 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.fine.att, options=
'c' )
1607 ax.text(p1, -cnt*1.5,
'Att Fine')
1609 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.coarse.vel, options=
'g' )
1610 ax.text(p1, -cnt*1.5,
'Vel Coarse')
1612 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.good.vel, options=
'g' )
1613 ax.text(p1, -cnt*1.5,
'Vel Good')
1615 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.coarse.pos, options=
'r' ) ax.text(p1, -cnt*1.5, 'Pos Coarse')
1617 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.align.good.pos, options=
'r' ) 1618 ax.text(p1, -cnt*1.5, 'Pos Good')
1623 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.usingGps, options=
'b' )
1624 ax.text(p1, -cnt*1.5,
'Using GPS')
1626 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.usingMag, options=
'm' )
1627 ax.text(p1, -cnt*1.5,
'Using MAG')
1630 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.navMode )
1631 ax.text(p1, -cnt*1.5,
'Nav Mode')
1634 pt.subplotSingle(ax, instime, -cnt*1.5+ (iStatus.solutionStatus)/4.0 )
1635 ax.text(p1, -cnt*1.5,
'Solution Status')
1639 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.magActiveCalSet )
1640 ax.text(p1, -cnt*1.5,
'Mag Active Cal Set')
1642 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.magRecalibrating )
1643 ax.text(p1, -cnt*1.5,
'Mag Recalibrating')
1645 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.magInterOrBadCal )
1646 ax.text(p1, -cnt*1.5,
'Mag Inter. or Bad Cal')
1650 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.rtosTaskPeriodOverrun )
1651 ax.text(p1, -cnt*1.5,
'RTOS Task Period Overrun')
1653 pt.subplotSingle(ax, instime, -cnt*1.5+ iStatus.generalFault )
1654 ax.text(p1, -cnt*1.5,
'General Fault')
1657 saveFigures(
'iStatus.svg', f)
1662 fig, ax = pt.subplots(f,1,
'Solution Status')
1663 pt.labels(
'Solution Status',
' ')
1664 pt.subplotSingle(ax, instime, iStatus.solutionStatus )
1666 saveFigures(
'SolutionStatus.svg', f)
1672 if peCheck(
'hStatus')
and ins:
1674 fig, ax = pt.subplots(f,1,
'Hdw Status')
1676 hStatus = ins.hStatus()
1678 pt.labels(
'Hardware Status')
1682 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.motionGyrSig )
1683 ax.text(p1, -cnt*1.5,
'Motion Gyr Sig')
1685 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.motionAccSig )
1686 ax.text(p1, -cnt*1.5,
'Motion Acc Sig')
1688 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.motionGyrDev )
1689 ax.text(p1, -cnt*1.5,
'Motion Gyr Dev')
1691 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.motionAccDev )
1692 ax.text(p1, -cnt*1.5,
'Motion Acc Dev')
1696 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.satellite_rx )
1697 ax.text(p1, -cnt*1.5,
'Satellite Rx')
1701 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.saturationGyr )
1702 ax.text(p1, -cnt*1.5,
'Saturation Gyr')
1704 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.saturationAcc )
1705 ax.text(p1, -cnt*1.5,
'Saturation Acc')
1707 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.saturationMag )
1708 ax.text(p1, -cnt*1.5,
'Saturation Mag')
1710 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.saturationBaro )
1711 ax.text(p1, -cnt*1.5,
'Saturation Baro')
1713 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.saturationHistory )
1714 ax.text(p1, -cnt*1.5,
'Saturation History')
1718 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.errComTxLimited )
1719 ax.text(p1, -cnt*1.5,
'Err Com Tx Limited')
1721 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.errComRxOverrun )
1722 ax.text(p1, -cnt*1.5,
'Err Com Rx Overrun')
1724 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.errGpsTxLimited )
1725 ax.text(p1, -cnt*1.5,
'Err GPS Tx Limited')
1727 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.errGpsRxOverrun )
1728 ax.text(p1, -cnt*1.5,
'Err GPS Rx Overrun')
1732 pt.subplotSingle(ax, ins.time, -cnt*1.5+ (hStatus.comParseErrCount)/4 )
1733 ax.text(p1, -cnt*1.5,
'Com Parse Error Count')
1735 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.selfTestFault )
1736 ax.text(p1, -cnt*1.5,
'Self Test Fault')
1738 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.errTemperature )
1739 ax.text(p1, -cnt*1.5,
'Temperature error')
1743 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.faultWatchdogReset )
1744 ax.text(p1, -cnt*1.5,
'Watchdog Reset')
1746 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.faultBODReset )
1747 ax.text(p1, -cnt*1.5,
'Brownout Reset')
1749 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.faultPORReset )
1750 ax.text(p1, -cnt*1.5,
'Power-on Reset')
1752 pt.subplotSingle(ax, ins.time, -cnt*1.5+ hStatus.faultCPUErrReset )
1753 ax.text(p1, -cnt*1.5,
'CPU Error Reset')
1757 saveFigures(
'hStatus.svg', f)
1762 if peCheck(
'Timestamp'):
1763 f += 1; legend = [];
1764 fig, ax = pt.subplots(f, 3,
'Timestamp', sharex=
True)
1768 dtIns = ins.time[1:] - ins.time[0:-1]
1769 timeIns = ins.time[1:]
1770 pt.subplotSingle(ax[0], timeIns, dtIns,
'INS dt',
's')
1772 print(
"INS dt (min, max, mean):", np.min(dtIns), np.max(dtIns), np.mean(dtIns))
1775 dtImu = imu1.time[1:] - imu1.time[0:-1]
1776 timeImu = imu1.time[1:]
1777 pt.subplotSingle(ax[1], timeImu, dtImu,
'IMU dt',
's')
1779 print(
"IMU dt (min, max, mean):", np.min(dtImu), np.max(dtImu), np.mean(dtImu))
1782 dtDImu = dimu.time[1:] - dimu.time[0:-1]
1783 timeDImu = dimu.time[1:]
1784 pt.subplotSingle(ax[1], timeDImu, dtDImu,
'IMU dt',
's')
1786 print(
"IMU dt (min, max, mean):", np.min(dtDImu), np.max(dtDImu), np.mean(dtDImu))
1789 dtGps = gps1Pos.time[1:] - gps1Pos.time[0:-1]
1790 timeGps = gps1Pos.time[1:]
1791 pt.subplotSingle(ax[2], timeGps, dtGps,
'GPS dt',
's')
1793 print(
"GPS dt (min, max, mean):", np.min(dtGps), np.max(dtGps), np.mean(dtGps))
1795 saveFigures(
'Timestamp.svg', f)
1801 IsLoggerPlot.serialNumbers = []
1806
GeneratorWrapper< T > range(T const &start, T const &end, T const &step)