cssrlib 0.8.0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cssrlib-0.8.0/src/cssrlib.egg-info → cssrlib-1.0.1}/PKG-INFO +14 -16
- {cssrlib-0.8.0 → cssrlib-1.0.1}/README.md +12 -14
- {cssrlib-0.8.0 → cssrlib-1.0.1}/setup.cfg +2 -2
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/cssr_bds.py +75 -45
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/cssr_has.py +10 -3
- cssrlib-1.0.1/src/cssrlib/cssr_pvs.py +176 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/cssrlib.py +224 -161
- cssrlib-1.0.1/src/cssrlib/dgps.py +289 -0
- cssrlib-1.0.1/src/cssrlib/ephemeris.py +894 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/gnss.py +139 -44
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/peph.py +126 -18
- cssrlib-1.0.1/src/cssrlib/pntpos.py +546 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/ppp.py +27 -2
- cssrlib-1.0.1/src/cssrlib/ppprtk.py +24 -0
- cssrlib-1.0.1/src/cssrlib/pppssr.py +1412 -0
- cssrlib-1.0.1/src/cssrlib/rawnav.py +1662 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/rinex.py +282 -51
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/rtcm.py +198 -113
- cssrlib-1.0.1/src/cssrlib/rtk.py +56 -0
- cssrlib-1.0.1/src/cssrlib/sbas.py +1073 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/test/test_eph.py +1 -1
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/test/test_gnss.py +5 -2
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/test/test_peph.py +26 -22
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/test/test_rtk.py +8 -7
- {cssrlib-0.8.0 → cssrlib-1.0.1/src/cssrlib.egg-info}/PKG-INFO +14 -16
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib.egg-info/SOURCES.txt +3 -1
- cssrlib-0.8.0/src/cssrlib/ephemeris.py +0 -332
- cssrlib-0.8.0/src/cssrlib/pntpos.py +0 -125
- cssrlib-0.8.0/src/cssrlib/pppigs.py +0 -926
- cssrlib-0.8.0/src/cssrlib/ppprtk.py +0 -416
- cssrlib-0.8.0/src/cssrlib/pppssr.py +0 -1045
- cssrlib-0.8.0/src/cssrlib/rawnav.py +0 -522
- cssrlib-0.8.0/src/cssrlib/rtk.py +0 -546
- {cssrlib-0.8.0 → cssrlib-1.0.1}/LICENSE +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/MANIFEST.in +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/pyproject.toml +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/__init__.py +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/data/30340780.21q +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/data/3034078M1.21O +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/data/SEPT078M.21P +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/data/SEPT078M1.21O +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/mlambda.py +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/plot.py +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/test/test_rnx.py +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib/tlesim.py +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib.egg-info/dependency_links.txt +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib.egg-info/not-zip-safe +0 -0
- {cssrlib-0.8.0 → cssrlib-1.0.1}/src/cssrlib.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cssrlib
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Python Toolkit for PPP/PPP-RTK positioning
|
|
5
5
|
Home-page: https://github.com/hirokawa/cssrlib
|
|
6
6
|
Author: Rui Hirokawa
|
|
7
7
|
Author-email: rui.hirokawa@gmail.com
|
|
@@ -30,7 +30,7 @@ It supports the following open format:
|
|
|
30
30
|
************************************************
|
|
31
31
|
Click this button for a quick demo in Google Colab
|
|
32
32
|
|
|
33
|
-
<a target="_blank" href="https://colab.research.google.com/github/
|
|
33
|
+
<a target="_blank" href="https://colab.research.google.com/github/hirokawa/cssrlib/blob/main/tutorials/cssrlib.ipynb">
|
|
34
34
|
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
|
35
35
|
</a>
|
|
36
36
|
|
|
@@ -38,17 +38,10 @@ Click this button for a quick demo in Google Colab
|
|
|
38
38
|
|
|
39
39
|
Prerequisites
|
|
40
40
|
=============
|
|
41
|
-
Additional python packages are required as prerequisites and can be installed via the following
|
|
41
|
+
Additional python packages are required as prerequisites and can be installed via the following command
|
|
42
42
|
|
|
43
43
|
```
|
|
44
|
-
pip install
|
|
45
|
-
pip install notebook numpy matplotlib
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Optionally, on linux, users can install the `cartopy` package
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
pip install cartopy
|
|
44
|
+
pip install -r requirements.txt
|
|
52
45
|
```
|
|
53
46
|
|
|
54
47
|
If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
|
|
@@ -89,9 +82,14 @@ Run RTK sample.
|
|
|
89
82
|
python test_rtk.py
|
|
90
83
|
```
|
|
91
84
|
|
|
92
|
-
Other samples are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
|
|
85
|
+
Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
|
|
86
|
+
|
|
87
|
+
- Galileo-HAS PPP (SIS/IDD) processing example
|
|
88
|
+
- BDS-PPP processing example
|
|
89
|
+
- QZSS MADOCA-PPP processing example
|
|
90
|
+
- QZSS CLAS PPP-RTK processing example
|
|
91
|
+
- IGS (SP3+BIAS) PPP-AR processing example
|
|
92
|
+
- (experimental) PPP via SouthPAN (PVS) processing example
|
|
93
|
+
- Binary message parser for Septentrio receiver (Mosaic/PolaRX5)
|
|
93
94
|
|
|
94
|
-
- Galileo-HAS decoder
|
|
95
|
-
- BDS-PPP decoder
|
|
96
|
-
- Jupyter-Notebook including samples for RTK/PPP-RTK.
|
|
97
95
|
|
|
@@ -15,7 +15,7 @@ It supports the following open format:
|
|
|
15
15
|
************************************************
|
|
16
16
|
Click this button for a quick demo in Google Colab
|
|
17
17
|
|
|
18
|
-
<a target="_blank" href="https://colab.research.google.com/github/
|
|
18
|
+
<a target="_blank" href="https://colab.research.google.com/github/hirokawa/cssrlib/blob/main/tutorials/cssrlib.ipynb">
|
|
19
19
|
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
|
|
20
20
|
</a>
|
|
21
21
|
|
|
@@ -23,17 +23,10 @@ Click this button for a quick demo in Google Colab
|
|
|
23
23
|
|
|
24
24
|
Prerequisites
|
|
25
25
|
=============
|
|
26
|
-
Additional python packages are required as prerequisites and can be installed via the following
|
|
26
|
+
Additional python packages are required as prerequisites and can be installed via the following command
|
|
27
27
|
|
|
28
28
|
```
|
|
29
|
-
pip install
|
|
30
|
-
pip install notebook numpy matplotlib
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Optionally, on linux, users can install the `cartopy` package
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
pip install cartopy
|
|
29
|
+
pip install -r requirements.txt
|
|
37
30
|
```
|
|
38
31
|
|
|
39
32
|
If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
|
|
@@ -74,9 +67,14 @@ Run RTK sample.
|
|
|
74
67
|
python test_rtk.py
|
|
75
68
|
```
|
|
76
69
|
|
|
77
|
-
Other samples are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
|
|
70
|
+
Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
|
|
71
|
+
|
|
72
|
+
- Galileo-HAS PPP (SIS/IDD) processing example
|
|
73
|
+
- BDS-PPP processing example
|
|
74
|
+
- QZSS MADOCA-PPP processing example
|
|
75
|
+
- QZSS CLAS PPP-RTK processing example
|
|
76
|
+
- IGS (SP3+BIAS) PPP-AR processing example
|
|
77
|
+
- (experimental) PPP via SouthPAN (PVS) processing example
|
|
78
|
+
- Binary message parser for Septentrio receiver (Mosaic/PolaRX5)
|
|
78
79
|
|
|
79
|
-
- Galileo-HAS decoder
|
|
80
|
-
- BDS-PPP decoder
|
|
81
|
-
- Jupyter-Notebook including samples for RTK/PPP-RTK.
|
|
82
80
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = cssrlib
|
|
3
|
-
version = 0.
|
|
3
|
+
version = 1.0.1
|
|
4
4
|
author = Rui Hirokawa
|
|
5
5
|
author_email = rui.hirokawa@gmail.com
|
|
6
|
-
description =
|
|
6
|
+
description = Python Toolkit for PPP/PPP-RTK positioning
|
|
7
7
|
long_description = file: README.md
|
|
8
8
|
long_description_content_type = text/markdown
|
|
9
9
|
url = https://github.com/hirokawa/cssrlib
|
|
@@ -19,6 +19,8 @@ class cssr_bds(cssr):
|
|
|
19
19
|
self.nsig_max = 8
|
|
20
20
|
self.iodp = -1
|
|
21
21
|
self.iodp_p = -1
|
|
22
|
+
self.cb_blen = 12
|
|
23
|
+
self.cb_scl = 0.017
|
|
22
24
|
|
|
23
25
|
def ssig2rsig(self, sys: sGNSS, utyp: uTYP, ssig):
|
|
24
26
|
gps_tbl = {
|
|
@@ -156,47 +158,61 @@ class cssr_bds(cssr):
|
|
|
156
158
|
self.add_gnss(mask_glo, 37, sGNSS.GLO)
|
|
157
159
|
|
|
158
160
|
inet = 0
|
|
159
|
-
self.lc[inet].dclk =
|
|
160
|
-
self.lc[inet].dorb =
|
|
161
|
-
self.lc[inet].iode =
|
|
162
|
-
self.lc[inet].iodc =
|
|
163
|
-
self.lc[inet].iodc_c =
|
|
164
|
-
self.lc[inet].cbias =
|
|
161
|
+
self.lc[inet].dclk = {}
|
|
162
|
+
self.lc[inet].dorb = {}
|
|
163
|
+
self.lc[inet].iode = {}
|
|
164
|
+
self.lc[inet].iodc = {}
|
|
165
|
+
self.lc[inet].iodc_c = {}
|
|
166
|
+
self.lc[inet].cbias = {}
|
|
165
167
|
self.nsig_n = np.ones(self.nsat_n, dtype=int)*self.nsig_max
|
|
166
|
-
self.sig_n =
|
|
167
|
-
self.ura =
|
|
168
|
+
self.sig_n = {}
|
|
169
|
+
self.ura = {}
|
|
168
170
|
|
|
169
171
|
# fallback for inconsistent clock update
|
|
170
|
-
self.lc[inet].dclk_p =
|
|
171
|
-
self.lc[inet].iodc_c_p =
|
|
172
|
+
self.lc[inet].dclk_p = {}
|
|
173
|
+
self.lc[inet].iodc_c_p = {}
|
|
172
174
|
|
|
173
175
|
self.iodssr = head['iodssr']
|
|
174
176
|
|
|
175
177
|
self.lc[0].cstat |= (1 << sCType.MASK)
|
|
176
|
-
self.lc[0].t0[sCType.MASK] = self.time
|
|
178
|
+
# self.lc[0].t0[0][sCType.MASK] = self.time
|
|
177
179
|
return i
|
|
178
180
|
|
|
179
181
|
def decode_cssr_orb_sat(self, msg, i, inet, sat_n):
|
|
180
|
-
slot, iodn, iodc
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
slot, iodn, iodc = bs.unpack_from('u9u10u3', msg, i)
|
|
183
|
+
i += 22
|
|
184
|
+
|
|
185
|
+
dx, dy, dz = bs.unpack_from('s{:d}s{:d}s{:d}'.format(
|
|
186
|
+
self.dorb_blen[0], self.dorb_blen[1], self.dorb_blen[2]), msg, i)
|
|
187
|
+
i += self.dorb_blen[0] + self.dorb_blen[1] + self.dorb_blen[2]
|
|
188
|
+
|
|
189
|
+
ucls, uval = bs.unpack_from('u3u3', msg, i)
|
|
190
|
+
i += 6
|
|
191
|
+
|
|
183
192
|
sys, prn = self.slot2prn(slot)
|
|
184
193
|
if sys == uGNSS.NONE:
|
|
185
194
|
return i
|
|
186
195
|
sat = prn2sat(sys, prn)
|
|
187
196
|
if sat not in sat_n:
|
|
188
197
|
return i
|
|
189
|
-
idx = np.where(sat == sat_n)[0][0]
|
|
190
198
|
|
|
191
199
|
if (sys == uGNSS.GPS) or (sys == uGNSS.BDS):
|
|
192
200
|
iodn = iodn & 0xff # IODC -> IODE
|
|
193
201
|
|
|
194
|
-
|
|
195
|
-
self.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
self.
|
|
202
|
+
dorb = np.zeros(3)
|
|
203
|
+
dorb[0] = self.sval(dx, self.dorb_blen[0], self.dorb_scl[0])
|
|
204
|
+
dorb[1] = self.sval(dy, self.dorb_blen[1], self.dorb_scl[1])
|
|
205
|
+
dorb[2] = self.sval(dz, self.dorb_blen[2], self.dorb_scl[2])
|
|
206
|
+
|
|
207
|
+
self.lc[inet].iode[sat] = iodn
|
|
208
|
+
self.lc[inet].iodc[sat] = iodc
|
|
209
|
+
self.lc[inet].dorb[sat] = dorb
|
|
210
|
+
self.ura[sat] = self.quality_idx(ucls, uval)
|
|
211
|
+
|
|
212
|
+
if sat not in self.lc[inet].t0:
|
|
213
|
+
self.lc[inet].t0[sat] = {}
|
|
214
|
+
|
|
215
|
+
self.lc[inet].t0[sat][sCType.ORBIT] = self.time
|
|
200
216
|
return i
|
|
201
217
|
|
|
202
218
|
def decode_cssr_orb(self, msg, i, inet=0):
|
|
@@ -212,8 +228,8 @@ class cssr_bds(cssr):
|
|
|
212
228
|
|
|
213
229
|
self.iodssr_c[sCType.ORBIT] = head['iodssr']
|
|
214
230
|
self.lc[inet].cstat |= (1 << sCType.ORBIT)
|
|
215
|
-
|
|
216
|
-
i += 19
|
|
231
|
+
|
|
232
|
+
i += 19 # reserve
|
|
217
233
|
return i
|
|
218
234
|
|
|
219
235
|
def decode_cssr_cbias(self, msg, i, inet=0):
|
|
@@ -233,30 +249,39 @@ class cssr_bds(cssr):
|
|
|
233
249
|
i += 13
|
|
234
250
|
sys, prn = self.slot2prn(slot)
|
|
235
251
|
sat = prn2sat(sys, prn)
|
|
236
|
-
|
|
237
|
-
if len(idx) == 0:
|
|
252
|
+
if sat not in sat_n:
|
|
238
253
|
continue
|
|
254
|
+
if sat not in self.lc[inet].t0:
|
|
255
|
+
self.lc[inet].t0[sat] = {}
|
|
256
|
+
self.lc[inet].t0[sat][sCType.CBIAS] = self.time
|
|
257
|
+
|
|
258
|
+
self.lc[inet].cbias[sat] = {}
|
|
239
259
|
for j in range(0, nsig):
|
|
240
|
-
sig, cb = bs.unpack_from(
|
|
241
|
-
|
|
242
|
-
self.
|
|
243
|
-
|
|
260
|
+
sig, cb = bs.unpack_from(
|
|
261
|
+
'u4s{:d}'.format(self.cb_blen), msg, i)
|
|
262
|
+
i += 4+self.cb_blen
|
|
263
|
+
sig_ = self.ssig2rsig(sys, uTYP.C, sig)
|
|
264
|
+
self.lc[inet].cbias[sat][sig_] = self.sval(
|
|
265
|
+
cb, self.cb_blen, self.cb_scl)
|
|
244
266
|
|
|
245
267
|
self.iodssr_c[sCType.CBIAS] = head['iodssr']
|
|
246
268
|
self.lc[inet].cstat |= (1 << sCType.CBIAS)
|
|
247
|
-
|
|
269
|
+
|
|
248
270
|
return i
|
|
249
271
|
|
|
250
|
-
def decode_cssr_clk_sat(self, msg, i, inet,
|
|
272
|
+
def decode_cssr_clk_sat(self, msg, i, inet, sat):
|
|
251
273
|
""" decode clock correction for satellite """
|
|
252
|
-
iodc, dclk = bs.unpack_from('
|
|
253
|
-
i +=
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
274
|
+
iodc, dclk = bs.unpack_from('u3s{:d}'.format(self.dclk_blen), msg, i)
|
|
275
|
+
i += 3+self.dclk_blen
|
|
276
|
+
|
|
277
|
+
if sat in self.lc[inet].iodc_c.keys() and \
|
|
278
|
+
iodc != self.lc[inet].iodc_c[sat]:
|
|
279
|
+
self.lc[inet].iodc_c_p[sat] = self.lc[inet].iodc_c[sat]
|
|
280
|
+
self.lc[inet].dclk_p[sat] = self.lc[inet].dclk[sat]
|
|
281
|
+
self.lc[inet].iodc_c[sat] = iodc
|
|
258
282
|
# note: the sign of the clock correction reversed
|
|
259
|
-
self.lc[inet].dclk[
|
|
283
|
+
self.lc[inet].dclk[sat] = - \
|
|
284
|
+
self.sval(dclk, self.dclk_blen, self.dclk_scl)
|
|
260
285
|
return i
|
|
261
286
|
|
|
262
287
|
def decode_cssr_clk(self, msg, i, inet=0):
|
|
@@ -273,11 +298,15 @@ class cssr_bds(cssr):
|
|
|
273
298
|
for k in range(23):
|
|
274
299
|
idx = st1*23+k
|
|
275
300
|
if idx < self.nsat_n:
|
|
276
|
-
|
|
301
|
+
sat = self.sat_n[idx]
|
|
302
|
+
i = self.decode_cssr_clk_sat(msg, i, inet, sat)
|
|
303
|
+
if sat not in self.lc[inet].t0:
|
|
304
|
+
self.lc[inet].t0[sat] = {}
|
|
305
|
+
self.lc[inet].t0[sat][sCType.CLOCK] = self.time
|
|
277
306
|
|
|
278
307
|
self.iodssr_c[sCType.CLOCK] = head['iodssr']
|
|
279
308
|
self.lc[inet].cstat |= (1 << sCType.CLOCK)
|
|
280
|
-
|
|
309
|
+
|
|
281
310
|
i += 10
|
|
282
311
|
return i
|
|
283
312
|
|
|
@@ -295,10 +324,11 @@ class cssr_bds(cssr):
|
|
|
295
324
|
i += 6
|
|
296
325
|
idx = st2*70+k
|
|
297
326
|
if idx < self.nsat_n:
|
|
298
|
-
|
|
327
|
+
sat = self.sat_n[idx]
|
|
328
|
+
self.ura[sat] = self.quality_idx(v['class'], v['val'])
|
|
299
329
|
|
|
300
330
|
self.lc[0].cstat |= (1 << sCType.URA)
|
|
301
|
-
self.lc[0].t0[sCType.URA] = self.time
|
|
331
|
+
# self.lc[0].t0[0][sCType.URA] = self.time
|
|
302
332
|
return i
|
|
303
333
|
|
|
304
334
|
def decode_cssr_comb1(self, msg, i, inet=0):
|
|
@@ -312,7 +342,8 @@ class cssr_bds(cssr):
|
|
|
312
342
|
i += 36
|
|
313
343
|
for k in range(numc):
|
|
314
344
|
idx = slot_s+k
|
|
315
|
-
|
|
345
|
+
sat = self.sat_n[idx]
|
|
346
|
+
i = self.decode_cssr_clk_sat(msg, i, inet, sat)
|
|
316
347
|
|
|
317
348
|
if numo > 0:
|
|
318
349
|
tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
|
|
@@ -335,8 +366,7 @@ class cssr_bds(cssr):
|
|
|
335
366
|
i += 9
|
|
336
367
|
sys, prn = self.slot2prn(slot)
|
|
337
368
|
sat = prn2sat(sys, prn)
|
|
338
|
-
|
|
339
|
-
i = self.decode_cssr_clk_sat(msg, i, inet, idx)
|
|
369
|
+
i = self.decode_cssr_clk_sat(msg, i, inet, sat)
|
|
340
370
|
|
|
341
371
|
if numo > 0:
|
|
342
372
|
tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
|
|
@@ -75,13 +75,20 @@ class cssr_has(cssr):
|
|
|
75
75
|
return head, i
|
|
76
76
|
|
|
77
77
|
def decode_cssr(self, msg, i=0):
|
|
78
|
-
|
|
78
|
+
# Galileo HAS-SIS only defines MT=1, MT=4073 is CSSR message used in the
|
|
79
|
+
# Galileo HAS test dataset
|
|
80
|
+
#
|
|
81
|
+
if self.msgtype != 1 and self.msgtype != 4073:
|
|
79
82
|
print(f"invalid MT={self.msgtype}")
|
|
80
83
|
return False
|
|
81
84
|
# time of hour
|
|
82
85
|
# flags: mask,orbit,clock,clock subset,cbias,pbias,mask_id,iodset_id
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
try:
|
|
87
|
+
self.toh, flags, res, mask_id, self.iodssr = \
|
|
88
|
+
bs.unpack_from('u12u6u4u5u5', msg, i)
|
|
89
|
+
except:
|
|
90
|
+
print(f"invalid content={self.msgtype}")
|
|
91
|
+
return False
|
|
85
92
|
i += 32
|
|
86
93
|
|
|
87
94
|
if self.monlevel > 0 and self.fh is not None:
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PVS (PPP via SouthPAN) correction data decoder
|
|
3
|
+
|
|
4
|
+
[1] Service Definition Document for Open Services, SBAS-STN-0001,
|
|
5
|
+
Revision 02, December 2022
|
|
6
|
+
|
|
7
|
+
[2] Service Definition Document for Data Access Services, SBAS-STN-0002,
|
|
8
|
+
Revision 01, November 2023
|
|
9
|
+
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
import bitstruct as bs
|
|
14
|
+
from cssrlib.cssrlib import cssr, sCSSR, sCSSRTYPE, prn2sat, sCType
|
|
15
|
+
from cssrlib.cssrlib import sat2id
|
|
16
|
+
from cssrlib.gnss import uGNSS, rCST, gpst2time, timediff, timeadd, time2gpst
|
|
17
|
+
from binascii import unhexlify
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def decode_sinca_line(line):
|
|
21
|
+
""" SINCA (SISNeT compression algorithm) decoder """
|
|
22
|
+
if line[0:4] != '*MSG':
|
|
23
|
+
return None
|
|
24
|
+
v = line.split(',')
|
|
25
|
+
s = v[3]
|
|
26
|
+
week, tow = int(v[1]), int(v[2])
|
|
27
|
+
t = gpst2time(week, tow)
|
|
28
|
+
for key in '|/':
|
|
29
|
+
if key in s:
|
|
30
|
+
while True:
|
|
31
|
+
pos = s.find(key)
|
|
32
|
+
if pos < 0:
|
|
33
|
+
break
|
|
34
|
+
c = s[pos-1]
|
|
35
|
+
k = 2 if key == '|' else 3
|
|
36
|
+
n = int(s[pos+1:pos+k], 16)
|
|
37
|
+
s = s.replace(s[pos-1:pos+k], c*n, 1)
|
|
38
|
+
|
|
39
|
+
sb = unhexlify(s.split('*')[0])
|
|
40
|
+
return t, sb
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class cssr_pvs(cssr):
|
|
44
|
+
def __init__(self, foutname=None):
|
|
45
|
+
super().__init__(foutname)
|
|
46
|
+
self.MAXNET = 1
|
|
47
|
+
self.cssrmode = sCSSRTYPE.PVS_PPP
|
|
48
|
+
self.nsig_max = 0
|
|
49
|
+
self.sat_n = []
|
|
50
|
+
|
|
51
|
+
self.lc[0].dclk = {}
|
|
52
|
+
self.lc[0].ddft = {}
|
|
53
|
+
self.lc[0].dorb = {}
|
|
54
|
+
self.lc[0].dvel = {}
|
|
55
|
+
self.lc[0].iode = {}
|
|
56
|
+
self.lc[0].t0 = {}
|
|
57
|
+
|
|
58
|
+
self.tmax = {sCType.CLOCK: 120.0, sCType.ORBIT: 120.0}
|
|
59
|
+
|
|
60
|
+
# GPS LNAV, Galileo F/NAV
|
|
61
|
+
self.nav_mode = {uGNSS.GPS: 0, uGNSS.GAL: 1}
|
|
62
|
+
|
|
63
|
+
def slot2sat(self, slot):
|
|
64
|
+
sat = 0
|
|
65
|
+
if slot >= 1 and slot <= 32:
|
|
66
|
+
prn = slot
|
|
67
|
+
sat = prn2sat(uGNSS.GPS, prn)
|
|
68
|
+
elif slot >= 38 and slot <= 69:
|
|
69
|
+
prn = slot-37
|
|
70
|
+
sat = prn2sat(uGNSS.GLO, prn)
|
|
71
|
+
elif slot >= 75 and slot <= 110:
|
|
72
|
+
prn = slot-74
|
|
73
|
+
sat = prn2sat(uGNSS.GAL, prn)
|
|
74
|
+
elif slot >= 120 and slot <= 158:
|
|
75
|
+
prn = slot
|
|
76
|
+
sat = prn2sat(uGNSS.SBS, prn)
|
|
77
|
+
elif slot >= 159 and slot <= 195:
|
|
78
|
+
prn = slot-158
|
|
79
|
+
sat = prn2sat(uGNSS.BDS, prn)
|
|
80
|
+
return sat
|
|
81
|
+
|
|
82
|
+
def adjust_time_week(self, time, time0):
|
|
83
|
+
dt = timediff(time, time0)
|
|
84
|
+
if dt > rCST.HALFWEEK_SEC:
|
|
85
|
+
time = timeadd(time, -rCST.WEEK_SEC)
|
|
86
|
+
elif dt < -rCST.HALFWEEK_SEC:
|
|
87
|
+
time = timeadd(time, rCST.WEEK_SEC)
|
|
88
|
+
return time
|
|
89
|
+
|
|
90
|
+
def check_validity(self, time):
|
|
91
|
+
for sat in self.sat_n:
|
|
92
|
+
if timediff(time, self.lc[0].t0[sat][sCType.CLOCK]) > \
|
|
93
|
+
self.tmax[sCType.CLOCK]:
|
|
94
|
+
self.lc[0].dclk[sat] = 0.0
|
|
95
|
+
if timediff(time, self.lc[0].t0[sat][sCType.ORBIT]) > \
|
|
96
|
+
self.tmax[sCType.ORBIT]:
|
|
97
|
+
self.lc[0].iode[sat] = -1
|
|
98
|
+
self.lc[0].dorb[sat] = np.zeros(3)
|
|
99
|
+
|
|
100
|
+
def decode_cssr_orb(self, msg, i, inet=0):
|
|
101
|
+
""" Types 32 clock-ephemeris correction and covariance matrix """
|
|
102
|
+
slot, iodn = bs.unpack_from('u8u10', msg, i)
|
|
103
|
+
i += 18
|
|
104
|
+
dx, dy, dz, db = bs.unpack_from('s11s11s11s12', msg, i)
|
|
105
|
+
i += 45
|
|
106
|
+
dxd, dyd, dzd, dbd, t0 = bs.unpack_from('s8s8s8s9u13', msg, i)
|
|
107
|
+
i += 46
|
|
108
|
+
|
|
109
|
+
# i, C = self.decode_cov(msg, i)
|
|
110
|
+
i += 99
|
|
111
|
+
# dfrei, dRcorr = bs.unpack_from('u4u4', msg, i)
|
|
112
|
+
i += 8
|
|
113
|
+
|
|
114
|
+
sat = self.slot2sat(slot)
|
|
115
|
+
|
|
116
|
+
if sat == 0 or t0 % 2 == 0: # for DFMC SBAS only
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
if sat not in self.sat_n:
|
|
120
|
+
self.sat_n.append(sat)
|
|
121
|
+
|
|
122
|
+
dorb = np.zeros(3)
|
|
123
|
+
dvel = np.zeros(3)
|
|
124
|
+
|
|
125
|
+
dorb[0] = dx*0.0625
|
|
126
|
+
dorb[1] = dy*0.0625
|
|
127
|
+
dorb[2] = dz*0.0625
|
|
128
|
+
|
|
129
|
+
dclk = db*0.03125
|
|
130
|
+
|
|
131
|
+
dvel[0] = dxd*0.00048828
|
|
132
|
+
dvel[1] = dyd*0.00048828
|
|
133
|
+
dvel[2] = dzd*0.00048828
|
|
134
|
+
|
|
135
|
+
ddft = dbd*0.00024414
|
|
136
|
+
|
|
137
|
+
tow = self.tow0 + t0*16.0
|
|
138
|
+
self.time = self.adjust_time_week(
|
|
139
|
+
gpst2time(self.week, tow), self.time0)
|
|
140
|
+
|
|
141
|
+
self.lc[0].iode[sat] = iodn
|
|
142
|
+
self.lc[0].dorb[sat] = -dorb
|
|
143
|
+
self.lc[0].dclk[sat] = dclk
|
|
144
|
+
self.lc[0].dvel[sat] = -dvel
|
|
145
|
+
self.lc[0].ddft[sat] = ddft
|
|
146
|
+
|
|
147
|
+
self.iodssr = 0
|
|
148
|
+
self.lc[0].cstat |= (1 << sCType.CLOCK) | (1 << sCType.ORBIT)
|
|
149
|
+
self.lc[0].t0[sat] = {
|
|
150
|
+
sCType.CLOCK: self.time0, sCType.ORBIT: self.time0}
|
|
151
|
+
|
|
152
|
+
self.iodssr_c[sCType.CLOCK] = self.iodssr
|
|
153
|
+
self.iodssr_c[sCType.ORBIT] = self.iodssr
|
|
154
|
+
|
|
155
|
+
if self.monlevel > 0:
|
|
156
|
+
self.fh.write("{:.1f} {:3s} {:3d}\n"
|
|
157
|
+
.format(tow, sat2id(sat), iodn))
|
|
158
|
+
|
|
159
|
+
return i
|
|
160
|
+
|
|
161
|
+
def decode_cssr(self, msg, i=0):
|
|
162
|
+
|
|
163
|
+
_, mt = bs.unpack_from('u4u6', msg, i)
|
|
164
|
+
i += 10
|
|
165
|
+
|
|
166
|
+
if mt == 32:
|
|
167
|
+
self.subtype = sCSSR.ORBIT
|
|
168
|
+
i = self.decode_cssr_orb(msg, i)
|
|
169
|
+
|
|
170
|
+
if self.monlevel > 3:
|
|
171
|
+
if self.time != -1:
|
|
172
|
+
_, tow = time2gpst(self.time)
|
|
173
|
+
else:
|
|
174
|
+
tow = -1
|
|
175
|
+
self.fh.write("mt={:2d} tow={:6.1f}\n"
|
|
176
|
+
.format(mt, tow))
|