cssrlib 0.2.1__tar.gz → 0.8.0__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.
Files changed (45) hide show
  1. {cssrlib-0.2.1 → cssrlib-0.8.0}/MANIFEST.in +13 -13
  2. cssrlib-0.8.0/PKG-INFO +97 -0
  3. cssrlib-0.8.0/README.md +82 -0
  4. {cssrlib-0.2.1 → cssrlib-0.8.0}/pyproject.toml +6 -6
  5. {cssrlib-0.2.1 → cssrlib-0.8.0}/setup.cfg +31 -31
  6. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/__init__.py +8 -8
  7. cssrlib-0.8.0/src/cssrlib/cssr_bds.py +380 -0
  8. cssrlib-0.8.0/src/cssrlib/cssr_has.py +141 -0
  9. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/cssrlib.py +1254 -924
  10. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/data/3034078M1.21O +1532 -1532
  11. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/data/SEPT078M.21P +1946 -1946
  12. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/data/SEPT078M1.21O +1474 -1474
  13. cssrlib-0.8.0/src/cssrlib/ephemeris.py +332 -0
  14. cssrlib-0.8.0/src/cssrlib/gnss.py +1393 -0
  15. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/mlambda.py +205 -206
  16. cssrlib-0.8.0/src/cssrlib/peph.py +1374 -0
  17. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/plot.py +87 -85
  18. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/pntpos.py +125 -99
  19. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/ppp.py +436 -424
  20. cssrlib-0.8.0/src/cssrlib/pppigs.py +926 -0
  21. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/ppprtk.py +416 -408
  22. cssrlib-0.8.0/src/cssrlib/pppssr.py +1045 -0
  23. cssrlib-0.8.0/src/cssrlib/rawnav.py +522 -0
  24. cssrlib-0.8.0/src/cssrlib/rinex.py +868 -0
  25. cssrlib-0.8.0/src/cssrlib/rtcm.py +1651 -0
  26. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/rtk.py +546 -551
  27. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/test/test_eph.py +50 -50
  28. cssrlib-0.8.0/src/cssrlib/test/test_gnss.py +57 -0
  29. cssrlib-0.8.0/src/cssrlib/test/test_peph.py +198 -0
  30. cssrlib-0.8.0/src/cssrlib/test/test_rnx.py +59 -0
  31. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/test/test_rtk.py +115 -70
  32. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/tlesim.py +68 -68
  33. cssrlib-0.8.0/src/cssrlib.egg-info/PKG-INFO +97 -0
  34. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib.egg-info/SOURCES.txt +10 -0
  35. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib.egg-info/not-zip-safe +1 -1
  36. cssrlib-0.2.1/PKG-INFO +0 -39
  37. cssrlib-0.2.1/README.md +0 -20
  38. cssrlib-0.2.1/src/cssrlib/ephemeris.py +0 -179
  39. cssrlib-0.2.1/src/cssrlib/gnss.py +0 -652
  40. cssrlib-0.2.1/src/cssrlib/rinex.py +0 -241
  41. cssrlib-0.2.1/src/cssrlib.egg-info/PKG-INFO +0 -39
  42. {cssrlib-0.2.1 → cssrlib-0.8.0}/LICENSE +0 -0
  43. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib/data/30340780.21q +0 -0
  44. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib.egg-info/dependency_links.txt +0 -0
  45. {cssrlib-0.2.1 → cssrlib-0.8.0}/src/cssrlib.egg-info/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
