cssrlib 1.0.1__tar.gz → 1.2.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 (49) hide show
  1. {cssrlib-1.0.1 → cssrlib-1.2.0}/PKG-INFO +33 -18
  2. cssrlib-1.0.1/src/cssrlib.egg-info/PKG-INFO → cssrlib-1.2.0/README.md +20 -26
  3. cssrlib-1.2.0/pyproject.toml +27 -0
  4. {cssrlib-1.0.1 → cssrlib-1.2.0}/setup.cfg +1 -1
  5. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/__init__.py +1 -1
  6. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/cssr_has.py +80 -2
  7. cssrlib-1.2.0/src/cssrlib/cssr_mdc.py +262 -0
  8. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/cssr_pvs.py +23 -24
  9. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/cssrlib.py +72 -31
  10. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/dgps.py +13 -3
  11. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/ephemeris.py +20 -4
  12. cssrlib-1.2.0/src/cssrlib/ewss.py +1496 -0
  13. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/gnss.py +101 -19
  14. cssrlib-1.2.0/src/cssrlib/mlambda.py +379 -0
  15. cssrlib-1.2.0/src/cssrlib/osnma.py +977 -0
  16. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/peph.py +36 -54
  17. cssrlib-1.2.0/src/cssrlib/plot.py +185 -0
  18. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/pntpos.py +7 -6
  19. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/ppp.py +10 -3
  20. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/ppprtk.py +1 -1
  21. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/pppssr.py +96 -18
  22. cssrlib-1.2.0/src/cssrlib/qznma.py +885 -0
  23. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/rawnav.py +712 -150
  24. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/rinex.py +467 -129
  25. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/rtcm.py +1055 -33
  26. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/sbas.py +45 -37
  27. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/test/test_peph.py +15 -5
  28. cssrlib-1.0.1/README.md → cssrlib-1.2.0/src/cssrlib.egg-info/PKG-INFO +41 -11
  29. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib.egg-info/SOURCES.txt +5 -0
  30. cssrlib-1.2.0/src/cssrlib.egg-info/requires.txt +9 -0
  31. cssrlib-1.0.1/pyproject.toml +0 -6
  32. cssrlib-1.0.1/src/cssrlib/mlambda.py +0 -205
  33. cssrlib-1.0.1/src/cssrlib/plot.py +0 -87
  34. {cssrlib-1.0.1 → cssrlib-1.2.0}/LICENSE +0 -0
  35. {cssrlib-1.0.1 → cssrlib-1.2.0}/MANIFEST.in +0 -0
  36. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/cssr_bds.py +0 -0
  37. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/data/30340780.21q +0 -0
  38. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/data/3034078M1.21O +0 -0
  39. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/data/SEPT078M.21P +0 -0
  40. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/data/SEPT078M1.21O +0 -0
  41. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/rtk.py +0 -0
  42. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/test/test_eph.py +0 -0
  43. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/test/test_gnss.py +0 -0
  44. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/test/test_rnx.py +0 -0
  45. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/test/test_rtk.py +0 -0
  46. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib/tlesim.py +0 -0
  47. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib.egg-info/dependency_links.txt +0 -0
  48. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib.egg-info/not-zip-safe +0 -0
  49. {cssrlib-1.0.1 → cssrlib-1.2.0}/src/cssrlib.egg-info/top_level.txt +0 -0
@@ -1,25 +1,31 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: cssrlib
3
- Version: 1.0.1
3
+ Version: 1.2.0
4
4
  Summary: Python Toolkit for PPP/PPP-RTK positioning
5
5
  Home-page: https://github.com/hirokawa/cssrlib
6
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
7
+ Author-email: Rui Hirokawa <rui.hirokawa@gmail.com>
12
8
  Requires-Python: >=3.10
13
9
  Description-Content-Type: text/markdown
14
10
  License-File: LICENSE
11
+ Requires-Dist: scipy
12
+ Requires-Dist: bitstruct
13
+ Requires-Dist: galois
14
+ Requires-Dist: crccheck
15
+ Requires-Dist: notebook
16
+ Requires-Dist: numpy
17
+ Requires-Dist: matplotlib
18
+ Requires-Dist: cartopy
19
+ Requires-Dist: pysolid
20
+ Dynamic: license-file
15
21
 
