gnss-js 2.10.0 → 2.11.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/README.md +1 -1
- package/dist/binex.d.cts +1 -1
- package/dist/binex.d.ts +1 -1
- package/dist/{chunk-WQX354KD.js → chunk-H3AKFD25.js} +1 -1
- package/dist/{chunk-YUW33VXK.js → chunk-HUXQABJI.js} +2 -0
- package/dist/{chunk-GH7MYXON.js → chunk-IQHQHUOB.js} +3 -3
- package/dist/{chunk-56HM5B6T.js → chunk-MDO77CCC.js} +132 -9
- package/dist/chunk-NL2ORX75.js +319 -0
- package/dist/{chunk-N6GQUHM4.js → chunk-PBENVPFL.js} +1 -1
- package/dist/{chunk-74IVYOQV.js → chunk-RFPR4LKM.js} +110 -4
- package/dist/{chunk-3KSDL3CO.js → chunk-SSWFX3P3.js} +1 -1
- package/dist/{chunk-SEYH4BEN.js → chunk-SZP4TLYR.js} +2 -2
- package/dist/{chunk-K3GLUWZI.js → chunk-UMINQTMK.js} +1 -1
- package/dist/index.cjs +626 -110
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -9
- package/dist/{nav-DImXUdbp.d.ts → nav-COp0Vmlw.d.cts} +83 -2
- package/dist/{nav-DImXUdbp.d.cts → nav-COp0Vmlw.d.ts} +83 -2
- package/dist/{nav-BYmYoh9A.d.cts → nav-CvZXmumD.d.cts} +1 -1
- package/dist/{nav-CN8rxL4h.d.ts → nav-D2DFlVpa.d.ts} +1 -1
- package/dist/novatel.d.cts +1 -1
- package/dist/novatel.d.ts +1 -1
- package/dist/novatel.js +3 -3
- package/dist/orbit.d.cts +2 -2
- package/dist/orbit.d.ts +2 -2
- package/dist/positioning.d.cts +2 -2
- package/dist/positioning.d.ts +2 -2
- package/dist/positioning.js +3 -3
- package/dist/rinex.cjs +140 -11
- package/dist/rinex.d.cts +9 -6
- package/dist/rinex.d.ts +9 -6
- package/dist/rinex.js +3 -2
- package/dist/rtcm3.cjs +1 -1
- package/dist/rtcm3.js +1 -1
- package/dist/sbf.cjs +420 -24
- package/dist/sbf.d.cts +46 -5
- package/dist/sbf.d.ts +46 -5
- package/dist/sbf.js +7 -4
- package/dist/trimble.d.cts +1 -1
- package/dist/trimble.d.ts +1 -1
- package/dist/ubx.d.cts +1 -1
- package/dist/ubx.d.ts +1 -1
- package/dist/ubx.js +4 -4
- package/package.json +1 -1
package/dist/sbf.cjs
CHANGED
|
@@ -30,6 +30,7 @@ __export(sbf_exports, {
|
|
|
30
30
|
isSbasL1Preamble: () => isSbasL1Preamble,
|
|
31
31
|
isSbasL5Correction: () => isSbasL5Correction,
|
|
32
32
|
parseSbfAlmanac: () => parseSbfAlmanac,
|
|
33
|
+
parseSbfBdsCnav: () => parseSbfBdsCnav,
|
|
33
34
|
parseSbfBdsNav: () => parseSbfBdsNav,
|
|
34
35
|
parseSbfCnav: () => parseSbfCnav,
|
|
35
36
|
parseSbfGalNav: () => parseSbfGalNav,
|
|
@@ -942,7 +943,7 @@ var isc = (b, pos) => {
|
|
|
942
943
|
return raw === -4096 ? null : raw * 2 ** -35;
|
|
943
944
|
};
|
|
944
945
|
function decodeClock(b, msgType) {
|
|
945
|
-
const
|
|
946
|
+
const clock2 = {
|
|
946
947
|
msgType,
|
|
947
948
|
top: getBitU(b, 38, 11) * 300,
|
|
948
949
|
uraNed0: getBitS(b, 49, 5),
|
|
@@ -954,26 +955,26 @@ function decodeClock(b, msgType) {
|
|
|
954
955
|
af2: getBitS(b, 117, 10) * 2 ** -60
|
|
955
956
|
};
|
|
956
957
|
if (msgType === 30) {
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
958
|
+
clock2.tgd = isc(b, 127);
|
|
959
|
+
clock2.iscL1ca = isc(b, 140);
|
|
960
|
+
clock2.iscL2c = isc(b, 153);
|
|
961
|
+
clock2.iscL5i5 = isc(b, 166);
|
|
962
|
+
clock2.iscL5q5 = isc(b, 179);
|
|
963
|
+
clock2.ionoAlpha = [
|
|
963
964
|
getBitS(b, 192, 8) * 2 ** -30,
|
|
964
965
|
getBitS(b, 200, 8) * 2 ** -27,
|
|
965
966
|
getBitS(b, 208, 8) * 2 ** -24,
|
|
966
967
|
getBitS(b, 216, 8) * 2 ** -24
|
|
967
968
|
];
|
|
968
|
-
|
|
969
|
+
clock2.ionoBeta = [
|
|
969
970
|
getBitS(b, 224, 8) * 2 ** 11,
|
|
970
971
|
getBitS(b, 232, 8) * 2 ** 14,
|
|
971
972
|
getBitS(b, 240, 8) * 2 ** 16,
|
|
972
973
|
getBitS(b, 248, 8) * 2 ** 16
|
|
973
974
|
];
|
|
974
|
-
|
|
975
|
+
clock2.wnOp = getBitU(b, 256, 8);
|
|
975
976
|
}
|
|
976
|
-
return
|
|
977
|
+
return clock2;
|
|
977
978
|
}
|
|
978
979
|
function resolveWeek(week, towSec, sec) {
|
|
979
980
|
if (sec < towSec - HALF_WEEK) return week + 1;
|
|
@@ -1011,10 +1012,10 @@ var CnavAssembler = class {
|
|
|
1011
1012
|
return this.tryEmit(prn, sat);
|
|
1012
1013
|
}
|
|
1013
1014
|
tryEmit(prn, sat) {
|
|
1014
|
-
const { t10, t11, clock, extras } = sat;
|
|
1015
|
-
if (!t10 || !t11 || !
|
|
1016
|
-
if (t10.toe !== t11.toe ||
|
|
1017
|
-
const key = `${t10.week}:${t10.toe}:${
|
|
1015
|
+
const { t10, t11, clock: clock2, extras } = sat;
|
|
1016
|
+
if (!t10 || !t11 || !clock2) return null;
|
|
1017
|
+
if (t10.toe !== t11.toe || clock2.toc !== t10.toe) return null;
|
|
1018
|
+
const key = `${t10.week}:${t10.toe}:${clock2.af0}:${clock2.af1}`;
|
|
1018
1019
|
if (key === sat.lastKey) return null;
|
|
1019
1020
|
sat.lastKey = key;
|
|
1020
1021
|
const weekToe = resolveWeek(t10.week, t10.tow, t10.toe);
|
|
@@ -1025,9 +1026,9 @@ var CnavAssembler = class {
|
|
|
1025
1026
|
week: t10.week,
|
|
1026
1027
|
health: t10.health,
|
|
1027
1028
|
uraEd: t10.uraEd,
|
|
1028
|
-
uraNed0:
|
|
1029
|
-
uraNed1:
|
|
1030
|
-
uraNed2:
|
|
1029
|
+
uraNed0: clock2.uraNed0,
|
|
1030
|
+
uraNed1: clock2.uraNed1,
|
|
1031
|
+
uraNed2: clock2.uraNed2,
|
|
1031
1032
|
top: t10.top,
|
|
1032
1033
|
toe: t10.toe,
|
|
1033
1034
|
toeDate: gpsDate(weekToe, t10.toe),
|
|
@@ -1050,12 +1051,12 @@ var CnavAssembler = class {
|
|
|
1050
1051
|
crc: t11.crc,
|
|
1051
1052
|
cus: t11.cus,
|
|
1052
1053
|
cuc: t11.cuc,
|
|
1053
|
-
toc:
|
|
1054
|
-
tocDate: gpsDate(weekToe,
|
|
1055
|
-
af0:
|
|
1056
|
-
af1:
|
|
1057
|
-
af2:
|
|
1058
|
-
clockMsgType:
|
|
1054
|
+
toc: clock2.toc,
|
|
1055
|
+
tocDate: gpsDate(weekToe, clock2.toc),
|
|
1056
|
+
af0: clock2.af0,
|
|
1057
|
+
af1: clock2.af1,
|
|
1058
|
+
af2: clock2.af2,
|
|
1059
|
+
clockMsgType: clock2.msgType,
|
|
1059
1060
|
tgd: extras?.tgd ?? null,
|
|
1060
1061
|
iscL1ca: extras?.iscL1ca ?? null,
|
|
1061
1062
|
iscL2c: extras?.iscL2c ?? null,
|
|
@@ -2168,6 +2169,378 @@ function parseSbfGloNav(data) {
|
|
|
2168
2169
|
return { ephemerides, badCrc, messages };
|
|
2169
2170
|
}
|
|
2170
2171
|
|
|
2172
|
+
// src/navbits/bds-cnav.ts
|
|
2173
|
+
var BDT_EPOCH_MS3 = Date.UTC(2006, 0, 1);
|
|
2174
|
+
var SEC_PER_WEEK8 = 7 * 86400;
|
|
2175
|
+
var HALF_WEEK4 = 302400;
|
|
2176
|
+
var BDS_CNAV_A_REF_MEO = 27906100;
|
|
2177
|
+
var BDS_CNAV_A_REF_IGSO_GEO = 42162200;
|
|
2178
|
+
function bdsCnavAref(satType) {
|
|
2179
|
+
return satType === 3 ? BDS_CNAV_A_REF_MEO : BDS_CNAV_A_REF_IGSO_GEO;
|
|
2180
|
+
}
|
|
2181
|
+
function ephI(b, p) {
|
|
2182
|
+
return {
|
|
2183
|
+
toe: getBitU(b, p, 11) * 300,
|
|
2184
|
+
satType: getBitU(b, p + 11, 2),
|
|
2185
|
+
deltaA: getBitS(b, p + 13, 26) * 2 ** -9,
|
|
2186
|
+
aDot: getBitS(b, p + 39, 25) * 2 ** -21,
|
|
2187
|
+
deltaN0: getBitS(b, p + 64, 17) * 2 ** -44 * GPS_PI,
|
|
2188
|
+
deltaN0Dot: getBitS(b, p + 81, 23) * 2 ** -57 * GPS_PI,
|
|
2189
|
+
m0: getBitS33(b, p + 104) * 2 ** -32 * GPS_PI,
|
|
2190
|
+
e: getBitU33(b, p + 137) * 2 ** -34,
|
|
2191
|
+
omega: getBitS33(b, p + 170) * 2 ** -32 * GPS_PI
|
|
2192
|
+
};
|
|
2193
|
+
}
|
|
2194
|
+
function ephII(b, p) {
|
|
2195
|
+
return {
|
|
2196
|
+
omega0: getBitS33(b, p) * 2 ** -32 * GPS_PI,
|
|
2197
|
+
i0: getBitS33(b, p + 33) * 2 ** -32 * GPS_PI,
|
|
2198
|
+
omegaDot: getBitS(b, p + 66, 19) * 2 ** -44 * GPS_PI,
|
|
2199
|
+
i0Dot: getBitS(b, p + 85, 15) * 2 ** -44 * GPS_PI,
|
|
2200
|
+
cis: getBitS(b, p + 100, 16) * 2 ** -30,
|
|
2201
|
+
cic: getBitS(b, p + 116, 16) * 2 ** -30,
|
|
2202
|
+
crs: getBitS(b, p + 132, 24) * 2 ** -8,
|
|
2203
|
+
crc: getBitS(b, p + 156, 24) * 2 ** -8,
|
|
2204
|
+
cus: getBitS(b, p + 180, 21) * 2 ** -30,
|
|
2205
|
+
cuc: getBitS(b, p + 201, 21) * 2 ** -30
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2208
|
+
function clock(b, p) {
|
|
2209
|
+
return {
|
|
2210
|
+
toc: getBitU(b, p, 11) * 300,
|
|
2211
|
+
af0: getBitS(b, p + 11, 25) * 2 ** -34,
|
|
2212
|
+
af1: getBitS(b, p + 36, 22) * 2 ** -50,
|
|
2213
|
+
af2: getBitS(b, p + 58, 11) * 2 ** -66
|
|
2214
|
+
};
|
|
2215
|
+
}
|
|
2216
|
+
function sisaiOc(b, p) {
|
|
2217
|
+
return {
|
|
2218
|
+
top: getBitU(b, p, 11) * 300,
|
|
2219
|
+
ocb: getBitS(b, p + 11, 5),
|
|
2220
|
+
oc1: getBitS(b, p + 16, 3),
|
|
2221
|
+
oc2: getBitS(b, p + 19, 3)
|
|
2222
|
+
};
|
|
2223
|
+
}
|
|
2224
|
+
var delay = (b, p) => getBitS(b, p, 12) * 2 ** -34;
|
|
2225
|
+
function crcOk(msg, dataBits) {
|
|
2226
|
+
const need = Math.ceil((dataBits + 24) / 8);
|
|
2227
|
+
return msg.length >= need && crc24q(msg, dataBits) === getBitU(msg, dataBits, 24);
|
|
2228
|
+
}
|
|
2229
|
+
var bdsCnav1Sf2CrcOk = (sf2) => crcOk(sf2, 576);
|
|
2230
|
+
var bdsCnav1Sf3CrcOk = (sf3) => crcOk(sf3, 240);
|
|
2231
|
+
var bdsCnav2CrcOk = (msg) => crcOk(msg, 264);
|
|
2232
|
+
var bdsCnav3CrcOk = (msg) => crcOk(msg, 462);
|
|
2233
|
+
function resolveWeek2(week, towSec, sec) {
|
|
2234
|
+
if (sec < towSec - HALF_WEEK4) return week + 1;
|
|
2235
|
+
if (sec > towSec + HALF_WEEK4) return week - 1;
|
|
2236
|
+
return week;
|
|
2237
|
+
}
|
|
2238
|
+
function bdtDate(week, sec) {
|
|
2239
|
+
return new Date(BDT_EPOCH_MS3 + (week * SEC_PER_WEEK8 + sec) * 1e3);
|
|
2240
|
+
}
|
|
2241
|
+
var emptyStatus = () => ({
|
|
2242
|
+
top: null,
|
|
2243
|
+
sisaiOe: null,
|
|
2244
|
+
sisaiOcb: null,
|
|
2245
|
+
sisaiOc1: null,
|
|
2246
|
+
sisaiOc2: null,
|
|
2247
|
+
sismai: null,
|
|
2248
|
+
health: null,
|
|
2249
|
+
integrityFlags: null
|
|
2250
|
+
});
|
|
2251
|
+
function applyOc(s, oc) {
|
|
2252
|
+
s.top = oc.top;
|
|
2253
|
+
s.sisaiOcb = oc.ocb;
|
|
2254
|
+
s.sisaiOc1 = oc.oc1;
|
|
2255
|
+
s.sisaiOc2 = oc.oc2;
|
|
2256
|
+
}
|
|
2257
|
+
function build(message, prn, wn, tTm, e1, e2, c, d, s) {
|
|
2258
|
+
const week = resolveWeek2(wn, tTm, e1.toe);
|
|
2259
|
+
const weekToc = resolveWeek2(wn, tTm, c.toc);
|
|
2260
|
+
return {
|
|
2261
|
+
system: "C",
|
|
2262
|
+
prn,
|
|
2263
|
+
message,
|
|
2264
|
+
week,
|
|
2265
|
+
toe: e1.toe,
|
|
2266
|
+
toeDate: bdtDate(week, e1.toe),
|
|
2267
|
+
toc: c.toc,
|
|
2268
|
+
tocDate: bdtDate(weekToc, c.toc),
|
|
2269
|
+
satType: e1.satType,
|
|
2270
|
+
a: bdsCnavAref(e1.satType) + e1.deltaA,
|
|
2271
|
+
deltaA: e1.deltaA,
|
|
2272
|
+
aDot: e1.aDot,
|
|
2273
|
+
deltaN0: e1.deltaN0,
|
|
2274
|
+
deltaN0Dot: e1.deltaN0Dot,
|
|
2275
|
+
m0: e1.m0,
|
|
2276
|
+
e: e1.e,
|
|
2277
|
+
omega: e1.omega,
|
|
2278
|
+
...e2,
|
|
2279
|
+
af0: c.af0,
|
|
2280
|
+
af1: c.af1,
|
|
2281
|
+
af2: c.af2,
|
|
2282
|
+
...d,
|
|
2283
|
+
...s,
|
|
2284
|
+
tow: tTm
|
|
2285
|
+
};
|
|
2286
|
+
}
|
|
2287
|
+
var prnLabel = (prn) => `C${String(prn).padStart(2, "0")}`;
|
|
2288
|
+
var BdsCnav1Assembler = class {
|
|
2289
|
+
status = /* @__PURE__ */ new Map();
|
|
2290
|
+
lastKey = /* @__PURE__ */ new Map();
|
|
2291
|
+
/**
|
|
2292
|
+
* Push one frame's CRC-valid subframes (bit-0 aligned; pass null for
|
|
2293
|
+
* a subframe that failed its CRC) for satellite `prn` (1-63). `tTm`
|
|
2294
|
+
* is the frame's transmit time, s of the BDT week. Returns the newly
|
|
2295
|
+
* seen ephemeris, or null.
|
|
2296
|
+
*/
|
|
2297
|
+
push(prn, sf2, sf3, tTm) {
|
|
2298
|
+
let s = this.status.get(prn);
|
|
2299
|
+
if (!s) this.status.set(prn, s = emptyStatus());
|
|
2300
|
+
if (sf3) {
|
|
2301
|
+
const page = getBitU(sf3, 0, 6);
|
|
2302
|
+
if (page >= 1 && page <= 4) {
|
|
2303
|
+
s.health = getBitU(sf3, 6, 2);
|
|
2304
|
+
s.integrityFlags = getBitU(sf3, 8, 3);
|
|
2305
|
+
s.sismai = getBitU(sf3, 11, 4);
|
|
2306
|
+
if (page === 1) {
|
|
2307
|
+
s.sisaiOe = getBitU(sf3, 15, 5);
|
|
2308
|
+
applyOc(s, sisaiOc(sf3, 20));
|
|
2309
|
+
} else if (page === 3) s.sisaiOe = getBitU(sf3, 15, 5);
|
|
2310
|
+
else applyOc(s, sisaiOc(sf3, 15));
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
2313
|
+
if (!sf2) return null;
|
|
2314
|
+
const wn = getBitU(sf2, 0, 13);
|
|
2315
|
+
const iodc = getBitU(sf2, 21, 10);
|
|
2316
|
+
const iode = getBitU(sf2, 31, 8);
|
|
2317
|
+
const e1 = ephI(sf2, 39);
|
|
2318
|
+
const c = clock(sf2, 464);
|
|
2319
|
+
const key = `${wn}:${iodc}:${iode}:${e1.toe}:${c.toc}`;
|
|
2320
|
+
if (this.lastKey.get(prn) === key) return null;
|
|
2321
|
+
this.lastKey.set(prn, key);
|
|
2322
|
+
return build(
|
|
2323
|
+
"CNV1",
|
|
2324
|
+
prnLabel(prn),
|
|
2325
|
+
wn,
|
|
2326
|
+
tTm,
|
|
2327
|
+
e1,
|
|
2328
|
+
ephII(sf2, 242),
|
|
2329
|
+
c,
|
|
2330
|
+
{
|
|
2331
|
+
iode,
|
|
2332
|
+
iodc,
|
|
2333
|
+
tgdB1Cp: delay(sf2, 557),
|
|
2334
|
+
tgdB2ap: delay(sf2, 533),
|
|
2335
|
+
iscB1Cd: delay(sf2, 545),
|
|
2336
|
+
iscB2ad: null,
|
|
2337
|
+
tgdB2bI: null
|
|
2338
|
+
},
|
|
2339
|
+
{ ...s }
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
};
|
|
2343
|
+
var BdsCnav2Assembler = class {
|
|
2344
|
+
sats = /* @__PURE__ */ new Map();
|
|
2345
|
+
/**
|
|
2346
|
+
* Push one CRC-valid 288-bit message (bit 0 = first PRN bit, the
|
|
2347
|
+
* preamble stripped). Returns the newly completed ephemeris, or null.
|
|
2348
|
+
*/
|
|
2349
|
+
push(msg) {
|
|
2350
|
+
const prn = getBitU(msg, 0, 6);
|
|
2351
|
+
const type = getBitU(msg, 6, 6);
|
|
2352
|
+
const sow = getBitU(msg, 12, 18) * 3;
|
|
2353
|
+
if (prn < 1) return null;
|
|
2354
|
+
let sat = this.sats.get(prn);
|
|
2355
|
+
if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
|
|
2356
|
+
const s = sat.status;
|
|
2357
|
+
if (type === 10) {
|
|
2358
|
+
sat.t10 = {
|
|
2359
|
+
wn: getBitU(msg, 30, 13),
|
|
2360
|
+
iode: getBitU(msg, 53, 8),
|
|
2361
|
+
e1: ephI(msg, 61),
|
|
2362
|
+
sow
|
|
2363
|
+
};
|
|
2364
|
+
s.integrityFlags = getBitU(msg, 43, 3) << 3 | getBitU(msg, 50, 3);
|
|
2365
|
+
s.sismai = getBitU(msg, 46, 4);
|
|
2366
|
+
if (sat.t11 && sat.t11.sow < sow) sat.t11 = void 0;
|
|
2367
|
+
} else if (type === 11 || type >= 30 && type <= 34 || type === 40) {
|
|
2368
|
+
s.health = getBitU(msg, 30, 2);
|
|
2369
|
+
s.integrityFlags = getBitU(msg, 32, 3) << 3 | getBitU(msg, 39, 3);
|
|
2370
|
+
s.sismai = getBitU(msg, 35, 4);
|
|
2371
|
+
if (type === 11) {
|
|
2372
|
+
if (!sat.t10 || sow <= sat.t10.sow) return null;
|
|
2373
|
+
sat.t11 = { e2: ephII(msg, 42), sow };
|
|
2374
|
+
} else if (type === 34) {
|
|
2375
|
+
applyOc(s, sisaiOc(msg, 42));
|
|
2376
|
+
sat.clock = { c: clock(msg, 64), iodc: getBitU(msg, 133, 10) };
|
|
2377
|
+
} else if (type === 40) {
|
|
2378
|
+
s.sisaiOe = getBitU(msg, 42, 5);
|
|
2379
|
+
applyOc(s, sisaiOc(msg, 47));
|
|
2380
|
+
return null;
|
|
2381
|
+
} else {
|
|
2382
|
+
sat.clock = { c: clock(msg, 42), iodc: getBitU(msg, 111, 10) };
|
|
2383
|
+
if (type === 30)
|
|
2384
|
+
sat.delays = {
|
|
2385
|
+
tgdB2ap: delay(msg, 121),
|
|
2386
|
+
iscB2ad: delay(msg, 133),
|
|
2387
|
+
tgdB1Cp: delay(msg, 219)
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
} else return null;
|
|
2391
|
+
const { t10, t11, clock: ck } = sat;
|
|
2392
|
+
if (!t10 || !t11 || !ck || (ck.iodc & 255) !== t10.iode) return null;
|
|
2393
|
+
const key = `${t10.wn}:${ck.iodc}:${t10.iode}:${t10.e1.toe}:${ck.c.toc}`;
|
|
2394
|
+
if (sat.lastKey === key) return null;
|
|
2395
|
+
sat.lastKey = key;
|
|
2396
|
+
return build(
|
|
2397
|
+
"CNV2",
|
|
2398
|
+
prnLabel(prn),
|
|
2399
|
+
t10.wn,
|
|
2400
|
+
t10.sow,
|
|
2401
|
+
t10.e1,
|
|
2402
|
+
t11.e2,
|
|
2403
|
+
ck.c,
|
|
2404
|
+
{
|
|
2405
|
+
iode: t10.iode,
|
|
2406
|
+
iodc: ck.iodc,
|
|
2407
|
+
tgdB1Cp: sat.delays?.tgdB1Cp ?? null,
|
|
2408
|
+
tgdB2ap: sat.delays?.tgdB2ap ?? null,
|
|
2409
|
+
iscB1Cd: null,
|
|
2410
|
+
iscB2ad: sat.delays?.iscB2ad ?? null,
|
|
2411
|
+
tgdB2bI: null
|
|
2412
|
+
},
|
|
2413
|
+
{ ...s }
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
};
|
|
2417
|
+
var BdsCnav3Assembler = class {
|
|
2418
|
+
sats = /* @__PURE__ */ new Map();
|
|
2419
|
+
/**
|
|
2420
|
+
* Push one CRC-valid 486-bit message (bit 0 = first MesType bit) from
|
|
2421
|
+
* satellite `prn`. Returns the newly completed ephemeris, or null.
|
|
2422
|
+
*/
|
|
2423
|
+
push(prn, msg) {
|
|
2424
|
+
const type = getBitU(msg, 0, 6);
|
|
2425
|
+
const sow = getBitU(msg, 6, 20);
|
|
2426
|
+
let sat = this.sats.get(prn);
|
|
2427
|
+
if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
|
|
2428
|
+
const s = sat.status;
|
|
2429
|
+
if (type === 10) {
|
|
2430
|
+
sat.t10 = { e1: ephI(msg, 30), e2: ephII(msg, 233), sow };
|
|
2431
|
+
s.integrityFlags = getBitU(msg, 455, 3);
|
|
2432
|
+
s.sismai = getBitU(msg, 458, 4);
|
|
2433
|
+
} else if (type === 30) {
|
|
2434
|
+
sat.t30 = {
|
|
2435
|
+
wn: getBitU(msg, 26, 13),
|
|
2436
|
+
c: clock(msg, 43),
|
|
2437
|
+
tgd: delay(msg, 112)
|
|
2438
|
+
};
|
|
2439
|
+
applyOc(s, sisaiOc(msg, 433));
|
|
2440
|
+
s.sisaiOe = getBitU(msg, 455, 5);
|
|
2441
|
+
s.health = getBitU(msg, 460, 2);
|
|
2442
|
+
} else return null;
|
|
2443
|
+
const { t10, t30 } = sat;
|
|
2444
|
+
if (!t10 || !t30 || t10.e1.toe !== t30.c.toc) return null;
|
|
2445
|
+
const key = `${t30.wn}:${t10.e1.toe}:${t30.c.af0}:${t10.e1.m0}`;
|
|
2446
|
+
if (sat.lastKey === key) return null;
|
|
2447
|
+
sat.lastKey = key;
|
|
2448
|
+
return build(
|
|
2449
|
+
"CNV3",
|
|
2450
|
+
prnLabel(prn),
|
|
2451
|
+
t30.wn,
|
|
2452
|
+
t10.sow,
|
|
2453
|
+
t10.e1,
|
|
2454
|
+
t10.e2,
|
|
2455
|
+
t30.c,
|
|
2456
|
+
{
|
|
2457
|
+
iode: null,
|
|
2458
|
+
iodc: null,
|
|
2459
|
+
tgdB1Cp: null,
|
|
2460
|
+
tgdB2ap: null,
|
|
2461
|
+
iscB1Cd: null,
|
|
2462
|
+
iscB2ad: null,
|
|
2463
|
+
tgdB2bI: t30.tgd
|
|
2464
|
+
},
|
|
2465
|
+
{ ...s }
|
|
2466
|
+
);
|
|
2467
|
+
}
|
|
2468
|
+
};
|
|
2469
|
+
|
|
2470
|
+
// src/sbf/rawnav-bds-cnav.ts
|
|
2471
|
+
var GPS_BDT_OFFSET = 14;
|
|
2472
|
+
var B1C_FRAME_S = 18;
|
|
2473
|
+
var TOW_DNU2 = 4294967295;
|
|
2474
|
+
function newBdsCnavAssemblers() {
|
|
2475
|
+
return {
|
|
2476
|
+
b1c: new BdsCnav1Assembler(),
|
|
2477
|
+
b2a: new BdsCnav2Assembler(),
|
|
2478
|
+
b2b: new BdsCnav3Assembler()
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
function navBits(view, wordsAt, start, nBits) {
|
|
2482
|
+
const out = new Uint8Array(Math.ceil(nBits / 8));
|
|
2483
|
+
for (let i = 0; i < nBits; i++) {
|
|
2484
|
+
const p = start + i;
|
|
2485
|
+
const w = view.getUint32(wordsAt + 4 * (p >>> 5), true);
|
|
2486
|
+
if (w >>> 31 - (p & 31) & 1) out[i >> 3] |= 128 >> (i & 7);
|
|
2487
|
+
}
|
|
2488
|
+
return out;
|
|
2489
|
+
}
|
|
2490
|
+
var MIN_LEN = { 4218: 248, 4219: 92, 4242: 144 };
|
|
2491
|
+
function feedBdsCnavBlock(view, b, id, len, asm) {
|
|
2492
|
+
if (len < (MIN_LEN[id] ?? Infinity)) return {};
|
|
2493
|
+
const prnStr = svidToPrn(view.getUint8(b + 14));
|
|
2494
|
+
if (!prnStr || prnStr[0] !== "C") return {};
|
|
2495
|
+
const prn = Number(prnStr.slice(1));
|
|
2496
|
+
const words = b + 20;
|
|
2497
|
+
if (id === 4218) {
|
|
2498
|
+
const towMs = view.getUint32(b + 8, true);
|
|
2499
|
+
if (towMs === TOW_DNU2) return {};
|
|
2500
|
+
const sf2 = navBits(view, words, 72, 600);
|
|
2501
|
+
const sf3 = navBits(view, words, 1272, 264);
|
|
2502
|
+
const sf2Ok = bdsCnav1Sf2CrcOk(sf2);
|
|
2503
|
+
const bdt = (towMs / 1e3 - GPS_BDT_OFFSET + 604800) % 604800;
|
|
2504
|
+
const tTm = (Math.floor(bdt) - B1C_FRAME_S + 604800) % 604800;
|
|
2505
|
+
const eph = asm.b1c.push(
|
|
2506
|
+
prn,
|
|
2507
|
+
sf2Ok ? sf2 : null,
|
|
2508
|
+
bdsCnav1Sf3CrcOk(sf3) ? sf3 : null,
|
|
2509
|
+
tTm
|
|
2510
|
+
);
|
|
2511
|
+
if (!sf2Ok) return { badCrc: true };
|
|
2512
|
+
return eph ? { eph } : {};
|
|
2513
|
+
}
|
|
2514
|
+
if (id === 4219) {
|
|
2515
|
+
const msg = navBits(view, words, 0, 288);
|
|
2516
|
+
if (!bdsCnav2CrcOk(msg)) return { badCrc: true };
|
|
2517
|
+
const eph = asm.b2a.push(msg);
|
|
2518
|
+
return eph ? { eph } : {};
|
|
2519
|
+
}
|
|
2520
|
+
if (id === 4242) {
|
|
2521
|
+
const msg = navBits(view, words, 12, 486);
|
|
2522
|
+
if (!bdsCnav3CrcOk(msg)) return { badCrc: true };
|
|
2523
|
+
const eph = asm.b2b.push(prn, msg);
|
|
2524
|
+
return eph ? { eph } : {};
|
|
2525
|
+
}
|
|
2526
|
+
return {};
|
|
2527
|
+
}
|
|
2528
|
+
function parseSbfBdsCnav(data) {
|
|
2529
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
2530
|
+
const asm = newBdsCnavAssemblers();
|
|
2531
|
+
const ephemerides = [];
|
|
2532
|
+
let badCrc = 0;
|
|
2533
|
+
let messages = 0;
|
|
2534
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
2535
|
+
if (id !== 4218 && id !== 4219 && id !== 4242) return;
|
|
2536
|
+
messages++;
|
|
2537
|
+
const r = feedBdsCnavBlock(view, b, id, len, asm);
|
|
2538
|
+
if (r.eph) ephemerides.push(r.eph);
|
|
2539
|
+
else if (r.badCrc) badCrc++;
|
|
2540
|
+
});
|
|
2541
|
+
return { ephemerides, badCrc, messages };
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2171
2544
|
// src/navbits/sbas.ts
|
|
2172
2545
|
var GPS_EPOCH_MS9 = Date.UTC(1980, 0, 6);
|
|
2173
2546
|
var MS_PER_WEEK4 = 7 * 86400 * 1e3;
|
|
@@ -2353,6 +2726,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2353
2726
|
const ephemerides = [];
|
|
2354
2727
|
const seen = /* @__PURE__ */ new Set();
|
|
2355
2728
|
const cnav = [];
|
|
2729
|
+
const bdsCnav = [];
|
|
2356
2730
|
const ionoCorrections = {};
|
|
2357
2731
|
let leapSeconds = null;
|
|
2358
2732
|
const counts = {
|
|
@@ -2362,6 +2736,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2362
2736
|
galRaw: 0,
|
|
2363
2737
|
gloRaw: 0,
|
|
2364
2738
|
bdsRaw: 0,
|
|
2739
|
+
bdsCnavRaw: 0,
|
|
2365
2740
|
sbasRaw: 0,
|
|
2366
2741
|
sbasL5Raw: 0,
|
|
2367
2742
|
navicRaw: 0,
|
|
@@ -2373,6 +2748,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2373
2748
|
const galAsm = newGalAssemblers();
|
|
2374
2749
|
const gloAsm = new GloStringAssembler();
|
|
2375
2750
|
const bdsAsm = new BdsAssembler();
|
|
2751
|
+
const bdsCnavAsm = newBdsCnavAssemblers();
|
|
2376
2752
|
const lnavAsm = new GpsLnavAssembler();
|
|
2377
2753
|
const navicAsm = new NavicAssembler();
|
|
2378
2754
|
const addEph = (e) => {
|
|
@@ -2479,6 +2855,17 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2479
2855
|
else if (r.badCrc) counts.badFrames++;
|
|
2480
2856
|
return;
|
|
2481
2857
|
}
|
|
2858
|
+
case 4218:
|
|
2859
|
+
// BDSRawB1C
|
|
2860
|
+
case 4219:
|
|
2861
|
+
// BDSRawB2a
|
|
2862
|
+
case 4242: {
|
|
2863
|
+
counts.bdsCnavRaw++;
|
|
2864
|
+
const r = feedBdsCnavBlock(view, b, id, len, bdsCnavAsm);
|
|
2865
|
+
if (r.eph) bdsCnav.push(r.eph);
|
|
2866
|
+
else if (r.badCrc) counts.badFrames++;
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2482
2869
|
case 4020: {
|
|
2483
2870
|
if (len < 52) return;
|
|
2484
2871
|
counts.sbasRaw++;
|
|
@@ -2535,7 +2922,15 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
2535
2922
|
prns: [...dfmcPrns].sort(),
|
|
2536
2923
|
messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
|
|
2537
2924
|
};
|
|
2538
|
-
return {
|
|
2925
|
+
return {
|
|
2926
|
+
ephemerides,
|
|
2927
|
+
cnav,
|
|
2928
|
+
bdsCnav,
|
|
2929
|
+
ionoCorrections,
|
|
2930
|
+
leapSeconds,
|
|
2931
|
+
dfmc,
|
|
2932
|
+
counts
|
|
2933
|
+
};
|
|
2539
2934
|
}
|
|
2540
2935
|
|
|
2541
2936
|
// src/navbits/rs255.ts
|
|
@@ -3740,6 +4135,7 @@ function parseSbfMeas(data) {
|
|
|
3740
4135
|
isSbasL1Preamble,
|
|
3741
4136
|
isSbasL5Correction,
|
|
3742
4137
|
parseSbfAlmanac,
|
|
4138
|
+
parseSbfBdsCnav,
|
|
3743
4139
|
parseSbfBdsNav,
|
|
3744
4140
|
parseSbfCnav,
|
|
3745
4141
|
parseSbfGalNav,
|
package/dist/sbf.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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-
|
|
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-CvZXmumD.cjs';
|
|
2
2
|
import { R as ReceiverPvt } from './receiver-pvt-CVFvi4kT.cjs';
|
|
3
|
-
import { K as KeplerEphemeris, C as CnavEphemeris, G as GlonassEphemeris, E as Ephemeris } from './nav-
|
|
3
|
+
import { K as KeplerEphemeris, C as CnavEphemeris, B as BdsCnavEphemeris, G as GlonassEphemeris, E as Ephemeris } from './nav-COp0Vmlw.cjs';
|
|
4
4
|
import { H as HasMessage } from './has-BaXnQarR.cjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -273,6 +273,43 @@ interface SbfCnavResult {
|
|
|
273
273
|
*/
|
|
274
274
|
declare function parseSbfCnav(data: Uint8Array): SbfCnavResult;
|
|
275
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Septentrio SBF raw BeiDou-3 navigation blocks — BDSRawB1C (4218),
|
|
278
|
+
* BDSRawB2a (4219) and BDSRawB2b (4242) — into B-CNAV1/2/3 ephemerides.
|
|
279
|
+
*
|
|
280
|
+
* Block layout: after the 8-byte SBF header, TOW u4 + WNc u2, SVID u1,
|
|
281
|
+
* then CRCPassed u1 (B1C: CRCSF2 u1 + CRCSF3 u1), Source/Reserved
|
|
282
|
+
* bytes, RxChannel u1, and NAVBits as u4 words at +20 — the first bit
|
|
283
|
+
* is the MSB of NAVBits[0], each u4 little-endian in the stream. The
|
|
284
|
+
* receiver has already run the LDPC decoding; the positions inside
|
|
285
|
+
* NAVBits were established on TU Delft DLF500 captures (every message
|
|
286
|
+
* passes CRC-24Q at these offsets) and the decoded fields match DLR's
|
|
287
|
+
* BRD400DLR RINEX 4 records:
|
|
288
|
+
*
|
|
289
|
+
* - B1C (u4[57]): subframe 1 as its 72 raw BCH symbols, then
|
|
290
|
+
* subframe 2's 600 decoded bits at bit 72 and subframe 3's 264 at
|
|
291
|
+
* bit 1272 — each at the start of its 1200/528-symbol slot.
|
|
292
|
+
* - B2a (u4[18]): the 288-bit message from the PRN (no preamble).
|
|
293
|
+
* - B2b (u4[31]): PRN (6) + reserved (6), then the 486-bit message.
|
|
294
|
+
*
|
|
295
|
+
* The receiver's CRC flags are ignored in favor of re-checking CRC-24Q,
|
|
296
|
+
* so `badCrc` counts exactly what this library rejected.
|
|
297
|
+
*/
|
|
298
|
+
|
|
299
|
+
interface SbfBdsCnavResult {
|
|
300
|
+
/** Assembled B-CNAV1/2/3 ephemerides in stream order, repeats suppressed. */
|
|
301
|
+
ephemerides: BdsCnavEphemeris[];
|
|
302
|
+
/** Messages whose CRC-24Q check failed (dropped). */
|
|
303
|
+
badCrc: number;
|
|
304
|
+
/** Total BDSRawB1C/B2a/B2b blocks seen (with valid SBF framing). */
|
|
305
|
+
messages: number;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Decode every BDSRawB1C/B2a/B2b block in an SBF byte stream into
|
|
309
|
+
* BeiDou-3 B-CNAV ephemerides (RINEX 4 CNV1/CNV2/CNV3).
|
|
310
|
+
*/
|
|
311
|
+
declare function parseSbfBdsCnav(data: Uint8Array): SbfBdsCnavResult;
|
|
312
|
+
|
|
276
313
|
/** Callback fed every CRC-valid SBAS message (any type), as MSB-first bits. */
|
|
277
314
|
type SbasMessageCb = (msg: Uint8Array, prn: number, week: number, tow: number) => void;
|
|
278
315
|
/** Callback fed every CRC-valid native-DFMC (L5) message, with its type. */
|
|
@@ -364,7 +401,7 @@ declare function parseSbfGeoL5(data: Uint8Array, opts?: {
|
|
|
364
401
|
* A Septentrio broadcasts navigation data as a mix of *decoded* blocks
|
|
365
402
|
* (GPSNav/GALNav/GLONav/BDSNav/QZSNav — already-parsed ephemeris) and
|
|
366
403
|
* *raw* navigation-frame blocks (GPSRawCA, GALRawINAV/FNAV, GLORawCA,
|
|
367
|
-
* BDSRaw, GPSRawL2C/L5, GEORawL1) whose bits must be assembled — and which class a
|
|
404
|
+
* BDSRaw, BDSRawB1C/B2a/B2b, GPSRawL2C/L5, GEORawL1) whose bits must be assembled — and which class a
|
|
368
405
|
* given receiver emits depends on its configuration. The granular
|
|
369
406
|
* `parseSbf*` functions each re-scan the whole stream for one class;
|
|
370
407
|
* this decoder walks the byte stream **once**, routing every navigation
|
|
@@ -394,6 +431,8 @@ interface SbfNavCounts {
|
|
|
394
431
|
gloRaw: number;
|
|
395
432
|
/** Raw BeiDou D1/D2 subframe blocks (BDSRaw). */
|
|
396
433
|
bdsRaw: number;
|
|
434
|
+
/** Raw BeiDou-3 B-CNAV blocks (BDSRawB1C/B2a/B2b). */
|
|
435
|
+
bdsCnavRaw: number;
|
|
397
436
|
/** Raw SBAS L1 GEO message blocks (GEORawL1). */
|
|
398
437
|
sbasRaw: number;
|
|
399
438
|
/** Raw SBAS L5 GEO message blocks (GEORawL5) — DO-229-on-L5 + native DFMC. */
|
|
@@ -412,6 +451,8 @@ interface SbfNavigation {
|
|
|
412
451
|
ephemerides: Ephemeris[];
|
|
413
452
|
/** GPS L2C/L5 CNAV ephemerides (RINEX-4 nav records). */
|
|
414
453
|
cnav: SbfCnavEphemeris[];
|
|
454
|
+
/** BeiDou-3 B-CNAV1/2/3 ephemerides (RINEX-4 CNV1/CNV2/CNV3 records). */
|
|
455
|
+
bdsCnav: BdsCnavEphemeris[];
|
|
415
456
|
/**
|
|
416
457
|
* Iono coefficient sets keyed like `NavHeader.ionoCorrections`
|
|
417
458
|
* (GPSA/GPSB, GAL, BDSA/BDSB); the last valid block of each type wins.
|
|
@@ -426,7 +467,7 @@ interface SbfNavigation {
|
|
|
426
467
|
}
|
|
427
468
|
/**
|
|
428
469
|
* Decode every navigation block in an SBF byte stream in a single pass:
|
|
429
|
-
* decoded ephemeris blocks, raw GPS/QZSS LNAV, GPS CNAV, Galileo I/NAV +
|
|
470
|
+
* decoded ephemeris blocks, raw GPS/QZSS LNAV, GPS CNAV, BeiDou-3 B-CNAV, Galileo I/NAV +
|
|
430
471
|
* F/NAV, GLONASS strings, BeiDou D1/D2, and the Klobuchar/NeQuick iono +
|
|
431
472
|
* GPS-UTC leap-second blocks. See the module header for merge semantics.
|
|
432
473
|
*/
|
|
@@ -671,4 +712,4 @@ interface SbfParseResult {
|
|
|
671
712
|
*/
|
|
672
713
|
declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
|
|
673
714
|
|
|
674
|
-
export { CnavEphemeris, type DfmcCensus, type DfmcMessageCb, type GeoL5Result, HasMessage, ReceiverPvt, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, type SbasMessageCb, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoL5Result, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavicResult, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, extractSbfNavicSubframe, feedGeoBlock, feedGeoL5Block, feedNavicBlock, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfNavic, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, crc16 as sbfCrc16, scanSbfFrames };
|
|
715
|
+
export { BdsCnavEphemeris, CnavEphemeris, type DfmcCensus, type DfmcMessageCb, type GeoL5Result, HasMessage, ReceiverPvt, SBAS_L5_MT_NAMES, SBAS_L5_PREAMBLE_UW, type SbasMessageCb, type SbfBdsCnavResult, type SbfBdsNavResult, type SbfCnavEphemeris, type SbfCnavResult, type SbfGalEphemeris, type SbfGalNavResult, type SbfGeoL5Result, type SbfGeoNavResult, type SbfGloNavResult, type SbfGpsNavResult, type SbfHasMessage, type SbfHasResult, type SbfIonoUtcResult, type SbfMeasEpoch, type SbfMeasurement, type SbfNavCounts, type SbfNavicResult, type SbfNavigation, type SbfParseResult, type SbfPvt, type SbfPvtResult, type SbfReceiverSetup, decodeSbfNavigation, extractSbfNavicSubframe, feedGeoBlock, feedGeoL5Block, feedNavicBlock, isSbasL1Preamble, isSbasL5Correction, parseSbfBdsCnav, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoL5, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfNavic, parseSbfPvt, parseSbfReceiverSetup, sbasL5MessageName, sbasL5MessageType, crc16 as sbfCrc16, scanSbfFrames };
|