Skip to content

Commit b9715dc

Browse files
committed
- Javad decoder: added glonass CDMA, NavIC L1
1 parent be80611 commit b9715dc

File tree

3 files changed

+134
-102
lines changed

3 files changed

+134
-102
lines changed

receiver/decode_jps.py

Lines changed: 95 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""
22
Javad Receiver GREIS messages decoder
33
4-
[1] GREIS: GNSS Receiver External Interface Specification for 4.3.00,
5-
June, 2023
4+
[1] GREIS: GNSS Receiver External Interface Specification for 4.5.00,
5+
October, 2024
66
77
@author: Rui Hirokawa
88
"""
@@ -12,7 +12,7 @@
1212
import struct as st
1313
import bitstruct.c as bs
1414
from cssrlib.gnss import epoch2time, time2gpst, prn2sat, uGNSS, uTYP, rSigRnx
15-
from cssrlib.gnss import Obs, rCST, gpst2time, uSIG
15+
from cssrlib.gnss import Obs, rCST, gpst2time, uSIG, copy_buff
1616
from cssrlib.rawnav import rcvDec, rcvOpt
1717
from glob import glob
1818
from enum import IntEnum
@@ -114,7 +114,7 @@ class jps(rcvDec):
114114
[uSIG.L2I, uSIG.L8X, uSIG.L7I, uSIG.L6I, uSIG.L5X, uSIG.L1X],
115115
[uSIG.L9A, 0, 0, 0, uSIG.L5A, uSIG.L1X],
116116
[0, 0, 0, 0, 0, 0],
117-
[uSIG.L4X, 0, 0, 0, uSIG.L6X, uSIG.L3X]]
117+
[uSIG.L4X, 0, 0, uSIG.L6X, uSIG.L3X, 0]]
118118
freqs = [[1, 1, 2, 2, 3, 1], [1, 1, 2, 2, 3, 0], [1, 0, 0, 0, 3, 0],
119119
[1, 6, 2, 4, 3, 0], [1, 1, 4, 2, 3, 1], [1, 6, 2, 3, 3, 1],
120120
[0, 0, 0, 0, 3, 1]]
@@ -142,6 +142,7 @@ def __init__(self, opt=None, prefix=''):
142142
self.CNO = np.zeros((self.nmax, self.nsigmax))
143143
self.CNOd = np.zeros((self.nmax, self.nsigmax))
144144

145+
self.nsat = 0
145146
self.qzl6_time_p = -1
146147
self.tod = -1
147148

@@ -405,7 +406,7 @@ def decode_nd(self, buff, sys=uGNSS.GPS):
405406
def decode(self, buff, len_, sys=[], prn=[]):
406407
head = buff[0:2].decode()
407408
if head == 'RE':
408-
if self.monlevel >= 1:
409+
if self.monlevel > 1:
409410
print("[{:2s}] {:}".format(head, buff[5:5+len_].decode()))
410411

411412
elif self.crc8(buff, len_-1) != buff[-1]:
@@ -414,19 +415,26 @@ def decode(self, buff, len_, sys=[], prn=[]):
414415

415416
if head == '~~': # receiver time [RT] (epoch start)
416417
self.tod = st.unpack_from('<L', buff, 5)[0]*1e-3
417-
if self.monlevel >= 0:
418+
if self.monlevel > 1:
418419
print("[RT] tod={:.1f}".format(self.tod))
419420
elif head == 'RE':
420421
return
421422
elif head == '::': # epoch time [ET] (epoch end)
422423
self.tod = st.unpack_from('<L', buff, 5)[0]*1e-3
423-
if self.monlevel >= 0:
424+
if self.monlevel > 1:
424425
print("[ET] tod={:.1f}".format(self.tod))
426+
427+
obs = self.decode_obs()
428+
if self.flg_rnxobs and obs is not None:
429+
self.obs = obs
430+
self.re.rnx_obs_header(obs.time, self.fh_rnxobs)
431+
self.re.rnx_obs_body(obs, self.fh_rnxobs)
432+
425433
elif head == 'GT': # GPS time [GT]
426434
tow, wn, cycle = st.unpack_from('<LHB', buff, 5) # ms
427435
self.week = wn+cycle*1024
428436
self.tow = tow*1e-3
429-
if self.monlevel >= 0:
437+
if self.monlevel > 1:
430438
print("[GT] tow={:.1f} week={:4d}".format(self.tow, self.week))
431439
elif head == 'RD': # Receiver Date and Receiver Time
432440
# base 0:GPS,1:UTC USNO,2:GLO,3:UTC SU
@@ -439,14 +447,15 @@ def decode(self, buff, len_, sys=[], prn=[]):
439447
ep = [year, month, day, h, m, s]
440448
self.week, self.tow = time2gpst(epoch2time(ep))
441449

442-
if self.monlevel >= 0:
450+
if self.monlevel > 1:
443451
print("[RD] {:d}/{:d}/{:d} {:d}".
444452
format(year, month, day, base))
445453
elif head == 'SX': # satellite index
446454
sys = []
447455
prn = []
448456
nsat = (len_-6)//2
449457
esi = st.unpack_from('<'+'B'*2*nsat, buff, 5)
458+
self.nsat = nsat
450459
self.freqn = np.zeros(nsat, dtype=int)
451460
for k in range(nsat):
452461
ssid = esi[k*2]
@@ -494,7 +503,7 @@ def decode(self, buff, len_, sys=[], prn=[]):
494503

495504
elif head == 'xd': # QZSS L6 Message Data
496505
prn, time_, type_, len_ = st.unpack_from('<BLBB', buff, 5)
497-
if self.monlevel >= 1:
506+
if self.monlevel > 1:
498507
print("[xd] prn={:d} tow={:d} type={:d} len={:d}".
499508
format(prn, time_, type_, len_))
500509
if self.week >= 0:
@@ -555,13 +564,78 @@ def decode(self, buff, len_, sys=[], prn=[]):
555564

556565
elif head == 'id': # NavIC Navigation data
557566
prn, time_, type_, len_ = st.unpack_from('<BLBB', buff, 5)
567+
sat = prn2sat(uGNSS.IRN, prn)
568+
# type 0 - L5, 1 - S, 2 - L1
569+
msg = st.unpack_from('>'+len_*'L', buff, 12)
570+
b = bytes(np.array(msg, dtype='uint32'))
571+
572+
if self.flg_rnxnav:
573+
eph = None
574+
if type_ == 0:
575+
eph = self.rn.decode_irn_lnav(self.week, time_, sat, b)
576+
elif type_ == 2:
577+
# for L1
578+
# data[0] – subframe 1 (toi)
579+
# data[1…19] – subframe 2
580+
# data[20…28] – subframe 3
581+
582+
msg = bytearray(228) # recover original L1C msg structure
583+
# toi: 9b, data2: 600b, data3: 274b
584+
toi = bs.unpack_from('u32', b, 0)[0]
585+
bs.pack_into('u9', msg, 0, toi)
586+
copy_buff(b, msg, 32, 52, 600)
587+
copy_buff(b, msg, 640, 1252, 274)
588+
msg = bytes(msg)
589+
eph = self.rn.decode_irn_l1nav(self.week, time_, sat, msg)
590+
591+
if eph is not None:
592+
self.re.rnx_nav_body(eph, self.fh_rnxnav)
593+
594+
if self.monlevel >= 2:
595+
print(f"[id] time={time_:6d} prn={prn:2d} type={type_}")
596+
558597
elif head == 'lD': # Glonass Raw Navigation data
559598
svn, fcn, time_, type_, len_ = st.unpack_from('<BbLBB', buff, 5)
560-
elif head == 'ED': # Galileo Navigation data
599+
# type 0 - L1, 2 - L2C, 3 - P1, 4 - P2
600+
msg = st.unpack_from('>'+len_*'L', buff, 12)
601+
b = bytes(np.array(msg, dtype='uint32'))
602+
603+
if self.flg_rnxnav:
604+
geph = None
605+
geph = self.rn.decode_glo_fdma(self.week, time_, sat, b)
606+
607+
if geph is not None:
608+
self.re.rnx_gnav_body(geph, self.fh_rnxnav)
609+
610+
if self.monlevel >= 2:
611+
print(f"[lD] time={time_:6d} svn={svn:2d} fcn{fcn:2d} " +
612+
f"type={type_}")
613+
614+
elif head == 'ud': # Glonass CDMA Raw Navigation data
615+
prn, time_, type_, len_ = st.unpack_from('<BLBB', buff, 5)
616+
# type: 0 - L1, 1 - L2, 3 - L3
617+
sat = prn2sat(uGNSS.GLO, prn)
618+
msg = st.unpack_from('>'+len_*'L', buff, 12)
619+
b = bytes(np.array(msg, dtype='uint32'))
620+
621+
if self.flg_rnxnav:
622+
geph = None
623+
if type_ == 0:
624+
geph = self.rn.decode_glo_l1oc(self.week, time_, sat, b)
625+
elif type_ == 2:
626+
geph = self.rn.decode_glo_l3oc(self.week, time_, sat, b)
627+
628+
if geph is not None:
629+
self.re.rnx_gnav_body(geph, self.fh_rnxnav)
630+
631+
if self.monlevel >= 2:
632+
print(f"[ud] time={time_:6d} prn={prn:2d} type={type_}")
633+
634+
elif head == 'ED': # Galileo Raw Navigation data
561635
prn, time_, type_, len_ = st.unpack_from('<BLBB', buff, 5)
562636
sat = prn2sat(uGNSS.GAL, prn)
563637
if self.monlevel >= 2:
564-
print("[ED] time={:6d} prn={:2d}".format(time_, prn))
638+
print(f"[ED] time={time_:6d} prn={prn:2d} type={type_}")
565639

566640
# [I/NAV]
567641
# even/odd,page-type,data(1/2),tail => 1,1,112,6
@@ -795,6 +869,12 @@ def decode(self, buff, len_, sys=[], prn=[]):
795869
ch = self.ch_t[head[0]]
796870
nsat = (len_-6)//2
797871
# srdp = st.unpack_from('h'*nsat, buff, 5)
872+
elif head in ('ST', 'SP', 'PV', 'PG'):
873+
# [ST] Solution Time-Tag
874+
# [SP] Position Covariance Matrix
875+
# [PV] Cartesian Position and Velocity
876+
# [PG] Geodetic Position
877+
None
798878
else:
799879
print("[{:s}] undef".format(head))
800880
return 0
@@ -826,7 +906,8 @@ def decode(self, buff, len_, sys=[], prn=[]):
826906
opt.flg_sbas = False
827907
opt.flg_rnxnav = True
828908

829-
prn_ref = 199
909+
# prn_ref = 199
910+
prn_ref = -1
830911
sbs_ref = -1
831912

832913
for f in glob(bdir+fnames):
@@ -837,7 +918,7 @@ def decode(self, buff, len_, sys=[], prn=[]):
837918

838919
prefix = bdir+fname[4:].removesuffix('.jps')+'_'
839920
jpsdec = jps(opt=opt, prefix=bdir+fname[4:].removesuffix('.jps')+'_')
840-
jpsdec.monlevel = 2
921+
jpsdec.monlevel = 1
841922

842923
jpsdec.re.anttype = "JAVRINGANT_DM JVDM"
843924
jpsdec.re.rectype = "JAVAD DELTA-3"

0 commit comments

Comments
 (0)