- include src/cssrlib/data/*.21?
2
- include src/cssrlib/test/test*.py
3
-
4
- graft docs
5
- prune docs/build
6
-
7
- prune tests
8
- prune example
9
- prune .github
10
-
11
- global-exclude *.py[cod]
12
- global-exclude __pycache__
13
- global-exclude *.egg-info
1
+ include src/cssrlib/data/*.21?
2
+ include src/cssrlib/test/test*.py
3
+
4
+ graft docs
5
+ prune docs/build
6
+
7
+ prune tests
8
+ prune example
9
+ prune .github
10
+
11
+ global-exclude *.py[cod]
12
+ global-exclude __pycache__
13
+ global-exclude *.egg-info
cssrlib-0.8.0/PKG-INFO ADDED
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.1
2
+ Name: cssrlib
3
+ Version: 0.8.0
4
+ Summary: Compact SSR Library for PPP/PPP-RTK
5
+ Home-page: https://github.com/hirokawa/cssrlib
6
+ Author: Rui Hirokawa
7
+ Author-email: rui.hirokawa@gmail.com
8
+ Project-URL: Bug Tracker, https://github.com/hirokawa/cssrlib/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+
16
+ *************************
17
+ CSSRlib - Toolkit for PPP-RTK/RTK in Python using Compact SSR
18
+ *************************
19
+
20
+ # What is CSSRlib?
21
+
22
+ CSSRLIB is a open toolkit in Python for high accuracy GNSS positioning. It supports SSR (State-Space Representation) based positioning for PPP (Precise Point Positioning) or PPP-RTK (Realtime Kinematic), while also supporting RTK. The goal of the CSSRlib toolkit is to provide an easy-to-understand open implementation to learn PPP/PPP-RTK positioning provided by satellite-based open PPP/PPP-RTK services such as QZSS CLAS, Galileo HAS, and BeiDou 3 PPP. It also supports ground based open service by IGS. The code is based on RTKlib.
23
+
24
+ It supports the following open format:
25
+
26
+ - The observation data and ephemeris in RINEX
27
+ - The PPP/PPP-RTK correction data in RTCM SSR, IGS SSR, Compact SSR, ...
28
+ - The precise orbit/clock data in SP3 format.
29
+
30
+ ************************************************
31
+ Click this button for a quick demo in Google Colab
32
+
33
+ <a target="_blank" href="https://colab.research.google.com/github/rtklibexplorer/cssrlib/blob/new_sig/tutorials/cssrlib.ipynb">
34
+ <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
35
+ </a>
36
+
37
+ ************************************************
38
+
39
+ Prerequisites
40
+ =============
41
+ Additional python packages are required as prerequisites and can be installed via the following commands
42
+
43
+ ```
44
+ pip install bitstruct galois crccheck
45
+ pip install notebook numpy matplotlib
46
+ ```
47
+
48
+ Optionally, on linux, users can install the `cartopy` package
49
+
50
+ ```
51
+ pip install cartopy
52
+ ```
53
+
54
+ If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
55
+
56
+ ```
57
+ sudo apt-get install libgeos++-dev
58
+ ```
59
+
60
+ Install
61
+ =======
62
+
63
+ You can install the official version of CSSRlib using pip
64
+
65
+ ```
66
+ pip install cssrlib
67
+ ```
68
+
69
+ If you want to install the development version from this repository, first clone or download the sources and then run
70
+
71
+ ```
72
+ pip install .
73
+ ```
74
+
75
+ in the root directory, where the ``setup.cfg`` file is located.
76
+
77
+ Testing
78
+ =======
79
+
80
+ Run orbit plot sample.
81
+
82
+ ```
83
+ python test_eph.py
84
+ ```
85
+
86
+ Run RTK sample.
87
+
88
+ ```
89
+ python test_rtk.py
90
+ ```
91
+
92
+ Other samples are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
93
+
94
+ - Galileo-HAS decoder
95
+ - BDS-PPP decoder
96
+ - Jupyter-Notebook including samples for RTK/PPP-RTK.
97
+
@@ -0,0 +1,82 @@
1
+ *************************
2
+ CSSRlib - Toolkit for PPP-RTK/RTK in Python using Compact SSR
3
+ *************************
4
+
5
+ # What is CSSRlib?
6
+
7
+ CSSRLIB is a open toolkit in Python for high accuracy GNSS positioning. It supports SSR (State-Space Representation) based positioning for PPP (Precise Point Positioning) or PPP-RTK (Realtime Kinematic), while also supporting RTK. The goal of the CSSRlib toolkit is to provide an easy-to-understand open implementation to learn PPP/PPP-RTK positioning provided by satellite-based open PPP/PPP-RTK services such as QZSS CLAS, Galileo HAS, and BeiDou 3 PPP. It also supports ground based open service by IGS. The code is based on RTKlib.
8
+
9
+ It supports the following open format:
10
+
11
+ - The observation data and ephemeris in RINEX
12
+ - The PPP/PPP-RTK correction data in RTCM SSR, IGS SSR, Compact SSR, ...
13
+ - The precise orbit/clock data in SP3 format.
14
+
15
+ ************************************************
16
+ Click this button for a quick demo in Google Colab
17
+
18
+ <a target="_blank" href="https://colab.research.google.com/github/rtklibexplorer/cssrlib/blob/new_sig/tutorials/cssrlib.ipynb">
19
+ <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
20
+ </a>
21
+
22
+ ************************************************
23
+
24
+ Prerequisites
25
+ =============
26
+ Additional python packages are required as prerequisites and can be installed via the following commands
27
+
28
+ ```
29
+ pip install bitstruct galois crccheck
30
+ pip install notebook numpy matplotlib
31
+ ```
32
+
33
+ Optionally, on linux, users can install the `cartopy` package
34
+
35
+ ```
36
+ pip install cartopy
37
+ ```
38
+
39
+ If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
40
+
41
+ ```
42
+ sudo apt-get install libgeos++-dev
43
+ ```
44
+
45
+ Install
46
+ =======
47
+
48
+ You can install the official version of CSSRlib using pip
49
+
50
+ ```
51
+ pip install cssrlib
52
+ ```
53
+
54
+ If you want to install the development version from this repository, first clone or download the sources and then run
55
+
56
+ ```
57
+ pip install .
58
+ ```
59
+
60
+ in the root directory, where the ``setup.cfg`` file is located.
61
+
62
+ Testing
63
+ =======
64
+
65
+ Run orbit plot sample.
66
+
67
+ ```
68
+ python test_eph.py
69
+ ```
70
+
71
+ Run RTK sample.
72
+
73
+ ```
74
+ python test_rtk.py
75
+ ```
76
+
77
+ Other samples are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
78
+
79
+ - Galileo-HAS decoder
80
+ - BDS-PPP decoder
81
+ - Jupyter-Notebook including samples for RTK/PPP-RTK.
82
+
@@ -1,6 +1,6 @@
1
- [build-system]
2
- requires = [
3
- "setuptools>=42",
4
- "wheel"
5
- ]
6
- build-backend = "setuptools.build_meta"
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=42",
4
+ "wheel"
5
+ ]
6
+ build-backend = "setuptools.build_meta"
@@ -1,31 +1,31 @@
1
- [metadata]
2
- name = cssrlib
3
- version = 0.2.1
4
- author = Rui Hirokawa
5
- author_email = rui.hirokawa@gmail.com
6
- description = Compact SSR Library for PPP/PPP-RTK
7
- long_description = file: README.md
8
- long_description_content_type = text/markdown
9
- url = https://github.com/hirokawa/cssrlib
10
- project_urls =
11
- Bug Tracker = https://github.com/hirokawa/cssrlib/issues
12
- classifiers =
13
- Programming Language :: Python :: 3
14
- License :: OSI Approved :: MIT License
15
- Operating System :: OS Independent
16
-
17
- [options]
18
- zip_safe = False
19
- include_package_data = True
20
- package_dir =
21
- = src
22
- packages = find:
23
- python_requires = >=3.8
24
-
25
- [options.packages.find]
26
- where = src
27
-
28
- [egg_info]
29
- tag_build =
30
- tag_date = 0
31
-
1
+ [metadata]
2
+ name = cssrlib
3
+ version = 0.8.0
4
+ author = Rui Hirokawa
5
+ author_email = rui.hirokawa@gmail.com
6
+ description = Compact SSR Library for PPP/PPP-RTK
7
+ long_description = file: README.md
8
+ long_description_content_type = text/markdown
9
+ url = https://github.com/hirokawa/cssrlib
10
+ project_urls =
11
+ Bug Tracker = https://github.com/hirokawa/cssrlib/issues
12
+ classifiers =
13
+ Programming Language :: Python :: 3
14
+ License :: OSI Approved :: MIT License
15
+ Operating System :: OS Independent
16
+
17
+ [options]
18
+ zip_safe = False
19
+ include_package_data = True
20
+ package_dir =
21
+ = src
22
+ packages = find:
23
+ python_requires = >=3.10
24
+
25
+ [options.packages.find]
26
+ where = src
27
+
28
+ [egg_info]
29
+ tag_build =
30
+ tag_date = 0
31
+
@@ -1,8 +1,8 @@
1
-
2
- from cssrlib.gnss import (gpst2time,epoch2time,ecef2pos,
3
- prn2sat)
4
- from cssrlib.gnss import (rCST,uGNSS,uSIG,Eph,gtime_t)
5
- from cssrlib.rinex import (rnxdec)
6
-
7
- __version__ = '2021.08.21'
8
- __author__ = 'Rui Hirokawa'
1
+
2
+ from cssrlib.gnss import (gpst2time,epoch2time,ecef2pos,
3
+ prn2sat)
4
+ from cssrlib.gnss import (rCST,uGNSS,uSIG,Eph,gtime_t)
5
+ from cssrlib.rinex import (rnxdec)
6
+
7
+ __version__ = '2021.08.21'
8
+ __author__ = 'Rui Hirokawa'
@@ -0,0 +1,380 @@
1
+ """
2
+ BDS PPP correction data decoder
3
+
4
+ [1] BeiDou Navigation Satellite System Signal In Space Interface Control Document
5
+ Precise Point Positioning Service Signal PPP-B2b (Version 1.0), 2020
6
+ """
7
+
8
+ import numpy as np
9
+ import bitstruct as bs
10
+ from cssrlib.cssrlib import cssr, sCSSR, sCSSRTYPE, sGNSS, prn2sat, sCType
11
+ from cssrlib.gnss import bdt2time, bdt2gpst, uGNSS, uSIG, uTYP, rSigRnx
12
+
13
+
14
+ class cssr_bds(cssr):
15
+ def __init__(self, foutname=None):
16
+ super().__init__(foutname)
17
+ self.MAXNET = 1
18
+ self.cssrmode = sCSSRTYPE.BDS_PPP
19
+ self.nsig_max = 8
20
+ self.iodp = -1
21
+ self.iodp_p = -1
22
+
23
+ def ssig2rsig(self, sys: sGNSS, utyp: uTYP, ssig):
24
+ gps_tbl = {
25
+ 0: uSIG.L1C,
26
+ 1: uSIG.L1P,
27
+ 4: uSIG.L1L,
28
+ 5: uSIG.L1X,
29
+ 7: uSIG.L2L,
30
+ 8: uSIG.L2X,
31
+ 11: uSIG.L5I,
32
+ 12: uSIG.L5Q,
33
+ 13: uSIG.L5X,
34
+ }
35
+ glo_tbl = {
36
+ 0: uSIG.L1C,
37
+ 1: uSIG.L1P,
38
+ 2: uSIG.L2C,
39
+ }
40
+
41
+ gal_tbl = {
42
+ 1: uSIG.L1B,
43
+ 2: uSIG.L1C,
44
+ 4: uSIG.L5Q,
45
+ 5: uSIG.L5I,
46
+ 7: uSIG.L7I,
47
+ 8: uSIG.L7Q,
48
+ 11: uSIG.L6C,
49
+ }
50
+
51
+ bds_tbl = {
52
+ 0: uSIG.L2I,
53
+ 1: uSIG.L1D,
54
+ 2: uSIG.L1P,
55
+ 4: uSIG.L5D,
56
+ 5: uSIG.L5P,
57
+ 7: uSIG.L7D,
58
+ 8: uSIG.L7P,
59
+ 12: uSIG.L6I,
60
+ }
61
+
62
+ usig_tbl_ = {
63
+ uGNSS.GPS: gps_tbl,
64
+ uGNSS.GLO: glo_tbl,
65
+ uGNSS.GAL: gal_tbl,
66
+ uGNSS.BDS: bds_tbl,
67
+ }
68
+
69
+ usig_tbl = usig_tbl_[sys]
70
+ return rSigRnx(sys, utyp, usig_tbl[ssig])
71
+
72
+ def sval(self, u, n, scl):
73
+ """ calculate signed value based on n-bit int, lsb """
74
+ invalid = -2**(n-1)
75
+ dnu = -(2**(n-1)-1) # this value seems to be invalid
76
+ y = np.nan if u == invalid or u == dnu else u*scl
77
+ return y
78
+
79
+ def slot2prn(self, slot):
80
+ prn = 0
81
+ sys = uGNSS.NONE
82
+ if slot >= 1 and slot <= 63:
83
+ prn = slot
84
+ sys = uGNSS.BDS
85
+ elif slot <= 100:
86
+ prn = slot-63
87
+ sys = uGNSS.GPS
88
+ elif slot <= 137:
89
+ prn = slot-100
90
+ sys = uGNSS.GAL
91
+ elif slot <= 174:
92
+ prn = slot-137
93
+ sys = uGNSS.GLO
94
+ return sys, prn
95
+
96
+ def decode_head(self, msg, i, st=-1):
97
+ self.tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
98
+ i += 23
99
+
100
+ if st == sCSSR.MASK:
101
+ self.iodssr = iodssr
102
+
103
+ if self.tow0 >= 0:
104
+ self.tow = self.tow0+self.tod
105
+ if self.week >= 0:
106
+ self.time = bdt2gpst(bdt2time(self.week, self.tow))
107
+
108
+ head = {'uint': 0, 'mi': 0, 'iodssr': iodssr}
109
+ return head, i
110
+
111
+ def add_gnss(self, mask, blen, gnss):
112
+ prn, nsat = self.decode_mask(mask, blen)
113
+ self.nsat_g[gnss] = nsat
114
+ self.nsat_n += nsat
115
+ if nsat > 0:
116
+ self.ngnss += 1
117
+ sys = self.gnss2sys(gnss)
118
+ for k in range(0, nsat):
119
+ sat = prn2sat(sys, prn[k])
120
+ self.sys_n.append(sys)
121
+ self.sat_n.append(sat)
122
+ self.gnss_n.append(gnss)
123
+
124
+ def decode_cssr_mask(self, msg, i):
125
+ """decode MT1 Mask message """
126
+ head, i = self.decode_head(msg, i, sCSSR.MASK)
127
+
128
+ self.iodp = bs.unpack_from('u4', msg, i)[0]
129
+ i += 4
130
+
131
+ mask_bds, mask_gps, mask_gal, mask_glo = \
132
+ bs.unpack_from('u63u37u37u37', msg, i)
133
+ i += 174
134
+
135
+ if self.iodp != self.iodp_p:
136
+ self.sat_n_p = self.sat_n
137
+ self.iodssr_p = self.iodssr
138
+ self.sig_n_p = self.sig_n
139
+ self.iodp_p = self.iodp
140
+
141
+ self.nsat_n = 0
142
+ self.nsig_n = []
143
+ self.sys_n = []
144
+ self.gnss_n = []
145
+ self.sat_n = []
146
+ self.nsig_total = 0
147
+ self.sig_n = []
148
+ self.nm_idx = np.zeros(self.SYSMAX, dtype=int)
149
+ self.ngnss = 0
150
+ # self.gnss_idx = np.zeros(self.ngnss, dtype=int)
151
+ self.nsat_g = np.zeros(self.SYSMAX, dtype=int)
152
+
153
+ self.add_gnss(mask_bds, 63, sGNSS.BDS)
154
+ self.add_gnss(mask_gps, 37, sGNSS.GPS)
155
+ self.add_gnss(mask_gal, 37, sGNSS.GAL)
156
+ self.add_gnss(mask_glo, 37, sGNSS.GLO)
157
+
158
+ inet = 0
159
+ self.lc[inet].dclk = np.ones(self.nsat_n)*np.nan
160
+ self.lc[inet].dorb = np.ones((self.nsat_n, 3))*np.nan
161
+ self.lc[inet].iode = np.zeros(self.nsat_n, dtype=int)
162
+ self.lc[inet].iodc = np.zeros(self.nsat_n, dtype=int)
163
+ self.lc[inet].iodc_c = np.zeros(self.nsat_n, dtype=int)
164
+ self.lc[inet].cbias = np.ones((self.nsat_n, self.nsig_max))*np.nan
165
+ self.nsig_n = np.ones(self.nsat_n, dtype=int)*self.nsig_max
166
+ self.sig_n = -1*np.ones((self.nsat_n, self.nsig_max), dtype=int)
167
+ self.ura = np.zeros(self.nsat_n)
168
+
169
+ # fallback for inconsistent clock update
170
+ self.lc[inet].dclk_p = np.ones(self.nsat_n)*np.nan
171
+ self.lc[inet].iodc_c_p = np.zeros(self.nsat_n, dtype=int)
172
+
173
+ self.iodssr = head['iodssr']
174
+
175
+ self.lc[0].cstat |= (1 << sCType.MASK)
176
+ self.lc[0].t0[sCType.MASK] = self.time
177
+ return i
178
+
179
+ def decode_cssr_orb_sat(self, msg, i, inet, sat_n):
180
+ slot, iodn, iodc, dx, dy, dz, ucls, uval = \
181
+ bs.unpack_from('u9u10u3s15s13s13u3u3', msg, i)
182
+ i += 69
183
+ sys, prn = self.slot2prn(slot)
184
+ if sys == uGNSS.NONE:
185
+ return i
186
+ sat = prn2sat(sys, prn)
187
+ if sat not in sat_n:
188
+ return i
189
+ idx = np.where(sat == sat_n)[0][0]
190
+
191
+ if (sys == uGNSS.GPS) or (sys == uGNSS.BDS):
192
+ iodn = iodn & 0xff # IODC -> IODE
193
+
194
+ self.lc[inet].iode[idx] = iodn
195
+ self.lc[inet].iodc[idx] = iodc
196
+ self.lc[inet].dorb[idx, 0] = self.sval(dx, 15, self.dorb_scl[0])
197
+ self.lc[inet].dorb[idx, 1] = self.sval(dy, 13, self.dorb_scl[1])
198
+ self.lc[inet].dorb[idx, 2] = self.sval(dz, 13, self.dorb_scl[2])
199
+ self.ura[idx] = self.quality_idx(ucls, uval)
200
+ return i
201
+
202
+ def decode_cssr_orb(self, msg, i, inet=0):
203
+ """decode MT2 orbit + URA message """
204
+ head, i = self.decode_head(msg, i)
205
+ sat_n = np.array(self.sat_n)
206
+
207
+ if self.iodssr != head['iodssr']:
208
+ return -1
209
+
210
+ for k in range(6):
211
+ i = self.decode_cssr_orb_sat(msg, i, inet, sat_n)
212
+
213
+ self.iodssr_c[sCType.ORBIT] = head['iodssr']
214
+ self.lc[inet].cstat |= (1 << sCType.ORBIT)
215
+ self.lc[inet].t0[sCType.ORBIT] = self.time
216
+ i += 19
217
+ return i
218
+
219
+ def decode_cssr_cbias(self, msg, i, inet=0):
220
+ """decode MT3 Code Bias Correction message """
221
+ head, i = self.decode_head(msg, i)
222
+ nsat = self.nsat_n
223
+ self.flg_net = False
224
+ if self.iodssr != head['iodssr']:
225
+ return -1
226
+
227
+ sat_n = np.array(self.sat_n)
228
+ nsat = bs.unpack_from('u5', msg, i)[0]
229
+ i += 5
230
+
231
+ for k in range(nsat):
232
+ slot, nsig = bs.unpack_from('u9u4', msg, i)
233
+ i += 13
234
+ sys, prn = self.slot2prn(slot)
235
+ sat = prn2sat(sys, prn)
236
+ idx = np.where(sat == sat_n)[0]
237
+ if len(idx) == 0:
238
+ continue
239
+ for j in range(0, nsig):
240
+ sig, cb = bs.unpack_from('u4s12', msg, i)
241
+ i += 16
242
+ self.sig_n[idx, j] = sig
243
+ self.lc[inet].cbias[idx, j] = self.sval(cb, 12, self.cb_scl)
244
+
245
+ self.iodssr_c[sCType.CBIAS] = head['iodssr']
246
+ self.lc[inet].cstat |= (1 << sCType.CBIAS)
247
+ self.lc[inet].t0[sCType.CBIAS] = self.time
248
+ return i
249
+
250
+ def decode_cssr_clk_sat(self, msg, i, inet, idx):
251
+ """ decode clock correction for satellite """
252
+ iodc, dclk = bs.unpack_from('u3s15', msg, i)
253
+ i += 18
254
+ if iodc != self.lc[inet].iodc_c[idx]:
255
+ self.lc[inet].iodc_c_p[idx] = self.lc[inet].iodc_c[idx]
256
+ self.lc[inet].dclk_p[idx] = self.lc[inet].dclk[idx]
257
+ self.lc[inet].iodc_c[idx] = iodc
258
+ # note: the sign of the clock correction reversed
259
+ self.lc[inet].dclk[idx] = -self.sval(dclk, 15, self.dclk_scl)
260
+ return i
261
+
262
+ def decode_cssr_clk(self, msg, i, inet=0):
263
+ """decode MT4 Clock Correction message """
264
+ head, i = self.decode_head(msg, i)
265
+ if self.iodssr != head['iodssr']:
266
+ return -1
267
+
268
+ iodp, st1 = bs.unpack_from('u4u5', msg, i)
269
+ i += 9
270
+ if iodp != self.iodp:
271
+ i += 23*18+10
272
+ return i
273
+ for k in range(23):
274
+ idx = st1*23+k
275
+ if idx < self.nsat_n:
276
+ i = self.decode_cssr_clk_sat(msg, i, inet, idx)
277
+
278
+ self.iodssr_c[sCType.CLOCK] = head['iodssr']
279
+ self.lc[inet].cstat |= (1 << sCType.CLOCK)
280
+ self.lc[inet].t0[sCType.CLOCK] = self.time
281
+ i += 10
282
+ return i
283
+
284
+ def decode_cssr_ura(self, msg, i):
285
+ """decode MT5 URA message """
286
+ head, i = self.decode_head(msg, i)
287
+ if self.iodssr != head['iodssr']:
288
+ return -1
289
+
290
+ iodp, st2 = bs.unpack_from('u4u3', msg, i)
291
+ i += 7
292
+
293
+ for k in range(70):
294
+ v = bs.unpack_from_dict('u3u3', ['class', 'val'], msg, i)
295
+ i += 6
296
+ idx = st2*70+k
297
+ if idx < self.nsat_n:
298
+ self.ura[idx] = self.quality_idx(v['class'], v['val'])
299
+
300
+ self.lc[0].cstat |= (1 << sCType.URA)
301
+ self.lc[0].t0[sCType.URA] = self.time
302
+ return i
303
+
304
+ def decode_cssr_comb1(self, msg, i, inet=0):
305
+ """decode MT6 combined message #1 """
306
+ numc, numo = bs.unpack_from('u5u3', msg, i)
307
+ sat_n = np.array(self.sat_n)
308
+
309
+ if numc > 0:
310
+ tod, _, iodssr, iodp, slot_s = \
311
+ bs.unpack_from('u17u4u2u4u9', msg, i)
312
+ i += 36
313
+ for k in range(numc):
314
+ idx = slot_s+k
315
+ i = self.decode_cssr_clk_sat(msg, i, inet, idx)
316
+
317
+ if numo > 0:
318
+ tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
319
+ i += 23
320
+ for k in range(numo):
321
+ i = self.decode_cssr_orb_sat(msg, i, inet, sat_n)
322
+
323
+ return i
324
+
325
+ def decode_cssr_comb2(self, msg, i, inet=0):
326
+ """decode MT7 combined message #2 """
327
+ numc, numo = bs.unpack_from('u5u3', msg, i)
328
+ sat_n = np.array(self.sat_n)
329
+
330
+ if numc > 0:
331
+ tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
332
+ i += 23
333
+ for k in range(numc):
334
+ slot = bs.unpack_from('u9', msg, i)
335
+ i += 9
336
+ sys, prn = self.slot2prn(slot)
337
+ sat = prn2sat(sys, prn)
338
+ idx = np.where(sat == sat_n)[0]
339
+ i = self.decode_cssr_clk_sat(msg, i, inet, idx)
340
+
341
+ if numo > 0:
342
+ tod, _, iodssr = bs.unpack_from('u17u4u2', msg, i)
343
+ i += 23
344
+ for k in range(numo):
345
+ i = self.decode_cssr_orb_sat(msg, i, inet, sat_n)
346
+
347
+ return i
348
+
349
+ def decode_cssr(self, msg, i=0):
350
+ mt = bs.unpack_from('u6', msg, i)[0]
351
+ i += 6
352
+
353
+ if mt == 1:
354
+ self.subtype = sCSSR.MASK
355
+ i = self.decode_cssr_mask(msg, i)
356
+ elif mt == 2:
357
+ self.subtype = sCSSR.ORBIT
358
+ i = self.decode_cssr_orb(msg, i)
359
+ if self.monlevel > 0 and self.fh is not None:
360
+ self.out_log()
361
+ elif mt == 3:
362
+ self.subtype = sCSSR.CBIAS
363
+ i = self.decode_cssr_cbias(msg, i)
364
+ if self.monlevel > 0 and self.fh is not None:
365
+ self.out_log()
366
+ elif mt == 4:
367
+ self.subtype = sCSSR.CLOCK
368
+ i = self.decode_cssr_clk(msg, i)
369
+ if self.monlevel > 0 and self.fh is not None:
370
+ self.out_log()
371
+ elif mt == 5:
372
+ self.subtype = sCSSR.URA
373
+ i = self.decode_cssr_ura(msg, i)
374
+ elif mt == 6:
375
+ i = self.decode_cssr_comb1(msg, i)
376
+ elif mt == 7:
377
+ i = self.decode_cssr_comb2(msg, i)
378
+
379
+ if self.monlevel > 0:
380
+ print(" mt={:2d} tow={:6.1f}".format(mt, self.tow))