16
- *************************
17
22
  CSSRlib - Toolkit for PPP-RTK/RTK in Python using Compact SSR
18
- *************************
23
+ =============
19
24
 
20
- # What is CSSRlib?
25
+ What is CSSRlib?
26
+ ----------------
21
27
 
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.
28
+ 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
29
 
24
30
  It supports the following open format:
25
31
 
@@ -27,17 +33,15 @@ It supports the following open format:
27
33
  - The PPP/PPP-RTK correction data in RTCM SSR, IGS SSR, Compact SSR, ...
28
34
  - The precise orbit/clock data in SP3 format.
29
35
 
30
- ************************************************
31
36
  Click this button for a quick demo in Google Colab
32
37
 
33
38
  <a target="_blank" href="https://colab.research.google.com/github/hirokawa/cssrlib/blob/main/tutorials/cssrlib.ipynb">
34
39
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
35
40
  </a>
36
41
 
37
- ************************************************
38
42
 
39
43
  Prerequisites
40
- =============
44
+ -------------
41
45
  Additional python packages are required as prerequisites and can be installed via the following command
42
46
 
43
47
  ```
@@ -50,8 +54,18 @@ If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
50
54
  sudo apt-get install libgeos++-dev
51
55
  ```
52
56
 
57
+ *NOTE*: the module `pysolid` is used for the computation of solid Earth tides. It contains a hard-coded leap second table with an expiration date, which is set to the next possible injection date of a leap second at the time of the last update. The table is frequently updated by the package maintainers. The following warning is issed when the expiration date is exceeded:
58
+
59
+ > Mild Warning -- time crossed leap second table boundaries. Boundary edge value used instead
60
+
61
+ If you encounter this warning when executing CSSRlib scripts, it can most likely be fixed by updating `pysolid` to the most recent version using
62
+
63
+ ```
64
+ pip install -upgrade pysolid
65
+ ```
66
+
53
67
  Install
54
- =======
68
+ -------
55
69
 
56
70
  You can install the official version of CSSRlib using pip
57
71
 
@@ -68,7 +82,7 @@ pip install .
68
82
  in the root directory, where the ``setup.cfg`` file is located.
69
83
 
70
84
  Testing
71
- =======
85
+ -------
72
86
 
73
87
  Run orbit plot sample.
74
88
 
@@ -82,14 +96,15 @@ Run RTK sample.
82
96
  python test_rtk.py
83
97
  ```
84
98
 
85
- Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
99
+ Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including:
86
100
 
87
101
  - Galileo-HAS PPP (SIS/IDD) processing example
88
102
  - BDS-PPP processing example
89
103
  - QZSS MADOCA-PPP processing example
90
104
  - QZSS CLAS PPP-RTK processing example
91
105
  - IGS (SP3+BIAS) PPP-AR processing example
92
- - (experimental) PPP via SouthPAN (PVS) processing example
106
+ - PPP via SouthPAN (PVS) processing example
107
+ - JPL GDGPS (GPSHAS) processing example
93
108
  - Binary message parser for Septentrio receiver (Mosaic/PolaRX5)
94
109
 
95
110
 
@@ -1,25 +1,10 @@
1
- Metadata-Version: 2.1
2
- Name: cssrlib
3
- Version: 1.0.1
4
- Summary: Python Toolkit for PPP/PPP-RTK positioning
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
1
  CSSRlib - Toolkit for PPP-RTK/RTK in Python using Compact SSR
18
- *************************
2
+ =============
19
3
 
20
- # What is CSSRlib?
4
+ What is CSSRlib?
5
+ ----------------
21
6
 
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.
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.
23
8
 
24
9
  It supports the following open format:
25
10
 
@@ -27,17 +12,15 @@ It supports the following open format:
27
12
  - The PPP/PPP-RTK correction data in RTCM SSR, IGS SSR, Compact SSR, ...
28
13
  - The precise orbit/clock data in SP3 format.
29
14
 
30
- ************************************************
31
15
  Click this button for a quick demo in Google Colab
32
16
 
33
17
  <a target="_blank" href="https://colab.research.google.com/github/hirokawa/cssrlib/blob/main/tutorials/cssrlib.ipynb">
34
18
  <img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
35
19
  </a>
36
20
 
37
- ************************************************
38
21
 
39
22
  Prerequisites
40
- =============
23
+ -------------
41
24
  Additional python packages are required as prerequisites and can be installed via the following command
42
25
 
43
26
  ```
