Skip to content

Commit e8689ee

Browse files
committed
- fixed sign of BCNAV1
- added STO/EOP/ION support for RINEX 4.02
1 parent 423014b commit e8689ee

File tree

3 files changed

+154
-57
lines changed

3 files changed

+154
-57
lines changed

src/cssrlib/gnss.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,31 @@ def __gt__(self, other):
616616
(self.time == other.time and self.sec > other.sec)
617617

618618

619+
class STOParam():
620+
""" System Time and UTC Office """
621+
sbas = 0 # SBAS ID
622+
prm = [0, 0] # System time offset parameter
623+
t_ot = None # reference epoch
624+
t_t = 0.0 # transmission time of message (Time of week [sec])
625+
a = np.zeros(3) # a0, a1, a2
626+
627+
628+
class EOPParam():
629+
""" Earth Orientation Parameter """
630+
prm = np.zeros(9)
631+
# EOP parameters (xp,dxp,ddxp,yp,dyp,ddyp,dut1,ddut1,dddut1)
632+
t_ot = None # reference epoch
633+
t_t = 0.0 # transmission time of message (Time of week [sec])
634+
635+
636+
class IONParam():
637+
""" Ionospheric delay model Parameter """
638+
iod = 0
639+
prm = np.zeros(9) # ION parameters
640+
t_tm = None # transmission time
641+
region = None
642+
643+
619644
class Obs():
620645
""" class to define the observation """
621646

@@ -787,8 +812,13 @@ def __init__(self, nf=2):
787812
[0.1167E+06, -0.2294E+06, -0.1311E+06, 0.1049E+07]])
788813
self.ion_gim = np.zeros(9)
789814
self.ion_region = 0 # 0: wide-area, 1: Japan-aera (QZSS only)
790-
self.sto = np.zeros(3)
791-
self.sto_prm = np.zeros(4, dtype=int)
815+
# self.sto = np.zeros(3)
816+
# self.sto_prm = np.zeros(4, dtype=int)
817+
818+
self.sto_prm = {}
819+
self.eop_prm = {}
820+
self.ion_prm = {}
821+
792822
self.eop = np.zeros(9)
793823
self.elmin = np.deg2rad(15.0)
794824
self.tidecorr = False

src/cssrlib/rawnav.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,14 @@ def getbitg(self, buff, pos, len_):
142142

143143
def urai2sva(self, urai, sys=uGNSS.GPS):
144144
""" GPS/QZSS SV accuracy [1] 20.3.3.3.1.3, [2] Tab. 5.4.3-2 """
145-
urai_t = [2.40, 3.40, 4.85, 6.85, 9.65, 13.65, 24.00, 48.00, 96.00,
146-
192.00, 384.00, 768.00, 1536.00, 3072.00, 6144.00, -1.0]
145+
# sva_t = [2.40, 3.40, 4.85, 6.85, 9.65, 13.65, 24.00, 48.00, 96.00,
146+
# 192.00, 384.00, 768.00, 1536.00, 3072.00, 6144.00, -1.0]
147147

148-
return urai_t[urai]
148+
# from RINEX 4.02
149+
sva_t = [2.0, 2.8, 4.0, 5.7, 8.0, 11.3, 16.0, 32.0,
150+
64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0]
151+
152+
return sva_t[urai]
149153

150154
def sisa2sva(self, sisa):
151155
""" Galileo SISA Index Values [3] Tab. 89 """
@@ -873,26 +877,32 @@ def decode_bds_b1c(self, week, time_, sat, msg):
873877

