pygnssutils 1.2.3__tar.gz → 1.2.4__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.
- {pygnssutils-1.2.3/src/pygnssutils.egg-info → pygnssutils-1.2.4}/PKG-INFO +7 -7
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/README.md +4 -4
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/pyproject.toml +2 -2
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/_version.py +1 -1
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rawnav.py +16 -12
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_conv.py +1 -1
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_conv_nav.py +123 -21
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_globals.py +6 -1
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_helpers.py +56 -1
- pygnssutils-1.2.4/src/pygnssutils/rinex_subframes_glo.py +136 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4/src/pygnssutils.egg-info}/PKG-INFO +7 -7
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils.egg-info/SOURCES.txt +1 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils.egg-info/requires.txt +2 -2
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_rinex.py +78 -57
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_rinex_defs.py +28 -16
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/LICENSE +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/setup.cfg +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/__init__.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/exceptions.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/globals.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssmqttclient.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssmqttclient_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssntripclient.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssntripclient_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssreader.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssserver.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssserver_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssstreamer.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/gnssstreamer_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/helpers.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/mqttmessage.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_conv_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_conv_met.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_conv_obs.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_subframes_bds.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_subframes_gal.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/rinex_subframes_gps.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils/socket_server.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils.egg-info/dependency_links.txt +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils.egg-info/entry_points.txt +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/src/pygnssutils.egg-info/top_level.txt +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_cli.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_gnssstreamer.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_rawnav.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_socketwrapper.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_sourcetable.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_static.py +0 -0
- {pygnssutils-1.2.3 → pygnssutils-1.2.4}/tests/test_stream.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygnssutils
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: GNSS Command Line Utilities
|
|
5
5
|
Author-email: Steve Smith <semuadmin@semuconsulting.com>
|
|
6
6
|
Maintainer-email: Steve Smith <semuadmin@semuconsulting.com>
|
|
@@ -35,10 +35,10 @@ Requires-Dist: paho-mqtt>=2.1.0
|
|
|
35
35
|
Requires-Dist: pyserial>=3.5
|
|
36
36
|
Requires-Dist: pyspartn>=1.0.8
|
|
37
37
|
Requires-Dist: pyubx2>=1.3.3
|
|
38
|
-
Requires-Dist: pynmeagps>=1.1.
|
|
38
|
+
Requires-Dist: pynmeagps>=1.1.5
|
|
39
39
|
Requires-Dist: pysbf2>=1.0.4
|
|
40
40
|
Requires-Dist: pyubxutils>=1.0.6
|
|
41
|
-
Requires-Dist: pyqgc>=0.
|
|
41
|
+
Requires-Dist: pyqgc>=1.0.0
|
|
42
42
|
Requires-Dist: pyunigps>=1.0.0
|
|
43
43
|
Dynamic: license-file
|
|
44
44
|
|
|
@@ -81,7 +81,7 @@ designated output stream.
|
|
|
81
81
|
a simple SPARTN IP (MQTT) Client which receives SPARTN correction data from an SPARTN IP location service and (optionally) sends this to a
|
|
82
82
|
designated output stream.
|
|
83
83
|
1. `SocketServer` class based on the native Python `ThreadingTCPServer`. Capable of operating in two modes - Socket Server or NTRIP Caster. Provides two alternate client request handler classes - `ClientHandler` (HTTP) or `ClientHandlerTLS` (HTTPS).
|
|
84
|
-
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB:
|
|
84
|
+
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB: RINEX conversion is currently an experimental work in progress (*contributions and feedback welcome*)**
|
|
85
85
|
|
|
86
86
|
The pygnssutils homepage is located at [https://github.com/semuconsulting/pygnssutils](https://github.com/semuconsulting/pygnssutils).
|
|
87
87
|
|
|
@@ -543,15 +543,15 @@ class pygnssutils.rinex_conv.RinexConvertor(app, rinex_version, rinex_type, gnss
|
|
|
543
543
|
|
|
544
544
|
A command line utility and Python class `RinexConverter` to convert binary GNSS data logs to RINEX text file format.
|
|
545
545
|
|
|
546
|
-
**NB: The current ALPHA release implements the following functionality:**
|
|
546
|
+
**NB: RINEX conversion is an experimental work in progress (*contributions and feedback welcome*). The current ALPHA release implements the following functionality:**
|
|
547
547
|
|
|
548
548
|
1. RINEX versions 3.05 and 4.02.
|
|
549
549
|
1. Convert binary UBX RXM-RAW or RXM-RAWX (raw observation) data from u-blox receivers (e.g. ZED-F9P) to RINEX Observation file format.
|
|
550
|
-
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
550
|
+
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2 & GLO L1OF**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
551
551
|
1. Convert RTCM3 Ephemerides messages (1019, 1020, 1041-1046) from any source (including NTRIP caster or RTK base station receiver) to RINEX Navigation file format.
|
|
552
552
|
1. Convert NMEA MWD (wind speed and direction) and XDR (temperature and pressure) sensor data to RINEX Meteorology file format.
|
|
553
553
|
|
|
554
|
-
A Graphical User Interface for this utility
|
|
554
|
+
A Graphical User Interface for this utility has been added to [PyGPSClient](https://github.com/semuconsulting/PyGPSClient).
|
|
555
555
|
|
|
556
556
|
Assuming the u-blox receiver is already configured to output raw observation (UBX-RXM-RAWX) and navigation subframe (UBX-RXM-SFRBX) data, a suitable input log file can be created using the pygnssutils `gnssstreamer` CLI utility e.g. ...
|
|
557
557
|
|
|
@@ -37,7 +37,7 @@ designated output stream.
|
|
|
37
37
|
a simple SPARTN IP (MQTT) Client which receives SPARTN correction data from an SPARTN IP location service and (optionally) sends this to a
|
|
38
38
|
designated output stream.
|
|
39
39
|
1. `SocketServer` class based on the native Python `ThreadingTCPServer`. Capable of operating in two modes - Socket Server or NTRIP Caster. Provides two alternate client request handler classes - `ClientHandler` (HTTP) or `ClientHandlerTLS` (HTTPS).
|
|
40
|
-
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB:
|
|
40
|
+
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB: RINEX conversion is currently an experimental work in progress (*contributions and feedback welcome*)**
|
|
41
41
|
|
|
42
42
|
The pygnssutils homepage is located at [https://github.com/semuconsulting/pygnssutils](https://github.com/semuconsulting/pygnssutils).
|
|
43
43
|
|
|
@@ -499,15 +499,15 @@ class pygnssutils.rinex_conv.RinexConvertor(app, rinex_version, rinex_type, gnss
|
|
|
499
499
|
|
|
500
500
|
A command line utility and Python class `RinexConverter` to convert binary GNSS data logs to RINEX text file format.
|
|
501
501
|
|
|
502
|
-
**NB: The current ALPHA release implements the following functionality:**
|
|
502
|
+
**NB: RINEX conversion is an experimental work in progress (*contributions and feedback welcome*). The current ALPHA release implements the following functionality:**
|
|
503
503
|
|
|
504
504
|
1. RINEX versions 3.05 and 4.02.
|
|
505
505
|
1. Convert binary UBX RXM-RAW or RXM-RAWX (raw observation) data from u-blox receivers (e.g. ZED-F9P) to RINEX Observation file format.
|
|
506
|
-
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
506
|
+
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2 & GLO L1OF**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
507
507
|
1. Convert RTCM3 Ephemerides messages (1019, 1020, 1041-1046) from any source (including NTRIP caster or RTK base station receiver) to RINEX Navigation file format.
|
|
508
508
|
1. Convert NMEA MWD (wind speed and direction) and XDR (temperature and pressure) sensor data to RINEX Meteorology file format.
|
|
509
509
|
|
|
510
|
-
A Graphical User Interface for this utility
|
|
510
|
+
A Graphical User Interface for this utility has been added to [PyGPSClient](https://github.com/semuconsulting/PyGPSClient).
|
|
511
511
|
|
|
512
512
|
Assuming the u-blox receiver is already configured to output raw observation (UBX-RXM-RAWX) and navigation subframe (UBX-RXM-SFRBX) data, a suitable input log file can be created using the pygnssutils `gnssstreamer` CLI utility e.g. ...
|
|
513
513
|
|
|
@@ -47,11 +47,11 @@ navigation data:
|
|
|
47
47
|
|
|
48
48
|
https://www.u-blox.com/sites/default/files/ZED-F9P_IntegrationManual_UBX-18010802.pdf
|
|
49
49
|
|
|
50
|
-
NB: Alpha
|
|
50
|
+
NB: Alpha release currently implements:
|
|
51
51
|
- GPS LNAV, CNAV
|
|
52
52
|
- GAL FNAV, INAV
|
|
53
|
-
- BDS D1
|
|
54
|
-
|
|
53
|
+
- BDS D1, D2
|
|
54
|
+
- GLO L1OF
|
|
55
55
|
|
|
56
56
|
Created on 20 Apr 2026
|
|
57
57
|
|
|
@@ -136,9 +136,10 @@ class RawNav:
|
|
|
136
136
|
self._gnss = gnss
|
|
137
137
|
self._svid = svid
|
|
138
138
|
self._sigcode = sigcode
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
if gnss != "R":
|
|
140
|
+
self.wn = -1
|
|
141
|
+
self.toc = -1
|
|
142
|
+
self.tow = -1
|
|
142
143
|
self._subframeacq = 0
|
|
143
144
|
self._msb = {}
|
|
144
145
|
self._isb = {}
|
|
@@ -603,16 +604,18 @@ class RawNavReader:
|
|
|
603
604
|
subframe = 0
|
|
604
605
|
subframeid = 0
|
|
605
606
|
subframepageid = 0
|
|
607
|
+
freqid = data.freqId
|
|
606
608
|
|
|
607
|
-
# for GLO, subframe = 85 bits,
|
|
608
|
-
#
|
|
609
|
-
|
|
609
|
+
# for GLO, subframe = 85 bits,
|
|
610
|
+
# 3 * 32 bit dwrds with 11 bits padding at end,
|
|
611
|
+
# plus a receiver-generated 4th dwrd containing superframe and frame ids
|
|
612
|
+
if sigcode in ("1C",): # GLO L1OF
|
|
610
613
|
for i in range(numw):
|
|
611
614
|
wrd = getattr(data, f"dwrd_{i+1:02d}")
|
|
612
615
|
subframe += wrd << (32 * (numw - 1 - i))
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
+
# strip 4th dwrd, leaving 85 bit subframe
|
|
617
|
+
subframe = (subframe >> 43) & 0x1FFFFFFFFFFFFFFFFFFFFF # 2**85-1
|
|
618
|
+
subframeid = (subframe >> 80) & 0b01111
|
|
616
619
|
|
|
617
620
|
return {
|
|
618
621
|
"gnss": gnss,
|
|
@@ -621,6 +624,7 @@ class RawNavReader:
|
|
|
621
624
|
"subframeid": subframeid,
|
|
622
625
|
"subframepageid": subframepageid,
|
|
623
626
|
"subframe": subframe,
|
|
627
|
+
"freqid": freqid,
|
|
624
628
|
}
|
|
625
629
|
|
|
626
630
|
def _process_rxm_sfrbx_sba(
|
|
@@ -327,7 +327,7 @@ class RinexConverter:
|
|
|
327
327
|
TypeError,
|
|
328
328
|
ValueError,
|
|
329
329
|
):
|
|
330
|
-
self.logger.exception(
|
|
330
|
+
self.logger.exception("RINEX NAV Conversion error")
|
|
331
331
|
res = RINEX_ERROR
|
|
332
332
|
except KeyboardInterrupt:
|
|
333
333
|
self.logger.warning("Terminated by user")
|
|
@@ -8,7 +8,6 @@ Converts NAV message data to RINEX Navigation text format.
|
|
|
8
8
|
NB: Alpha release currently limited to following data sources:
|
|
9
9
|
|
|
10
10
|
- RawNav objects containing data collated from UBX RXM-SFRBX messages
|
|
11
|
-
(GPS LNAV/CNAV, GAL FNAV,INAV, BDS D1 only)
|
|
12
11
|
- RTCM3 ephemerides messages 1019, 1020, 1041-1046 e.g. from RTK receiver
|
|
13
12
|
or NTRIP data stream
|
|
14
13
|
|
|
@@ -52,6 +51,7 @@ from pygnssutils.rinex_globals import (
|
|
|
52
51
|
ION,
|
|
53
52
|
IRN,
|
|
54
53
|
KLOB,
|
|
54
|
+
L1OF,
|
|
55
55
|
LNAV,
|
|
56
56
|
NAV,
|
|
57
57
|
NEQUICK,
|
|
@@ -75,12 +75,15 @@ from pygnssutils.rinex_helpers import ( # format_timefirstlast,
|
|
|
75
75
|
format_sto,
|
|
76
76
|
format_time_corr,
|
|
77
77
|
get_epoch,
|
|
78
|
+
get_epoch_glo,
|
|
78
79
|
get_fithours,
|
|
79
80
|
get_svcode,
|
|
81
|
+
glotk2sec,
|
|
80
82
|
gpsura2m,
|
|
81
83
|
)
|
|
82
84
|
from pygnssutils.rinex_subframes_bds import BDS_SUBFRAMEACQ_MAP
|
|
83
85
|
from pygnssutils.rinex_subframes_gal import GAL_SUBFRAMEACQ_MAP
|
|
86
|
+
from pygnssutils.rinex_subframes_glo import GLO_SUBFRAMEACQ_MAP
|
|
84
87
|
from pygnssutils.rinex_subframes_gps import GPS_SUBFRAMEACQ_MAP
|
|
85
88
|
|
|
86
89
|
CLKBIAS = "clkbias"
|
|
@@ -268,6 +271,11 @@ class RinexConverterNavigation:
|
|
|
268
271
|
sfrmap = BDS_SUBFRAMEACQ_MAP[D2]
|
|
269
272
|
formatter = self._format_rawnav_bds_d1d2
|
|
270
273
|
kwargs = {"d1d2": sfrdata.get("d1d2", 0)}
|
|
274
|
+
elif gnss == GLO:
|
|
275
|
+
if sigcode in ("1C",):
|
|
276
|
+
sfrmap = GLO_SUBFRAMEACQ_MAP[L1OF]
|
|
277
|
+
formatter = self._format_rawnav_glo_l1of
|
|
278
|
+
kwargs = {"freqid": sfrdata.get("freqid", 0)}
|
|
271
279
|
# elif other gnss/sigcode, as and when I get to it TODO
|
|
272
280
|
|
|
273
281
|
if sfrmap is None or formatter is None:
|
|
@@ -874,8 +882,8 @@ class RinexConverterNavigation:
|
|
|
874
882
|
raw NAV subframe sources.
|
|
875
883
|
"""
|
|
876
884
|
|
|
877
|
-
self._navdata[(data.svcode, data.
|
|
878
|
-
nvd = self._navdata[(data.svcode, data.
|
|
885
|
+
self._navdata[(data.svcode, data.iode)] = {}
|
|
886
|
+
nvd = self._navdata[(data.svcode, data.iode)]
|
|
879
887
|
|
|
880
888
|
epoch, wn_cont = get_epoch(wno=data.wn, tow=data.tow, gnss=data.gnss)
|
|
881
889
|
self.__app.set_current_epoch(epoch, NAV)
|
|
@@ -927,7 +935,7 @@ class RinexConverterNavigation:
|
|
|
927
935
|
|
|
928
936
|
if self._rinex_version < RINEX4:
|
|
929
937
|
if self._timecorrflag:
|
|
930
|
-
self._format_timecorr_3(data)
|
|
938
|
+
self._format_timecorr_3(data, 2)
|
|
931
939
|
if self._ionocorrflag:
|
|
932
940
|
self._format_ionocorr_3(data)
|
|
933
941
|
else: # RINEX 4.02
|
|
@@ -953,7 +961,7 @@ class RinexConverterNavigation:
|
|
|
953
961
|
raw NAV subframe sources.
|
|
954
962
|
"""
|
|
955
963
|
|
|
956
|
-
self._navdata[(data.svcode, data.top)] = {} #
|
|
964
|
+
self._navdata[(data.svcode, data.top)] = {} # have assumed top => iode
|
|
957
965
|
nvd = self._navdata[(data.svcode, data.top)]
|
|
958
966
|
|
|
959
967
|
epoch, wn_cont = get_epoch(wno=data.wn, tow=data.tow, gnss=data.gnss)
|
|
@@ -1016,7 +1024,7 @@ class RinexConverterNavigation:
|
|
|
1016
1024
|
|
|
1017
1025
|
if self._rinex_version < RINEX4:
|
|
1018
1026
|
if self._timecorrflag:
|
|
1019
|
-
self._format_timecorr_3(data)
|
|
1027
|
+
self._format_timecorr_3(data, 2)
|
|
1020
1028
|
if self._ionocorrflag:
|
|
1021
1029
|
self._format_ionocorr_3(data)
|
|
1022
1030
|
else: # RINEX 4.02
|
|
@@ -1129,7 +1137,7 @@ class RinexConverterNavigation:
|
|
|
1129
1137
|
|
|
1130
1138
|
if self._rinex_version < RINEX4:
|
|
1131
1139
|
if self._timecorrflag:
|
|
1132
|
-
self._format_timecorr_3(data)
|
|
1140
|
+
self._format_timecorr_3(data, 5)
|
|
1133
1141
|
if self._ionocorrflag:
|
|
1134
1142
|
self._format_ionocorr_3(data)
|
|
1135
1143
|
else: # RINEX 4.02
|
|
@@ -1157,8 +1165,8 @@ class RinexConverterNavigation:
|
|
|
1157
1165
|
"""
|
|
1158
1166
|
|
|
1159
1167
|
d1d2 = kwargs.get("d1d2", 0)
|
|
1160
|
-
self._navdata[(data.svcode, data.
|
|
1161
|
-
nvd = self._navdata[(data.svcode, data.
|
|
1168
|
+
self._navdata[(data.svcode, data.aode)] = {}
|
|
1169
|
+
nvd = self._navdata[(data.svcode, data.aode)]
|
|
1162
1170
|
|
|
1163
1171
|
epoch, wn_cont = get_epoch(wno=data.wn, tow=data.tow, gnss=data.gnss)
|
|
1164
1172
|
self.__app.set_current_epoch(epoch, NAV)
|
|
@@ -1210,7 +1218,7 @@ class RinexConverterNavigation:
|
|
|
1210
1218
|
|
|
1211
1219
|
if self._rinex_version < RINEX4:
|
|
1212
1220
|
if self._timecorrflag:
|
|
1213
|
-
self._format_timecorr_3(data)
|
|
1221
|
+
self._format_timecorr_3(data, 7)
|
|
1214
1222
|
if self._ionocorrflag:
|
|
1215
1223
|
self._format_ionocorr_3(data)
|
|
1216
1224
|
else: # RINEX 4.02
|
|
@@ -1230,24 +1238,107 @@ class RinexConverterNavigation:
|
|
|
1230
1238
|
data=data,
|
|
1231
1239
|
)
|
|
1232
1240
|
|
|
1233
|
-
def
|
|
1241
|
+
def _format_rawnav_glo_l1of(self, data: RawNav, **kwargs):
|
|
1242
|
+
"""
|
|
1243
|
+
Format RawNav GLO L1OF (FDMA) broadcast orbit blocks.
|
|
1244
|
+
|
|
1245
|
+
:param RawNav data: RawNav object containing data \
|
|
1246
|
+
collated from UBX RXM-SFRBX messages or other \
|
|
1247
|
+
raw NAV subframe sources.
|
|
1248
|
+
"""
|
|
1249
|
+
|
|
1250
|
+
freqid = kwargs.get("freqid", 0)
|
|
1251
|
+
self._navdata[(data.svcode, data.tb)] = {} # have assumed tb => iode
|
|
1252
|
+
nvd = self._navdata[(data.svcode, data.tb)]
|
|
1253
|
+
|
|
1254
|
+
epoch = get_epoch_glo(data.nt, data.n4, data.tk)
|
|
1255
|
+
nd = (epoch.weekday() + 1) % 7 # GPS week Sunday = 0
|
|
1256
|
+
self.__app.set_current_epoch(epoch, NAV)
|
|
1257
|
+
nvd[EPOCH] = epoch
|
|
1258
|
+
nvd[RECTYPE] = "FDMA"
|
|
1259
|
+
nvd[CLKBIAS] = -data.tauntb # clock bias (sec)
|
|
1260
|
+
nvd[CLKDRIFT] = data.gammantb # clock relative freq bias (sec)
|
|
1261
|
+
nvd[CLKRATE] = glotk2sec(data.tk) + (nd * 86400) # - msg timeframe (s)
|
|
1262
|
+
nvd[BOD] = []
|
|
1263
|
+
nvb = nvd[BOD]
|
|
1264
|
+
for _ in range(4): # broadcast orbit data blocks * 7
|
|
1265
|
+
nvb.append(["", "", "", ""]) # 4X,4D19.12
|
|
1266
|
+
# BROADCAST ORBIT - 1
|
|
1267
|
+
nvb[0][0] = data.xntb # - pos (km)
|
|
1268
|
+
nvb[0][1] = data.xntbdot # - vel (km/s)
|
|
1269
|
+
nvb[0][2] = data.xntbdot2 # - acc (km/s2)
|
|
1270
|
+
nvb[0][3] = (data.bn >> 2) & 0b1 # - health
|
|
1271
|
+
# BROADCAST ORBIT - 2
|
|
1272
|
+
nvb[1][0] = data.yntb # - pos (km)
|
|
1273
|
+
nvb[1][1] = data.yntbdot # - vel (km/s)
|
|
1274
|
+
nvb[1][2] = data.yntbdot2 # - acc (km/s2)
|
|
1275
|
+
nvb[1][3] = freqid # - freq id
|
|
1276
|
+
# BROADCAST ORBIT - 3
|
|
1277
|
+
nvb[2][0] = data.zntb # - pos (km)
|
|
1278
|
+
nvb[2][1] = data.zntbdot # - vel (km/s)
|
|
1279
|
+
nvb[2][2] = data.zntbdot2 # - acc (km/s2)
|
|
1280
|
+
nvb[2][3] = data.en # - age of operation info (days)
|
|
1281
|
+
health = (
|
|
1282
|
+
(data.m << 6)
|
|
1283
|
+
+ (data.p4 << 5)
|
|
1284
|
+
+ (data.p3 << 4)
|
|
1285
|
+
+ (data.p2 << 3)
|
|
1286
|
+
+ (data.p1 << 1)
|
|
1287
|
+
+ data.p
|
|
1288
|
+
)
|
|
1289
|
+
nvb[3][0] = health # - health status flags
|
|
1290
|
+
nvb[3][1] = data.deltataun # - L1/L2 group delay diff (sec)
|
|
1291
|
+
nvb[3][2] = data.ft # - URAI (GLO-M/K only)
|
|
1292
|
+
nvb[3][3] = data.ln << 2 # - health flags
|
|
1293
|
+
|
|
1294
|
+
if self._rinex_version < RINEX4:
|
|
1295
|
+
if self._timecorrflag:
|
|
1296
|
+
self._format_timecorr_3(data, 3)
|
|
1297
|
+
# if self._ionocorrflag:
|
|
1298
|
+
# self._format_ionocorr_3(data)
|
|
1299
|
+
else: # RINEX 4.02
|
|
1300
|
+
if self._timecorrflag:
|
|
1301
|
+
nvd[STO] = self._format_timecorr_4(
|
|
1302
|
+
msgtype="FDMA",
|
|
1303
|
+
msgsubtype="",
|
|
1304
|
+
timecode="GLUT",
|
|
1305
|
+
utcid="UTC(SU)",
|
|
1306
|
+
data=data,
|
|
1307
|
+
)
|
|
1308
|
+
# if self._ionocorrflag:
|
|
1309
|
+
# nvd[ION] = self._format_ionocorr_4(
|
|
1310
|
+
# msgtype="IFNV", msgsubtype="", model=NEQUICK, data=data
|
|
1311
|
+
# )
|
|
1312
|
+
|
|
1313
|
+
def _format_timecorr_3(self, data: RawNav, source: int = 0):
|
|
1234
1314
|
"""
|
|
1235
1315
|
Format RINEX 3 ime correction blocks.
|
|
1236
1316
|
|
|
1237
1317
|
RINEX 3 places these as TIME SYSTEM CORR header lines.
|
|
1238
1318
|
|
|
1239
1319
|
:param RawNav data: data containing time corrections
|
|
1320
|
+
:param int source: time correction source
|
|
1240
1321
|
"""
|
|
1241
1322
|
|
|
1323
|
+
if data.gnss == GLO:
|
|
1324
|
+
a0 = -data.tauc
|
|
1325
|
+
a1 = 0
|
|
1326
|
+
timeref = 0
|
|
1327
|
+
weekno = 0
|
|
1328
|
+
else:
|
|
1329
|
+
a0 = data.a0
|
|
1330
|
+
a1 = data.a1
|
|
1331
|
+
timeref = data.toc
|
|
1332
|
+
weekno = data.wn
|
|
1242
1333
|
timecode = f"{RINEXGNSSR[data.gnss][0:2]}UT"
|
|
1243
1334
|
self._timecorr[timecode] = format_time_corr(
|
|
1244
1335
|
corrtype=timecode,
|
|
1245
1336
|
svcode=data.svcode,
|
|
1246
|
-
source=
|
|
1247
|
-
timeref=
|
|
1248
|
-
weekno=
|
|
1249
|
-
a0=
|
|
1250
|
-
a1=
|
|
1337
|
+
source=source,
|
|
1338
|
+
timeref=timeref,
|
|
1339
|
+
weekno=weekno,
|
|
1340
|
+
a0=a0,
|
|
1341
|
+
a1=a1,
|
|
1251
1342
|
)
|
|
1252
1343
|
|
|
1253
1344
|
def _format_timecorr_4(
|
|
@@ -1267,7 +1358,18 @@ class RinexConverterNavigation:
|
|
|
1267
1358
|
:rtype: str
|
|
1268
1359
|
"""
|
|
1269
1360
|
|
|
1270
|
-
|
|
1361
|
+
if data.gnss == GLO:
|
|
1362
|
+
a0 = -data.tauc
|
|
1363
|
+
a1 = 0
|
|
1364
|
+
a2 = 0
|
|
1365
|
+
epoch = get_epoch_glo(data.nt, data.n4, data.tk)
|
|
1366
|
+
tot = 0
|
|
1367
|
+
else:
|
|
1368
|
+
a0 = data.a0
|
|
1369
|
+
a1 = data.a1
|
|
1370
|
+
a2 = getattr(data, "a2", 0)
|
|
1371
|
+
epoch, _ = get_epoch(wno=data.wn, tow=data.tow, gnss=data.gnss)
|
|
1372
|
+
tot = data.toc
|
|
1271
1373
|
return format_sto(
|
|
1272
1374
|
svcode=data.svcode,
|
|
1273
1375
|
msgtype=msgtype,
|
|
@@ -1276,10 +1378,10 @@ class RinexConverterNavigation:
|
|
|
1276
1378
|
timecode=timecode,
|
|
1277
1379
|
sbasid="",
|
|
1278
1380
|
utcid=utcid,
|
|
1279
|
-
tot=
|
|
1280
|
-
a0=
|
|
1281
|
-
a1=
|
|
1282
|
-
a2=
|
|
1381
|
+
tot=tot,
|
|
1382
|
+
a0=a0,
|
|
1383
|
+
a1=a1,
|
|
1384
|
+
a2=a2,
|
|
1283
1385
|
)
|
|
1284
1386
|
|
|
1285
1387
|
def _format_ionocorr_3(self, data: RawNav):
|
|
@@ -34,6 +34,7 @@ EPOCH0_GPS = datetime(1980, 1, 6, 0, 0, 0, tzinfo=timezone.utc)
|
|
|
34
34
|
EPOCH0_IRN = datetime(1999, 8, 22, 0, 0, 0, tzinfo=timezone.utc)
|
|
35
35
|
EPOCHMAX = datetime(9999, 12, 31, tzinfo=timezone.utc)
|
|
36
36
|
EPOCHMIN = datetime(1900, 1, 1, tzinfo=timezone.utc)
|
|
37
|
+
FDMA = "FDMA"
|
|
37
38
|
FNAV = "FNAV"
|
|
38
39
|
GAL = "E"
|
|
39
40
|
GLO = "R"
|
|
@@ -42,6 +43,8 @@ INAV = "INAV"
|
|
|
42
43
|
ION = "ION"
|
|
43
44
|
IRN = "I"
|
|
44
45
|
KLOB = "KLOBUCHAR"
|
|
46
|
+
L1OF = "L1OF"
|
|
47
|
+
L2OF = "L2OF"
|
|
45
48
|
LEAPS0 = datetime(1900, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
|
|
46
49
|
LNAV = "LNAV"
|
|
47
50
|
MET = "M"
|
|
@@ -51,7 +54,7 @@ NAV = "N"
|
|
|
51
54
|
NEQUICK = "NEQUICK"
|
|
52
55
|
OBS = "O"
|
|
53
56
|
OMEGADOTREF = -2.6e-9
|
|
54
|
-
PYRINEXCONV_VERSION = "0.1.
|
|
57
|
+
PYRINEXCONV_VERSION = "0.1.4 Alpha"
|
|
55
58
|
QZS = "J"
|
|
56
59
|
RINEX_CANCELLED = 2
|
|
57
60
|
RINEX_ERROR = 99
|
|
@@ -83,6 +86,7 @@ P2_N5 = 0.03125 # 2**-5
|
|
|
83
86
|
P2_N6 = 0.015625 # 2**-6
|
|
84
87
|
P2_N8 = 0.00390625 # 2**-8
|
|
85
88
|
P2_N9 = 0.001953125 # 2**-9
|
|
89
|
+
P2_N11 = 0.00048828125 # 2**-11
|
|
86
90
|
P2_N14 = 6.103515625e-05 # 2**-14
|
|
87
91
|
P2_N15 = 3.0517578125e-05 # 2**-15
|
|
88
92
|
P2_N16 = 1.52587890625e-05 # 2**-16
|
|
@@ -104,6 +108,7 @@ P2_N34 = 5.820766091346741e-11 # 2**-34
|
|
|
104
108
|
P2_N35 = 2.9103830456733704e-11 # 2**-35
|
|
105
109
|
P2_N37 = 7.275957614183426e-12 # 2**-37
|
|
106
110
|
P2_N38 = 3.637978807091713e-12 # 2**-38
|
|
111
|
+
P2_N40 = 9.094947017729282e-13 # 2**-40
|
|
107
112
|
P2_N43 = 1.1368683772161603e-13 # 2**-43
|
|
108
113
|
P2_N44 = 5.684341886080802e-14 # 2**-44
|
|
109
114
|
P2_N46 = 1.4210854715202004e-14 # 2**-46
|
|
@@ -14,7 +14,7 @@ Created on 6 Oct 2025
|
|
|
14
14
|
|
|
15
15
|
# pylint: disable=invalid-name, too-many-arguments, too-many-positional-arguments
|
|
16
16
|
|
|
17
|
-
from datetime import datetime, timezone
|
|
17
|
+
from datetime import datetime, timedelta, timezone
|
|
18
18
|
from getpass import getuser
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
from types import NoneType
|
|
@@ -108,6 +108,61 @@ def get_epoch(
|
|
|
108
108
|
return epoch, wn
|
|
109
109
|
|
|
110
110
|
|
|
111
|
+
def glotk2sec(tk: int) -> int:
|
|
112
|
+
"""
|
|
113
|
+
Convert GLONASS tk value to seconds.
|
|
114
|
+
|
|
115
|
+
:param int tk: GLONASS time
|
|
116
|
+
:return: seconds
|
|
117
|
+
:rtype: int
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
hour = (tk >> 7) & 0b11111
|
|
121
|
+
minute = (tk >> 1) & 0b111111
|
|
122
|
+
seconds = (tk & 0b1) * 30
|
|
123
|
+
return (hour * 3600) + (minute * 60) + seconds
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def get_epoch_glo(nt: int, n4: int, tk: int) -> datetime:
|
|
127
|
+
"""
|
|
128
|
+
Get epoch from GLONASS day and time attributes.
|
|
129
|
+
|
|
130
|
+
See GLONASS ICD A.3.1.3
|
|
131
|
+
|
|
132
|
+
:param int nt: number of days in 4 year cycle
|
|
133
|
+
:param int n4: 4 year cycle number
|
|
134
|
+
:param int tk: time
|
|
135
|
+
:return: epoch
|
|
136
|
+
:rtype: datetime
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
j = 0
|
|
140
|
+
md = 365
|
|
141
|
+
if 1 <= nt <= 366:
|
|
142
|
+
j = 1
|
|
143
|
+
md = 366
|
|
144
|
+
elif 367 <= nt <= 731:
|
|
145
|
+
j = 2
|
|
146
|
+
elif 732 <= nt <= 1096:
|
|
147
|
+
j = 3
|
|
148
|
+
elif 1097 <= nt <= 1461:
|
|
149
|
+
j = 4
|
|
150
|
+
year = 1996 + (4 * (n4 - 1)) + (j - 1)
|
|
151
|
+
basedate = datetime(year, 1, 1, tzinfo=timezone.utc) + timedelta(days=(nt % md) - 2)
|
|
152
|
+
hour = ((tk >> 7) & 0b11111) - 3 # GLO time 3 hours ahead of UTC
|
|
153
|
+
minute = (tk >> 1) & 0b111111
|
|
154
|
+
seconds = (tk & 0b1) * 30
|
|
155
|
+
return datetime(
|
|
156
|
+
basedate.year,
|
|
157
|
+
basedate.month,
|
|
158
|
+
basedate.day,
|
|
159
|
+
hour,
|
|
160
|
+
minute,
|
|
161
|
+
seconds,
|
|
162
|
+
tzinfo=timezone.utc,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
111
166
|
def get_fithours(iodc: int, fit: int, gnss: str) -> int | str:
|
|
112
167
|
"""
|
|
113
168
|
Get FIT interval in hours for given IODC and fit flag.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""
|
|
2
|
+
rinex_subframes_glo.py
|
|
3
|
+
|
|
4
|
+
GLONASS NAV Subframe definitions.
|
|
5
|
+
|
|
6
|
+
https://web.archive.org/web/20161020203029/http://russianspacesystems.ru/wp-content/uploads/2016/08/ICD_GLONASS_eng_v5.1.pdf
|
|
7
|
+
|
|
8
|
+
These are provided as the basis of a capability to parse and store
|
|
9
|
+
the payloads of raw NAV subframe messages, via the associated
|
|
10
|
+
`pygnssutils.RawNav` class defined in `rawnav.py`.
|
|
11
|
+
|
|
12
|
+
NB:
|
|
13
|
+
|
|
14
|
+
- MSB and LSB fields MUST be suffixed '_msb' and '_lsb' respectively.
|
|
15
|
+
- Non-data bits (reserved, parity, non) MUST be prefixed '_'.
|
|
16
|
+
- Avoid the following reserved field names: gnss, svid, sigid, subframeacq, epoch
|
|
17
|
+
|
|
18
|
+
Created on 6 Oct 2025
|
|
19
|
+
|
|
20
|
+
:author: semuadmin (Steve Smith)
|
|
21
|
+
:copyright: semuadmin © 2025
|
|
22
|
+
:license: BSD 3-Clause
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from pygnssutils.rawnav import SID, S, U
|
|
26
|
+
from pygnssutils.rinex_globals import (
|
|
27
|
+
L1OF,
|
|
28
|
+
P2_N11,
|
|
29
|
+
P2_N20,
|
|
30
|
+
P2_N30,
|
|
31
|
+
P2_N31,
|
|
32
|
+
P2_N40,
|
|
33
|
+
START,
|
|
34
|
+
TARGET,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# **********************************************************************
|
|
38
|
+
# L1OF (FDMA) - "1C" (same as L2OF - "2C")
|
|
39
|
+
# **********************************************************************
|
|
40
|
+
|
|
41
|
+
# GLONASS ICD refers to subframes as 'strings'
|
|
42
|
+
|
|
43
|
+
GLO_L1OF_SUBFRAME_TLM = {
|
|
44
|
+
"_idle": (0, 1, U, 0),
|
|
45
|
+
SID: (1, 4, U, 0), # subframe (string) number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
GLO_L1OF_SUBFRAME_END = {
|
|
49
|
+
"_hamming": (77, 8, U, 0),
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# content of 4 32-bit dwrds in RXM-SFRBX payload:
|
|
53
|
+
GLO_SUPERFRAME = {
|
|
54
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
55
|
+
"data": (5, 72, U, 0),
|
|
56
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
57
|
+
"_padding1": (85, 11, U, 0),
|
|
58
|
+
"superframeid": (96, 16, U, 0),
|
|
59
|
+
"_padding2": (112, 8, U, 0),
|
|
60
|
+
"frameid": (120, 8, U, 0),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# attribute_name: (bit offset, bit length, bit encoding, scaling)
|
|
64
|
+
GLO_L1OF_SUBFRAME_1 = {
|
|
65
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
66
|
+
"_reserved1": (5, 2, U, 0),
|
|
67
|
+
"p1": (7, 2, U, 1),
|
|
68
|
+
"tk": (9, 12, U, 0),
|
|
69
|
+
# "tk_hours": (9, 5, U, 0),
|
|
70
|
+
# "tk_mins": (14, 6, U, 0),
|
|
71
|
+
# "tk_secs": (20, 1, U, 30),
|
|
72
|
+
"xntbdot": (21, 24, S, P2_N20),
|
|
73
|
+
"xntbdot2": (45, 5, S, P2_N30),
|
|
74
|
+
"xntb": (50, 27, S, P2_N11),
|
|
75
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
76
|
+
}
|
|
77
|
+
GLO_L1OF_SUBFRAME_2 = {
|
|
78
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
79
|
+
"bn": (5, 3, U, 0),
|
|
80
|
+
"p2": (8, 1, U, 1),
|
|
81
|
+
"tb": (9, 7, U, 15),
|
|
82
|
+
"_reserved1": (16, 5, U, 0),
|
|
83
|
+
"yntbdot": (21, 24, S, P2_N20),
|
|
84
|
+
"yntbdot2": (45, 5, S, P2_N30),
|
|
85
|
+
"yntb": (50, 27, S, P2_N11),
|
|
86
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
87
|
+
}
|
|
88
|
+
GLO_L1OF_SUBFRAME_3 = {
|
|
89
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
90
|
+
"p3": (5, 1, U, 1),
|
|
91
|
+
"gammantb": (6, 11, S, P2_N40),
|
|
92
|
+
"_reserved1": (17, 1, U, 0),
|
|
93
|
+
"p": (18, 2, U, 1),
|
|
94
|
+
"ln": (20, 1, U, 1),
|
|
95
|
+
"zntbdot": (21, 24, S, P2_N20),
|
|
96
|
+
"zntbdot2": (45, 5, S, P2_N30),
|
|
97
|
+
"zntb": (50, 27, S, P2_N11),
|
|
98
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
99
|
+
}
|
|
100
|
+
GLO_L1OF_SUBFRAME_4 = {
|
|
101
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
102
|
+
"tauntb": (5, 22, S, P2_N30),
|
|
103
|
+
"deltataun": (27, 5, S, P2_N30),
|
|
104
|
+
"en": (32, 5, U, 1),
|
|
105
|
+
"_reserved1": (37, 14, U, 0),
|
|
106
|
+
"p4": (51, 1, U, 1),
|
|
107
|
+
"ft": (52, 4, U, 0),
|
|
108
|
+
"_reserved2": (56, 3, U, 0),
|
|
109
|
+
"nt": (59, 11, U, 0),
|
|
110
|
+
"n": (70, 5, U, 0),
|
|
111
|
+
"m": (75, 2, U, 0), # 0 = GLONASS, 1 = GLONASS-M
|
|
112
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
113
|
+
}
|
|
114
|
+
GLO_L1OF_SUBFRAME_5 = {
|
|
115
|
+
**GLO_L1OF_SUBFRAME_TLM,
|
|
116
|
+
"na": (5, 11, S, P2_N30),
|
|
117
|
+
"tauc": (16, 32, S, P2_N31),
|
|
118
|
+
"_reserved1": (48, 1, U, 0),
|
|
119
|
+
"n4": (49, 5, U, 1),
|
|
120
|
+
"taugps": (54, 22, S, P2_N30),
|
|
121
|
+
"ln": (76, 1, U, 0),
|
|
122
|
+
**GLO_L1OF_SUBFRAME_END,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# mapping for (subframe, page) acquisition mask subframeacq
|
|
126
|
+
GLO_SUBFRAMEACQ_MAP = {
|
|
127
|
+
L1OF: {
|
|
128
|
+
TARGET: 0b11111, # subframes 1,2,3,4,5
|
|
129
|
+
START: 1,
|
|
130
|
+
(1, 0): (GLO_L1OF_SUBFRAME_1, 1),
|
|
131
|
+
(2, 0): (GLO_L1OF_SUBFRAME_2, 2),
|
|
132
|
+
(3, 0): (GLO_L1OF_SUBFRAME_3, 4),
|
|
133
|
+
(4, 0): (GLO_L1OF_SUBFRAME_4, 8),
|
|
134
|
+
(5, 0): (GLO_L1OF_SUBFRAME_5, 16),
|
|
135
|
+
},
|
|
136
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygnssutils
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.4
|
|
4
4
|
Summary: GNSS Command Line Utilities
|
|
5
5
|
Author-email: Steve Smith <semuadmin@semuconsulting.com>
|
|
6
6
|
Maintainer-email: Steve Smith <semuadmin@semuconsulting.com>
|
|
@@ -35,10 +35,10 @@ Requires-Dist: paho-mqtt>=2.1.0
|
|
|
35
35
|
Requires-Dist: pyserial>=3.5
|
|
36
36
|
Requires-Dist: pyspartn>=1.0.8
|
|
37
37
|
Requires-Dist: pyubx2>=1.3.3
|
|
38
|
-
Requires-Dist: pynmeagps>=1.1.
|
|
38
|
+
Requires-Dist: pynmeagps>=1.1.5
|
|
39
39
|
Requires-Dist: pysbf2>=1.0.4
|
|
40
40
|
Requires-Dist: pyubxutils>=1.0.6
|
|
41
|
-
Requires-Dist: pyqgc>=0.
|
|
41
|
+
Requires-Dist: pyqgc>=1.0.0
|
|
42
42
|
Requires-Dist: pyunigps>=1.0.0
|
|
43
43
|
Dynamic: license-file
|
|
44
44
|
|
|
@@ -81,7 +81,7 @@ designated output stream.
|
|
|
81
81
|
a simple SPARTN IP (MQTT) Client which receives SPARTN correction data from an SPARTN IP location service and (optionally) sends this to a
|
|
82
82
|
designated output stream.
|
|
83
83
|
1. `SocketServer` class based on the native Python `ThreadingTCPServer`. Capable of operating in two modes - Socket Server or NTRIP Caster. Provides two alternate client request handler classes - `ClientHandler` (HTTP) or `ClientHandlerTLS` (HTTPS).
|
|
84
|
-
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB:
|
|
84
|
+
1. `RinexConverter` class and its associated [`pyrinexconv`](#rinexconvert) CLI utility. This implements a binary GNSS data log file to RINEX text file conversion facility. **NB: RINEX conversion is currently an experimental work in progress (*contributions and feedback welcome*)**
|
|
85
85
|
|
|
86
86
|
The pygnssutils homepage is located at [https://github.com/semuconsulting/pygnssutils](https://github.com/semuconsulting/pygnssutils).
|
|
87
87
|
|
|
@@ -543,15 +543,15 @@ class pygnssutils.rinex_conv.RinexConvertor(app, rinex_version, rinex_type, gnss
|
|
|
543
543
|
|
|
544
544
|
A command line utility and Python class `RinexConverter` to convert binary GNSS data logs to RINEX text file format.
|
|
545
545
|
|
|
546
|
-
**NB: The current ALPHA release implements the following functionality:**
|
|
546
|
+
**NB: RINEX conversion is an experimental work in progress (*contributions and feedback welcome*). The current ALPHA release implements the following functionality:**
|
|
547
547
|
|
|
548
548
|
1. RINEX versions 3.05 and 4.02.
|
|
549
549
|
1. Convert binary UBX RXM-RAW or RXM-RAWX (raw observation) data from u-blox receivers (e.g. ZED-F9P) to RINEX Observation file format.
|
|
550
|
-
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
550
|
+
1. Convert binary RXM-SFRBX (navigation subframe) data from u-blox receivers to RINEX Navigation file format. **Currently supports GPS LNAV/CNAV, GAL FNAV/INAV, BDS D1/D2 & GLO L1OF**, but the underlying `RinexConverterNavigation` class will be enhanced in future releases.
|
|
551
551
|
1. Convert RTCM3 Ephemerides messages (1019, 1020, 1041-1046) from any source (including NTRIP caster or RTK base station receiver) to RINEX Navigation file format.
|
|
552
552
|
1. Convert NMEA MWD (wind speed and direction) and XDR (temperature and pressure) sensor data to RINEX Meteorology file format.
|
|
553
553
|
|
|
554
|
-
A Graphical User Interface for this utility
|
|
554
|
+
A Graphical User Interface for this utility has been added to [PyGPSClient](https://github.com/semuconsulting/PyGPSClient).
|
|
555
555
|
|
|
556
556
|
Assuming the u-blox receiver is already configured to output raw observation (UBX-RXM-RAWX) and navigation subframe (UBX-RXM-SFRBX) data, a suitable input log file can be created using the pygnssutils `gnssstreamer` CLI utility e.g. ...
|
|
557
557
|
|
|
@@ -26,6 +26,7 @@ src/pygnssutils/rinex_globals.py
|
|
|
26
26
|
src/pygnssutils/rinex_helpers.py
|
|
27
27
|
src/pygnssutils/rinex_subframes_bds.py
|
|
28
28
|
src/pygnssutils/rinex_subframes_gal.py
|
|
29
|
+
src/pygnssutils/rinex_subframes_glo.py
|
|
29
30
|
src/pygnssutils/rinex_subframes_gps.py
|
|
30
31
|
src/pygnssutils/socket_server.py
|
|
31
32
|
src/pygnssutils.egg-info/PKG-INFO
|
|
@@ -13,7 +13,6 @@ Created on 26 May 2022
|
|
|
13
13
|
import unittest
|
|
14
14
|
from datetime import datetime, timedelta, timezone
|
|
15
15
|
from pathlib import Path
|
|
16
|
-
from platform import system
|
|
17
16
|
from time import sleep
|
|
18
17
|
|
|
19
18
|
from pygnssutils.rinex_conv import RinexConverter
|
|
@@ -21,9 +20,6 @@ from pygnssutils.rinex_globals import BDS, EPOCH0_GPS, EPOCHMAX, EPOCHMIN, GAL,
|
|
|
21
20
|
from pygnssutils.rinex_helpers import (
|
|
22
21
|
DRNX,
|
|
23
22
|
FRNX,
|
|
24
|
-
get_epoch,
|
|
25
|
-
get_svcode_ubx,
|
|
26
|
-
get_svcode,
|
|
27
23
|
adjust_time_units,
|
|
28
24
|
format_antennabsight,
|
|
29
25
|
format_antennadeltahen,
|
|
@@ -36,24 +32,27 @@ from pygnssutils.rinex_helpers import (
|
|
|
36
32
|
format_clockoffset,
|
|
37
33
|
format_cnrunit,
|
|
38
34
|
format_comments,
|
|
35
|
+
format_eop,
|
|
39
36
|
format_fileend,
|
|
40
37
|
format_filename,
|
|
41
38
|
format_glonassfrq,
|
|
42
39
|
format_glonassphasebias,
|
|
43
40
|
format_headerend,
|
|
44
41
|
format_interval,
|
|
45
|
-
|
|
42
|
+
format_ion,
|
|
46
43
|
format_iono_corr,
|
|
47
44
|
format_leapseconds,
|
|
48
45
|
format_marker,
|
|
49
46
|
format_met_obstypes,
|
|
50
47
|
format_met_sensorpos,
|
|
51
48
|
format_met_sensortype,
|
|
49
|
+
format_nav_typesvmssg,
|
|
52
50
|
format_numsats,
|
|
53
51
|
format_observer,
|
|
54
52
|
format_obstypes,
|
|
55
53
|
format_rcvrtype,
|
|
56
54
|
format_runby,
|
|
55
|
+
format_sto,
|
|
57
56
|
format_sys_antennaphasecentre,
|
|
58
57
|
format_sys_dcbsapplied,
|
|
59
58
|
format_sys_pcvsapplied,
|
|
@@ -62,11 +61,13 @@ from pygnssutils.rinex_helpers import (
|
|
|
62
61
|
format_time_corr,
|
|
63
62
|
format_timefirstlast,
|
|
64
63
|
format_version,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
get_epoch,
|
|
65
|
+
get_epoch_glo,
|
|
66
|
+
get_svcode,
|
|
67
|
+
get_svcode_ubx,
|
|
69
68
|
gpsura2m,
|
|
69
|
+
glotk2sec,
|
|
70
|
+
listify,
|
|
70
71
|
)
|
|
71
72
|
|
|
72
73
|
SENSORTYPES = {
|
|
@@ -133,7 +134,7 @@ SENSORTYPES = {
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
# only run RINEX file tests locally
|
|
136
|
-
RINEXFILETEST = False
|
|
137
|
+
RINEXFILETEST = False # system() == "Darwin"
|
|
137
138
|
|
|
138
139
|
|
|
139
140
|
class StaticTest(unittest.TestCase):
|
|
@@ -166,22 +167,22 @@ class StaticTest(unittest.TestCase):
|
|
|
166
167
|
self.assertEqual(DRNX(" ", 14, 8), " ")
|
|
167
168
|
|
|
168
169
|
def testgetsvcodeubx(self):
|
|
169
|
-
self.assertEqual(get_svcode_ubx(0,3),"G03")
|
|
170
|
-
self.assertEqual(get_svcode_ubx(0,3,False),"G 3")
|
|
171
|
-
self.assertEqual(get_svcode_ubx(2,12),"E12")
|
|
172
|
-
self.assertEqual(get_svcode_ubx(2,12,False),"E12")
|
|
173
|
-
self.assertEqual(get_svcode_ubx(1,112),"S12")
|
|
174
|
-
self.assertEqual(get_svcode_ubx(1,112,False),"S12")
|
|
175
|
-
self.assertEqual(get_svcode_ubx(5,194),"J02")
|
|
176
|
-
self.assertEqual(get_svcode_ubx(5,194,False),"J 2")
|
|
170
|
+
self.assertEqual(get_svcode_ubx(0, 3), "G03")
|
|
171
|
+
self.assertEqual(get_svcode_ubx(0, 3, False), "G 3")
|
|
172
|
+
self.assertEqual(get_svcode_ubx(2, 12), "E12")
|
|
173
|
+
self.assertEqual(get_svcode_ubx(2, 12, False), "E12")
|
|
174
|
+
self.assertEqual(get_svcode_ubx(1, 112), "S12")
|
|
175
|
+
self.assertEqual(get_svcode_ubx(1, 112, False), "S12")
|
|
176
|
+
self.assertEqual(get_svcode_ubx(5, 194), "J02")
|
|
177
|
+
self.assertEqual(get_svcode_ubx(5, 194, False), "J 2")
|
|
177
178
|
|
|
178
179
|
def testgetsvcodertcm(self):
|
|
179
|
-
self.assertEqual(get_svcode("G",3),"G03")
|
|
180
|
-
self.assertEqual(get_svcode("G",3,None, False),"G 3")
|
|
181
|
-
self.assertEqual(get_svcode("S",112-100),"S12")
|
|
182
|
-
self.assertEqual(get_svcode("S",112-100,None, False),"S12")
|
|
183
|
-
self.assertEqual(get_svcode("J",194-192),"J02")
|
|
184
|
-
self.assertEqual(get_svcode("J",194-192,None, False),"J 2")
|
|
180
|
+
self.assertEqual(get_svcode("G", 3), "G03")
|
|
181
|
+
self.assertEqual(get_svcode("G", 3, None, False), "G 3")
|
|
182
|
+
self.assertEqual(get_svcode("S", 112 - 100), "S12")
|
|
183
|
+
self.assertEqual(get_svcode("S", 112 - 100, None, False), "S12")
|
|
184
|
+
self.assertEqual(get_svcode("J", 194 - 192), "J02")
|
|
185
|
+
self.assertEqual(get_svcode("J", 194 - 192, None, False), "J 2")
|
|
185
186
|
|
|
186
187
|
def testformat_filename(self):
|
|
187
188
|
firstobs = datetime(2026, 3, 14, 12, 4, 6)
|
|
@@ -206,13 +207,13 @@ class StaticTest(unittest.TestCase):
|
|
|
206
207
|
)
|
|
207
208
|
firstobs = datetime(2026, 3, 14, 12, 4, 6)
|
|
208
209
|
lastobs = firstobs + timedelta(minutes=60)
|
|
209
|
-
interval=15
|
|
210
|
+
interval = 15
|
|
210
211
|
res = format_filename(
|
|
211
|
-
rinextype="O",
|
|
212
|
+
rinextype="O",
|
|
212
213
|
gnssfilter=[GPS],
|
|
213
|
-
startepoch=firstobs,
|
|
214
|
+
startepoch=firstobs,
|
|
214
215
|
endepoch=lastobs,
|
|
215
|
-
interval=interval,
|
|
216
|
+
interval=interval,
|
|
216
217
|
outputpath=Path("/Users/steve/Downloads"),
|
|
217
218
|
form="IGS",
|
|
218
219
|
site="SITE",
|
|
@@ -226,9 +227,30 @@ class StaticTest(unittest.TestCase):
|
|
|
226
227
|
)
|
|
227
228
|
|
|
228
229
|
def test_getepoch(self):
|
|
229
|
-
res = get_epoch(366,411634,"G")
|
|
230
|
+
res = get_epoch(366, 411634, "G")
|
|
231
|
+
# print(res)
|
|
232
|
+
self.assertEqual(
|
|
233
|
+
res, (datetime(2026, 4, 16, 18, 20, 34, tzinfo=timezone.utc), 2414)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
def test_glotk2sec(self):
|
|
237
|
+
res = glotk2sec(1584)
|
|
238
|
+
# print(res)
|
|
239
|
+
self.assertEqual(res, 44640)
|
|
240
|
+
res = glotk2sec(1585)
|
|
241
|
+
# print(res)
|
|
242
|
+
self.assertEqual(res, 44670)
|
|
243
|
+
res = glotk2sec(1586)
|
|
230
244
|
# print(res)
|
|
231
|
-
self.assertEqual(res,
|
|
245
|
+
self.assertEqual(res, 44700)
|
|
246
|
+
|
|
247
|
+
def test_getepochglo(self):
|
|
248
|
+
res = get_epoch_glo(884, 8, 1584)
|
|
249
|
+
# print(res)
|
|
250
|
+
self.assertEqual(res, datetime(2026, 6, 2, 9, 24, 0, tzinfo=timezone.utc))
|
|
251
|
+
res = get_epoch_glo(884, 8, 1646)
|
|
252
|
+
# print(res)
|
|
253
|
+
self.assertEqual(res, (datetime(2026, 6, 2, 9, 55, 0, tzinfo=timezone.utc)))
|
|
232
254
|
|
|
233
255
|
def testformat_antennabsight(self):
|
|
234
256
|
res = format_antennabsight()
|
|
@@ -346,7 +368,7 @@ class StaticTest(unittest.TestCase):
|
|
|
346
368
|
"GPSB 1.2481e-07 5.0391e-06 2.3771e-07 1.2346e-13 B 14 IONOSPHERIC CORR\n"
|
|
347
369
|
)
|
|
348
370
|
res = format_iono_corr(
|
|
349
|
-
svid=2,
|
|
371
|
+
svid=2,
|
|
350
372
|
timemark="A",
|
|
351
373
|
corrtype="GPSA",
|
|
352
374
|
parm1=0.00000012481234567890,
|
|
@@ -355,7 +377,7 @@ class StaticTest(unittest.TestCase):
|
|
|
355
377
|
parm4=0.00000000000012345678909,
|
|
356
378
|
)
|
|
357
379
|
res += format_iono_corr(
|
|
358
|
-
svid=14,
|
|
380
|
+
svid=14,
|
|
359
381
|
timemark="B",
|
|
360
382
|
corrtype="GPSB",
|
|
361
383
|
parm1=0.00000012481234567890,
|
|
@@ -369,7 +391,7 @@ class StaticTest(unittest.TestCase):
|
|
|
369
391
|
def testformat_ion(self):
|
|
370
392
|
EXPECTED_RESULT = (
|
|
371
393
|
"> ION G24 LNAV XXXX\n"
|
|
372
|
-
" 2026 05 13 08 34 02 1.234567000000e-12 1.234567000000e-12-1.234567000000e-12\n"
|
|
394
|
+
" 2026 05 13 08 34 02 1.234567000000e-12 1.234567000000e-12-1.234567000000e-12\n"
|
|
373
395
|
" 1.234567000000e-12 1.234567000000e-12 1.234567000000e-12-1.234567000000e-12\n"
|
|
374
396
|
" 1.234567000000e-12\n"
|
|
375
397
|
)
|
|
@@ -377,7 +399,7 @@ class StaticTest(unittest.TestCase):
|
|
|
377
399
|
svcode="G24",
|
|
378
400
|
msgtype="LNAV",
|
|
379
401
|
msgsubtype="XXXX",
|
|
380
|
-
epoch=datetime(2026,5,13,8,34,2,tzinfo=timezone.utc),
|
|
402
|
+
epoch=datetime(2026, 5, 13, 8, 34, 2, tzinfo=timezone.utc),
|
|
381
403
|
a0=1.234567e-12,
|
|
382
404
|
a1=1.234567e-12,
|
|
383
405
|
a2=-1.234567e-12,
|
|
@@ -387,13 +409,13 @@ class StaticTest(unittest.TestCase):
|
|
|
387
409
|
b2=-1.234567e-12,
|
|
388
410
|
b3=1.234567e-12,
|
|
389
411
|
)
|
|
390
|
-
#print(res)
|
|
412
|
+
# print(res)
|
|
391
413
|
self.assertEqual(res, EXPECTED_RESULT)
|
|
392
414
|
|
|
393
415
|
def testformat_eop(self):
|
|
394
416
|
EXPECTED_RESULT = (
|
|
395
417
|
"> EOP G24 LNAV XXXX\n"
|
|
396
|
-
" 2026 05 13 08 34 02 2.082471847534e-01-6.551742553711e-04 0.000000000000e+00\n"
|
|
418
|
+
" 2026 05 13 08 34 02 2.082471847534e-01-6.551742553711e-04 0.000000000000e+00\n"
|
|
397
419
|
" 3.444433212280e-01-9.121894836426e-04 0.000000000000e+00\n"
|
|
398
420
|
" 1.729860000000e+05-1.754972934723e-01 5.635917186737e-04 0.000000000000e+00\n"
|
|
399
421
|
)
|
|
@@ -401,17 +423,17 @@ class StaticTest(unittest.TestCase):
|
|
|
401
423
|
svcode="G24",
|
|
402
424
|
msgtype="LNAV",
|
|
403
425
|
msgsubtype="XXXX",
|
|
404
|
-
epoch=datetime(2026,5,13,8,34,2,tzinfo=timezone.utc),
|
|
405
|
-
tom=1.
|
|
426
|
+
epoch=datetime(2026, 5, 13, 8, 34, 2, tzinfo=timezone.utc),
|
|
427
|
+
tom=1.729860000000e05,
|
|
406
428
|
xp=2.082471847534e-01,
|
|
407
429
|
dxpdt=-6.551742553711e-04,
|
|
408
|
-
dxpdt2=0.
|
|
430
|
+
dxpdt2=0.000000000000e00,
|
|
409
431
|
yp=3.444433212280e-01,
|
|
410
432
|
dypdt=-9.121894836426e-04,
|
|
411
|
-
dypdt2=0.
|
|
433
|
+
dypdt2=0.000000000000e00,
|
|
412
434
|
deltaut1=-1.754972934723e-01,
|
|
413
435
|
ddeltaut1dt=5.635917186737e-04,
|
|
414
|
-
d2deltaut1dt2=0.
|
|
436
|
+
d2deltaut1dt2=0.000000000000e00,
|
|
415
437
|
)
|
|
416
438
|
print(res)
|
|
417
439
|
self.assertEqual(res, EXPECTED_RESULT)
|
|
@@ -425,33 +447,32 @@ class StaticTest(unittest.TestCase):
|
|
|
425
447
|
weekno=1849,
|
|
426
448
|
source="5",
|
|
427
449
|
a0=0.000000003725290298,
|
|
428
|
-
a1=0.00000000000000532907052
|
|
450
|
+
a1=0.00000000000000532907052,
|
|
429
451
|
)
|
|
430
452
|
# print(res)
|
|
431
453
|
self.assertEqual(res, EXPECTED_RESULT)
|
|
432
454
|
|
|
433
|
-
|
|
434
455
|
def testformat_sto(self):
|
|
435
456
|
EXPECTED_RESULT = (
|
|
436
457
|
"> STO G24 LNAV XXXX\n"
|
|
437
|
-
" 2026 05 13 08 34 02 GPUT SSSS UTC(USNO) \n"
|
|
458
|
+
" 2026 05 13 08 34 02 GPUT SSSS UTC(USNO) \n"
|
|
438
459
|
" 4.567890000000e+05 1.234567000000e-23 1.234567000000e-23-1.234567800000e-12\n"
|
|
439
460
|
)
|
|
440
461
|
res = format_sto(
|
|
441
462
|
svcode="G24",
|
|
442
463
|
msgtype="LNAV",
|
|
443
464
|
msgsubtype="XXXX",
|
|
444
|
-
epoch=datetime(2026,5,13,8,34,2,tzinfo=timezone.utc),
|
|
465
|
+
epoch=datetime(2026, 5, 13, 8, 34, 2, tzinfo=timezone.utc),
|
|
445
466
|
timecode="GPUT",
|
|
446
467
|
sbasid="SSSS",
|
|
447
468
|
utcid="UTC(USNO)",
|
|
448
469
|
tot=456789,
|
|
449
470
|
a0=1.234567e-23,
|
|
450
471
|
a1=1.234567e-23,
|
|
451
|
-
a2=-1.2345678e-12
|
|
472
|
+
a2=-1.2345678e-12,
|
|
452
473
|
)
|
|
453
474
|
# print(res)
|
|
454
|
-
self.assertEqual(res,EXPECTED_RESULT)
|
|
475
|
+
self.assertEqual(res, EXPECTED_RESULT)
|
|
455
476
|
|
|
456
477
|
def testformat_met_obstypes(self):
|
|
457
478
|
EXPECTED_RESULT = (
|
|
@@ -514,16 +535,16 @@ class StaticTest(unittest.TestCase):
|
|
|
514
535
|
|
|
515
536
|
def testgpsura2m(self):
|
|
516
537
|
|
|
517
|
-
self.assertEqual(gpsura2m(1),2.8)
|
|
518
|
-
self.assertEqual(gpsura2m(2),4.0)
|
|
519
|
-
self.assertEqual(gpsura2m(3),5.7)
|
|
520
|
-
self.assertEqual(gpsura2m(5),11.3)
|
|
521
|
-
self.assertEqual(gpsura2m(8),64)
|
|
522
|
-
self.assertEqual(gpsura2m(14),4096)
|
|
523
|
-
self.assertEqual(gpsura2m(15),0)
|
|
524
|
-
self.assertEqual(gpsura2m(-16),0)
|
|
525
|
-
self.assertEqual(gpsura2m(-8),0.1)
|
|
526
|
-
|
|
538
|
+
self.assertEqual(gpsura2m(1), 2.8)
|
|
539
|
+
self.assertEqual(gpsura2m(2), 4.0)
|
|
540
|
+
self.assertEqual(gpsura2m(3), 5.7)
|
|
541
|
+
self.assertEqual(gpsura2m(5), 11.3)
|
|
542
|
+
self.assertEqual(gpsura2m(8), 64)
|
|
543
|
+
self.assertEqual(gpsura2m(14), 4096)
|
|
544
|
+
self.assertEqual(gpsura2m(15), 0)
|
|
545
|
+
self.assertEqual(gpsura2m(-16), 0)
|
|
546
|
+
self.assertEqual(gpsura2m(-8), 0.1)
|
|
547
|
+
|
|
527
548
|
def testrinexnav(self):
|
|
528
549
|
EXPECTED_RESULT_OBS = [
|
|
529
550
|
r" 3.05 O: OBSERVATION M: MIXED RINEX VERSION / TYPE\n",
|
|
@@ -6,17 +6,17 @@ length are consistent with ICD definition.
|
|
|
6
6
|
|
|
7
7
|
Created on 26 May 2022
|
|
8
8
|
|
|
9
|
-
*** NB: must be saved in UTF-8 format ***
|
|
10
|
-
|
|
11
9
|
@author: semuadmin
|
|
12
10
|
"""
|
|
13
11
|
|
|
14
12
|
import unittest
|
|
15
13
|
|
|
16
|
-
from pygnssutils.rawnav import VALPREAMBLE
|
|
17
|
-
import pygnssutils.rinex_subframes_gps as gps
|
|
18
|
-
import pygnssutils.rinex_subframes_gal as gal
|
|
19
14
|
import pygnssutils.rinex_subframes_bds as bds
|
|
15
|
+
import pygnssutils.rinex_subframes_gal as gal
|
|
16
|
+
import pygnssutils.rinex_subframes_glo as glo
|
|
17
|
+
import pygnssutils.rinex_subframes_gps as gps
|
|
18
|
+
from pygnssutils.rawnav import VALPREAMBLE
|
|
19
|
+
|
|
20
20
|
|
|
21
21
|
class StaticTest(unittest.TestCase):
|
|
22
22
|
def setUp(self):
|
|
@@ -48,7 +48,7 @@ class StaticTest(unittest.TestCase):
|
|
|
48
48
|
gps.GPS_LNAV_SUBFRAME_4_P18,
|
|
49
49
|
)
|
|
50
50
|
sfrlen = 300
|
|
51
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
51
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
52
52
|
|
|
53
53
|
def testGPSCNAVdefs(self):
|
|
54
54
|
sfrdefs = (
|
|
@@ -66,10 +66,10 @@ class StaticTest(unittest.TestCase):
|
|
|
66
66
|
gps.GPS_CNAV_SUBFRAME_35,
|
|
67
67
|
gps.GPS_CNAV_SUBFRAME_36,
|
|
68
68
|
gps.GPS_CNAV_SUBFRAME_37,
|
|
69
|
-
gps.GPS_CNAV_SUBFRAME_40
|
|
69
|
+
gps.GPS_CNAV_SUBFRAME_40,
|
|
70
70
|
)
|
|
71
71
|
sfrlen = 300
|
|
72
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
72
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
73
73
|
|
|
74
74
|
def testGALFNAV(self):
|
|
75
75
|
|
|
@@ -79,16 +79,16 @@ class StaticTest(unittest.TestCase):
|
|
|
79
79
|
gal.GAL_FNAV_SUBFRAME_3,
|
|
80
80
|
gal.GAL_FNAV_SUBFRAME_4,
|
|
81
81
|
gal.GAL_FNAV_SUBFRAME_5,
|
|
82
|
-
gal.GAL_FNAV_SUBFRAME_6
|
|
82
|
+
gal.GAL_FNAV_SUBFRAME_6,
|
|
83
83
|
)
|
|
84
84
|
sfrlen = 244
|
|
85
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
85
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
86
86
|
|
|
87
87
|
def testGALINAV(self):
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
sfrdefs = (gal.GAL_INAV_SUBFRAME,)
|
|
90
90
|
sfrlen = 256
|
|
91
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
91
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
92
92
|
|
|
93
93
|
sfrdefs = (
|
|
94
94
|
gal.GAL_INAV_WORD_1,
|
|
@@ -101,10 +101,10 @@ class StaticTest(unittest.TestCase):
|
|
|
101
101
|
gal.GAL_INAV_WORD_8,
|
|
102
102
|
gal.GAL_INAV_WORD_9,
|
|
103
103
|
gal.GAL_INAV_WORD_10,
|
|
104
|
-
gal.GAL_INAV_WORD_16
|
|
104
|
+
gal.GAL_INAV_WORD_16,
|
|
105
105
|
)
|
|
106
106
|
sfrlen = 128
|
|
107
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
107
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
108
108
|
|
|
109
109
|
def testBDSD1(self):
|
|
110
110
|
|
|
@@ -116,7 +116,7 @@ class StaticTest(unittest.TestCase):
|
|
|
116
116
|
bds.BDS_D1_SUBFRAME_5_P10,
|
|
117
117
|
)
|
|
118
118
|
sfrlen = 300
|
|
119
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
119
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
120
120
|
|
|
121
121
|
def testBDSD2(self):
|
|
122
122
|
|
|
@@ -133,4 +133,16 @@ class StaticTest(unittest.TestCase):
|
|
|
133
133
|
bds.BDS_D2_SUBFRAME_1_P10,
|
|
134
134
|
)
|
|
135
135
|
sfrlen = 300
|
|
136
|
-
self.scandefs(sfrdefs,sfrlen)
|
|
136
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
137
|
+
|
|
138
|
+
def testGLOL1OF(self):
|
|
139
|
+
|
|
140
|
+
sfrdefs = (
|
|
141
|
+
glo.GLO_L1OF_SUBFRAME_1,
|
|
142
|
+
glo.GLO_L1OF_SUBFRAME_2,
|
|
143
|
+
glo.GLO_L1OF_SUBFRAME_3,
|
|
144
|
+
glo.GLO_L1OF_SUBFRAME_4,
|
|
145
|
+
glo.GLO_L1OF_SUBFRAME_5,
|
|
146
|
+
)
|
|
147
|
+
sfrlen = 85
|
|
148
|
+
self.scandefs(sfrdefs, sfrlen)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|