@@ -50,8 +33,18 @@ If the installation of `cartopy` fails, try installing `libgeos++-dev` first.
50
33
  sudo apt-get install libgeos++-dev
51
34
  ```
52
35
 
36
+ *NOTE*: the module `pysolid` is used for the computation of solid Earth tides. It contains a hard-coded leap second table with an expiration date, which is set to the next possible injection date of a leap second at the time of the last update. The table is frequently updated by the package maintainers. The following warning is issed when the expiration date is exceeded:
37
+
38
+ > Mild Warning -- time crossed leap second table boundaries. Boundary edge value used instead
39
+
40
+ If you encounter this warning when executing CSSRlib scripts, it can most likely be fixed by updating `pysolid` to the most recent version using
41
+
42
+ ```
43
+ pip install -upgrade pysolid
44
+ ```
45
+
53
46
  Install
54
- =======
47
+ -------
55
48
 
56
49
  You can install the official version of CSSRlib using pip
57
50
 
@@ -68,7 +61,7 @@ pip install .
68
61
  in the root directory, where the ``setup.cfg`` file is located.
69
62
 
70
63
  Testing
71
- =======
64
+ -------
72
65
 
73
66
  Run orbit plot sample.
74
67
 
@@ -82,14 +75,15 @@ Run RTK sample.
82
75
  python test_rtk.py
83
76
  ```
84
77
 
85
- Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including :
78
+ Other samples with dataset are also available in a separate repository [`cssrlib-data`](https://github.com/hirokawa/cssrlib-data) including:
86
79
 
87
80
  - Galileo-HAS PPP (SIS/IDD) processing example
88
81
  - BDS-PPP processing example
89
82
  - QZSS MADOCA-PPP processing example
90
83
  - QZSS CLAS PPP-RTK processing example
91
84
  - IGS (SP3+BIAS) PPP-AR processing example
92
- - (experimental) PPP via SouthPAN (PVS) processing example
85
+ - PPP via SouthPAN (PVS) processing example
86
+ - JPL GDGPS (GPSHAS) processing example
93
87
  - Binary message parser for Septentrio receiver (Mosaic/PolaRX5)
94
88
 
95
89
 
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=42",
4
+ "wheel"
5
+ ]
6
+ build-backend = "setuptools.build_meta"
7
+
8
+ [project]
9
+ name = "cssrlib"
10
+ version = "1.2.0"
11
+ description = "Python Toolkit for PPP/PPP-RTK positioning"
12
+ authors = [
13
+ {name="Rui Hirokawa", email="rui.hirokawa@gmail.com"},
14
+ ]
15
+ readme = "README.md"
16
+ requires-python = ">=3.10"
17
+ dependencies = [
18
+ "scipy",
19
+ "bitstruct",
20
+ "galois",
21
+ "crccheck",
22
+ "notebook",
23
+ "numpy",
24
+ "matplotlib",
25
+ "cartopy",
26
+ "pysolid",
27
+ ]
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = cssrlib
3
- version = 1.0.1
3
+ version = 1.2.0
4
4
  author = Rui Hirokawa
5
5
  author_email = rui.hirokawa@gmail.com
6
6
  description = Python Toolkit for PPP/PPP-RTK positioning
