2 Created on Feb 22, 2014 6 from numbers
import Number
13 import pylib.pose
as pose
14 import pylib.filterTools
as ft
17 import time
as systime
21 refLla = np.r_[ 40.0557114, -111.6585476, 1426.77 ]
33 if size
and size[0] > 1:
51 _fields_ = [(
'marker', ct.c_uint32),
52 (
'version', ct.c_uint16),
53 (
'classification', ct.c_uint16),
54 (
'name', ct.c_char * 4),
55 (
'invName', ct.c_char * 4),
56 (
'dataSize', ct.c_uint32),
57 (
'invDataSize', ct.c_uint32),
58 (
'grpNum', ct.c_uint32),
59 (
'serialNum', ct.c_uint32),
60 (
'pHandle', ct.c_uint32),
61 (
'reserved', ct.c_uint32)]
65 _fields_ = [(
'id', ct.c_uint32),
66 (
'size', ct.c_uint32),
67 (
'offset', ct.c_uint32)]
71 _fields_ = [(
'reserved', ct.c_uint32),
72 (
'serialNumber', ct.c_uint32),
73 (
'hardwareVer', ct.c_uint8 * 4),
74 (
'firmwareVer', ct.c_uint8 * 4),
75 (
'build', ct.c_uint32),
76 (
'commVer', ct.c_uint8 * 4),
77 (
'repoRevision', ct.c_uint32),
78 (
'manufacturer', ct.c_uint8 * 24),
83 _fields_ = [(
'time', ct.c_double),
84 (
'pqr', ct.c_float * 3),
85 (
'acc', ct.c_float * 3),
86 (
'mag', ct.c_float * 3),
87 (
'mslBar', ct.c_float)]
91 _fields_ = [(
'week', ct.c_uint32),
92 (
'time', ct.c_double),
93 (
'iStatus', ct.c_uint32),
94 (
'hStatus', ct.c_uint32),
95 (
'euler', ct.c_float * 3),
96 (
'uvw', ct.c_float * 3),
97 (
'lla', ct.c_double * 3),
98 (
'ned', ct.c_float * 3),
103 _fields_ = [(
'week', ct.c_uint32),
104 (
'time', ct.c_double),
105 (
'iStatus', ct.c_uint32),
106 (
'hStatus', ct.c_uint32),
107 (
'q', ct.c_float * 4),
108 (
'uvw', ct.c_float * 3),
109 (
'lla', ct.c_double * 3),
114 _fields_ = [(
'timeMs', ct.c_uint32),
115 (
'x_dot.lla', ct.c_double * 3),
116 (
'x_dot.uvw', ct.c_float * 3),
117 (
'x_dot.q', ct.c_float * 4),
118 (
'ned_dot', ct.c_float * 3),
119 (
'accCoriolis', ct.c_float * 3),
120 (
'geoMagNed', ct.c_float * 3),
121 (
'magRefNed', ct.c_float * 3),
122 (
'magYawOffset', ct.c_float),
127 _fields_ = [(
'week', ct.c_uint32),
128 (
'time', ct.c_double),
129 (
'iStatus', ct.c_uint32),
130 (
'hStatus', ct.c_uint32),
131 (
'euler', ct.c_float * 3),
132 (
'uvw', ct.c_float * 3),
133 (
'lla', ct.c_double * 3),
134 (
'ned', ct.c_float * 3),
135 (
'eulerErr', ct.c_float * 3),
136 (
'uvwErr', ct.c_float * 3),
137 (
'nedErr', ct.c_float * 3),
142 _fields_ = [(
'week', ct.c_uint32),
143 (
'timeMs', ct.c_uint32),
144 (
'satsUsed', ct.c_uint32),
145 (
'cno', ct.c_uint32),
146 (
'lla', ct.c_double * 3),
147 (
'mMSL', ct.c_float),
148 (
'hAcc', ct.c_float),
149 (
'vAcc', ct.c_float),
155 _fields_ = [(
'timeMs', ct.c_uint32),
156 (
'ned', ct.c_float * 3),
159 (
'sAcc', ct.c_float),
160 (
'course', ct.c_float),
161 (
'cAcc', ct.c_float),
166 _fields_ = [(
'pos', sGpsPos),
168 (
'rxps', ct.c_uint32),
169 (
'timeOffset', ct.c_double),
174 _fields_ = [(
'lla', ct.c_double * 3),
175 (
'uvw', ct.c_float * 3),
176 (
'q', ct.c_float * 4),
181 _fields_ = [(
'time', ct.c_double),
182 (
'timeMs', ct.c_uint32),
184 (
'theta', ct.c_float * 3),
185 (
'ned', ct.c_float * 3),
186 (
'dcm', ct.c_float * 9),
187 (
'pqr', ct.c_float * 3),
188 (
'acc', ct.c_float * 3),
189 (
'mag', ct.c_float * 3),
190 (
'mslBar', ct.c_float),
195 _fields_ = [(
'timeMs', ct.c_uint32),
196 (
'iStatus', ct.c_uint32),
197 (
'hStatus', ct.c_uint32),
198 (
'alignAttDetect', ct.c_float),
199 (
'alignAttError', ct.c_float),
200 (
'alignVelError', ct.c_float),
201 (
'alignPosError', ct.c_float),
202 (
'insDtMs', ct.c_uint32),
203 (
'ftf0', ct.c_float),
204 (
'magInclination', ct.c_float),
205 (
'magDeclination', ct.c_float),
206 (
'genFaultCode', ct.c_uint32),
211 _fields_ = [(
'timeMs', ct.c_uint32),
212 (
'debugI4', ct.c_int32 * 4),
213 (
'debugF3', ct.c_float * 3),
214 (
'debugV3', ct.c_float * 3),
215 (
'debugV3g', ct.c_float * 3),
216 (
'sensorState', ct.c_uint32),
217 (
'obsK.psi', ct.c_float),
218 (
'obsK.vel', ct.c_float),
219 (
'obsK.pos', ct.c_float),
220 (
'theta', ct.c_float * 3),
221 (
'magTimeMs', ct.c_uint32),
222 (
'vMagTiltCmp', ct.c_float * 3),
223 (
'magHeading', ct.c_float),
224 (
'yawErrMag', ct.c_float),
225 (
'pqrEffIF', ct.c_float * 3),
226 (
'pqrEff', ct.c_float * 3),
227 (
'uvwEff', ct.c_float * 3),
232 _fields_ = [(
'timeMs', ct.c_uint32),
234 (
'uvw.timeMs', ct.c_uint32),
235 (
'uvw.ref', ct.c_float * 3),
236 (
'uvw.refValid', ct.c_uint32),
237 (
'uvw.ins', ct.c_float * 3),
239 (
'accNed.timeMs', ct.c_uint32),
240 (
'accNed.ref', ct.c_float * 3),
241 (
'accNed.refValid', ct.c_uint32),
242 (
'accNed.ins', ct.c_float * 3),
244 (
'velNed.timeMs', ct.c_uint32),
245 (
'velNed.ref', ct.c_double * 3),
246 (
'velNed.refValid', ct.c_uint32),
247 (
'velNed.ins', ct.c_double * 3),
249 (
'lla.timeMs', ct.c_uint32),
250 (
'lla.ref', ct.c_float * 3),
251 (
'lla.refValid', ct.c_uint32),
252 (
'lla.ins', ct.c_float * 3),
254 (
'mslBar', ct.c_float),
255 (
'mslBarDot', ct.c_float),
256 (
'uvwErr', ct.c_float * 3),
257 (
'nedErr', ct.c_float * 3),
262 _fields_ = [(
'i', ct.c_uint32 * 9),
263 (
'f', ct.c_float * 9),
264 (
'lf', ct.c_double * 3),
269 _fields_ = [(
'timeMs', ct.c_uint32),
270 (
'pqr', ct.c_float * 3),
271 (
'acc', ct.c_float * 3),
272 (
'mslBar', ct.c_float),
277 _fields_ = [(
'timeMs', ct.c_uint32),
278 (
'gpioStatus', ct.c_uint32),
283 _fields_ = [(
'ch', ct.c_uint32 * 8),
290 return dict((field, getattr(struct, field))
for field, _
in struct._fields_)
294 return (
'devInfo', sDevInfo)
298 return (
'ins1', sIns1)
300 return (
'ins2', sIns2)
302 return (
'insMisc', sInsMisc)
304 return (
'sysParams', sSysParams)
306 return (
'gpsPos', sGpsPos)
308 return (
'gpsVel', sGpsVel)
312 return (
'insResources', sInsRes)
314 return (
'sensorBias', sSensorBias)
316 return (
'insParams', sInsParams)
318 return (
'obsParams', sObsParams)
320 return (
'debugArray', sDebugArray)
322 return (
'insDev1', sInsDev1)
371 return np.c_[ _v[name+
'[0]'].T, _v[name+
'[1]'].T, _v[name+
'[2]'].T ]
374 return np.c_[ _v[name+
'[0]'].T, _v[name+
'[1]'].T, _v[name+
'[2]'].T, _v[name+
'[3]'].T ]
378 def __init__(self, index, directory, serialNumber, refIns=None ):
382 timeStart = systime.time()
396 print "#%2d Opening: Ref INS %s" % (index,directory)
398 fileMask =
"LOG_REF_INS*.dat" 401 print "#%2d Opening: %s %s" %(index,serialNumber,directory)
403 fileMask =
"LOG_"+serialNumber+
"*.dat" 405 if not os.path.isdir(directory):
406 print "Directory doesn't exist!" 413 raise Exception(
'Load Error: .dat files not found.')
418 self.
loadTime = systime.time() - timeStart
419 print "Load time: %.2fs" % (self.
loadTime)
443 if not name
in rdat.keys():
452 for key
in dct.keys():
453 rd[
'isNum'][key] = isinstance(dct[key], Number)
or isinstance(dct[key], ct.Array)
465 for key
in dct.keys():
477 rd[key].append(dct[key])
480 for i
in range(size):
481 fList.append(dct[key][i])
482 rd[key].append(fList)
491 with open(filename,
'rb')
as f:
496 dHdrSize = ct.sizeof(sDataHdr)
497 while f.readinto(cHdr)
and cHdr.marker == 0xFC05EA32:
500 cDat = bytearray(f.read(cHdr.dataSize))
504 while n < cHdr.dataSize:
506 dHdr = (sDataHdr).from_buffer(cDat,n)
514 (sName, sType) = self.
structs.get(dHdr)
520 print "Unknown data id: ", dHdr.id,
" size: ", dHdr.size
521 (ct.c_ubyte*dHdr.size).from_buffer(cDat,n)
526 if ct.sizeof(sType) != dHdr.size:
527 print "Size mismatch, data id: ", dHdr.id,
" size: ", dHdr.size
528 (ct.c_ubyte*dHdr.size).from_buffer(cDat,n)
542 if type(rdat)
is dict:
544 for key
in rdat.keys():
548 data[key] = self.
__toNumpy(rdat[key], depth)
551 elif type(rdat)
is list:
554 if type(rdat[0])
is dict:
556 data.append( self.
__toNumpy(obj, depth) )
558 elif type(rdat[0])
is list
or isinstance(rdat[0], Number):
560 data = np.array(rdat)
566 data.append( self.
__toNumpy(obj.__dict__, depth) )
570 data = np.array(rdat)
588 def loadData(self, directory=None, serialNumbers=None, postProcessed=None, refIns=None, startDev=0, devCount=-1):
592 timeLoadStart = systime.time()
596 raise Exception(
'refIns not supported right now.')
600 directory = directory.replace(
'\\',
'/')
606 selectionFileName =
'selection.txt' 607 if os.path.exists(selectionFileName):
608 with open(selectionFileName)
as f:
609 lines = f.read().splitlines()
612 directory += lines[0].replace(
'\\',
'/')
615 serialNumbers=lines[1:]
617 if postProcessed==1 :
618 directory +=
'/post_processed' 621 if serialNumbers ==
None or serialNumbers == []:
623 files = os.listdir(directory)
626 if str.find(
'.dat') != -1:
627 str = str.replace(
'.dat',
'')
628 if str.find(
'LOG_SN') != -1:
630 if not str
in serNums:
632 elif str.find(
'LOG_P') != -1:
633 str = str.replace(
'LOG_',
'')
634 str = str[:str.find(
'_')]
635 if not str
in serNums:
637 serialNumbers = serNums
639 count = len(serialNumbers)
643 print "No files found..." 647 if devCount > 0
and devCount < count:
649 endIndex = min(startDev+count, len(serialNumbers))
654 for i
in range(startDev, endIndex):
655 device =
cDevice(i, directory, serialNumbers[i], refIns)
659 self.
loadTime = systime.time() - timeLoadStart
660 print "Total load time: %.2fs" % (self.
loadTime)
665 size = np.shape(gpsWeek)
666 if size
and size[0] > 1:
670 gpsWeek = np.max(gpsWeek)
674 gpsEpoch = (1980, 1, 6, 0, 0, 0)
677 epochTuple = gpsEpoch + (-1, -1, 0)
678 t0 = systime.mktime(epochTuple) - systime.timezone
679 tdiff = (gpsWeek * secsInWeek) + gpsSOW - leapSecs
694 self.
__flt.pqr =
None 695 self.
__flt.acc =
None 696 self.
__flt.pqrNoBias =
None 697 self.
__flt.accNoBias =
None 698 self.
__flt.barNoBias =
None 706 if self.
__flt.acc ==
None:
708 return self.
__flt.acc
711 if self.
__flt.pqr ==
None:
713 return self.
__flt.pqr
716 if 'pqrNoBias' in self.
v.dtype.names
and self.
__flt.pqrNoBias==
None:
717 self.
__flt.pqrNoBias = ft.lpfNoDelay(self.
v[
'pqrNoBias'], self.
cornerFreqHz, time=self.
v[
'time'])
718 return self.
__flt.pqrNoBias
721 if 'accNoBias' in self.
v.dtype.names
and self.
__flt.accNoBias==
None:
722 self.
__flt.accNoBias = ft.lpfNoDelay(self.
v[
'accNoBias'], self.
cornerFreqHz, time=self.
v[
'time'])
723 return self.
__flt.accNoBias
726 if 'mslBarNoBias' in self.
v.dtype.names
and self.
__flt.barNoBias==
None:
727 self.
__flt.mslBarNoBias = ft.lpfNoDelay(self.
v[
'mslBarNoBias'], self.
cornerFreqHz, time=self.
v[
'time'])
728 return self.
__flt.mslBarNoBias
743 if not 'euler' in self.
v.dtype.names
and 'q' in self.
v.dtype.names:
744 self.
v[
'euler'] = pose.quat2eulerArray(self.
v[
'q'])
746 if 'euler' in self.
v.dtype.names
and not 'q' in self.
v.dtype.names:
747 self.
v[
'q'] = pose.euler2quatArray(self.
v[
'euler'])
753 self.
__velNED = np.zeros(np.shape(self.
v[
'uvw']))
756 DCM = pose.eulerDCM(self.
v[
'euler'][i,:])
757 velNED = np.dot(DCM.T, self.
v[
'uvw'][i,:])
764 self.
__course = np.arctan2( self.velNED[:,1], self.velNED[:,0] )
769 if self.
__ned ==
None:
770 self.
__ned = pose.lla2ned(refLla, self.
v[
'lla'])
777 return np.sqrt( np.square(self.
v[
'uvw'][:,0]) +
778 np.square(self.
v[
'uvw'][:,1]) )
781 return np.sqrt( np.square(self.
v[
'uvw'][:,0]) +
782 np.square(self.
v[
'uvw'][:,1]) +
783 np.square(self.
v[
'uvw'][:,2]) )
788 accBias = np.r_[0,0,0],
789 pqrBias = np.r_[0,0,0],
790 rotate = np.r_[0,0,0]):
794 self.
__flt.pqr =
None 795 self.
__flt.acc =
None 797 if accBias[0]!=0
or accBias[1]!=0
or accBias[2]!=0:
798 self.
v[
'acc'] += accBias
800 if pqrBias[0]!=0
or pqrBias[1]!=0
or pqrBias[2]!=0:
801 self.
v[
'pqr'] += pqrBias
803 if rotate[0]!=0
or rotate[1]!=0
or rotate[2]!=0:
804 self.
v[
'acc'] = pose.vectorRotateInertialToBody2(self.
v[
'acc'], rotate)
805 self.
v[
'pqr'] = pose.vectorRotateInertialToBody2(self.
v[
'pqr'], rotate)
808 if self.
__flt.pqr==
None:
810 return self.
__flt.pqr
813 if self.
__flt.acc==
None:
815 return self.
__flt.acc
837 self.
__ned = pose.lla2ned(refLla, self.
v[
'lla'])
842 self.
__nedDotDot = ft.derivative(self.
v[
'time'], self.
v[
'nedDot'], delta=2)
850 self.
__uvw = pose.vectorRotateInertialToBody(self.
v[
'nedDot'], self.
v[
'euler'])
863 self.
__acc.ned =
None 867 self.
__ned = pose.lla2ned(refLla, self.
v[
'lla'])
871 if self.
__acc.ned ==
None:
874 self.
__acc.ned = ft.meanDerivative(self.
v[
'time'], self.
v[
'vel.ned'], 2, 2)
875 return self.
__acc.ned
898 self.
v[
'course'] = pose.unwrapAngle(self.
v[
'course'])
905 self.
__acc.ned = ft.meanDerivative(self.
time, self.
v[
'ned'], 2, 2)
920 self.
ned = pose.lla2ned(refLla, _v[
'lla'])
957 self.
aligned.coarse.att = (_v[
'iStatus'] >> 0) & 1
958 self.
aligned.coarse.vel = (_v[
'iStatus'] >> 1) & 1
959 self.
aligned.coarse.pos = (_v[
'iStatus'] >> 2) & 1
961 self.
aligned.att = (_v[
'iStatus'] >> 4) & 1
962 self.
aligned.vel = (_v[
'iStatus'] >> 5) & 1
963 self.
aligned.pos = (_v[
'iStatus'] >> 6) & 1
964 self.
aligned.attFine = (_v[
'iStatus'] >> 7) & 1
966 self.
aligning.attGps = (_v[
'iStatus'] >> 8) & 1
967 self.
aligning.vel = (_v[
'iStatus'] >> 9) & 1
968 self.
aligning.pos = (_v[
'iStatus'] >> 10) & 1
969 self.
aligning.attMag = (_v[
'iStatus'] >> 11) & 1
1045 self.
accNed.refHdg = np.arctan2( self.
v[
'accNed.ref'][:,1], self.
v[
'accNed.ref'][:,0] )
1046 self.
accNed.insHdg = np.arctan2( self.
v[
'accNed.ins'][:,1], self.
v[
'accNed.ins'][:,0] )
1048 self.
lla.refNed = pose.lla2ned(refLla, _v[
'lla.ref'])
1049 self.
lla.insNed = pose.lla2ned(refLla, _v[
'lla.ins'])
1060 if 'magTimeMs' in _v:
1066 def lla2kml(time, lla, serialNumber, kmlFileName="log.kml", **kwargs ):
1067 kml = simplekml.Kml()
1069 color = kwargs.pop(
'color', simplekml.Color.yellow)
1070 altitudeMode = kwargs.pop(
'altitudeMode', simplekml.constants.AltitudeMode.absolute)
1071 timeStep = kwargs.pop(
'timeStep', 0)
1076 for i
in range( 0, np.shape(lla)[0]):
1077 latLon.append( (lla[i,1], lla[i,0], lla[i,2]) )
1086 if time[i] >= tNext:
1089 if time[i] >= lNext:
1090 if timeStep > lNext:
1094 pt = kml.newpoint(name=
"%.2f" % time[i], coords=[latLon[i]])
1096 pt = kml.newpoint(coords=[latLon[i]])
1097 pt.style.iconstyle.color = color
1098 pt.style.iconstyle.scale = 0.4
1099 pt.style.labelstyle.scale = 0.6
1100 pt.altitudemode = altitudeMode
1103 ls = kml.newlinestring(name=
"Tracks", description=serialNumber+
" tracks", coords=latLon)
1107 ls.altitudemode = altitudeMode
1108 ls.style.linestyle.width = 2
1109 ls.style.linestyle.color = color
1110 kml.save(kmlFileName)
GeneratorWrapper< T > range(T const &start, T const &end, T const &step)