874878
# decode Subframe 3
875879
i = 608
876-
page, eph.svh, eph.integ, eph.sismai = bs.unpack_from('u6u2u3u4',
880+
page, eph.svh, eph.integ, eph.sismai = bs.unpack_from('u6u2u3s4',
877881
msg, i)
878882
i += 15
879883
if page == 1: # Iono, BDT-UTC
880-
eph.sisai[0] = bs.unpack_from('u5', msg, i)[0]
884+
eph.sisai[0] = bs.unpack_from('u5', msg, i)[0] # SISAI_oe
881885
i += 5
882886
i = self.decode_bds_cnav_sisai(msg, eph, i)
883887
elif page == 2: # Reduced almanac
884888
i = self.decode_bds_cnav_sisai(msg, eph, i)
885889
i += 22
886890
elif page == 3: # EOP, BGTO
887-
eph.sisai[0] = bs.unpack_from('u5', msg, i)[0]
891+
eph.sisai[0] = bs.unpack_from('u5', msg, i)[0] # SISAI_oe
888892
i += 5
893+
# EOP
894+
# BGTO
889895
elif page == 4: # Midi almanac
890896
i = self.decode_bds_cnav_sisai(msg, eph, i)
891897
i += 22
898+
# Midi Almanac
892899

893900
# i += 264-15
894901
eph.mode = 1 # B-CNAV1
895902

903+
if page != 1: # page 1 include SISAI*
904+
return None
905+
896906
return eph
897907

898908
def decode_bds_b2a(self, week, time_, sat, msg):
@@ -918,7 +928,7 @@ def decode_bds_b2a(self, week, time_, sat, msg):
918928
id4, sow4 = bs.unpack_from('u6u18', buff, 320*3+6)
919929
id5, sow5 = bs.unpack_from('u6u18', buff, 320*4+6)
920930

921-
if id1 != 10 or id2 != 11 or id3 != 30 or id4 != 34 or id5 != 40:
931+
if id1 != 10 or id2 != 11 or id3 != 30 or id5 != 40:
922932
return None
923933

924934
if sow2 != sow1+1 or sow3 != sow2+1:
@@ -936,11 +946,13 @@ def decode_bds_b2a(self, week, time_, sat, msg):
936946
if id5 == 40:
937947
i = 320*4+42
938948
eph.sisai[0] = bs.unpack_from('u5', buff, i)[0]
949+
i += 5
950+
i = self.decode_bds_cnav_sisai(buff, eph, i)
939951

940952
# decode MT10
941953
i = 30
942954
eph.week, ib2a, eph.sismai, ib1c, eph.iode = bs.unpack_from(
943-
'u13u3u4u3u8', buff, i)
955+
'u13u3s4u3u8', buff, i)
944956
i += 31
945957
i = self.decode_bds_cnav_eph1(buff, eph, i)
946958
eph.integ = (ib2a << 3)+ib1c
@@ -962,7 +974,7 @@ def decode_bds_b2a(self, week, time_, sat, msg):
962974
return None
963975

964976
i = self.decode_bds_cnav_iono(buff, i)
965-
tgd_b1cp = bs.unpack_from('u12', buff, i)[0]
977+
tgd_b1cp = bs.unpack_from('s12', buff, i)[0]
966978

967979
eph.tgd = tgd_b1cp*rCST.P2_34
968980
eph.isc[1] = isc_b2ad*rCST.P2_34
@@ -1009,7 +1021,7 @@ def decode_bds_b2b(self, week, time_, sat, msg, ofst=12):
10091021
i = self.decode_bds_cnav_eph1(buff, eph, i)
10101022
i = self.decode_bds_cnav_eph2(buff, eph, i)
10111023

1012-
eph.integ, eph.sismai = bs.unpack_from('u3u4', buff, i)
1024+
eph.integ, eph.sismai = bs.unpack_from('u3s4', buff, i)
10131025
i += 7
10141026

10151027
# decode MT30

src/cssrlib/rinex.py

Lines changed: 100 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
from cssrlib.gnss import gpst2time, bdt2time, epoch2time, timediff, gtime_t
1212
from cssrlib.gnss import prn2sat, char2sys, timeget, utc2gpst, time2epoch
1313
from cssrlib.gnss import Eph, Geph, Obs, sat2id, sat2prn, gpst2bdt, time2gpst
14-
from cssrlib.gnss import timeadd, id2sat, gpst2utc, Seph
14+
from cssrlib.gnss import timeadd, id2sat, gpst2utc, Seph, STOParam, EOPParam
15+
from cssrlib.gnss import IONParam
1516

1617

1718
class pclk_t:
@@ -49,6 +50,13 @@ def __init__(self):
4950
self.mode_nav = 0
5051
self.glo_ch = {}
5152

53+
self.ofst_src = {'GP': uGNSS.GPS, 'GL': uGNSS.GLO,
54+
'GA': uGNSS.GAL, 'BD': uGNSS.BDS,
55+
'QZ': uGNSS.QZS, 'IR': uGNSS.IRN,
56+
'SB': uGNSS.SBS, 'UT': uGNSS.NONE}
57+
self.itype_t = {'LNAV': 0, 'FDMA': 1, 'IFNV': 2, 'D1D2': 3,
58+
'SBAS': 4, 'CNVX': 5, 'L1NV': 6, 'LXOC': 7}
59+
5260
def setSignals(self, sigList):
5361
""" define the signal list for each constellation """
5462

@@ -172,111 +180,155 @@ def decode_nav(self, navfile, nav, append=False):
172180
if self.ver >= 4.0:
173181