@@ -4,5 +4,5 @@ from cssrlib.gnss import (gpst2time,epoch2time,ecef2pos,
4
4
  from cssrlib.gnss import (rCST,uGNSS,uSIG,Eph,gtime_t)
5
5
  from cssrlib.rinex import (rnxdec)
6
6
 
7
- __version__ = '2021.08.21'
7
+ __version__ = '2025.10.14'
8
8
  __author__ = 'Rui Hirokawa'
@@ -11,6 +11,7 @@ import bitstruct as bs
11
11
  import galois
12
12
  from cssrlib.cssrlib import cssr, sCSSR, sCSSRTYPE
13
13
  from cssrlib.gnss import gpst2time
14
+ from binascii import unhexlify
14
15
 
15
16
 
16
17
  class cssr_has(cssr):
@@ -27,8 +28,6 @@ class cssr_has(cssr):
27
28
  self.pb_blen = 11
28
29
  self.pb_scl = 0.01 # cycles
29
30
 
30
- self.GF = galois.GF(256)
31
-
32
31
  def sval(self, u, n, scl):
33
32
  """ calculate signed value based on n-bit int, lsb """
34
33
  invalid = -2**(n-1)
@@ -59,6 +58,7 @@ class cssr_has(cssr):
59
58
  return i
60
59
 
61
60
  def decode_head(self, msg, i, st=-1):
61
+ """ decode header part of HAS messages """
62
62
 
63
63
  if st == sCSSR.MASK:
64
64
  ui = 0
@@ -75,6 +75,8 @@ class cssr_has(cssr):
75
75
  return head, i
76
76
 
77
77
  def decode_cssr(self, msg, i=0):
78
+ """ decode HAS messages """
79
+
78
80
  # Galileo HAS-SIS only defines MT=1, MT=4073 is CSSR message used in the
79
81
  # Galileo HAS test dataset
80
82
  #
@@ -127,7 +129,29 @@ class cssr_has(cssr):
127
129
  if self.monlevel > 0 and self.fh is not None:
128
130
  self.out_log()
129
131
 
132
+
133
+ class cnav_msg():
134
+ """ class to handle Galileo E6 (CNAV) message """
135
+
136
+ def __init__(self):
137
+ self.mid_decoded = []
138
+ self.mid_ = -1
139
+ self.ms_ = -1
140
+ self.rec = []
141
+ self.has_pages = np.zeros((255, 53), dtype=int)
142
+ self.gMat = None
143
+ self.GF = galois.GF(256)
144
+
145
+ self.icnt = 0
146
+ self.msgtype = -1
147
+
148
+ self.monlevel = 0
149
+
150
+ def load_gmat(self, file_gm):
151
+ self.gMat = np.genfromtxt(file_gm, dtype="u1", delimiter=",")
152
+
130
153
  def decode_has_header(self, buff, i):
154
+ """ decode header of HAS pages (obsoleted) """
131
155
  if bs.unpack_from('u24', buff, i)[0] == 0xaf3bc3:
132
156
  return 0, 0, 0, 0, 0
133
157
 
@@ -146,3 +170,57 @@ class cssr_has(cssr):
146
170
  HASmsg = np.array(Md).tobytes()
147
171
 
148
172
  return HASmsg
173
+
174
+ def decode_cnav(self, tow, vi):
175
+ """ decode Galileo CNAV message """
176
+
177
+ HASmsg = None
178
+
179
+ for vn in vi:
180
+ buff = unhexlify(vn['nav'])
181
+ i = 14
182
+ if bs.unpack_from('u24', buff, i)[0] == 0xaf3bc3:
183
+ continue
184
+ hass, res = bs.unpack_from('u2u2', buff, i)
185
+ i += 4
186
+ if hass >= 2: # 0:test,1:operational,2:res,3:dnu
187
+ continue
188
+ mt, mid, ms, pid = bs.unpack_from('u2u5u5u8', buff, i)
189
+
190
+ self.msgtype = mt
191
+ ms += 1
192
+ i += 20
193
+
194
+ if self.mid_ == -1 and mid not in self.mid_decoded:
195
+ self.mid_ = mid
196
+ self.ms_ = ms
197
+ if mid == self.mid_ and pid-1 not in self.rec:
198
+ page = bs.unpack_from('u8'*53, buff, i)
199
+ self.rec += [pid-1]
200
+ self.has_pages[pid-1, :] = page
201
+
202
+ if self.monlevel >= 2:
203
+ print(f"{mt} {mid} {ms} {pid}")
204
+
205
+ if len(self.rec) >= self.ms_:
206
+ if self.monlevel >= 2:
207
+ print(" data collected mid={:2d} ms={:2d} tow={:.0f}"
208
+ .format(self.mid_, self.ms_, tow))
209
+ HASmsg = self.decode_has_page(
210
+ self.rec, self.has_pages, self.gMat, self.ms_)
211
+ self.rec = []
212
+
213
+ self.mid_decoded += [self.mid_]
214
+ self.mid_ = -1
215
+ if len(self.mid_decoded) > 10:
216
+ self.mid_decoded = self.mid_decoded[1:]
217
+ else:
218
+ self.icnt += 1
219
+ if self.icnt > 2*self.ms_ and self.mid_ != -1:
220
+ self.icnt = 0
221
+ if self.monlevel >= 2:
222
+ print(f" reset mid={self.mid_} ms={self.ms_} tow={tow}")
223
+ self.rec = []
224
+ self.mid_ = -1
225
+
226
+ return HASmsg
@@ -0,0 +1,262 @@
1
+ """
2
+ QZSS MADOCA-PPP correction data decoder
3
+
4
+ [1] Quasi-Zenith Satellite System Interface Specification Multi-GNSS
5
+ Advanced Orbit and Clock Augmentation - Precise Point Positioning
6
+ (IS-QZSS-MDC-004), 2025
7
+
8
+ """
9
+
10
+ import numpy as np
11
+ import bitstruct as bs
12
+ from cssrlib.cssrlib import cssr, sCSSRTYPE, sCSSR, local_corr, sCType
13
+ from cssrlib.gnss import gpst2time, uGNSS, prn2sat, rCST
14
+
15
+
16
+ class areaInfo():
17
+ def __init__(self, sid, latr, lonr, p1=0, p2=0):
18
+ self.sid = sid
19
+ self.latr = latr
20
+ self.lonr = lonr
21
+ if sid == 0:
22
+ self.lats = p1
23
+ self.lons = p2
24
+ elif sid == 1:
25
+ self.rng = p1
26
+
27
+
28
+ class ionoCorr():
29
+ def __init__(self):
30
+ self.t0 = None
31
+ self.qi = []
32
+ self.iodssr = 0
33
+ self.ct = 0
34
+ self.sat = []
35
+ self.c = np.zeros((6))
36
+
37
+
38
+ class cssr_mdc(cssr):
39
+ def __init__(self, foutname=None):
40
+ super().__init__(foutname)
41
+
42
+ self.cssrmode = sCSSRTYPE.QZS_MADOCA
43
+ self.buff = bytearray(250*10)
44
+
45
+ self.pnt = {}
46
+ self.ci = {}
47
+
48
+ self.area = -1
49
+ self.narea_t = {1: 8, 2: 16, 3: 5, 4: 1, 5: 8}
50
+ self.MAXNET = np.sum(list(self.narea_t.values()))
51
+
52
+ for inet in range(self.MAXNET+1):
53
+ self.lc.append(local_corr())
54
+ self.lc[inet].inet = inet
55
+ self.lc[inet].flg_trop = 0
56
+ self.lc[inet].flg_stec = 0
57
+ self.lc[inet].nsat_n = 0
58
+ self.lc[inet].t0 = {}
59
+
60
+ def find_grid_index(self, pos):
61
+ """ find region/area """
62
+
63
+ latd, lond = np.rad2deg(pos[0:2])
64
+ self.reg = self.area = -1
65
+
66
+ for reg in self.pnt.key():
67
+ for area in self.pnt[reg].key():
68
+ p = self.pnt[reg][area]
69
+ if p.sid == 0: # rectangle shape:
70
+ if p.latr-p.lats <= latd and latd <= p.latr+p.lats and \
71
+ p.lonr-p.lons <= lond and lond <= p.lonr+p.lons:
72
+ self.reg = reg
73
+ self.area = area
74
+ break
75
+ elif p.sid == 1: # circle
76
+ dn = (latd - p.latr)*rCST.D2R*rCST.RE_WGS84
77
+ de = (lond - p.lonr)*rCST.D2R * \
78
+ rCST.RE_WGS84*np.cos(p.lonr*rCST.D2R)
79
+ r = np.sqrt(dn**2+de**2)
80
+ if r <= p.rng:
81
+ self.reg = reg
82
+ self.area = area
83
+ break
84
+
85
+ inet = self.get_inet(self.reg, self.area)
86
+ return inet
87
+
88
+ def get_dpos(self, pos):
89
+ """ calculate position offset from reference """
90
+ if self.reg < 0 or self.area < 0:
91
+ print("get_dpos: region, area not defined.")
92
+ return 0, 0
93
+
94
+ latd, lond = np.rad2deg(pos[0:2])
95
+ p = self.pnt[self.reg][self.area]
96
+ dlat = latd - p.latr
97
+ dlon = lond - p.lonr
98
+
99
+ return dlat, dlon
100
+
101
+ def get_stec(self, dlat=0.0, dlon=0.0):
102
+ """ calculate STEC correction by interporation """
103
+ if self.inet < 0:
104
+ print("get_stec: region, area not defined.")
105
+ return 0.0
106
+
107
+ p = self.lc[self.inet]
108
+ # if p.inet_ref != self.iodssr:
109
+ # return 0.0
110
+ stec = np.zeros(self.nsat_n)
111
+
112
+ for i, sat in enumerate(self.sat_n):
113
+ stec[i] = [1, dlat, dlon, dlat*dlon, dlat**2, dlon**2]@p.ci[sat]
114
+
115
+ return stec
116
+
117
+ def decode_mdc_stec_area(self, buff, i=0):
118
+ """ decoder for MT1 - STEC Coverage Message """
119
+ tow, uid, mi, iodssr = bs.unpack_from('u20u4u1u4', buff, i)
120
+ i += 29
121
+ self.tow0 = tow//3600*3600
122
+ reg, alrt, len_, narea = bs.unpack_from('u8u1u16u5', buff, i)
123
+ i += 30
124
+ if reg not in self.pnt:
125
+ self.pnt[reg] = {}
126
+
127
+ for k in range(narea):
128
+ area, sid = bs.unpack_from('u5u1', buff, i)
129
+ i += 6
130
+
131
+ if sid == 0: # rectangle shape
132
+ latr, lonr, lats, lons = bs.unpack_from('s11u12u8u8', buff, i)
133
+ if self.monlevel > 2:
134
+ print(f"{reg} {area:2d} {sid} {latr*0.1:5.1f} "
135
+ f"{lonr*0.1:5.1f} {lats*0.1:3.1f} {lons*0.1:3.1f}")
136
+ self.pnt[reg][area] = areaInfo(
137
+ sid, latr*0.1, lonr*0.1, lats*0.1, lons*0.1)
138
+ else: # circle range
139
+ latr, lonr, rng = bs.unpack_from('s15u16u8', buff, i)
140
+ if self.monlevel > 2:
141
+ print(f"{reg} {area:2d} {sid} {latr*0.01:6.2f} "
142
+ f"{lonr*0.01:6.2f} {rng*10}")
143
+ self.pnt[reg][area] = areaInfo(
144
+ sid, latr*0.01, lonr*0.01, rng*10.0)
145
+ i += 39
146
+ return i
147
+
148
+ def get_inet(self, reg, area):
149
+ """ region, area to inet conversion """
150
+
151
+ inet = 0
152
+ for r in self.narea_t.keys():
153
+ if r >= reg:
154
+ break
155
+ inet += self.narea_t[r]
156
+
157
+ inet += area
158
+
159
+ return inet
160
+
161
+ def decode_mdc_stec_corr(self, buff, i=0):
162
+ """ decoder for MT2 - STEC Correction Message """
163
+ dtow, uid, mi, iodssr = bs.unpack_from('u12u4u1u4', buff, i)
164
+ i += 21
165
+ reg, area, stype_ = bs.unpack_from('u8u5u2', buff, i)
166
+ i += 15
167
+
168
+ nsat = bs.unpack_from('u5u5u5u5u5', buff, i)
169
+ i += 25
170
+ # gps, glo, gal, bds, qzss
171
+ sys_t = [uGNSS.GPS, uGNSS.GLO, uGNSS.GAL, uGNSS.BDS, uGNSS.QZS]
172
+
173
+ inet = self.get_inet(reg, area)
174
+
175
+ self.lc[inet].nsat_n = np.sum(nsat)
176
+ ci = {}
177
+ qi = {}
178
+ stype = {}
179
+ sat_ = []
180
+ j = 0
181
+ for gnss in range(5):
182
+ sys = sys_t[gnss]
183
+ for k in range(nsat[gnss]):
184
+ c01 = c10 = c11 = c02 = c20 = 0.0
185
+
186
+ prn, qi_, c00 = bs.unpack_from('u6u6s14', buff, i)
187
+ i += 26
188
+
189
+ if sys == uGNSS.QZS:
190
+ prn += 192
191
+ sat = prn2sat(sys, prn)
192
+ qi[sat] = qi_
193
+ stype[sat] = stype_
194
+
195
+ if stype_ > 0:
196
+ c01, c10 = bs.unpack_from('s12s12', buff, i)
197
+ i += 24
198
+ if stype_ > 1:
199
+ c11 = bs.unpack_from('s10', buff, i)[0]
200
+ i += 10
201
+ if stype_ > 2:
202
+ c02, c20 = bs.unpack_from('s8s8', buff, i)
203
+ i += 16
204
+
205
+ sat_ += [sat]
206
+ ci[sat] = np.array(
207
+ [c00*0.05, c01*0.02, c10*0.02, c11*0.02,
208
+ c02*5e-3, c20*5e-3])
209
+ j += 1
210
+
211
+ self.lc[inet].stype = stype
212
+ self.lc[inet].sat_n = sat_
213
+ self.lc[inet].ci = ci
214
+ self.lc[inet].stec_quality = qi
215
+
216
+ t0 = gpst2time(self.week, self.tow0+dtow)
217
+ self.set_t0(inet, 0, sCType.STEC, t0)
218
+ self.lc[inet].cstat |= (1 << sCType.STEC)
219
+
220
+ self.lc[inet].inet_ref = iodssr
221
+
222
+ return i
223
+
224
+ def decode_cssr(self, msg, i=0):
225
+ """decode Compact SSR message with MADOCA-PPP extension """
226
+ df = {'msgtype': 4073}
227
+ while df['msgtype'] in [1, 2, 4073]:
228
+ df = bs.unpack_from_dict('u12u4', ['msgtype', 'subtype'], msg, i)
229
+ i += 16
230
+ if df['msgtype'] not in [1, 2, 4073]:
231
+ return -1
232
+
233
+ self.subtype = df['subtype']
234
+ if df['msgtype'] == 4073: # Compact SSR
235
+ if self.subtype == sCSSR.MASK:
236
+ i = self.decode_cssr_mask(msg, i)
237
+ elif self.subtype == sCSSR.ORBIT: # orbit
238
+ i = self.decode_cssr_orb(msg, i)
239
+ elif self.subtype == sCSSR.CLOCK: # clock
240
+ i = self.decode_cssr_clk(msg, i)
241
+ elif self.subtype == sCSSR.CBIAS: # cbias
242
+ i = self.decode_cssr_cbias(msg, i)
243
+ elif self.subtype == sCSSR.PBIAS: # pbias
244
+ i = self.decode_cssr_pbias(msg, i)
245
+ elif self.subtype == sCSSR.BIAS: # bias
246
+ i = self.decode_cssr_bias(msg, i)
247
+ elif self.subtype == sCSSR.URA: # ura
248
+ i = self.decode_cssr_ura(msg, i)
249
+ elif df['msgtype'] in [1, 2] and df['subtype'] == 0:
250
+ if df['msgtype'] == 1: # MADOCA MT1
251
+ i = self.decode_mdc_stec_area(msg, i)
252
+ elif df['msgtype'] == 2: # MADOCA MT2
253
+ i = self.decode_mdc_stec_corr(msg, i)
254
+
255
+ if i <= 0:
256
+ return 0
257
+ if self.monlevel >= 2:
258
+ print(f"tow={int(self.tow):6d} msgtype={df['msgtype']:4d} "
259
+ f"subtype={self.subtype:2d} inet={self.inet:2d}")
260
+
261
+ if self.monlevel > 0 and self.fh is not None:
262
+ self.out_log()