gnss-js 1.36.0 → 1.38.0
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.
- package/dist/binex.js +2 -2
- package/dist/{chunk-AFEDNWXI.js → chunk-4TAN27LO.js} +368 -111
- package/dist/{chunk-F4CM6Q4F.js → chunk-5X4AG4MK.js} +2 -2
- package/dist/{chunk-5RNDQQ6J.js → chunk-6SWJTN6H.js} +2 -2
- package/dist/{chunk-OK4GGNOO.js → chunk-D25WNE43.js} +1 -1
- package/dist/{chunk-5AUK42AL.js → chunk-FA2UTLEQ.js} +2 -2
- package/dist/{chunk-IQ5OIMQD.js → chunk-V2D5KUKH.js} +33 -0
- package/dist/{chunk-726LQBGM.js → chunk-YUW33VXK.js} +1 -1
- package/dist/{chunk-FEOMYZEU.js → chunk-ZQDLYLQA.js} +9 -28
- package/dist/index.cjs +410 -142
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +14 -8
- package/dist/novatel.js +3 -3
- package/dist/rinex.js +3 -3
- package/dist/sbf.cjs +536 -111
- package/dist/sbf.d.cts +169 -14
- package/dist/sbf.d.ts +169 -14
- package/dist/sbf.js +12 -4
- package/dist/ubx.cjs +37 -24
- package/dist/ubx.js +4 -4
- package/package.json +1 -1
package/dist/sbf.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { S as SbfAlmanac, a as SbfAlmanacResult, b as SbfGlonassAlmanac, c as SbfKeplerAlmanac, d as SbfNavResult, p as parseSbfAlmanac, e as parseSbfNav } from './nav-BYmYoh9A.cjs';
|
|
2
|
-
import { C as CnavEphemeris,
|
|
2
|
+
import { K as KeplerEphemeris, C as CnavEphemeris, E as Ephemeris, G as GlonassEphemeris } from './nav-DImXUdbp.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Septentrio SBF framing shared by the measurement and navigation
|
|
@@ -58,6 +58,108 @@ interface SbfIonoUtcResult {
|
|
|
58
58
|
*/
|
|
59
59
|
declare function parseSbfIonoUtc(data: Uint8Array): SbfIonoUtcResult;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Septentrio SBF ReceiverSetup (5902) — station identity: marker,
|
|
63
|
+
* receiver, antenna and the reference position. Broadcast every 60 s and
|
|
64
|
+
* on any setup change; it's what a RINEX header's marker/receiver/antenna
|
|
65
|
+
* and APPROX POSITION lines come from.
|
|
66
|
+
*
|
|
67
|
+
* Layout (AsteRx / mosaic reference guide §4.2, "ReceiverSetup"): after
|
|
68
|
+
* the 8-byte SBF header, TOW u4 + WNc u2, Reserved u1[2], then fixed-width
|
|
69
|
+
* zero-padded strings — MarkerName c1[60], MarkerNumber c1[20],
|
|
70
|
+
* Observer c1[20], Agency c1[40], RxSerialNumber c1[20], RxName c1[20],
|
|
71
|
+
* RxVersion c1[20], AntSerialNbr c1[20], AntType c1[20] — then deltaH/E/N
|
|
72
|
+
* f4 (antenna offsets, m). Later block revisions append MarkerType c1[20]
|
|
73
|
+
* (rev1), GNSSFWVersion c1[40] (rev2), ProductName c1[40] + the reference
|
|
74
|
+
* position Latitude f8 / Longitude f8 (radians) / Height f4 (m, WGS84)
|
|
75
|
+
* (rev3), and StationCode c1[10] … (rev4). Every trailing field is read
|
|
76
|
+
* only when the block length covers it, so older revisions decode fine.
|
|
77
|
+
*/
|
|
78
|
+
interface SbfReceiverSetup {
|
|
79
|
+
/** Marker (station) name. */
|
|
80
|
+
markerName: string;
|
|
81
|
+
markerNumber: string;
|
|
82
|
+
observer: string;
|
|
83
|
+
agency: string;
|
|
84
|
+
/** Receiver serial number. */
|
|
85
|
+
rxSerialNumber: string;
|
|
86
|
+
/** Receiver GNSS engine name (e.g. "MOSAIC-X5"). */
|
|
87
|
+
rxName: string;
|
|
88
|
+
/** Receiver firmware version. */
|
|
89
|
+
rxVersion: string;
|
|
90
|
+
/** Main antenna serial number. */
|
|
91
|
+
antSerialNumber: string;
|
|
92
|
+
/** Main antenna type (IGS antenna name). */
|
|
93
|
+
antType: string;
|
|
94
|
+
/** Antenna offset from the marker, metres (H/E/N). */
|
|
95
|
+
deltaH: number;
|
|
96
|
+
deltaE: number;
|
|
97
|
+
deltaN: number;
|
|
98
|
+
/** Marker type (rev 1+), e.g. "GEODETIC". */
|
|
99
|
+
markerType: string | null;
|
|
100
|
+
/** GNSS firmware version string (rev 2+). */
|
|
101
|
+
gnssFwVersion: string | null;
|
|
102
|
+
/** Product name (rev 3+). */
|
|
103
|
+
productName: string | null;
|
|
104
|
+
/** Reference latitude, radians (rev 3+), or null if absent/do-not-use. */
|
|
105
|
+
latitude: number | null;
|
|
106
|
+
/** Reference longitude, radians (rev 3+), or null if absent/do-not-use. */
|
|
107
|
+
longitude: number | null;
|
|
108
|
+
/** Reference ellipsoidal height, metres WGS84 (rev 3+), or null. */
|
|
109
|
+
height: number | null;
|
|
110
|
+
/**
|
|
111
|
+
* Reference position as ECEF metres `[x, y, z]` (from lat/lon/height),
|
|
112
|
+
* or null when the block carries no valid reference position. Matches
|
|
113
|
+
* the `StationMeta.position` convention.
|
|
114
|
+
*/
|
|
115
|
+
position: [number, number, number] | null;
|
|
116
|
+
/** Station code, e.g. the 4-char IGS code (rev 4+). */
|
|
117
|
+
stationCode: string | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Decode the ReceiverSetup (5902) block from an SBF byte stream. Returns
|
|
121
|
+
* the LAST valid block (the most recent setup), or null when none is
|
|
122
|
+
* present. Trailing revision fields are decoded only when the block is
|
|
123
|
+
* long enough, so all block revisions are handled.
|
|
124
|
+
*/
|
|
125
|
+
declare function parseSbfReceiverSetup(data: Uint8Array): SbfReceiverSetup | null;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Septentrio SBF raw GPS / QZSS LNAV navigation-bit blocks: GPSRawCA
|
|
129
|
+
* (4017) and QZSRawL1CA (4066) each carry one 300-bit L1 C/A (LNAV)
|
|
130
|
+
* subframe. Subframes 1–3 are assembled per satellite into a Keplerian
|
|
131
|
+
* ephemeris by the shared {@link GpsLnavAssembler} (also behind
|
|
132
|
+
* `parseUbxNav`).
|
|
133
|
+
*
|
|
134
|
+
* Block layout (mosaic-X5 / AsteRx reference guide §4.2.2): after the
|
|
135
|
+
* 8-byte SBF header, TOW u4 + WNc u2 (a full GPS week — no rollover to
|
|
136
|
+
* resolve), SVID u1, CRCPassed u1, ViterbiCnt u1, Source u1, FreqNr u1,
|
|
137
|
+
* RxChannel u1, then NAVBits as u4[10]. Each 32-bit word holds the 24
|
|
138
|
+
* source data bits d_n (already polarity-corrected for D30*) in bits
|
|
139
|
+
* 6–29 with the first received bit as the MSB — so extraction is the
|
|
140
|
+
* same `(word >>> 6) & 0xffffff` u-blox delivers, and the two share
|
|
141
|
+
* {@link GpsLnavAssembler}. Bits 0–5 are the parity bits (unused here:
|
|
142
|
+
* the receiver has already parity-checked, flagged by CRCPassed).
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
interface SbfGpsNavResult {
|
|
146
|
+
/** Assembled GPS/QZSS LNAV ephemerides in stream order, repeats suppressed. */
|
|
147
|
+
ephemerides: KeplerEphemeris[];
|
|
148
|
+
/** Completed 1/2/3 sets rejected by the IODC/IODE cross-check (dropped). */
|
|
149
|
+
badParity: number;
|
|
150
|
+
/** Total GPSRawCA/QZSRawL1CA blocks seen (with valid SBF framing). */
|
|
151
|
+
messages: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decode every GPSRawCA (4017) / QZSRawL1CA (4066) block in an SBF byte
|
|
155
|
+
* stream and assemble the carried LNAV subframes into ephemerides
|
|
156
|
+
* (`system` 'G'/'J', same fields and conventions as `parseSbfNav`'s
|
|
157
|
+
* GPSNav/QZSNav records). Only subframes the receiver marked
|
|
158
|
+
* CRC/parity-valid (CRCPassed = 1) are used; the block's full WNc week
|
|
159
|
+
* resolves the 10-bit broadcast week directly.
|
|
160
|
+
*/
|
|
161
|
+
declare function parseSbfGpsNav(data: Uint8Array): SbfGpsNavResult;
|
|
162
|
+
|
|
61
163
|
/**
|
|
62
164
|
* Septentrio SBF raw CNAV navigation-bit blocks: GPSRawL2C (4018) and
|
|
63
165
|
* GPSRawL5 (4019) each carry one 300-bit GPS CNAV message.
|
|
@@ -98,6 +200,71 @@ interface SbfCnavResult {
|
|
|
98
200
|
*/
|
|
99
201
|
declare function parseSbfCnav(data: Uint8Array): SbfCnavResult;
|
|
100
202
|
|
|
203
|
+
/**
|
|
204
|
+
* One-pass SBF navigation decoder.
|
|
205
|
+
*
|
|
206
|
+
* A Septentrio broadcasts navigation data as a mix of *decoded* blocks
|
|
207
|
+
* (GPSNav/GALNav/GLONav/BDSNav/QZSNav — already-parsed ephemeris) and
|
|
208
|
+
* *raw* navigation-frame blocks (GPSRawCA, GALRawINAV/FNAV, GLORawCA,
|
|
209
|
+
* BDSRaw, GPSRawL2C/L5) whose bits must be assembled — and which class a
|
|
210
|
+
* given receiver emits depends on its configuration. The granular
|
|
211
|
+
* `parseSbf*` functions each re-scan the whole stream for one class;
|
|
212
|
+
* this decoder walks the byte stream **once**, routing every navigation
|
|
213
|
+
* block through a single dispatch to the same per-block `feed*` helpers,
|
|
214
|
+
* and returns the merged, de-duplicated result. It is the decoder a
|
|
215
|
+
* consumer that just wants "all the ephemeris in this SBF" should call.
|
|
216
|
+
*
|
|
217
|
+
* Merge/de-dup: assemblers already suppress repeats of an unchanged
|
|
218
|
+
* issue of data within a scan; across the decoded and raw paths, records
|
|
219
|
+
* are de-duped by (prn, time-of-clock, Galileo I/NAV-vs-F/NAV source),
|
|
220
|
+
* so a stream carrying both a decoded GALNav block and the raw I/NAV
|
|
221
|
+
* pages for the same epoch yields one record, while the distinct Galileo
|
|
222
|
+
* I/NAV and F/NAV clock sets are both kept.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
/** Per-source diagnostics — how many blocks of each class were seen. */
|
|
226
|
+
interface SbfNavCounts {
|
|
227
|
+
/** Decoded ephemeris blocks (GPSNav/GALNav/GLONav/BDSNav/QZSNav). */
|
|
228
|
+
decodedNav: number;
|
|
229
|
+
/** Raw GPS/QZSS LNAV blocks (GPSRawCA/QZSRawL1CA). */
|
|
230
|
+
gpsLnavRaw: number;
|
|
231
|
+
/** Raw GPS CNAV blocks (GPSRawL2C/L5). */
|
|
232
|
+
cnavRaw: number;
|
|
233
|
+
/** Raw Galileo page blocks (GALRawINAV/FNAV). */
|
|
234
|
+
galRaw: number;
|
|
235
|
+
/** Raw GLONASS string blocks (GLORawCA). */
|
|
236
|
+
gloRaw: number;
|
|
237
|
+
/** Raw BeiDou D1/D2 subframe blocks (BDSRaw). */
|
|
238
|
+
bdsRaw: number;
|
|
239
|
+
/** Frames dropped by a CRC/parity check across all raw decoders. */
|
|
240
|
+
badFrames: number;
|
|
241
|
+
}
|
|
242
|
+
interface SbfNavigation {
|
|
243
|
+
/**
|
|
244
|
+
* Legacy Keplerian + GLONASS ephemerides, merged from the decoded Nav
|
|
245
|
+
* blocks and the raw GAL I/NAV+F/NAV, GLO strings, BDS D1/D2 and
|
|
246
|
+
* GPS/QZSS LNAV assemblers, de-duped as described in the module header.
|
|
247
|
+
*/
|
|
248
|
+
ephemerides: Ephemeris[];
|
|
249
|
+
/** GPS L2C/L5 CNAV ephemerides (RINEX-4 nav records). */
|
|
250
|
+
cnav: SbfCnavEphemeris[];
|
|
251
|
+
/**
|
|
252
|
+
* Iono coefficient sets keyed like `NavHeader.ionoCorrections`
|
|
253
|
+
* (GPSA/GPSB, GAL, BDSA/BDSB); the last valid block of each type wins.
|
|
254
|
+
*/
|
|
255
|
+
ionoCorrections: Record<string, number[]>;
|
|
256
|
+
/** GPS-UTC ΔtLS from the last GPSUtc block, if any. */
|
|
257
|
+
leapSeconds: number | null;
|
|
258
|
+
counts: SbfNavCounts;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Decode every navigation block in an SBF byte stream in a single pass:
|
|
262
|
+
* decoded ephemeris blocks, raw GPS/QZSS LNAV, GPS CNAV, Galileo I/NAV +
|
|
263
|
+
* F/NAV, GLONASS strings, BeiDou D1/D2, and the Klobuchar/NeQuick iono +
|
|
264
|
+
* GPS-UTC leap-second blocks. See the module header for merge semantics.
|
|
265
|
+
*/
|
|
266
|
+
declare function decodeSbfNavigation(data: Uint8Array): SbfNavigation;
|
|
267
|
+
|
|
101
268
|
/**
|
|
102
269
|
* Septentrio SBF raw Galileo navigation-page blocks: GALRawINAV (4023)
|
|
103
270
|
* carries one I/NAV nominal page pair (234 bits: the 114-bit even part
|
|
@@ -195,18 +362,6 @@ interface SbfGloNavResult {
|
|
|
195
362
|
/** Total GLORawCA blocks seen (with valid SBF framing). */
|
|
196
363
|
messages: number;
|
|
197
364
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Decode every GLORawCA (4026) block in an SBF byte stream and
|
|
200
|
-
* assemble the carried navigation strings into ephemerides (same
|
|
201
|
-
* conventions as `parseSbfNav`'s GLONav records: UTC `tocDate`, RINEX
|
|
202
|
-
* `tauN` sign, km state vectors, `messageFrameTime` in seconds of the
|
|
203
|
-
* UTC week — here from the broadcast tk, see the oracle notes in
|
|
204
|
-
* test/bdsglo-raw.test.ts). The block's TOW/WNc time stamp resolves
|
|
205
|
-
* the GLONASS day; blocks without one (do-not-use) are skipped, as
|
|
206
|
-
* are SVID-62 blocks (GLONASS satellite with unknown slot number).
|
|
207
|
-
* L1 C/A and L2 C/A strings are identical and share one assembler
|
|
208
|
-
* per slot, as in RTKLIB.
|
|
209
|
-
*/
|
|
210
365
|
declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
|
|
211
366
|
|
|
212
367
|
/** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
|
|
@@ -444,4 +599,4 @@ interface SbfParseResult {
|
|
|
444
599
|
*/
|
|
445
600
|
declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
|
|
446
601
|
|
|
447
|
-
export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
|
|
602
|
+
export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
|
package/dist/sbf.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { S as SbfAlmanac, a as SbfAlmanacResult, b as SbfGlonassAlmanac, c as SbfKeplerAlmanac, d as SbfNavResult, p as parseSbfAlmanac, e as parseSbfNav } from './nav-CN8rxL4h.js';
|
|
2
|
-
import { C as CnavEphemeris,
|
|
2
|
+
import { K as KeplerEphemeris, C as CnavEphemeris, E as Ephemeris, G as GlonassEphemeris } from './nav-DImXUdbp.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Septentrio SBF framing shared by the measurement and navigation
|
|
@@ -58,6 +58,108 @@ interface SbfIonoUtcResult {
|
|
|
58
58
|
*/
|
|
59
59
|
declare function parseSbfIonoUtc(data: Uint8Array): SbfIonoUtcResult;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Septentrio SBF ReceiverSetup (5902) — station identity: marker,
|
|
63
|
+
* receiver, antenna and the reference position. Broadcast every 60 s and
|
|
64
|
+
* on any setup change; it's what a RINEX header's marker/receiver/antenna
|
|
65
|
+
* and APPROX POSITION lines come from.
|
|
66
|
+
*
|
|
67
|
+
* Layout (AsteRx / mosaic reference guide §4.2, "ReceiverSetup"): after
|
|
68
|
+
* the 8-byte SBF header, TOW u4 + WNc u2, Reserved u1[2], then fixed-width
|
|
69
|
+
* zero-padded strings — MarkerName c1[60], MarkerNumber c1[20],
|
|
70
|
+
* Observer c1[20], Agency c1[40], RxSerialNumber c1[20], RxName c1[20],
|
|
71
|
+
* RxVersion c1[20], AntSerialNbr c1[20], AntType c1[20] — then deltaH/E/N
|
|
72
|
+
* f4 (antenna offsets, m). Later block revisions append MarkerType c1[20]
|
|
73
|
+
* (rev1), GNSSFWVersion c1[40] (rev2), ProductName c1[40] + the reference
|
|
74
|
+
* position Latitude f8 / Longitude f8 (radians) / Height f4 (m, WGS84)
|
|
75
|
+
* (rev3), and StationCode c1[10] … (rev4). Every trailing field is read
|
|
76
|
+
* only when the block length covers it, so older revisions decode fine.
|
|
77
|
+
*/
|
|
78
|
+
interface SbfReceiverSetup {
|
|
79
|
+
/** Marker (station) name. */
|
|
80
|
+
markerName: string;
|
|
81
|
+
markerNumber: string;
|
|
82
|
+
observer: string;
|
|
83
|
+
agency: string;
|
|
84
|
+
/** Receiver serial number. */
|
|
85
|
+
rxSerialNumber: string;
|
|
86
|
+
/** Receiver GNSS engine name (e.g. "MOSAIC-X5"). */
|
|
87
|
+
rxName: string;
|
|
88
|
+
/** Receiver firmware version. */
|
|
89
|
+
rxVersion: string;
|
|
90
|
+
/** Main antenna serial number. */
|
|
91
|
+
antSerialNumber: string;
|
|
92
|
+
/** Main antenna type (IGS antenna name). */
|
|
93
|
+
antType: string;
|
|
94
|
+
/** Antenna offset from the marker, metres (H/E/N). */
|
|
95
|
+
deltaH: number;
|
|
96
|
+
deltaE: number;
|
|
97
|
+
deltaN: number;
|
|
98
|
+
/** Marker type (rev 1+), e.g. "GEODETIC". */
|
|
99
|
+
markerType: string | null;
|
|
100
|
+
/** GNSS firmware version string (rev 2+). */
|
|
101
|
+
gnssFwVersion: string | null;
|
|
102
|
+
/** Product name (rev 3+). */
|
|
103
|
+
productName: string | null;
|
|
104
|
+
/** Reference latitude, radians (rev 3+), or null if absent/do-not-use. */
|
|
105
|
+
latitude: number | null;
|
|
106
|
+
/** Reference longitude, radians (rev 3+), or null if absent/do-not-use. */
|
|
107
|
+
longitude: number | null;
|
|
108
|
+
/** Reference ellipsoidal height, metres WGS84 (rev 3+), or null. */
|
|
109
|
+
height: number | null;
|
|
110
|
+
/**
|
|
111
|
+
* Reference position as ECEF metres `[x, y, z]` (from lat/lon/height),
|
|
112
|
+
* or null when the block carries no valid reference position. Matches
|
|
113
|
+
* the `StationMeta.position` convention.
|
|
114
|
+
*/
|
|
115
|
+
position: [number, number, number] | null;
|
|
116
|
+
/** Station code, e.g. the 4-char IGS code (rev 4+). */
|
|
117
|
+
stationCode: string | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Decode the ReceiverSetup (5902) block from an SBF byte stream. Returns
|
|
121
|
+
* the LAST valid block (the most recent setup), or null when none is
|
|
122
|
+
* present. Trailing revision fields are decoded only when the block is
|
|
123
|
+
* long enough, so all block revisions are handled.
|
|
124
|
+
*/
|
|
125
|
+
declare function parseSbfReceiverSetup(data: Uint8Array): SbfReceiverSetup | null;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Septentrio SBF raw GPS / QZSS LNAV navigation-bit blocks: GPSRawCA
|
|
129
|
+
* (4017) and QZSRawL1CA (4066) each carry one 300-bit L1 C/A (LNAV)
|
|
130
|
+
* subframe. Subframes 1–3 are assembled per satellite into a Keplerian
|
|
131
|
+
* ephemeris by the shared {@link GpsLnavAssembler} (also behind
|
|
132
|
+
* `parseUbxNav`).
|
|
133
|
+
*
|
|
134
|
+
* Block layout (mosaic-X5 / AsteRx reference guide §4.2.2): after the
|
|
135
|
+
* 8-byte SBF header, TOW u4 + WNc u2 (a full GPS week — no rollover to
|
|
136
|
+
* resolve), SVID u1, CRCPassed u1, ViterbiCnt u1, Source u1, FreqNr u1,
|
|
137
|
+
* RxChannel u1, then NAVBits as u4[10]. Each 32-bit word holds the 24
|
|
138
|
+
* source data bits d_n (already polarity-corrected for D30*) in bits
|
|
139
|
+
* 6–29 with the first received bit as the MSB — so extraction is the
|
|
140
|
+
* same `(word >>> 6) & 0xffffff` u-blox delivers, and the two share
|
|
141
|
+
* {@link GpsLnavAssembler}. Bits 0–5 are the parity bits (unused here:
|
|
142
|
+
* the receiver has already parity-checked, flagged by CRCPassed).
|
|
143
|
+
*/
|
|
144
|
+
|
|
145
|
+
interface SbfGpsNavResult {
|
|
146
|
+
/** Assembled GPS/QZSS LNAV ephemerides in stream order, repeats suppressed. */
|
|
147
|
+
ephemerides: KeplerEphemeris[];
|
|
148
|
+
/** Completed 1/2/3 sets rejected by the IODC/IODE cross-check (dropped). */
|
|
149
|
+
badParity: number;
|
|
150
|
+
/** Total GPSRawCA/QZSRawL1CA blocks seen (with valid SBF framing). */
|
|
151
|
+
messages: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Decode every GPSRawCA (4017) / QZSRawL1CA (4066) block in an SBF byte
|
|
155
|
+
* stream and assemble the carried LNAV subframes into ephemerides
|
|
156
|
+
* (`system` 'G'/'J', same fields and conventions as `parseSbfNav`'s
|
|
157
|
+
* GPSNav/QZSNav records). Only subframes the receiver marked
|
|
158
|
+
* CRC/parity-valid (CRCPassed = 1) are used; the block's full WNc week
|
|
159
|
+
* resolves the 10-bit broadcast week directly.
|
|
160
|
+
*/
|
|
161
|
+
declare function parseSbfGpsNav(data: Uint8Array): SbfGpsNavResult;
|
|
162
|
+
|
|
61
163
|
/**
|
|
62
164
|
* Septentrio SBF raw CNAV navigation-bit blocks: GPSRawL2C (4018) and
|
|
63
165
|
* GPSRawL5 (4019) each carry one 300-bit GPS CNAV message.
|
|
@@ -98,6 +200,71 @@ interface SbfCnavResult {
|
|
|
98
200
|
*/
|
|
99
201
|
declare function parseSbfCnav(data: Uint8Array): SbfCnavResult;
|
|
100
202
|
|
|
203
|
+
/**
|
|
204
|
+
* One-pass SBF navigation decoder.
|
|
205
|
+
*
|
|
206
|
+
* A Septentrio broadcasts navigation data as a mix of *decoded* blocks
|
|
207
|
+
* (GPSNav/GALNav/GLONav/BDSNav/QZSNav — already-parsed ephemeris) and
|
|
208
|
+
* *raw* navigation-frame blocks (GPSRawCA, GALRawINAV/FNAV, GLORawCA,
|
|
209
|
+
* BDSRaw, GPSRawL2C/L5) whose bits must be assembled — and which class a
|
|
210
|
+
* given receiver emits depends on its configuration. The granular
|
|
211
|
+
* `parseSbf*` functions each re-scan the whole stream for one class;
|
|
212
|
+
* this decoder walks the byte stream **once**, routing every navigation
|
|
213
|
+
* block through a single dispatch to the same per-block `feed*` helpers,
|
|
214
|
+
* and returns the merged, de-duplicated result. It is the decoder a
|
|
215
|
+
* consumer that just wants "all the ephemeris in this SBF" should call.
|
|
216
|
+
*
|
|
217
|
+
* Merge/de-dup: assemblers already suppress repeats of an unchanged
|
|
218
|
+
* issue of data within a scan; across the decoded and raw paths, records
|
|
219
|
+
* are de-duped by (prn, time-of-clock, Galileo I/NAV-vs-F/NAV source),
|
|
220
|
+
* so a stream carrying both a decoded GALNav block and the raw I/NAV
|
|
221
|
+
* pages for the same epoch yields one record, while the distinct Galileo
|
|
222
|
+
* I/NAV and F/NAV clock sets are both kept.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
/** Per-source diagnostics — how many blocks of each class were seen. */
|
|
226
|
+
interface SbfNavCounts {
|
|
227
|
+
/** Decoded ephemeris blocks (GPSNav/GALNav/GLONav/BDSNav/QZSNav). */
|
|
228
|
+
decodedNav: number;
|
|
229
|
+
/** Raw GPS/QZSS LNAV blocks (GPSRawCA/QZSRawL1CA). */
|
|
230
|
+
gpsLnavRaw: number;
|
|
231
|
+
/** Raw GPS CNAV blocks (GPSRawL2C/L5). */
|
|
232
|
+
cnavRaw: number;
|
|
233
|
+
/** Raw Galileo page blocks (GALRawINAV/FNAV). */
|
|
234
|
+
galRaw: number;
|
|
235
|
+
/** Raw GLONASS string blocks (GLORawCA). */
|
|
236
|
+
gloRaw: number;
|
|
237
|
+
/** Raw BeiDou D1/D2 subframe blocks (BDSRaw). */
|
|
238
|
+
bdsRaw: number;
|
|
239
|
+
/** Frames dropped by a CRC/parity check across all raw decoders. */
|
|
240
|
+
badFrames: number;
|
|
241
|
+
}
|
|
242
|
+
interface SbfNavigation {
|
|
243
|
+
/**
|
|
244
|
+
* Legacy Keplerian + GLONASS ephemerides, merged from the decoded Nav
|
|
245
|
+
* blocks and the raw GAL I/NAV+F/NAV, GLO strings, BDS D1/D2 and
|
|
246
|
+
* GPS/QZSS LNAV assemblers, de-duped as described in the module header.
|
|
247
|
+
*/
|
|
248
|
+
ephemerides: Ephemeris[];
|
|
249
|
+
/** GPS L2C/L5 CNAV ephemerides (RINEX-4 nav records). */
|
|
250
|
+
cnav: SbfCnavEphemeris[];
|
|
251
|
+
/**
|
|
252
|
+
* Iono coefficient sets keyed like `NavHeader.ionoCorrections`
|
|
253
|
+
* (GPSA/GPSB, GAL, BDSA/BDSB); the last valid block of each type wins.
|
|
254
|
+
*/
|
|
255
|
+
ionoCorrections: Record<string, number[]>;
|
|
256
|
+
/** GPS-UTC ΔtLS from the last GPSUtc block, if any. */
|
|
257
|
+
leapSeconds: number | null;
|
|
258
|
+
counts: SbfNavCounts;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Decode every navigation block in an SBF byte stream in a single pass:
|
|
262
|
+
* decoded ephemeris blocks, raw GPS/QZSS LNAV, GPS CNAV, Galileo I/NAV +
|
|
263
|
+
* F/NAV, GLONASS strings, BeiDou D1/D2, and the Klobuchar/NeQuick iono +
|
|
264
|
+
* GPS-UTC leap-second blocks. See the module header for merge semantics.
|
|
265
|
+
*/
|
|
266
|
+
declare function decodeSbfNavigation(data: Uint8Array): SbfNavigation;
|
|
267
|
+
|
|
101
268
|
/**
|
|
102
269
|
* Septentrio SBF raw Galileo navigation-page blocks: GALRawINAV (4023)
|
|
103
270
|
* carries one I/NAV nominal page pair (234 bits: the 114-bit even part
|
|
@@ -195,18 +362,6 @@ interface SbfGloNavResult {
|
|
|
195
362
|
/** Total GLORawCA blocks seen (with valid SBF framing). */
|
|
196
363
|
messages: number;
|
|
197
364
|
}
|
|
198
|
-
/**
|
|
199
|
-
* Decode every GLORawCA (4026) block in an SBF byte stream and
|
|
200
|
-
* assemble the carried navigation strings into ephemerides (same
|
|
201
|
-
* conventions as `parseSbfNav`'s GLONav records: UTC `tocDate`, RINEX
|
|
202
|
-
* `tauN` sign, km state vectors, `messageFrameTime` in seconds of the
|
|
203
|
-
* UTC week — here from the broadcast tk, see the oracle notes in
|
|
204
|
-
* test/bdsglo-raw.test.ts). The block's TOW/WNc time stamp resolves
|
|
205
|
-
* the GLONASS day; blocks without one (do-not-use) are skipped, as
|
|
206
|
-
* are SVID-62 blocks (GLONASS satellite with unknown slot number).
|
|
207
|
-
* L1 C/A and L2 C/A strings are identical and share one assembler
|
|
208
|
-
* per slot, as in RTKLIB.
|
|
209
|
-
*/
|
|
210
365
|
declare function parseSbfGloNav(data: Uint8Array): SbfGloNavResult;
|
|
211
366
|
|
|
212
367
|
/** Constellations HAS corrects: GPS (GNSS ID 0), Galileo (GNSS ID 2). */
|
|
@@ -444,4 +599,4 @@ interface SbfParseResult {
|
|
|
444
599
|
*/
|
|
445
600
|
declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
|
|
446
601
|
|
|
447
|
-
export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, crc16 as sbfCrc16, scanSbfFrames };
|
|
602
|
+
export { CnavEphemeris, type HasMessage, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavigation, type SbfParseResult, type SbfReceiverSetup, decodeSbfNavigation, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, crc16 as sbfCrc16, scanSbfFrames };
|
package/dist/sbf.js
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
1
|
import {
|
|
2
2
|
crc16,
|
|
3
|
+
decodeSbfNavigation,
|
|
3
4
|
parseSbfAlmanac,
|
|
4
5
|
parseSbfBdsNav,
|
|
5
6
|
parseSbfCnav,
|
|
6
7
|
parseSbfGalNav,
|
|
7
8
|
parseSbfGloNav,
|
|
9
|
+
parseSbfGpsNav,
|
|
8
10
|
parseSbfHas,
|
|
9
11
|
parseSbfIonoUtc,
|
|
10
12
|
parseSbfMeas,
|
|
11
13
|
parseSbfNav,
|
|
14
|
+
parseSbfReceiverSetup,
|
|
12
15
|
scanSbfFrames
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-4TAN27LO.js";
|
|
17
|
+
import "./chunk-FA2UTLEQ.js";
|
|
18
|
+
import "./chunk-37QNKGTC.js";
|
|
19
|
+
import "./chunk-6FAL6P4G.js";
|
|
20
|
+
import "./chunk-YUW33VXK.js";
|
|
21
|
+
import "./chunk-V2D5KUKH.js";
|
|
17
22
|
import "./chunk-HVXYFUCB.js";
|
|
18
23
|
import "./chunk-LEEU5OIO.js";
|
|
19
24
|
export {
|
|
25
|
+
decodeSbfNavigation,
|
|
20
26
|
parseSbfAlmanac,
|
|
21
27
|
parseSbfBdsNav,
|
|
22
28
|
parseSbfCnav,
|
|
23
29
|
parseSbfGalNav,
|
|
24
30
|
parseSbfGloNav,
|
|
31
|
+
parseSbfGpsNav,
|
|
25
32
|
parseSbfHas,
|
|
26
33
|
parseSbfIonoUtc,
|
|
27
34
|
parseSbfMeas,
|
|
28
35
|
parseSbfNav,
|
|
36
|
+
parseSbfReceiverSetup,
|
|
29
37
|
crc16 as sbfCrc16,
|
|
30
38
|
scanSbfFrames
|
|
31
39
|
};
|
package/dist/ubx.cjs
CHANGED
|
@@ -88,6 +88,38 @@ function setBitU(buff, pos, len, data) {
|
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
+
var GpsLnavAssembler = class _GpsLnavAssembler {
|
|
92
|
+
buffers = /* @__PURE__ */ new Map();
|
|
93
|
+
last = /* @__PURE__ */ new Map();
|
|
94
|
+
/** Subframe ID (1–5) from the HOW word of a parity-stripped subframe. */
|
|
95
|
+
static subframeId(subframe) {
|
|
96
|
+
return getBitU(subframe, 43, 3);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Push one parity-stripped 30-byte LNAV subframe for `prn`, resolving
|
|
100
|
+
* the 10-bit week against `refWeek`. See {@link LnavPush} for outcomes.
|
|
101
|
+
*/
|
|
102
|
+
push(prn, subframe, refWeek) {
|
|
103
|
+
const id = _GpsLnavAssembler.subframeId(subframe);
|
|
104
|
+
if (id < 1 || id > 3) return { kind: "skipped" };
|
|
105
|
+
let sf = this.buffers.get(prn);
|
|
106
|
+
if (!sf) {
|
|
107
|
+
sf = { buf: new Uint8Array(90), have: 0 };
|
|
108
|
+
this.buffers.set(prn, sf);
|
|
109
|
+
}
|
|
110
|
+
sf.buf.set(subframe, (id - 1) * 30);
|
|
111
|
+
sf.have |= 1 << id - 1;
|
|
112
|
+
if (id !== 3 || sf.have !== 7) return { kind: "incomplete" };
|
|
113
|
+
const eph = decodeGpsLnavFrame(sf.buf, { prn, refWeek });
|
|
114
|
+
if (!eph) return { kind: "decodeFailed" };
|
|
115
|
+
const prev = this.last.get(prn);
|
|
116
|
+
if (prev && prev.iode === eph.iode && prev.tocDate.getTime() === eph.tocDate.getTime()) {
|
|
117
|
+
return { kind: "duplicate" };
|
|
118
|
+
}
|
|
119
|
+
this.last.set(prn, eph);
|
|
120
|
+
return { kind: "eph", eph };
|
|
121
|
+
}
|
|
122
|
+
};
|
|
91
123
|
function decodeGpsLnavFrame(subframes, opts = {}) {
|
|
92
124
|
if (subframes.length < 90) return null;
|
|
93
125
|
const b = subframes;
|
|
@@ -245,38 +277,19 @@ function parseUbxNav(data, opts = {}) {
|
|
|
245
277
|
}
|
|
246
278
|
}
|
|
247
279
|
if (refWeek === void 0) return { ephemerides, badParity };
|
|
248
|
-
const
|
|
249
|
-
const last = /* @__PURE__ */ new Map();
|
|
280
|
+
const assembler = new GpsLnavAssembler();
|
|
250
281
|
for (const f of ubxFrames(data)) {
|
|
251
282
|
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
252
283
|
const lnav = readLnavSubframe(view, f);
|
|
253
284
|
if (!lnav) continue;
|
|
254
|
-
const { prn,
|
|
285
|
+
const { prn, buff, id } = lnav;
|
|
255
286
|
if (id < 1 || id > 5) {
|
|
256
287
|
badParity++;
|
|
257
288
|
continue;
|
|
258
289
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (!sf) {
|
|
263
|
-
sf = { buf: new Uint8Array(90), have: 0 };
|
|
264
|
-
subframes.set(key, sf);
|
|
265
|
-
}
|
|
266
|
-
sf.buf.set(buff, (id - 1) * 30);
|
|
267
|
-
sf.have |= 1 << id - 1;
|
|
268
|
-
if (id !== 3 || sf.have !== 7) continue;
|
|
269
|
-
const eph = decodeGpsLnavFrame(sf.buf, { prn, refWeek });
|
|
270
|
-
if (!eph) {
|
|
271
|
-
badParity++;
|
|
272
|
-
continue;
|
|
273
|
-
}
|
|
274
|
-
const prev = last.get(prn);
|
|
275
|
-
if (prev && prev.iode === eph.iode && prev.tocDate.getTime() === eph.tocDate.getTime()) {
|
|
276
|
-
continue;
|
|
277
|
-
}
|
|
278
|
-
last.set(prn, eph);
|
|
279
|
-
ephemerides.push(eph);
|
|
290
|
+
const r = assembler.push(prn, buff, refWeek);
|
|
291
|
+
if (r.kind === "eph") ephemerides.push(r.eph);
|
|
292
|
+
else if (r.kind === "decodeFailed") badParity++;
|
|
280
293
|
}
|
|
281
294
|
return { ephemerides, badParity };
|
|
282
295
|
}
|
package/dist/ubx.js
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
parseUbxRawNav,
|
|
6
6
|
parseUbxRawx,
|
|
7
7
|
ubxFrames
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-ZQDLYLQA.js";
|
|
9
|
+
import "./chunk-FA2UTLEQ.js";
|
|
10
|
+
import "./chunk-YUW33VXK.js";
|
|
11
|
+
import "./chunk-V2D5KUKH.js";
|
|
12
12
|
import "./chunk-HVXYFUCB.js";
|
|
13
13
|
import "./chunk-LEEU5OIO.js";
|
|
14
14
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.38.0",
|
|
4
4
|
"description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|