174182
if line[0:5] == '> STO': # system time offset (TBD)
175-
ofst_src = {'GP': uGNSS.GPS, 'GL': uGNSS.GLO,
176-
'GA': uGNSS.GAL, 'BD': uGNSS.BDS,
177-
'QZ': uGNSS.QZS, 'IR': uGNSS.IRN,
178-
'SB': uGNSS.SBS, 'UT': uGNSS.NONE}
183+
179184
sys = char2sys(line[6])
180185
itype = line[10:14]
186+
187+
if sys not in nav.sto_prm:
188+
nav.sto_prm[sys] = {}
189+
190+
if itype not in self.itype_t:
191+
fnav.readline()
192+
fnav.readline()
193+
continue
194+
195+
im = self.itype_t[itype]
196+
197+
if im not in nav.sto_prm[sys]:
198+
nav.sto_prm[sys][im] = STOParam()
199+
181200
line = fnav.readline()
182-
ttm = self.decode_time(line, 4)
201+
nav.sto_prm[sys][im].t_ot = self.decode_time(line, 4)
183202
mode = line[24:28]
184-
if mode[0:2] in ofst_src and mode[2:4] in ofst_src:
185-
nav.sto_prm[0] = ofst_src[mode[0:2]]
186-
nav.sto_prm[1] = ofst_src[mode[2:4]]
203+
if mode[0:2] in self.ofst_src and \
204+
mode[2:4] in self.ofst_src:
205+
nav.sto_prm[sys][im].prm[0] = \
206+
self.ofst_src[mode[0:2]]
207+
nav.sto_prm[sys][im].prm[1] = \
208+
self.ofst_src[mode[2:4]]
187209

188210
line = fnav.readline()
189-
ttm = self.flt(line, 0)
211+
nav.sto_prm[sys][im].t_t = self.flt(line, 0)
190212
for k in range(3):
191-
nav.sto[k] = self.flt(line, k+1)
213+
nav.sto_prm[sys][im].a[k] = self.flt(line, k+1)
192214
continue
193215

194216
elif line[0:5] == '> EOP': # earth orientation param
195217
sys = char2sys(line[6])
196218
itype = line[10:14]
219+
220+
if sys not in nav.eop_prm:
221+
nav.eop_prm[sys] = {}
222+
223+
if itype not in self.itype_t:
224+
fnav.readline()
225+
fnav.readline()
226+
fnav.readline()
227+
continue
228+
229+
im = self.itype_t[itype]
230+
231+
if im not in nav.eop_prm[sys]:
232+
nav.eop_prm[sys][im] = EOPParam()
233+
197234
line = fnav.readline()
198-
ttm = self.decode_time(line, 4)
235+
nav.eop_prm[sys][im].t_eop = self.decode_time(line, 4)
199236
for k in range(3):
200-
nav.eop[k] = self.flt(line, k+1)
237+
nav.eop_prm[sys][im].prm[k] = self.flt(line, k+1)
201238
line = fnav.readline()
202239
for k in range(3):
203-
nav.eop[k+3] = self.flt(line, k+1)
240+
nav.eop_prm[sys][im].prm[k+3] = self.flt(line, k+1)
204241
line = fnav.readline()
205-
ttm = self.flt(line, 0)
242+
nav.eop_prm[sys][im].t_t = self.flt(line, 0)
206243
for k in range(3):
207-
nav.eop[k+6] = self.flt(line, k+1)
244+
nav.eop_prm[sys][im].prm[k+6] = self.flt(line, k+1)
208245
continue
209246

