Skip to content

Commit 6804340

Browse files
committed
fix some bugs
1 parent 5a4942b commit 6804340

File tree

6 files changed

+166
-84
lines changed

6 files changed

+166
-84
lines changed

com.py

+5
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ def DrMat(loc, itype = 0):
182182
Dr = np.diag([1 / (Rm + loc[2]), 1 / ((Rn + loc[2]) * np.cos(loc[0])), -1])
183183
return Dr
184184

185+
def rv2m(rv):
186+
mat = antisym(rv)
187+
mat = np.identity(3) - mat
188+
return mat
189+
185190

186191
# inpos = [0.0107951084511778 * glv.D2R, -2.14251290749072 * glv.D2R, -75.7498049314083 * glv.D2R]
187192
# qua = euler2quater(inpos)

config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(self):
4545
self.ACC_SCF_STD = np.array([100, 100, 100]) * 1e-6 # unit : ppm
4646
self.ACC_SCF_VAL = np.array([0, 0, 0]) * 1e-6 # unit : ppm
4747

48-
init_rn = com.DrMat(self.init_loc) @ self.init_loc
48+
init_rn = self.init_loc
4949
self.init_x = np.hstack((
5050
init_rn,
5151
self.init_vel,

data/rbin.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import struct
2+
3+
4+
with open("./Data1_PureINS.bin",'rb') as f:
5+
for i in range(100):
6+
if i % 10 == 0:
7+
print('=======')
8+
data = f.read(8)
9+
data_float = struct.unpack("d",data)
10+
print(data_float[0])
11+
12+
13+

imu.py

+112-71
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,13 @@ def __init__(self, imudata):
211211
self.vel = []
212212
self.pos = []
213213

214+
self.gyo_bias = []
215+
self.acc_bias = []
216+
self.gyo_fact = []
217+
self.acc_fact = []
218+
219+
self.rot_ = None
220+
self.qua_ = None
214221
self.rot = None # Rotation matrix
215222
self.qua = None # Quaternion
216223

@@ -224,33 +231,50 @@ def load_initstatus(self, fp):
224231
self.vel.append(self.imudata.init_vel)
225232
self.pos.append(self.imudata.init_pos)
226233

234+
self.gyo_bias = self.config.GYO_BIA_VAL
235+
self.acc_bias = self.config.ACC_BIA_VAL
236+
self.gyo_fact = self.config.GYO_SCF_VAL
237+
self.acc_fact = self.config.ACC_SCF_VAL
238+
227239
self.rot = com.euler2rotation(self.pos[-1])
228240
self.qua = com.euler2quater(self.pos[-1])
229241

230242
self.Qx = np.zeros((9,9))
231-
243+
self.load_gnssstatus()
244+
232245
def load_gnssstatus(self):
246+
self.gtim = []
247+
self.gloc = []
248+
self.gloc_std = []
233249
with open(self.gnssf) as f:
234250
for line in f:
235251
linedata = [float(i) for i in line.split()]
236-
t = linedata[0]
237-
gnss_loc = np.asarray([linedata[1] * glv.D2R, linedata[2] * glv.D2R, linedata[3]])
238-
loc_std = np.asarray(linedata[4:])
239-
yield t, gnss_loc, loc_std
240-
252+
self.gtim.append(linedata[0])
253+
self.gloc.append([linedata[1] * glv.D2R, linedata[2] * glv.D2R, linedata[3]])
254+
self.gloc_std.append(linedata[4:])
255+
256+
def find_gpsref_data_index(self, index, reftime):
257+
n = len(self.gtim)
258+
for i in range(index, n):
259+
t = self.gtim[i]
260+
if t - reftime < self.imudata.intv and t > reftime:
261+
return 1, i
262+
elif t > reftime:
263+
return 0, i
264+
return 0, -1
241265

242-
def antenna_cor(self, imu_loc):
243-
Dr_I = com.DrMat(imu_loc, 1)
244-
gnss_imuloc = imu_loc + Dr_I @ self.rot @ self.config.antenna_arm
245-
return gnss_imuloc
266+
def antenna_cor(self, imuloc, gloc):
267+
Dr_I = com.DrMat(imuloc, 1)
268+
gloc_c = gloc - Dr_I @ self.rot @ self.config.antenna_arm
269+
return gloc_c
246270

247271
def updepoch_imu(self):
248272
for t,ls_g,ls_a in self.imudata.loadbinepoch(self.binf):
249273
if t < self.imudata.init_ts:
250274
continue
251275
self.iep += 1
252276
if self.iep == 1:
253-
yield self.tim[-1], self.pos[-1], self.vel[-1], self.loc[-1]
277+
# yield self.tim[-1], self.pos[-1], self.vel[-1], self.loc[-1]
254278
continue
255279
self.tim.append(t)
256280
loc_p = self.loc[-1]
@@ -263,6 +287,8 @@ def updepoch_imu(self):
263287
vel_m = vel_p + (vel_p - self.vel[-2]) / 2
264288
loc_m = loc_p + (loc_p - self.loc[-2]) / 2
265289

290+
self.__cor_imu()
291+
266292
omega_n_ie, omega_n_en = com.earthrotatvec(loc_m, vel_m)
267293
grav_n = com.getgravity(loc_m[0], loc_m[2])
268294

@@ -278,9 +304,13 @@ def updepoch_imu(self):
278304
vel_m = (vel_n + vel_p) / 2
279305
loc_m = (loc_n + loc_p) / 2
280306
omega_n_ie, omega_n_en = com.earthrotatvec(loc_m, vel_m)
281-
q_b_n = self.__updpos(omega_n_ie, omega_n_en)
307+
q_b_n = self.__updpos(omega_n_ie, omega_n_en)
308+
309+
self.qua_ = np.copy(self.qua)
310+
self.rot_ = np.copy(self.rot)
282311
self.qua = q_b_n
283312
self.rot = com.quater2rotation(q_b_n)
313+
284314
pos_n = com.rotation2euler(self.rot)
285315
self.pos.append(pos_n)
286316

@@ -289,37 +319,42 @@ def updepoch_imu(self):
289319
def updepoch(self):
290320
x = np.asarray(self.config.init_x)
291321
Qx = np.asarray(self.config.init_Qx)
322+
gps_refdata_index = 0
292323
for t, pos_n, vel_n, loc_n in self.updepoch_imu():
324+
cloc_n = np.copy(loc_n)
293325
dx = np.zeros(3 * 7)
294-
PHI, Qw = self.get_status_equation_matrix()
295-
# update status
296-
dx_ = PHI @ dx
297-
Qx_ = PHI @ Qx @ PHI.T + Qw
298-
for tg, gnss_pureloc, gloc_std in self.load_gnssstatus():
299-
if np.abs(t - tg) < 0.01:
300-
Dr = com.DrMat(loc_n)
301-
Hr, Rk = self.get_observation_equation_matrix(Dr @ gloc_std)
302-
gnss_imuloc = self.antenna_cor(loc_n)
303-
Z = Dr @ (gnss_imuloc - gnss_pureloc)
304-
S = Hr @ Qx_ @ Hr.T + Rk
305-
K = Qx_ @ Hr.T @ np.linalg.inv(S)
306-
break
307-
elif t < tg:
308-
Hr = np.zeros((3, 21))
309-
Z = np.zeros(3)
310-
Rk = np.zeros((3, 3))
311-
K = np.zeros((21, 3))
312-
break
313-
dx = dx_ + K @ (Z - Hr @ dx_)
314-
temp = np.eye(len(x)) - K @ Hr
315-
Qx = temp @ Qx_ @ temp.T + K @ Rk @ K.T
316-
x += dx
317-
Dr_I = com.DrMat(loc_n, 1)
318-
dx[:3] = Dr_I @ dx[:3]
319-
for i in range(3):
320-
self.loc[-1][i] += dx[i]
321-
self.vel[-1][i] += dx[i + 3]
322-
self.pos[-1][i] += dx[i + 6]
326+
ok, gps_refdata_index = self.find_gpsref_data_index(gps_refdata_index, t)
327+
if ok:
328+
# update status
329+
PHI, Qw = self.get_status_equation_matrix()
330+
dx_ = PHI @ dx
331+
Qx_ = PHI @ Qx @ PHI.T + Qw
332+
gnss_pureloc = np.asarray(self.gloc[gps_refdata_index])
333+
gloc_std = np.asarray(self.gloc_std[gps_refdata_index])
334+
Dr = com.DrMat(cloc_n)
335+
Hr, Rk = self.get_observation_equation_matrix(gloc_std)
336+
gloc_c = self.antenna_cor(cloc_n, gnss_pureloc)
337+
Z = Dr @ (cloc_n - gloc_c)
338+
S = Hr @ Qx_ @ Hr.T + Rk
339+
K = Qx_ @ Hr.T @ np.linalg.inv(S)
340+
dx = dx_ + K @ (Z - Hr @ dx_)
341+
temp = np.eye(len(x)) - K @ Hr
342+
Qx = temp @ Qx_ @ temp.T + K @ Rk @ K.T
343+
else:
344+
PHI, Qw = self.get_status_equation_matrix()
345+
dx = PHI @ dx
346+
Qx = PHI @ Qx @ PHI.T + Qw
347+
Rm,Rn = com.mcucradius(cloc_n[0])
348+
dx[0] /= Rm
349+
dx[1] /= (Rn * np.cos(cloc_n[0]))
350+
dx[2] /= -1
351+
self.loc[-1] -= dx[:3]
352+
self.vel[-1] -= dx[3:6]
353+
self.pos[-1] = com.rotation2euler(np.linalg.inv(com.rv2m(dx[6:9])) @ self.rot)
354+
self.gyo_bias += dx[9:12]
355+
self.gyo_fact += dx[12:15]
356+
self.acc_bias += dx[15:18]
357+
self.acc_fact += dx[18:]
323358
self.qua = com.euler2quater(self.pos[-1])
324359
self.rot = com.quater2rotation(self.qua)
325360
yield x, Qx
@@ -336,10 +371,15 @@ def get_observation_equation_matrix(self, loc_std):
336371
lb = self.config.antenna_arm
337372
Hr = np.zeros((3, 3*7))
338373
Hr[:,:3] = np.identity(3)
339-
Hr[:,6:9] = com.antisym(self.rot @ lb)
374+
Hr[:,6:9] = self.rot @ com.antisym(lb)
340375
Rk = np.diag(loc_std**2)
341376
return Hr, Rk
342377

378+
def __cor_imu(self):
379+
dt = self.imudata.imu_tim[-1] - self.imudata.imu_tim[-2]
380+
self.imudata.imu_acc[-1] = (self.imudata.imu_acc[-1] - self.acc_bias * dt) # / (1 + self.acc_fact)
381+
self.imudata.imu_gyo[-1] = (self.imudata.imu_gyo[-1] - self.gyo_bias * dt) # / (1 + self.gyo_fact)
382+
343383
def __updpos(self, omega_n_ie, omega_n_en):
344384
dt = self.imudata.imu_tim[-1] - self.imudata.imu_tim[-2]
345385

@@ -391,16 +431,16 @@ def __updloc(self):
391431

392432
loc_n = np.array([lat, lon, h])
393433
return loc_n
394-
395-
434+
435+
396436

397437
def __transfer_mat(self):
398438
# get transfer matrix : PHI_k/k-1
399439
dt = self.imudata.imu_tim[-1] - self.imudata.imu_tim[-2]
400440

401-
loc_n = self.loc[-1]
402-
vel_n = self.vel[-1]
403-
pos_n = self.pos[-1]
441+
loc_n = self.loc[-2]
442+
vel_n = self.vel[-2]
443+
pos_n = self.pos[-2]
404444

405445

406446
lat, lon, h = loc_n
@@ -411,8 +451,8 @@ def __transfer_mat(self):
411451
omega_n_ie, omega_n_en = com.earthrotatvec(loc_n, vel_n)
412452
omega_n_in = omega_n_ie + omega_n_en
413453

414-
ls_g = np.asarray(self.imudata.imu_gyo[-1])
415-
ls_a = np.asarray(self.imudata.imu_acc[-1])
454+
ls_g = np.asarray(self.imudata.imu_gyo[-2])
455+
ls_a = np.asarray(self.imudata.imu_acc[-2])
416456

417457
Frr = np.array([
418458
[-vd / (Rm + h), 0, vn / (Rm + h)],
@@ -446,34 +486,35 @@ def __transfer_mat(self):
446486
F[3:6,3:6] = Fvv
447487
F[6:9,:3] = Fphir
448488
F[6:9,3:6] = Fphiv
449-
F[3:6,6:9] = com.antisym(self.rot @ ls_a)
489+
F[3:6,6:9] = com.antisym(self.rot_ @ ls_a)
450490
F[6:9,6:9] = -com.antisym(omega_n_in)
451-
F[6:9,9:12] = -self.rot
452-
F[3:6,12:15] = self.rot
453-
F[3:6,-3:] = self.rot @ np.diag(ls_a)
454-
F[6:9,-6:-3] = -self.rot @ np.diag(ls_g)
455-
F[9:12,9:12] = 1 / self.config.GYO_BIA_TAU * np.identity(3)
456-
F[12:15,12:15] = 1 / self.config.ACC_BIA_TAU * np.identity(3)
457-
F[-6:-3,-6:-3] = 1 / self.config.GYO_SCF_TAU * np.identity(3)
458-
F[-3:,-3:] = 1 / self.config.ACC_SCF_TAU * np.identity(3)
491+
F[6:9,9:12] = -self.rot_
492+
F[3:6,12:15] = self.rot_
493+
F[3:6,-3:] = self.rot_ @ np.diag(ls_a/dt)
494+
F[6:9,-6:-3] = -self.rot_ @ np.diag(ls_g/dt)
495+
F[9:12,9:12] = - 1 / self.config.GYO_BIA_TAU * np.identity(3)
496+
F[12:15,12:15] = - 1 / self.config.ACC_BIA_TAU * np.identity(3)
497+
F[-6:-3,-6:-3] = - 1 / self.config.GYO_SCF_TAU * np.identity(3)
498+
F[-3:,-3:] = - 1 / self.config.ACC_SCF_TAU * np.identity(3)
459499
return np.identity(21) + F * dt
460500

461501
def __sys_noise_cov(self):
462-
qw = np.zeros((18, 18))
463-
qw[:3,:3] = self.config.GYOARW**2 * np.identity(3)
464-
qw[3:6,3:6] = self.config.ACCVRW**2 * np.identity(3)
465-
qw[6:9,6:9] = 2*self.config.GYO_BIA_STD**2 / self.config.GYO_BIA_TAU * np.identity(3)
466-
qw[9:12,9:12] = 2*self.config.ACC_BIA_STD**2 / self.config.ACC_BIA_TAU * np.identity(3)
502+
qw = np.zeros((21, 21))
503+
qw[:3,:3] = self.config.GYOARW**2 * np.identity(3)
504+
qw[3:6,3:6] = self.config.ACCVRW**2 * np.identity(3)
505+
506+
qw[9:12,9:12] = 2*self.config.GYO_BIA_STD**2 / self.config.GYO_BIA_TAU * np.identity(3)
507+
qw[12:15,12:15] = 2*self.config.ACC_BIA_STD**2 / self.config.ACC_BIA_TAU * np.identity(3)
467508
qw[-6:-3,-6:-3] = 2*self.config.GYO_SCF_STD**2 / self.config.GYO_SCF_TAU * np.identity(3)
468-
qw[-3:,-3:] = 2*self.config.ACC_SCF_STD**2 / self.config.ACC_SCF_TAU * np.identity(3)
509+
qw[-3:,-3:] = 2*self.config.ACC_SCF_STD**2 / self.config.ACC_SCF_TAU * np.identity(3)
469510
return qw
470511

471512
def __sys_control_mat(self):
472-
gc = np.zeros((21, 18))
473-
gc[3:6,:3] = self.rot
474-
gc[6:9,3:6] = self.rot
475-
gc[9:12,6:9] = np.identity(3)
476-
gc[-9:-6,-9:-6] = np.identity(3)
477-
gc[-6:-3,-6:-3] = np.identity(3)
478-
gc[-3:,-3:] = np.identity(3)
513+
gc = np.zeros((21, 21))
514+
gc[:3,:3] = self.rot_
515+
gc[3:6,3:6] = -self.rot_
516+
gc[9:12,9:12] = np.identity(3)
517+
gc[12:15,12:15] = np.identity(3)
518+
gc[15:18,15:18] = np.identity(3)
519+
gc[18:,18:] = np.identity(3)
479520
return gc

main.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def fread(fp):
185185

186186

187187

188-
with open("./data/Data1_PureINS.bin","rb") as f:
188+
with open("./results/m_sol.txt","w") as fw:
189189
for x, Qx in imuupd.updepoch():
190190
# for tim,euler,vel_n,loc_n in fread("./data/ref.txt"):
191191
# refdata = [] # time(sec), lat(rad), lon(rad), h(m), vn(m/s), ve(m/s), vd(m/s), phi(rad), theta(rad), psi(rad)
@@ -195,19 +195,16 @@ def fread(fp):
195195
# refdata.append(data_float)
196196
# mloc = np.array([loc_n[0] * glv.R2D, loc_n[1] * glv.R2D, loc_n[2]])
197197
tim = imuupd.tim[-1]
198-
# mloc = np.array(imuupd.loc[-1])
199-
# mvel = np.array(imuupd.vel[-1])
200-
# mpos = np.array(imuupd.pos[-1]) * glv.R2D
201-
# dloc = mloc - np.array(refdata[1:4])
202-
# dvel = vel_n - np.array(refdata[4:7])
203-
# dpos = meuler - np.array(refdata[7:])
204-
# timeList.append(tim)
205-
# dlocList.append(mloc)
206-
# dposList.append(mvel)
207-
# dvelList.append(mpos)
198+
mloc = np.array(imuupd.loc[-1])
199+
mloc[:2] *= glv.R2D
200+
mvel = np.array(imuupd.vel[-1])
201+
mpos = np.array(imuupd.pos[-1]) * glv.R2D
202+
mpos[-1] += 360
203+
fw.write("%10.3f %16.10f %16.10f %10.3f %10.3f %10.3f %10.3f %13.8f %13.8f %13.8f\n" % (
204+
tim, *mloc, *mvel, *mpos
205+
))
208206
print("======================")
209207
print("Porcessing Time : ", tim)
210-
# print(tim, mloc, vel_n, euler);
211208

212209
plotData(imuupd.tim,imuupd.loc,"LOC")
213210
plotData(imuupd.tim,imuupd.vel,"VEL")

plotdif.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on Mon Jul 27 16:14:58 2020
4+
5+
@author: mocki
6+
"""
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
10+
fref = "./data/ref.txt"
11+
fsol = "./results/m_sol.txt"
12+
13+
14+
dif = []
15+
with open(fref) as f1, open(fsol) as f2:
16+
f2.readline()
17+
for line_ref in f1:
18+
refdata = [float(i) for i in line_ref.split()]
19+
try:
20+
soldata = [float(i) for i in f2.readline().split()]
21+
dif.append([i - j for i,j in zip(soldata, refdata)])
22+
except Exception:
23+
break
24+
dif = np.asarray(dif)
25+
for i in range(8):
26+
plt.plot(dif[:,i+1])

0 commit comments

Comments
 (0)