210247
elif line[0:5] == '> ION': # iono (TBD)
211248
sys = char2sys(line[6])
212249
itype = line[10:14]
213250
stype = '' if len(line) < 20 else line[15:19]
251+
252+
if sys not in nav.ion_prm:
253+
nav.ion_prm[sys] = {}
254+
255+
im = self.itype_t[itype]
256+
nav.ion_prm[sys][im] = IONParam()
257+
214258
line = fnav.readline()
215-
ttm = self.decode_time(line, 4)
259+
nav.ion_prm[sys][im].t_tm = self.decode_time(line, 4)
216260
if sys == uGNSS.GAL and itype == 'IFNV': # Nequick-G
217261
for k in range(3): # ai0, ai1, ai2
218-
nav.ion[0, k] = self.flt(line, k+1)
262+
nav.ion_prm[sys][im].prm[k] = \
263+
self.flt(line, k+1)
219264
line = fnav.readline()
220265
# disturbance flags
221-
nav.ion[0, 3] = int(self.flt(line, 0))
266+
nav.ion_prm[sys][im].prm[3] = \
267+
int(self.flt(line, 0))
222268
elif sys == uGNSS.BDS and itype == 'CNVX': # BDGIM
223-
ttm = self.decode_time(line, 4)
224-
self.ion_gim = np.zeros(9)
225269
for k in range(3):
226-
nav.ion_gim[k] = self.flt(line, k+1)
270+
nav.ion_prm[sys][im].prm[k] = \
271+
self.flt(line, k+1)
227272
line = fnav.readline()
228273
for k in range(4):
229-
nav.ion_gim[k+3] = self.flt(line, k)
274+
nav.ion_prm[sys][im].prm[k+3] = \
275+
self.flt(line, k)
230276
line = fnav.readline()
231277
for k in range(2):
232-
nav.ion_gim[k+7] = self.flt(line, k)
278+
nav.ion_prm[sys][im].prm[k+7] = \
279+
self.flt(line, k)
233280
elif sys == uGNSS.IRN and itype == 'L1NV': # L1NAV
234281
if stype == 'KLOB': #
235282
iodk = self.flt(line, 1)
236283
line = fnav.readline()
237284
for k in range(4):
238-
nav.ion[0, k] = self.flt(line, k)
285+
nav.ion_prm[sys][im].prm[k] = \
286+
self.flt(line, k)
239287
line = fnav.readline()
240288
for k in range(4):
241-
nav.ion[1, k] = self.flt(line, k)
289+
nav.ion_prm[sys][im].prm[k+4] = \
290+
self.flt(line, k)
291+
nav.ion_prm[sys][im].iod = iodk
242292
line = fnav.readline()
243-
nav.ion_region = np.zeros(4)
293+
nav.ion_prm[sys][im].region = np.zeros(4)
244294
for k in range(4):
245-
nav.ion_region[k] = self.flt(line, k)
246-
295+
nav.ion_prm[sys][im].region[k] = \
296+
self.flt(line, k)
247297
elif stype == 'NEQN':
248-
nav.ion_region = np.zeros((3, 4))
249-
iodn = self.flt(line, 1)
250-
298+
nav.ion_prm[sys][im].iod = self.flt(line, 1)
299+
prm = np.zeros((3, 8))
251300
for j in range(3):
252301
line = fnav.readline()
253-
nav.ion = np.zeros((3, 4))
254302
for k in range(4): # a0, a1, a2, idf
255-
nav.ion[j, k] = self.flt(line, k)
303+
prm[j, k] = self.flt(line, k)
256304
line = fnav.readline()
257305
# lon_min, lon_max, mopid_min, mopid_max
258306
for k in range(4):
259-
nav.ion_region[j, k] = \
260-
self.flt(line, k)
307+
prm[j, k+4] = self.flt(line, k)
308+
nav.ion_prm[sys][im].prm = prm
261309

262310
elif sys == uGNSS.GLO and itype == 'LXOC':
263311
c_A = self.flt(line, 1)
264312
c_F10_7 = self.flt(line, 2)
265313
c_Ap = self.flt(line, 3)
266-
nav.ion[0, 0:3] = [c_A, c_F10_7, c_Ap]
314+
nav.ion_prm[sys][im].prm[0:3] = \
315+
[c_A, c_F10_7, c_Ap]
267316

268317
else: # Klobucher (LNAV, D1D2, CNVX)
269-
self.ion_gim = np.zeros(9)
318+
nav.ion_prm[sys][im].prm = np.zeros(9)
319+
270320
for k in range(3):
271-
nav.ion[0, k] = self.flt(line, k+1)
321+
nav.ion_prm[sys][im].prm[k] = \
322+
self.flt(line, k+1)
272323
line = fnav.readline()
273-
nav.ion[0, 3] = self.flt(line, 0)
274-
for k in range(3):
275-
nav.ion[1, k] = self.flt(line, k+1)
324+
for k in range(4):
325+
nav.ion_prm[sys][im].prm[k+3] = \
326+
self.flt(line, k)
276327
line = fnav.readline()
277-
nav.ion[1, 3] = self.flt(line, 0)
328+
nav.ion_prm[sys][im].prm[7] = self.flt(line, 0)
278329
if len(line) >= 42:
279-
nav.ion_region = int(self.flt(line, 1))
330+
nav.ion_prm[sys][im].prm[8] = \
331+
int(self.flt(line, 1))
280332
continue
281333

282334
elif line[0:5] == '> EPH':
@@ -540,7 +592,10 @@ def decode_nav(self, navfile, nav, append=False):
540592
eph.sisai[2] = int(self.flt(line, 2)) # oc1
541593
eph.sisai[3] = int(self.flt(line, 3)) # oc2
542594
elif sys == uGNSS.IRN:
543-
eph.urai = int(self.flt(line, 0))
595+
if self.mode_nav == 0:
596+
eph.sva = self.flt(line, 0)
597+
else: # L1NV
598+
eph.urai = self.flt(line, 0)
544599
eph.svh = int(self.flt(line, 1))
545600
if self.mode_nav == 2 and eph.integ == 1:
546601
eph.tgd = int(self.flt(line, 3))

0 commit comments

Comments
 (0)