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/index.cjs
CHANGED
|
@@ -288,6 +288,7 @@ __export(src_exports, {
|
|
|
288
288
|
parseNovatelRange: () => parseNovatelRange,
|
|
289
289
|
parseRinexStream: () => parseRinexStream,
|
|
290
290
|
parseSbfAlmanac: () => parseSbfAlmanac,
|
|
291
|
+
parseSbfBdsCnav: () => parseSbfBdsCnav,
|
|
291
292
|
parseSbfBdsNav: () => parseSbfBdsNav,
|
|
292
293
|
parseSbfCnav: () => parseSbfCnav,
|
|
293
294
|
parseSbfGalNav: () => parseSbfGalNav,
|
|
@@ -3026,7 +3027,7 @@ var isc = (b, pos) => {
|
|
|
3026
3027
|
return raw === -4096 ? null : raw * 2 ** -35;
|
|
3027
3028
|
};
|
|
3028
3029
|
function decodeClock(b, msgType) {
|
|
3029
|
-
const
|
|
3030
|
+
const clock2 = {
|
|
3030
3031
|
msgType,
|
|
3031
3032
|
top: getBitU(b, 38, 11) * 300,
|
|
3032
3033
|
uraNed0: getBitS(b, 49, 5),
|
|
@@ -3038,26 +3039,26 @@ function decodeClock(b, msgType) {
|
|
|
3038
3039
|
af2: getBitS(b, 117, 10) * 2 ** -60
|
|
3039
3040
|
};
|
|
3040
3041
|
if (msgType === 30) {
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3042
|
+
clock2.tgd = isc(b, 127);
|
|
3043
|
+
clock2.iscL1ca = isc(b, 140);
|
|
3044
|
+
clock2.iscL2c = isc(b, 153);
|
|
3045
|
+
clock2.iscL5i5 = isc(b, 166);
|
|
3046
|
+
clock2.iscL5q5 = isc(b, 179);
|
|
3047
|
+
clock2.ionoAlpha = [
|
|
3047
3048
|
getBitS(b, 192, 8) * 2 ** -30,
|
|
3048
3049
|
getBitS(b, 200, 8) * 2 ** -27,
|
|
3049
3050
|
getBitS(b, 208, 8) * 2 ** -24,
|
|
3050
3051
|
getBitS(b, 216, 8) * 2 ** -24
|
|
3051
3052
|
];
|
|
3052
|
-
|
|
3053
|
+
clock2.ionoBeta = [
|
|
3053
3054
|
getBitS(b, 224, 8) * 2 ** 11,
|
|
3054
3055
|
getBitS(b, 232, 8) * 2 ** 14,
|
|
3055
3056
|
getBitS(b, 240, 8) * 2 ** 16,
|
|
3056
3057
|
getBitS(b, 248, 8) * 2 ** 16
|
|
3057
3058
|
];
|
|
3058
|
-
|
|
3059
|
+
clock2.wnOp = getBitU(b, 256, 8);
|
|
3059
3060
|
}
|
|
3060
|
-
return
|
|
3061
|
+
return clock2;
|
|
3061
3062
|
}
|
|
3062
3063
|
function resolveWeek(week, towSec, sec) {
|
|
3063
3064
|
if (sec < towSec - HALF_WEEK) return week + 1;
|
|
@@ -3095,10 +3096,10 @@ var CnavAssembler = class {
|
|
|
3095
3096
|
return this.tryEmit(prn, sat);
|
|
3096
3097
|
}
|
|
3097
3098
|
tryEmit(prn, sat) {
|
|
3098
|
-
const { t10, t11, clock, extras } = sat;
|
|
3099
|
-
if (!t10 || !t11 || !
|
|
3100
|
-
if (t10.toe !== t11.toe ||
|
|
3101
|
-
const key = `${t10.week}:${t10.toe}:${
|
|
3099
|
+
const { t10, t11, clock: clock2, extras } = sat;
|
|
3100
|
+
if (!t10 || !t11 || !clock2) return null;
|
|
3101
|
+
if (t10.toe !== t11.toe || clock2.toc !== t10.toe) return null;
|
|
3102
|
+
const key = `${t10.week}:${t10.toe}:${clock2.af0}:${clock2.af1}`;
|
|
3102
3103
|
if (key === sat.lastKey) return null;
|
|
3103
3104
|
sat.lastKey = key;
|
|
3104
3105
|
const weekToe = resolveWeek(t10.week, t10.tow, t10.toe);
|
|
@@ -3109,9 +3110,9 @@ var CnavAssembler = class {
|
|
|
3109
3110
|
week: t10.week,
|
|
3110
3111
|
health: t10.health,
|
|
3111
3112
|
uraEd: t10.uraEd,
|
|
3112
|
-
uraNed0:
|
|
3113
|
-
uraNed1:
|
|
3114
|
-
uraNed2:
|
|
3113
|
+
uraNed0: clock2.uraNed0,
|
|
3114
|
+
uraNed1: clock2.uraNed1,
|
|
3115
|
+
uraNed2: clock2.uraNed2,
|
|
3115
3116
|
top: t10.top,
|
|
3116
3117
|
toe: t10.toe,
|
|
3117
3118
|
toeDate: gpsDate(weekToe, t10.toe),
|
|
@@ -3134,12 +3135,12 @@ var CnavAssembler = class {
|
|
|
3134
3135
|
crc: t11.crc,
|
|
3135
3136
|
cus: t11.cus,
|
|
3136
3137
|
cuc: t11.cuc,
|
|
3137
|
-
toc:
|
|
3138
|
-
tocDate: gpsDate(weekToe,
|
|
3139
|
-
af0:
|
|
3140
|
-
af1:
|
|
3141
|
-
af2:
|
|
3142
|
-
clockMsgType:
|
|
3138
|
+
toc: clock2.toc,
|
|
3139
|
+
tocDate: gpsDate(weekToe, clock2.toc),
|
|
3140
|
+
af0: clock2.af0,
|
|
3141
|
+
af1: clock2.af1,
|
|
3142
|
+
af2: clock2.af2,
|
|
3143
|
+
clockMsgType: clock2.msgType,
|
|
3143
3144
|
tgd: extras?.tgd ?? null,
|
|
3144
3145
|
iscL1ca: extras?.iscL1ca ?? null,
|
|
3145
3146
|
iscL2c: extras?.iscL2c ?? null,
|
|
@@ -3155,6 +3156,304 @@ var CnavAssembler = class {
|
|
|
3155
3156
|
}
|
|
3156
3157
|
};
|
|
3157
3158
|
|
|
3159
|
+
// src/navbits/bds-cnav.ts
|
|
3160
|
+
var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
|
|
3161
|
+
var SEC_PER_WEEK3 = 7 * 86400;
|
|
3162
|
+
var HALF_WEEK2 = 302400;
|
|
3163
|
+
var BDS_CNAV_A_REF_MEO = 27906100;
|
|
3164
|
+
var BDS_CNAV_A_REF_IGSO_GEO = 42162200;
|
|
3165
|
+
function bdsCnavAref(satType) {
|
|
3166
|
+
return satType === 3 ? BDS_CNAV_A_REF_MEO : BDS_CNAV_A_REF_IGSO_GEO;
|
|
3167
|
+
}
|
|
3168
|
+
function ephI(b, p) {
|
|
3169
|
+
return {
|
|
3170
|
+
toe: getBitU(b, p, 11) * 300,
|
|
3171
|
+
satType: getBitU(b, p + 11, 2),
|
|
3172
|
+
deltaA: getBitS(b, p + 13, 26) * 2 ** -9,
|
|
3173
|
+
aDot: getBitS(b, p + 39, 25) * 2 ** -21,
|
|
3174
|
+
deltaN0: getBitS(b, p + 64, 17) * 2 ** -44 * GPS_PI,
|
|
3175
|
+
deltaN0Dot: getBitS(b, p + 81, 23) * 2 ** -57 * GPS_PI,
|
|
3176
|
+
m0: getBitS33(b, p + 104) * 2 ** -32 * GPS_PI,
|
|
3177
|
+
e: getBitU33(b, p + 137) * 2 ** -34,
|
|
3178
|
+
omega: getBitS33(b, p + 170) * 2 ** -32 * GPS_PI
|
|
3179
|
+
};
|
|
3180
|
+
}
|
|
3181
|
+
function ephII(b, p) {
|
|
3182
|
+
return {
|
|
3183
|
+
omega0: getBitS33(b, p) * 2 ** -32 * GPS_PI,
|
|
3184
|
+
i0: getBitS33(b, p + 33) * 2 ** -32 * GPS_PI,
|
|
3185
|
+
omegaDot: getBitS(b, p + 66, 19) * 2 ** -44 * GPS_PI,
|
|
3186
|
+
i0Dot: getBitS(b, p + 85, 15) * 2 ** -44 * GPS_PI,
|
|
3187
|
+
cis: getBitS(b, p + 100, 16) * 2 ** -30,
|
|
3188
|
+
cic: getBitS(b, p + 116, 16) * 2 ** -30,
|
|
3189
|
+
crs: getBitS(b, p + 132, 24) * 2 ** -8,
|
|
3190
|
+
crc: getBitS(b, p + 156, 24) * 2 ** -8,
|
|
3191
|
+
cus: getBitS(b, p + 180, 21) * 2 ** -30,
|
|
3192
|
+
cuc: getBitS(b, p + 201, 21) * 2 ** -30
|
|
3193
|
+
};
|
|
3194
|
+
}
|
|
3195
|
+
function clock(b, p) {
|
|
3196
|
+
return {
|
|
3197
|
+
toc: getBitU(b, p, 11) * 300,
|
|
3198
|
+
af0: getBitS(b, p + 11, 25) * 2 ** -34,
|
|
3199
|
+
af1: getBitS(b, p + 36, 22) * 2 ** -50,
|
|
3200
|
+
af2: getBitS(b, p + 58, 11) * 2 ** -66
|
|
3201
|
+
};
|
|
3202
|
+
}
|
|
3203
|
+
function sisaiOc(b, p) {
|
|
3204
|
+
return {
|
|
3205
|
+
top: getBitU(b, p, 11) * 300,
|
|
3206
|
+
ocb: getBitS(b, p + 11, 5),
|
|
3207
|
+
oc1: getBitS(b, p + 16, 3),
|
|
3208
|
+
oc2: getBitS(b, p + 19, 3)
|
|
3209
|
+
};
|
|
3210
|
+
}
|
|
3211
|
+
var delay = (b, p) => getBitS(b, p, 12) * 2 ** -34;
|
|
3212
|
+
function crcOk(msg, dataBits) {
|
|
3213
|
+
const need = Math.ceil((dataBits + 24) / 8);
|
|
3214
|
+
return msg.length >= need && crc24q(msg, dataBits) === getBitU(msg, dataBits, 24);
|
|
3215
|
+
}
|
|
3216
|
+
var bdsCnav1Sf2CrcOk = (sf2) => crcOk(sf2, 576);
|
|
3217
|
+
var bdsCnav1Sf3CrcOk = (sf3) => crcOk(sf3, 240);
|
|
3218
|
+
var bdsCnav2CrcOk = (msg) => crcOk(msg, 264);
|
|
3219
|
+
var bdsCnav3CrcOk = (msg) => crcOk(msg, 462);
|
|
3220
|
+
function resolveWeek2(week, towSec, sec) {
|
|
3221
|
+
if (sec < towSec - HALF_WEEK2) return week + 1;
|
|
3222
|
+
if (sec > towSec + HALF_WEEK2) return week - 1;
|
|
3223
|
+
return week;
|
|
3224
|
+
}
|
|
3225
|
+
function bdtDate(week, sec) {
|
|
3226
|
+
return new Date(BDT_EPOCH_MS + (week * SEC_PER_WEEK3 + sec) * 1e3);
|
|
3227
|
+
}
|
|
3228
|
+
var emptyStatus = () => ({
|
|
3229
|
+
top: null,
|
|
3230
|
+
sisaiOe: null,
|
|
3231
|
+
sisaiOcb: null,
|
|
3232
|
+
sisaiOc1: null,
|
|
3233
|
+
sisaiOc2: null,
|
|
3234
|
+
sismai: null,
|
|
3235
|
+
health: null,
|
|
3236
|
+
integrityFlags: null
|
|
3237
|
+
});
|
|
3238
|
+
function applyOc(s, oc) {
|
|
3239
|
+
s.top = oc.top;
|
|
3240
|
+
s.sisaiOcb = oc.ocb;
|
|
3241
|
+
s.sisaiOc1 = oc.oc1;
|
|
3242
|
+
s.sisaiOc2 = oc.oc2;
|
|
3243
|
+
}
|
|
3244
|
+
function build(message, prn, wn, tTm, e1, e22, c, d, s) {
|
|
3245
|
+
const week = resolveWeek2(wn, tTm, e1.toe);
|
|
3246
|
+
const weekToc = resolveWeek2(wn, tTm, c.toc);
|
|
3247
|
+
return {
|
|
3248
|
+
system: "C",
|
|
3249
|
+
prn,
|
|
3250
|
+
message,
|
|
3251
|
+
week,
|
|
3252
|
+
toe: e1.toe,
|
|
3253
|
+
toeDate: bdtDate(week, e1.toe),
|
|
3254
|
+
toc: c.toc,
|
|
3255
|
+
tocDate: bdtDate(weekToc, c.toc),
|
|
3256
|
+
satType: e1.satType,
|
|
3257
|
+
a: bdsCnavAref(e1.satType) + e1.deltaA,
|
|
3258
|
+
deltaA: e1.deltaA,
|
|
3259
|
+
aDot: e1.aDot,
|
|
3260
|
+
deltaN0: e1.deltaN0,
|
|
3261
|
+
deltaN0Dot: e1.deltaN0Dot,
|
|
3262
|
+
m0: e1.m0,
|
|
3263
|
+
e: e1.e,
|
|
3264
|
+
omega: e1.omega,
|
|
3265
|
+
...e22,
|
|
3266
|
+
af0: c.af0,
|
|
3267
|
+
af1: c.af1,
|
|
3268
|
+
af2: c.af2,
|
|
3269
|
+
...d,
|
|
3270
|
+
...s,
|
|
3271
|
+
tow: tTm
|
|
3272
|
+
};
|
|
3273
|
+
}
|
|
3274
|
+
var prnLabel = (prn) => `C${String(prn).padStart(2, "0")}`;
|
|
3275
|
+
var BdsCnav1Assembler = class {
|
|
3276
|
+
status = /* @__PURE__ */ new Map();
|
|
3277
|
+
lastKey = /* @__PURE__ */ new Map();
|
|
3278
|
+
/**
|
|
3279
|
+
* Push one frame's CRC-valid subframes (bit-0 aligned; pass null for
|
|
3280
|
+
* a subframe that failed its CRC) for satellite `prn` (1-63). `tTm`
|
|
3281
|
+
* is the frame's transmit time, s of the BDT week. Returns the newly
|
|
3282
|
+
* seen ephemeris, or null.
|
|
3283
|
+
*/
|
|
3284
|
+
push(prn, sf2, sf3, tTm) {
|
|
3285
|
+
let s = this.status.get(prn);
|
|
3286
|
+
if (!s) this.status.set(prn, s = emptyStatus());
|
|
3287
|
+
if (sf3) {
|
|
3288
|
+
const page = getBitU(sf3, 0, 6);
|
|
3289
|
+
if (page >= 1 && page <= 4) {
|
|
3290
|
+
s.health = getBitU(sf3, 6, 2);
|
|
3291
|
+
s.integrityFlags = getBitU(sf3, 8, 3);
|
|
3292
|
+
s.sismai = getBitU(sf3, 11, 4);
|
|
3293
|
+
if (page === 1) {
|
|
3294
|
+
s.sisaiOe = getBitU(sf3, 15, 5);
|
|
3295
|
+
applyOc(s, sisaiOc(sf3, 20));
|
|
3296
|
+
} else if (page === 3) s.sisaiOe = getBitU(sf3, 15, 5);
|
|
3297
|
+
else applyOc(s, sisaiOc(sf3, 15));
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
if (!sf2) return null;
|
|
3301
|
+
const wn = getBitU(sf2, 0, 13);
|
|
3302
|
+
const iodc = getBitU(sf2, 21, 10);
|
|
3303
|
+
const iode = getBitU(sf2, 31, 8);
|
|
3304
|
+
const e1 = ephI(sf2, 39);
|
|
3305
|
+
const c = clock(sf2, 464);
|
|
3306
|
+
const key = `${wn}:${iodc}:${iode}:${e1.toe}:${c.toc}`;
|
|
3307
|
+
if (this.lastKey.get(prn) === key) return null;
|
|
3308
|
+
this.lastKey.set(prn, key);
|
|
3309
|
+
return build(
|
|
3310
|
+
"CNV1",
|
|
3311
|
+
prnLabel(prn),
|
|
3312
|
+
wn,
|
|
3313
|
+
tTm,
|
|
3314
|
+
e1,
|
|
3315
|
+
ephII(sf2, 242),
|
|
3316
|
+
c,
|
|
3317
|
+
{
|
|
3318
|
+
iode,
|
|
3319
|
+
iodc,
|
|
3320
|
+
tgdB1Cp: delay(sf2, 557),
|
|
3321
|
+
tgdB2ap: delay(sf2, 533),
|
|
3322
|
+
iscB1Cd: delay(sf2, 545),
|
|
3323
|
+
iscB2ad: null,
|
|
3324
|
+
tgdB2bI: null
|
|
3325
|
+
},
|
|
3326
|
+
{ ...s }
|
|
3327
|
+
);
|
|
3328
|
+
}
|
|
3329
|
+
};
|
|
3330
|
+
var BdsCnav2Assembler = class {
|
|
3331
|
+
sats = /* @__PURE__ */ new Map();
|
|
3332
|
+
/**
|
|
3333
|
+
* Push one CRC-valid 288-bit message (bit 0 = first PRN bit, the
|
|
3334
|
+
* preamble stripped). Returns the newly completed ephemeris, or null.
|
|
3335
|
+
*/
|
|
3336
|
+
push(msg) {
|
|
3337
|
+
const prn = getBitU(msg, 0, 6);
|
|
3338
|
+
const type = getBitU(msg, 6, 6);
|
|
3339
|
+
const sow = getBitU(msg, 12, 18) * 3;
|
|
3340
|
+
if (prn < 1) return null;
|
|
3341
|
+
let sat = this.sats.get(prn);
|
|
3342
|
+
if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
|
|
3343
|
+
const s = sat.status;
|
|
3344
|
+
if (type === 10) {
|
|
3345
|
+
sat.t10 = {
|
|
3346
|
+
wn: getBitU(msg, 30, 13),
|
|
3347
|
+
iode: getBitU(msg, 53, 8),
|
|
3348
|
+
e1: ephI(msg, 61),
|
|
3349
|
+
sow
|
|
3350
|
+
};
|
|
3351
|
+
s.integrityFlags = getBitU(msg, 43, 3) << 3 | getBitU(msg, 50, 3);
|
|
3352
|
+
s.sismai = getBitU(msg, 46, 4);
|
|
3353
|
+
if (sat.t11 && sat.t11.sow < sow) sat.t11 = void 0;
|
|
3354
|
+
} else if (type === 11 || type >= 30 && type <= 34 || type === 40) {
|
|
3355
|
+
s.health = getBitU(msg, 30, 2);
|
|
3356
|
+
s.integrityFlags = getBitU(msg, 32, 3) << 3 | getBitU(msg, 39, 3);
|
|
3357
|
+
s.sismai = getBitU(msg, 35, 4);
|
|
3358
|
+
if (type === 11) {
|
|
3359
|
+
if (!sat.t10 || sow <= sat.t10.sow) return null;
|
|
3360
|
+
sat.t11 = { e2: ephII(msg, 42), sow };
|
|
3361
|
+
} else if (type === 34) {
|
|
3362
|
+
applyOc(s, sisaiOc(msg, 42));
|
|
3363
|
+
sat.clock = { c: clock(msg, 64), iodc: getBitU(msg, 133, 10) };
|
|
3364
|
+
} else if (type === 40) {
|
|
3365
|
+
s.sisaiOe = getBitU(msg, 42, 5);
|
|
3366
|
+
applyOc(s, sisaiOc(msg, 47));
|
|
3367
|
+
return null;
|
|
3368
|
+
} else {
|
|
3369
|
+
sat.clock = { c: clock(msg, 42), iodc: getBitU(msg, 111, 10) };
|
|
3370
|
+
if (type === 30)
|
|
3371
|
+
sat.delays = {
|
|
3372
|
+
tgdB2ap: delay(msg, 121),
|
|
3373
|
+
iscB2ad: delay(msg, 133),
|
|
3374
|
+
tgdB1Cp: delay(msg, 219)
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3377
|
+
} else return null;
|
|
3378
|
+
const { t10, t11, clock: ck } = sat;
|
|
3379
|
+
if (!t10 || !t11 || !ck || (ck.iodc & 255) !== t10.iode) return null;
|
|
3380
|
+
const key = `${t10.wn}:${ck.iodc}:${t10.iode}:${t10.e1.toe}:${ck.c.toc}`;
|
|
3381
|
+
if (sat.lastKey === key) return null;
|
|
3382
|
+
sat.lastKey = key;
|
|
3383
|
+
return build(
|
|
3384
|
+
"CNV2",
|
|
3385
|
+
prnLabel(prn),
|
|
3386
|
+
t10.wn,
|
|
3387
|
+
t10.sow,
|
|
3388
|
+
t10.e1,
|
|
3389
|
+
t11.e2,
|
|
3390
|
+
ck.c,
|
|
3391
|
+
{
|
|
3392
|
+
iode: t10.iode,
|
|
3393
|
+
iodc: ck.iodc,
|
|
3394
|
+
tgdB1Cp: sat.delays?.tgdB1Cp ?? null,
|
|
3395
|
+
tgdB2ap: sat.delays?.tgdB2ap ?? null,
|
|
3396
|
+
iscB1Cd: null,
|
|
3397
|
+
iscB2ad: sat.delays?.iscB2ad ?? null,
|
|
3398
|
+
tgdB2bI: null
|
|
3399
|
+
},
|
|
3400
|
+
{ ...s }
|
|
3401
|
+
);
|
|
3402
|
+
}
|
|
3403
|
+
};
|
|
3404
|
+
var BdsCnav3Assembler = class {
|
|
3405
|
+
sats = /* @__PURE__ */ new Map();
|
|
3406
|
+
/**
|
|
3407
|
+
* Push one CRC-valid 486-bit message (bit 0 = first MesType bit) from
|
|
3408
|
+
* satellite `prn`. Returns the newly completed ephemeris, or null.
|
|
3409
|
+
*/
|
|
3410
|
+
push(prn, msg) {
|
|
3411
|
+
const type = getBitU(msg, 0, 6);
|
|
3412
|
+
const sow = getBitU(msg, 6, 20);
|
|
3413
|
+
let sat = this.sats.get(prn);
|
|
3414
|
+
if (!sat) this.sats.set(prn, sat = { status: emptyStatus() });
|
|
3415
|
+
const s = sat.status;
|
|
3416
|
+
if (type === 10) {
|
|
3417
|
+
sat.t10 = { e1: ephI(msg, 30), e2: ephII(msg, 233), sow };
|
|
3418
|
+
s.integrityFlags = getBitU(msg, 455, 3);
|
|
3419
|
+
s.sismai = getBitU(msg, 458, 4);
|
|
3420
|
+
} else if (type === 30) {
|
|
3421
|
+
sat.t30 = {
|
|
3422
|
+
wn: getBitU(msg, 26, 13),
|
|
3423
|
+
c: clock(msg, 43),
|
|
3424
|
+
tgd: delay(msg, 112)
|
|
3425
|
+
};
|
|
3426
|
+
applyOc(s, sisaiOc(msg, 433));
|
|
3427
|
+
s.sisaiOe = getBitU(msg, 455, 5);
|
|
3428
|
+
s.health = getBitU(msg, 460, 2);
|
|
3429
|
+
} else return null;
|
|
3430
|
+
const { t10, t30 } = sat;
|
|
3431
|
+
if (!t10 || !t30 || t10.e1.toe !== t30.c.toc) return null;
|
|
3432
|
+
const key = `${t30.wn}:${t10.e1.toe}:${t30.c.af0}:${t10.e1.m0}`;
|
|
3433
|
+
if (sat.lastKey === key) return null;
|
|
3434
|
+
sat.lastKey = key;
|
|
3435
|
+
return build(
|
|
3436
|
+
"CNV3",
|
|
3437
|
+
prnLabel(prn),
|
|
3438
|
+
t30.wn,
|
|
3439
|
+
t10.sow,
|
|
3440
|
+
t10.e1,
|
|
3441
|
+
t10.e2,
|
|
3442
|
+
t30.c,
|
|
3443
|
+
{
|
|
3444
|
+
iode: null,
|
|
3445
|
+
iodc: null,
|
|
3446
|
+
tgdB1Cp: null,
|
|
3447
|
+
tgdB2ap: null,
|
|
3448
|
+
iscB1Cd: null,
|
|
3449
|
+
iscB2ad: null,
|
|
3450
|
+
tgdB2bI: t30.tgd
|
|
3451
|
+
},
|
|
3452
|
+
{ ...s }
|
|
3453
|
+
);
|
|
3454
|
+
}
|
|
3455
|
+
};
|
|
3456
|
+
|
|
3158
3457
|
// src/rinex/nav.ts
|
|
3159
3458
|
var DATA_LINES = {
|
|
3160
3459
|
G: 7,
|
|
@@ -3180,16 +3479,17 @@ var R4_MSG_LINES = {
|
|
|
3180
3479
|
// RINEX 4 adds orbit-4 (status flags) vs 3 in RINEX 3
|
|
3181
3480
|
// EPH type parsed into RinexCnavEphemeris for G/J (skipped otherwise)
|
|
3182
3481
|
CNAV: 9,
|
|
3183
|
-
//
|
|
3482
|
+
// BeiDou-3 B-CNAV, parsed into BdsCnavEphemeris
|
|
3184
3483
|
CNV1: 10,
|
|
3185
3484
|
CNV2: 10,
|
|
3186
3485
|
CNV3: 9,
|
|
3486
|
+
// EPH types we skip (different field layout)
|
|
3187
3487
|
L1NV: 8,
|
|
3188
3488
|
L1OC: 9,
|
|
3189
3489
|
L3OC: 9
|
|
3190
3490
|
};
|
|
3191
3491
|
var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
|
|
3192
|
-
var
|
|
3492
|
+
var SEC_PER_WEEK4 = 7 * 86400;
|
|
3193
3493
|
var QZSS_CNAV_A_REF = 42164200;
|
|
3194
3494
|
var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
|
|
3195
3495
|
"LNAV",
|
|
@@ -3334,8 +3634,8 @@ function buildCnavEphemeris(sys, prn, date, epochVals, d) {
|
|
|
3334
3634
|
const num = (r, c) => d[r]?.[c] ?? 0;
|
|
3335
3635
|
const opt = (r, c) => d[r]?.[c] ?? null;
|
|
3336
3636
|
const t = (date.getTime() - GPS_EPOCH_MS3) / 1e3;
|
|
3337
|
-
const week = Math.floor(t /
|
|
3338
|
-
const toc = t - week *
|
|
3637
|
+
const week = Math.floor(t / SEC_PER_WEEK4);
|
|
3638
|
+
const toc = t - week * SEC_PER_WEEK4;
|
|
3339
3639
|
const sqrtA = num(1, 3);
|
|
3340
3640
|
const a = sqrtA * sqrtA;
|
|
3341
3641
|
const aRef = sys === "J" ? QZSS_CNAV_A_REF : CNAV_A_REF;
|
|
@@ -3392,6 +3692,68 @@ function buildCnavEphemeris(sys, prn, date, epochVals, d) {
|
|
|
3392
3692
|
tow: num(7, 0)
|
|
3393
3693
|
};
|
|
3394
3694
|
}
|
|
3695
|
+
var BDT_EPOCH_MS2 = Date.UTC(2006, 0, 1);
|
|
3696
|
+
function buildBdsCnavEphemeris(message, prn, date, epochVals, d) {
|
|
3697
|
+
const num = (r, c) => d[r]?.[c] ?? 0;
|
|
3698
|
+
const opt = (r, c) => d[r]?.[c] ?? null;
|
|
3699
|
+
const cnv3 = message === "CNV3";
|
|
3700
|
+
const t = (date.getTime() - BDT_EPOCH_MS2) / 1e3;
|
|
3701
|
+
const weekToc = Math.floor(t / SEC_PER_WEEK4);
|
|
3702
|
+
const toc = t - weekToc * SEC_PER_WEEK4;
|
|
3703
|
+
const toe = num(2, 0);
|
|
3704
|
+
const week = toe - toc > SEC_PER_WEEK4 / 2 ? weekToc - 1 : toc - toe > SEC_PER_WEEK4 / 2 ? weekToc + 1 : weekToc;
|
|
3705
|
+
const sqrtA = num(1, 3);
|
|
3706
|
+
const a = sqrtA * sqrtA;
|
|
3707
|
+
const satType = num(4, 2);
|
|
3708
|
+
return {
|
|
3709
|
+
system: "C",
|
|
3710
|
+
prn,
|
|
3711
|
+
message,
|
|
3712
|
+
week,
|
|
3713
|
+
toe,
|
|
3714
|
+
toeDate: new Date(BDT_EPOCH_MS2 + (week * SEC_PER_WEEK4 + toe) * 1e3),
|
|
3715
|
+
toc,
|
|
3716
|
+
tocDate: date,
|
|
3717
|
+
satType,
|
|
3718
|
+
a,
|
|
3719
|
+
deltaA: a - bdsCnavAref(satType),
|
|
3720
|
+
aDot: num(0, 0),
|
|
3721
|
+
deltaN0: num(0, 2),
|
|
3722
|
+
deltaN0Dot: num(4, 1),
|
|
3723
|
+
m0: num(0, 3),
|
|
3724
|
+
e: num(1, 1),
|
|
3725
|
+
omega: num(3, 2),
|
|
3726
|
+
omega0: num(2, 2),
|
|
3727
|
+
i0: num(3, 0),
|
|
3728
|
+
omegaDot: num(3, 3),
|
|
3729
|
+
i0Dot: num(4, 0),
|
|
3730
|
+
cis: num(2, 3),
|
|
3731
|
+
cic: num(2, 1),
|
|
3732
|
+
crs: num(0, 1),
|
|
3733
|
+
crc: num(3, 1),
|
|
3734
|
+
cus: num(1, 2),
|
|
3735
|
+
cuc: num(1, 0),
|
|
3736
|
+
af0: epochVals[0] ?? 0,
|
|
3737
|
+
af1: epochVals[1] ?? 0,
|
|
3738
|
+
af2: epochVals[2] ?? 0,
|
|
3739
|
+
iode: cnv3 ? null : opt(8, 3),
|
|
3740
|
+
iodc: cnv3 ? null : opt(7, 3),
|
|
3741
|
+
tgdB1Cp: cnv3 ? null : opt(6, 2),
|
|
3742
|
+
tgdB2ap: cnv3 ? null : opt(6, 3),
|
|
3743
|
+
iscB1Cd: cnv3 ? null : opt(6, 0),
|
|
3744
|
+
iscB2ad: cnv3 ? null : opt(6, 1),
|
|
3745
|
+
tgdB2bI: cnv3 ? opt(6, 3) : null,
|
|
3746
|
+
top: opt(4, 3),
|
|
3747
|
+
sisaiOe: opt(5, 0),
|
|
3748
|
+
sisaiOcb: opt(5, 1),
|
|
3749
|
+
sisaiOc1: opt(5, 2),
|
|
3750
|
+
sisaiOc2: opt(5, 3),
|
|
3751
|
+
sismai: cnv3 ? opt(6, 0) : opt(7, 0),
|
|
3752
|
+
health: cnv3 ? opt(6, 1) : opt(7, 1),
|
|
3753
|
+
integrityFlags: cnv3 ? opt(6, 2) : opt(7, 2),
|
|
3754
|
+
tow: cnv3 ? num(7, 0) : num(8, 0)
|
|
3755
|
+
};
|
|
3756
|
+
}
|
|
3395
3757
|
function parseNavFile(text) {
|
|
3396
3758
|
const lines = text.split("\n");
|
|
3397
3759
|
const header = {
|
|
@@ -3402,6 +3764,7 @@ function parseNavFile(text) {
|
|
|
3402
3764
|
};
|
|
3403
3765
|
const ephemerides = [];
|
|
3404
3766
|
const cnav = [];
|
|
3767
|
+
const bdsCnav = [];
|
|
3405
3768
|
let inHeader = true;
|
|
3406
3769
|
let i = 0;
|
|
3407
3770
|
while (i < lines.length) {
|
|
@@ -3470,7 +3833,8 @@ function parseNavFile(text) {
|
|
|
3470
3833
|
continue;
|
|
3471
3834
|
}
|
|
3472
3835
|
const isCnav = msgType === "CNAV" && (svSys === "G" || svSys === "J");
|
|
3473
|
-
|
|
3836
|
+
const isBdsCnav = svSys === "C" && (msgType === "CNV1" || msgType === "CNV2" || msgType === "CNV3");
|
|
3837
|
+
if (!SUPPORTED_EPH_MSGS.has(msgType) && !isCnav && !isBdsCnav) {
|
|
3474
3838
|
const totalLines = R4_MSG_LINES[msgType] ?? 2;
|
|
3475
3839
|
i += totalLines + 1;
|
|
3476
3840
|
continue;
|
|
@@ -3482,17 +3846,34 @@ function parseNavFile(text) {
|
|
|
3482
3846
|
const sys2 = epochLine.charAt(0);
|
|
3483
3847
|
const parsed = parseNavEpochV3(epochLine);
|
|
3484
3848
|
const prn2 = `${sys2}${parsed.prn.substring(1)}`;
|
|
3485
|
-
if (isCnav) {
|
|
3849
|
+
if (isCnav || isBdsCnav) {
|
|
3486
3850
|
const slotLines = [];
|
|
3487
3851
|
for (let j = 0; j < numDataLines2; j++) {
|
|
3488
3852
|
i++;
|
|
3489
3853
|
if (i >= lines.length) break;
|
|
3490
3854
|
slotLines.push(parseDataLineSlots(lines[i]));
|
|
3491
3855
|
}
|
|
3492
|
-
if (slotLines.length === numDataLines2
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3856
|
+
if (slotLines.length === numDataLines2) {
|
|
3857
|
+
if (isBdsCnav && sys2 === "C")
|
|
3858
|
+
bdsCnav.push(
|
|
3859
|
+
buildBdsCnavEphemeris(
|
|
3860
|
+
msgType,
|
|
3861
|
+
prn2,
|
|
3862
|
+
parsed.date,
|
|
3863
|
+
parsed.values,
|
|
3864
|
+
slotLines
|
|
3865
|
+
)
|
|
3866
|
+
);
|
|
3867
|
+
else if (sys2 === "G" || sys2 === "J")
|
|
3868
|
+
cnav.push(
|
|
3869
|
+
buildCnavEphemeris(
|
|
3870
|
+
sys2,
|
|
3871
|
+
prn2,
|
|
3872
|
+
parsed.date,
|
|
3873
|
+
parsed.values,
|
|
3874
|
+
slotLines
|
|
3875
|
+
)
|
|
3876
|
+
);
|
|
3496
3877
|
}
|
|
3497
3878
|
i++;
|
|
3498
3879
|
continue;
|
|
@@ -3570,7 +3951,12 @@ function parseNavFile(text) {
|
|
|
3570
3951
|
}
|
|
3571
3952
|
i++;
|
|
3572
3953
|
}
|
|
3573
|
-
return
|
|
3954
|
+
return {
|
|
3955
|
+
header,
|
|
3956
|
+
ephemerides,
|
|
3957
|
+
...cnav.length > 0 && { cnav },
|
|
3958
|
+
...bdsCnav.length > 0 && { bdsCnav }
|
|
3959
|
+
};
|
|
3574
3960
|
}
|
|
3575
3961
|
|
|
3576
3962
|
// src/rinex/nav-writer.ts
|
|
@@ -3766,6 +4152,30 @@ function cnavRecord(eph) {
|
|
|
3766
4152
|
orbitLine4([eph.tow, resolveWnOp(eph.week, eph.wnOp)])
|
|
3767
4153
|
].join("\n");
|
|
3768
4154
|
}
|
|
4155
|
+
function bdsCnavRecord(eph) {
|
|
4156
|
+
const lines = [
|
|
4157
|
+
epochLine4(eph.prn, eph.tocDate, [eph.af0, eph.af1, eph.af2]),
|
|
4158
|
+
orbitLine4([eph.aDot, eph.crs, eph.deltaN0, eph.m0]),
|
|
4159
|
+
orbitLine4([eph.cuc, eph.e, eph.cus, Math.sqrt(eph.a)]),
|
|
4160
|
+
orbitLine4([eph.toe, eph.cic, eph.omega0, eph.cis]),
|
|
4161
|
+
orbitLine4([eph.i0, eph.crc, eph.omega, eph.omegaDot]),
|
|
4162
|
+
orbitLine4([eph.i0Dot, eph.deltaN0Dot, eph.satType, eph.top]),
|
|
4163
|
+
orbitLine4([eph.sisaiOe, eph.sisaiOcb, eph.sisaiOc1, eph.sisaiOc2])
|
|
4164
|
+
];
|
|
4165
|
+
if (eph.message === "CNV3") {
|
|
4166
|
+
lines.push(
|
|
4167
|
+
orbitLine4([eph.sismai, eph.health, eph.integrityFlags, eph.tgdB2bI]),
|
|
4168
|
+
orbitLine4([eph.tow])
|
|
4169
|
+
);
|
|
4170
|
+
} else {
|
|
4171
|
+
lines.push(
|
|
4172
|
+
orbitLine4([eph.iscB1Cd, eph.iscB2ad, eph.tgdB1Cp, eph.tgdB2ap]),
|
|
4173
|
+
orbitLine4([eph.sismai, eph.health, eph.integrityFlags, eph.iodc]),
|
|
4174
|
+
orbitLine4([eph.tow, null, null, eph.iode])
|
|
4175
|
+
);
|
|
4176
|
+
}
|
|
4177
|
+
return lines.join("\n");
|
|
4178
|
+
}
|
|
3769
4179
|
var KLOBUCHAR_SOURCES = [
|
|
3770
4180
|
["GPSA", "GPSB", "G", "LNAV"],
|
|
3771
4181
|
["QZSA", "QZSB", "J", "LNAV"],
|
|
@@ -3843,6 +4253,15 @@ function writeRinexNav4(nav) {
|
|
|
3843
4253
|
` + cnavRecord(eph)
|
|
3844
4254
|
});
|
|
3845
4255
|
}
|
|
4256
|
+
for (const eph of nav.bdsCnav ?? []) {
|
|
4257
|
+
records.push({
|
|
4258
|
+
prn: eph.prn,
|
|
4259
|
+
time: eph.tocDate.getTime(),
|
|
4260
|
+
label: eph.message,
|
|
4261
|
+
body: `> EPH ${padL(eph.prn, 3)} ${eph.message}
|
|
4262
|
+
` + bdsCnavRecord(eph)
|
|
4263
|
+
});
|
|
4264
|
+
}
|
|
3846
4265
|
records.sort(
|
|
3847
4266
|
(a, b) => a.prn.localeCompare(b.prn) || a.time - b.time || a.label.localeCompare(b.label)
|
|
3848
4267
|
);
|
|
@@ -6729,7 +7148,7 @@ function updateStreamStats(stats, frames, rawBytes) {
|
|
|
6729
7148
|
entry.count++;
|
|
6730
7149
|
entry.lastSeen = now;
|
|
6731
7150
|
entry.totalBytes += frame.length + 6;
|
|
6732
|
-
const obsEpoch = decodeObs(frame);
|
|
7151
|
+
const obsEpoch = decodeObs(frame, { compactMsm: true });
|
|
6733
7152
|
if (obsEpoch) {
|
|
6734
7153
|
for (const obs of obsEpoch.observations) {
|
|
6735
7154
|
const signals = [];
|
|
@@ -6937,11 +7356,11 @@ function parseUbxCnav(data) {
|
|
|
6937
7356
|
}
|
|
6938
7357
|
|
|
6939
7358
|
// src/navbits/bds.ts
|
|
6940
|
-
var
|
|
6941
|
-
var
|
|
6942
|
-
var MS_PER_WEEK2 =
|
|
6943
|
-
var
|
|
6944
|
-
var sowOf = (dateMs) => dateMs / 1e3 %
|
|
7359
|
+
var BDT_EPOCH_MS3 = Date.UTC(2006, 0, 1);
|
|
7360
|
+
var SEC_PER_WEEK5 = 7 * 86400;
|
|
7361
|
+
var MS_PER_WEEK2 = SEC_PER_WEEK5 * 1e3;
|
|
7362
|
+
var HALF_WEEK3 = 302400;
|
|
7363
|
+
var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK5;
|
|
6945
7364
|
var BDS_SUBFRAME_BYTES = 38;
|
|
6946
7365
|
function getBitU2(b, p1, l1, p2, l2) {
|
|
6947
7366
|
return getBitU(b, p1, l1) * 2 ** l2 + getBitU(b, p2, l2);
|
|
@@ -6975,9 +7394,9 @@ function bdsSubframeParityOk(subframe) {
|
|
|
6975
7394
|
}
|
|
6976
7395
|
function buildBdsEphemeris(prn, f) {
|
|
6977
7396
|
let week = f.week;
|
|
6978
|
-
if (f.toes < f.sow -
|
|
6979
|
-
else if (f.toes > f.sow +
|
|
6980
|
-
const tocDate = new Date(
|
|
7397
|
+
if (f.toes < f.sow - HALF_WEEK3) week++;
|
|
7398
|
+
else if (f.toes > f.sow + HALF_WEEK3) week--;
|
|
7399
|
+
const tocDate = new Date(BDT_EPOCH_MS3 + week * MS_PER_WEEK2 + f.tocSec * 1e3);
|
|
6981
7400
|
return {
|
|
6982
7401
|
system: "C",
|
|
6983
7402
|
prn,
|
|
@@ -7216,8 +7635,8 @@ var BdsAssembler = class {
|
|
|
7216
7635
|
|
|
7217
7636
|
// src/navbits/gal.ts
|
|
7218
7637
|
var GPS_EPOCH_MS5 = Date.UTC(1980, 0, 6);
|
|
7219
|
-
var
|
|
7220
|
-
var
|
|
7638
|
+
var SEC_PER_WEEK6 = 7 * 86400;
|
|
7639
|
+
var HALF_WEEK4 = 302400;
|
|
7221
7640
|
var GST_GPS_WEEK_OFFSET = 1024;
|
|
7222
7641
|
function galInavPageCrcOk(page) {
|
|
7223
7642
|
if (page.length < 28) return false;
|
|
@@ -7228,11 +7647,11 @@ function galFnavPageCrcOk(page) {
|
|
|
7228
7647
|
return crc24q(page, 214) === getBitU(page, 214, 24);
|
|
7229
7648
|
}
|
|
7230
7649
|
function gpsDate2(week, sec) {
|
|
7231
|
-
return new Date(GPS_EPOCH_MS5 + (week *
|
|
7650
|
+
return new Date(GPS_EPOCH_MS5 + (week * SEC_PER_WEEK6 + sec) * 1e3);
|
|
7232
7651
|
}
|
|
7233
7652
|
function weekOfToe(week, tow, toe) {
|
|
7234
|
-
if (toe - tow >
|
|
7235
|
-
if (toe - tow < -
|
|
7653
|
+
if (toe - tow > HALF_WEEK4) return week - 1;
|
|
7654
|
+
if (toe - tow < -HALF_WEEK4) return week + 1;
|
|
7236
7655
|
return week;
|
|
7237
7656
|
}
|
|
7238
7657
|
var two4 = (n) => String(n).padStart(2, "0");
|
|
@@ -7324,7 +7743,7 @@ function decodeGalInavWords(words) {
|
|
|
7324
7743
|
return {
|
|
7325
7744
|
system: "E",
|
|
7326
7745
|
prn: `E${two4(svid)}`,
|
|
7327
|
-
toc: tocDate.getTime() / 1e3 %
|
|
7746
|
+
toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK6,
|
|
7328
7747
|
tocDate,
|
|
7329
7748
|
af0,
|
|
7330
7749
|
af1,
|
|
@@ -7432,7 +7851,7 @@ function decodeGalFnavPages(pages) {
|
|
|
7432
7851
|
return {
|
|
7433
7852
|
system: "E",
|
|
7434
7853
|
prn: `E${two4(svid)}`,
|
|
7435
|
-
toc: tocDate.getTime() / 1e3 %
|
|
7854
|
+
toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK6,
|
|
7436
7855
|
tocDate,
|
|
7437
7856
|
af0,
|
|
7438
7857
|
af1,
|
|
@@ -7524,7 +7943,7 @@ var GalFnavAssembler = class {
|
|
|
7524
7943
|
|
|
7525
7944
|
// src/navbits/glo.ts
|
|
7526
7945
|
var GPS_EPOCH_MS6 = Date.UTC(1980, 0, 6);
|
|
7527
|
-
var
|
|
7946
|
+
var SEC_PER_WEEK7 = 7 * 86400;
|
|
7528
7947
|
var SEC_PER_DAY = 86400;
|
|
7529
7948
|
var GLO_STRING_BYTES = 10;
|
|
7530
7949
|
function getBitG(b, pos, len) {
|
|
@@ -7618,8 +8037,8 @@ function decodeGloStrings(strings, refDate, opts = {}) {
|
|
|
7618
8037
|
if (frn1 !== 1 || frn2 !== 2 || frn3 !== 3 || frn4 !== 4) return null;
|
|
7619
8038
|
if (slot < 1 || slot > 27) return null;
|
|
7620
8039
|
const utcSec = (getUtcDate(refDate).getTime() - GPS_EPOCH_MS6) / 1e3;
|
|
7621
|
-
const week = Math.floor(utcSec /
|
|
7622
|
-
let tow = utcSec - week *
|
|
8040
|
+
const week = Math.floor(utcSec / SEC_PER_WEEK7);
|
|
8041
|
+
let tow = utcSec - week * SEC_PER_WEEK7;
|
|
7623
8042
|
const tod = tow % SEC_PER_DAY;
|
|
7624
8043
|
tow -= tod;
|
|
7625
8044
|
let tof = tkH * 3600 + tkM * 60 + tkS - 10800;
|
|
@@ -7632,12 +8051,12 @@ function decodeGloStrings(strings, refDate, opts = {}) {
|
|
|
7632
8051
|
system: "R",
|
|
7633
8052
|
prn: `R${String(slot).padStart(2, "0")}`,
|
|
7634
8053
|
// RINEX GLONASS epochs are UTC: build the UTC toe Date directly.
|
|
7635
|
-
tocDate: new Date(GPS_EPOCH_MS6 + (week *
|
|
8054
|
+
tocDate: new Date(GPS_EPOCH_MS6 + (week * SEC_PER_WEEK7 + tow + toe) * 1e3),
|
|
7636
8055
|
tauN: -tauN,
|
|
7637
8056
|
// RINEX stores −τn; the SIS carries τn (ICD sign)
|
|
7638
8057
|
gammaN,
|
|
7639
8058
|
// v3 message frame time: seconds of the UTC week (RTKLIB tof).
|
|
7640
|
-
messageFrameTime: ((tow + tof) %
|
|
8059
|
+
messageFrameTime: ((tow + tof) % SEC_PER_WEEK7 + SEC_PER_WEEK7) % SEC_PER_WEEK7,
|
|
7641
8060
|
x,
|
|
7642
8061
|
xDot,
|
|
7643
8062
|
xAcc,
|
|
@@ -7730,7 +8149,7 @@ function decodeSbasGeoNav(msg, prn, week, tow) {
|
|
|
7730
8149
|
|
|
7731
8150
|
// src/ubx/rawnav.ts
|
|
7732
8151
|
var GPS_EPOCH_MS8 = Date.UTC(1980, 0, 6);
|
|
7733
|
-
var
|
|
8152
|
+
var SEC_PER_WEEK8 = 7 * 86400;
|
|
7734
8153
|
var two6 = (n) => String(n).padStart(2, "0");
|
|
7735
8154
|
function parseUbxRawNav(data, opts = {}) {
|
|
7736
8155
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
@@ -7752,7 +8171,7 @@ function parseUbxRawNav(data, opts = {}) {
|
|
|
7752
8171
|
if (week === 0 && opts.refWeek !== void 0) week = opts.refWeek;
|
|
7753
8172
|
if (week > 0) {
|
|
7754
8173
|
refDate = new Date(
|
|
7755
|
-
GPS_EPOCH_MS8 + (week *
|
|
8174
|
+
GPS_EPOCH_MS8 + (week * SEC_PER_WEEK8 + rcvTow) * 1e3
|
|
7756
8175
|
);
|
|
7757
8176
|
refWeek = week;
|
|
7758
8177
|
refTow = rcvTow;
|
|
@@ -8066,9 +8485,9 @@ function svidToPrn(svid) {
|
|
|
8066
8485
|
// src/sbf/nav.ts
|
|
8067
8486
|
var PI2 = Math.PI;
|
|
8068
8487
|
var GPS_EPOCH_MS11 = Date.UTC(1980, 0, 6);
|
|
8069
|
-
var
|
|
8070
|
-
var
|
|
8071
|
-
var MS_PER_WEEK5 =
|
|
8488
|
+
var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
|
|
8489
|
+
var SEC_PER_WEEK9 = 7 * 86400;
|
|
8490
|
+
var MS_PER_WEEK5 = SEC_PER_WEEK9 * 1e3;
|
|
8072
8491
|
var F4_DNU = -2e10;
|
|
8073
8492
|
var U4_DNU = 4294967295;
|
|
8074
8493
|
function adjustWeek(refWeek, wn, mod) {
|
|
@@ -8078,7 +8497,7 @@ function adjustWeek(refWeek, wn, mod) {
|
|
|
8078
8497
|
return refWeek - offset;
|
|
8079
8498
|
}
|
|
8080
8499
|
var gpsMs = (week, sec) => GPS_EPOCH_MS11 + week * MS_PER_WEEK5 + sec * 1e3;
|
|
8081
|
-
var sowOf2 = (dateMs) => dateMs / 1e3 %
|
|
8500
|
+
var sowOf2 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK9;
|
|
8082
8501
|
function decodeGpsQzsNav(view, b, sys) {
|
|
8083
8502
|
const svid = view.getUint8(b + 14);
|
|
8084
8503
|
const prn = sys === "G" ? svid : svid - 180;
|
|
@@ -8181,7 +8600,7 @@ function decodeBdsNav(view, b) {
|
|
|
8181
8600
|
const toes = view.getUint32(b + 88, true);
|
|
8182
8601
|
const wnToc = adjustWeek(bdsWeekRef, view.getUint16(b + 136, true), 8192);
|
|
8183
8602
|
const wnToe = adjustWeek(bdsWeekRef, view.getUint16(b + 138, true), 8192);
|
|
8184
|
-
const tocDate = new Date(
|
|
8603
|
+
const tocDate = new Date(BDT_EPOCH_MS4 + wnToc * MS_PER_WEEK5 + tocs * 1e3);
|
|
8185
8604
|
return {
|
|
8186
8605
|
system: "C",
|
|
8187
8606
|
prn,
|
|
@@ -8227,7 +8646,7 @@ function decodeGloNav(view, b) {
|
|
|
8227
8646
|
const tocDate = new Date(toeGpsMs - leapMs);
|
|
8228
8647
|
const tofGpsMs = gpsMs(wnc, 0) + view.getUint32(b + 8, true);
|
|
8229
8648
|
const tofLeapMs = getGpsLeap(new Date(tofGpsMs)) * 1e3;
|
|
8230
|
-
const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS11) / 1e3 %
|
|
8649
|
+
const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS11) / 1e3 % SEC_PER_WEEK9;
|
|
8231
8650
|
return {
|
|
8232
8651
|
system: "R",
|
|
8233
8652
|
prn,
|
|
@@ -8550,7 +8969,7 @@ function parseSbfGpsNav(data) {
|
|
|
8550
8969
|
|
|
8551
8970
|
// src/navbits/navic.ts
|
|
8552
8971
|
var GPS_EPOCH_MS13 = Date.UTC(1980, 0, 6);
|
|
8553
|
-
var
|
|
8972
|
+
var SEC_PER_WEEK10 = 604800;
|
|
8554
8973
|
var DATA = 30;
|
|
8555
8974
|
function navicSubframeCrcOk(sf) {
|
|
8556
8975
|
return crc24q(sf, 262) === getBitU(sf, 262, 24);
|
|
@@ -8612,16 +9031,16 @@ function decodeNavicSubframes(sf1, sf2, opts = {}) {
|
|
|
8612
9031
|
j += 22;
|
|
8613
9032
|
const i0 = getBitS(sf2, j, 32) * 2 ** -31 * GPS_PI;
|
|
8614
9033
|
if (sqrtA <= 0 || e >= 1) return null;
|
|
8615
|
-
const week = opts.refWeek ?? Math.floor((Date.now() - GPS_EPOCH_MS13) / 1e3 /
|
|
9034
|
+
const week = opts.refWeek ?? Math.floor((Date.now() - GPS_EPOCH_MS13) / 1e3 / SEC_PER_WEEK10);
|
|
8616
9035
|
const prn = opts.prn ?? "I00";
|
|
8617
9036
|
const tocDate = new Date(
|
|
8618
|
-
GPS_EPOCH_MS13 + (week *
|
|
9037
|
+
GPS_EPOCH_MS13 + (week * SEC_PER_WEEK10 + tocSec) * 1e3
|
|
8619
9038
|
);
|
|
8620
9039
|
return {
|
|
8621
9040
|
system: "I",
|
|
8622
9041
|
prn,
|
|
8623
9042
|
tocDate,
|
|
8624
|
-
toc: tocDate.getTime() / 1e3 %
|
|
9043
|
+
toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK10,
|
|
8625
9044
|
af0,
|
|
8626
9045
|
af1,
|
|
8627
9046
|
af2,
|
|
@@ -8896,6 +9315,80 @@ function parseSbfGloNav(data) {
|
|
|
8896
9315
|
return { ephemerides, badCrc, messages };
|
|
8897
9316
|
}
|
|
8898
9317
|
|
|
9318
|
+
// src/sbf/rawnav-bds-cnav.ts
|
|
9319
|
+
var GPS_BDT_OFFSET = 14;
|
|
9320
|
+
var B1C_FRAME_S = 18;
|
|
9321
|
+
var TOW_DNU2 = 4294967295;
|
|
9322
|
+
function newBdsCnavAssemblers() {
|
|
9323
|
+
return {
|
|
9324
|
+
b1c: new BdsCnav1Assembler(),
|
|
9325
|
+
b2a: new BdsCnav2Assembler(),
|
|
9326
|
+
b2b: new BdsCnav3Assembler()
|
|
9327
|
+
};
|
|
9328
|
+
}
|
|
9329
|
+
function navBits(view, wordsAt, start, nBits) {
|
|
9330
|
+
const out = new Uint8Array(Math.ceil(nBits / 8));
|
|
9331
|
+
for (let i = 0; i < nBits; i++) {
|
|
9332
|
+
const p = start + i;
|
|
9333
|
+
const w = view.getUint32(wordsAt + 4 * (p >>> 5), true);
|
|
9334
|
+
if (w >>> 31 - (p & 31) & 1) out[i >> 3] |= 128 >> (i & 7);
|
|
9335
|
+
}
|
|
9336
|
+
return out;
|
|
9337
|
+
}
|
|
9338
|
+
var MIN_LEN = { 4218: 248, 4219: 92, 4242: 144 };
|
|
9339
|
+
function feedBdsCnavBlock(view, b, id, len, asm) {
|
|
9340
|
+
if (len < (MIN_LEN[id] ?? Infinity)) return {};
|
|
9341
|
+
const prnStr = svidToPrn(view.getUint8(b + 14));
|
|
9342
|
+
if (!prnStr || prnStr[0] !== "C") return {};
|
|
9343
|
+
const prn = Number(prnStr.slice(1));
|
|
9344
|
+
const words = b + 20;
|
|
9345
|
+
if (id === 4218) {
|
|
9346
|
+
const towMs = view.getUint32(b + 8, true);
|
|
9347
|
+
if (towMs === TOW_DNU2) return {};
|
|
9348
|
+
const sf2 = navBits(view, words, 72, 600);
|
|
9349
|
+
const sf3 = navBits(view, words, 1272, 264);
|
|
9350
|
+
const sf2Ok = bdsCnav1Sf2CrcOk(sf2);
|
|
9351
|
+
const bdt = (towMs / 1e3 - GPS_BDT_OFFSET + 604800) % 604800;
|
|
9352
|
+
const tTm = (Math.floor(bdt) - B1C_FRAME_S + 604800) % 604800;
|
|
9353
|
+
const eph = asm.b1c.push(
|
|
9354
|
+
prn,
|
|
9355
|
+
sf2Ok ? sf2 : null,
|
|
9356
|
+
bdsCnav1Sf3CrcOk(sf3) ? sf3 : null,
|
|
9357
|
+
tTm
|
|
9358
|
+
);
|
|
9359
|
+
if (!sf2Ok) return { badCrc: true };
|
|
9360
|
+
return eph ? { eph } : {};
|
|
9361
|
+
}
|
|
9362
|
+
if (id === 4219) {
|
|
9363
|
+
const msg = navBits(view, words, 0, 288);
|
|
9364
|
+
if (!bdsCnav2CrcOk(msg)) return { badCrc: true };
|
|
9365
|
+
const eph = asm.b2a.push(msg);
|
|
9366
|
+
return eph ? { eph } : {};
|
|
9367
|
+
}
|
|
9368
|
+
if (id === 4242) {
|
|
9369
|
+
const msg = navBits(view, words, 12, 486);
|
|
9370
|
+
if (!bdsCnav3CrcOk(msg)) return { badCrc: true };
|
|
9371
|
+
const eph = asm.b2b.push(prn, msg);
|
|
9372
|
+
return eph ? { eph } : {};
|
|
9373
|
+
}
|
|
9374
|
+
return {};
|
|
9375
|
+
}
|
|
9376
|
+
function parseSbfBdsCnav(data) {
|
|
9377
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
9378
|
+
const asm = newBdsCnavAssemblers();
|
|
9379
|
+
const ephemerides = [];
|
|
9380
|
+
let badCrc = 0;
|
|
9381
|
+
let messages = 0;
|
|
9382
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
9383
|
+
if (id !== 4218 && id !== 4219 && id !== 4242) return;
|
|
9384
|
+
messages++;
|
|
9385
|
+
const r = feedBdsCnavBlock(view, b, id, len, asm);
|
|
9386
|
+
if (r.eph) ephemerides.push(r.eph);
|
|
9387
|
+
else if (r.badCrc) badCrc++;
|
|
9388
|
+
});
|
|
9389
|
+
return { ephemerides, badCrc, messages };
|
|
9390
|
+
}
|
|
9391
|
+
|
|
8899
9392
|
// src/navbits/sbas-l5.ts
|
|
8900
9393
|
var SBAS_L5_PREAMBLE_UW = 6056250;
|
|
8901
9394
|
function isSbasL1Preamble(msg) {
|
|
@@ -9038,6 +9531,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
9038
9531
|
const ephemerides = [];
|
|
9039
9532
|
const seen = /* @__PURE__ */ new Set();
|
|
9040
9533
|
const cnav = [];
|
|
9534
|
+
const bdsCnav = [];
|
|
9041
9535
|
const ionoCorrections = {};
|
|
9042
9536
|
let leapSeconds = null;
|
|
9043
9537
|
const counts = {
|
|
@@ -9047,6 +9541,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
9047
9541
|
galRaw: 0,
|
|
9048
9542
|
gloRaw: 0,
|
|
9049
9543
|
bdsRaw: 0,
|
|
9544
|
+
bdsCnavRaw: 0,
|
|
9050
9545
|
sbasRaw: 0,
|
|
9051
9546
|
sbasL5Raw: 0,
|
|
9052
9547
|
navicRaw: 0,
|
|
@@ -9058,6 +9553,7 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
9058
9553
|
const galAsm = newGalAssemblers();
|
|
9059
9554
|
const gloAsm = new GloStringAssembler();
|
|
9060
9555
|
const bdsAsm = new BdsAssembler();
|
|
9556
|
+
const bdsCnavAsm = newBdsCnavAssemblers();
|
|
9061
9557
|
const lnavAsm = new GpsLnavAssembler();
|
|
9062
9558
|
const navicAsm = new NavicAssembler();
|
|
9063
9559
|
const addEph = (e) => {
|
|
@@ -9164,6 +9660,17 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
9164
9660
|
else if (r.badCrc) counts.badFrames++;
|
|
9165
9661
|
return;
|
|
9166
9662
|
}
|
|
9663
|
+
case 4218:
|
|
9664
|
+
// BDSRawB1C
|
|
9665
|
+
case 4219:
|
|
9666
|
+
// BDSRawB2a
|
|
9667
|
+
case 4242: {
|
|
9668
|
+
counts.bdsCnavRaw++;
|
|
9669
|
+
const r = feedBdsCnavBlock(view, b, id, len, bdsCnavAsm);
|
|
9670
|
+
if (r.eph) bdsCnav.push(r.eph);
|
|
9671
|
+
else if (r.badCrc) counts.badFrames++;
|
|
9672
|
+
return;
|
|
9673
|
+
}
|
|
9167
9674
|
case 4020: {
|
|
9168
9675
|
if (len < 52) return;
|
|
9169
9676
|
counts.sbasRaw++;
|
|
@@ -9220,7 +9727,15 @@ function decodeSbfNavigation(data, opts = {}) {
|
|
|
9220
9727
|
prns: [...dfmcPrns].sort(),
|
|
9221
9728
|
messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
|
|
9222
9729
|
};
|
|
9223
|
-
return {
|
|
9730
|
+
return {
|
|
9731
|
+
ephemerides,
|
|
9732
|
+
cnav,
|
|
9733
|
+
bdsCnav,
|
|
9734
|
+
ionoCorrections,
|
|
9735
|
+
leapSeconds,
|
|
9736
|
+
dfmc,
|
|
9737
|
+
counts
|
|
9738
|
+
};
|
|
9224
9739
|
}
|
|
9225
9740
|
|
|
9226
9741
|
// src/navbits/rs255.ts
|
|
@@ -10470,12 +10985,12 @@ var ID_BDSEPHEMERIS = 1696;
|
|
|
10470
10985
|
var ID_RAWWAASFRAME = 287;
|
|
10471
10986
|
var ID_RAWSBASFRAME = 973;
|
|
10472
10987
|
var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
|
|
10473
|
-
var
|
|
10474
|
-
var
|
|
10988
|
+
var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
|
|
10989
|
+
var SEC_PER_WEEK11 = 7 * 86400;
|
|
10475
10990
|
var SEC_PER_DAY2 = 86400;
|
|
10476
|
-
var MS_PER_WEEK8 =
|
|
10991
|
+
var MS_PER_WEEK8 = SEC_PER_WEEK11 * 1e3;
|
|
10477
10992
|
var gpsMs2 = (week, sec) => GPS_EPOCH_MS16 + week * MS_PER_WEEK8 + sec * 1e3;
|
|
10478
|
-
var sowOf3 = (dateMs) => dateMs / 1e3 %
|
|
10993
|
+
var sowOf3 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK11;
|
|
10479
10994
|
function nearWeekMs(refMs, sow) {
|
|
10480
10995
|
const refWeek = Math.floor((refMs - GPS_EPOCH_MS16) / MS_PER_WEEK8);
|
|
10481
10996
|
let ms = gpsMs2(refWeek, sow);
|
|
@@ -10504,8 +11019,8 @@ function decodeGloEphemeris(view, p) {
|
|
|
10504
11019
|
tof += Math.floor(tow / SEC_PER_DAY2) * SEC_PER_DAY2;
|
|
10505
11020
|
if (tof < tow - 43200) tof += SEC_PER_DAY2;
|
|
10506
11021
|
else if (tof > tow + 43200) tof -= SEC_PER_DAY2;
|
|
10507
|
-
const toeGpsMs = GPS_EPOCH_MS16 + (week *
|
|
10508
|
-
const tofGpsMs = GPS_EPOCH_MS16 + (week *
|
|
11022
|
+
const toeGpsMs = GPS_EPOCH_MS16 + (week * SEC_PER_WEEK11 + tow) * 1e3;
|
|
11023
|
+
const tofGpsMs = GPS_EPOCH_MS16 + (week * SEC_PER_WEEK11 + tof) * 1e3;
|
|
10509
11024
|
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS16) / 1e3;
|
|
10510
11025
|
return {
|
|
10511
11026
|
system: "R",
|
|
@@ -10514,7 +11029,7 @@ function decodeGloEphemeris(view, p) {
|
|
|
10514
11029
|
tauN: -view.getFloat64(p + 100, true),
|
|
10515
11030
|
// RINEX stores −τ_n
|
|
10516
11031
|
gammaN: view.getFloat64(p + 116, true),
|
|
10517
|
-
messageFrameTime: (tofUtcSec %
|
|
11032
|
+
messageFrameTime: (tofUtcSec % SEC_PER_WEEK11 + SEC_PER_WEEK11) % SEC_PER_WEEK11,
|
|
10518
11033
|
x: view.getFloat64(p + 28, true) / 1e3,
|
|
10519
11034
|
y: view.getFloat64(p + 36, true) / 1e3,
|
|
10520
11035
|
z: view.getFloat64(p + 44, true) / 1e3,
|
|
@@ -10588,7 +11103,7 @@ function decodeBdsEphemeris2(view, p) {
|
|
|
10588
11103
|
const tgd1 = view.getFloat64(p + 20, true);
|
|
10589
11104
|
const tocs = view.getUint32(p + 40, true);
|
|
10590
11105
|
const toes = view.getUint32(p + 72, true);
|
|
10591
|
-
const tocDate = new Date(
|
|
11106
|
+
const tocDate = new Date(BDT_EPOCH_MS5 + week * MS_PER_WEEK8 + tocs * 1e3);
|
|
10592
11107
|
return {
|
|
10593
11108
|
system: "C",
|
|
10594
11109
|
prn: `C${String(prn).padStart(2, "0")}`,
|
|
@@ -10936,7 +11451,7 @@ function parseNovatelRange(data) {
|
|
|
10936
11451
|
const sigtype = stat >>> 21 & 31;
|
|
10937
11452
|
const plock = stat >>> 10 & 1;
|
|
10938
11453
|
const parity = stat >>> 11 & 1;
|
|
10939
|
-
const
|
|
11454
|
+
const clock2 = stat >>> 12 & 1;
|
|
10940
11455
|
const sig = SIGNALS2[satsys]?.[sigtype];
|
|
10941
11456
|
if (!sig) continue;
|
|
10942
11457
|
let [sysL, code] = sig;
|
|
@@ -10966,7 +11481,7 @@ function parseNovatelRange(data) {
|
|
|
10966
11481
|
meas.push({
|
|
10967
11482
|
prn: `${sysL}${String(prnNum).padStart(2, "0")}`,
|
|
10968
11483
|
code,
|
|
10969
|
-
pr:
|
|
11484
|
+
pr: clock2 ? psr : null,
|
|
10970
11485
|
cp: plock ? cp : null,
|
|
10971
11486
|
doppler: plock ? dop : null,
|
|
10972
11487
|
cn0,
|
|
@@ -10993,7 +11508,7 @@ function parseNovatelRange(data) {
|
|
|
10993
11508
|
const sigtype = stat >>> 21 & 31;
|
|
10994
11509
|
const plock = stat >>> 10 & 1;
|
|
10995
11510
|
const parity = stat >>> 11 & 1;
|
|
10996
|
-
const
|
|
11511
|
+
const clock2 = stat >>> 12 & 1;
|
|
10997
11512
|
const sig = SIGNALS2[satsys]?.[sigtype];
|
|
10998
11513
|
if (!sig) continue;
|
|
10999
11514
|
let [sysL, code] = sig;
|
|
@@ -11018,7 +11533,7 @@ function parseNovatelRange(data) {
|
|
|
11018
11533
|
meas.push({
|
|
11019
11534
|
prn,
|
|
11020
11535
|
code,
|
|
11021
|
-
pr:
|
|
11536
|
+
pr: clock2 ? psr : null,
|
|
11022
11537
|
cp: plock ? -adr : null,
|
|
11023
11538
|
doppler: plock ? dop : null,
|
|
11024
11539
|
cn0: snr,
|
|
@@ -11081,14 +11596,14 @@ function* trimbleFrames(data, stats) {
|
|
|
11081
11596
|
|
|
11082
11597
|
// src/trimble/nav.ts
|
|
11083
11598
|
var GPS_EPOCH_MS19 = Date.UTC(1980, 0, 6);
|
|
11084
|
-
var
|
|
11085
|
-
var
|
|
11086
|
-
var MS_PER_WEEK10 =
|
|
11599
|
+
var BDT_EPOCH_MS6 = Date.UTC(2006, 0, 1);
|
|
11600
|
+
var SEC_PER_WEEK12 = 7 * 86400;
|
|
11601
|
+
var MS_PER_WEEK10 = SEC_PER_WEEK12 * 1e3;
|
|
11087
11602
|
var GPS_PI2 = 3.1415926535898;
|
|
11088
11603
|
var BDS_WEEK_OFFSET = 1356;
|
|
11089
11604
|
var BDS_LEAP_SEC = 14;
|
|
11090
11605
|
var gpsMs3 = (week, sec) => GPS_EPOCH_MS19 + week * MS_PER_WEEK10 + sec * 1e3;
|
|
11091
|
-
var sowOf4 = (dateMs) => dateMs / 1e3 %
|
|
11606
|
+
var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK12;
|
|
11092
11607
|
var SUB_GPS_EPHEMERIS = 1;
|
|
11093
11608
|
var SUB_ION_UTC = 3;
|
|
11094
11609
|
var SUB_GLO_EPHEMERIS = 9;
|
|
@@ -11169,7 +11684,7 @@ function decodeBdsEphemeris3(view, base) {
|
|
|
11169
11684
|
const tocSec = r.tocSec - BDS_LEAP_SEC;
|
|
11170
11685
|
const toeSec = r.toeSec - BDS_LEAP_SEC;
|
|
11171
11686
|
const tocDate = new Date(
|
|
11172
|
-
|
|
11687
|
+
BDT_EPOCH_MS6 + bdsWeek * MS_PER_WEEK10 + tocSec * 1e3
|
|
11173
11688
|
);
|
|
11174
11689
|
return {
|
|
11175
11690
|
system: "C",
|
|
@@ -11240,7 +11755,7 @@ function decodeGloEphemeris2(view, base) {
|
|
|
11240
11755
|
// RINEX stores −τn as the clock bias; the record carries τn (ICD sign).
|
|
11241
11756
|
tauN: -view.getFloat64(base + 113, false),
|
|
11242
11757
|
gammaN: view.getFloat64(base + 121, false),
|
|
11243
|
-
messageFrameTime: (tocMs - GPS_EPOCH_MS19) / 1e3 %
|
|
11758
|
+
messageFrameTime: (tocMs - GPS_EPOCH_MS19) / 1e3 % SEC_PER_WEEK12,
|
|
11244
11759
|
// State vector: metres / m·s⁻¹ / m·s⁻² → km / km·s⁻¹ / km·s⁻².
|
|
11245
11760
|
x: view.getFloat64(base + 33, false) / 1e3,
|
|
11246
11761
|
xDot: view.getFloat64(base + 41, false) / 1e3,
|
|
@@ -11692,12 +12207,12 @@ function* binexRecords(data, view, stats) {
|
|
|
11692
12207
|
// src/binex/nav.ts
|
|
11693
12208
|
var GPS_EPOCH_MS21 = Date.UTC(1980, 0, 6);
|
|
11694
12209
|
var GLO_DAY0_MS = Date.UTC(1980, 0, 1);
|
|
11695
|
-
var
|
|
11696
|
-
var
|
|
11697
|
-
var MS_PER_WEEK12 =
|
|
12210
|
+
var BDT_EPOCH_MS7 = Date.UTC(2006, 0, 1);
|
|
12211
|
+
var SEC_PER_WEEK13 = 7 * 86400;
|
|
12212
|
+
var MS_PER_WEEK12 = SEC_PER_WEEK13 * 1e3;
|
|
11698
12213
|
var SC2RAD = GPS_PI;
|
|
11699
12214
|
var gpsMs4 = (week, sec) => GPS_EPOCH_MS21 + week * MS_PER_WEEK12 + sec * 1e3;
|
|
11700
|
-
var sowOf5 = (dateMs) => (dateMs / 1e3 %
|
|
12215
|
+
var sowOf5 = (dateMs) => (dateMs / 1e3 % SEC_PER_WEEK13 + SEC_PER_WEEK13) % SEC_PER_WEEK13;
|
|
11701
12216
|
var two9 = (n) => String(n).padStart(2, "0");
|
|
11702
12217
|
var Reader = class {
|
|
11703
12218
|
constructor(view, start, le) {
|
|
@@ -11861,7 +12376,7 @@ function decodeBeidou(view, p, le) {
|
|
|
11861
12376
|
const iode = flag1 >> 6 & 31;
|
|
11862
12377
|
const svHealth = flag1 & 1;
|
|
11863
12378
|
const tgd = bdsTgd(flag2 >> 4);
|
|
11864
|
-
const tocDate = new Date(
|
|
12379
|
+
const tocDate = new Date(BDT_EPOCH_MS7 + week * MS_PER_WEEK12 + toes * 1e3);
|
|
11865
12380
|
return {
|
|
11866
12381
|
system: "C",
|
|
11867
12382
|
prn: `C${two9(prn)}`,
|
|
@@ -12389,13 +12904,13 @@ var GM_GPS = 3986005e8;
|
|
|
12389
12904
|
var GM_GAL = 3986004418e5;
|
|
12390
12905
|
var GM_BDS = 3986004418e5;
|
|
12391
12906
|
var GPS_EPOCH_MS23 = Date.UTC(1980, 0, 6);
|
|
12392
|
-
var
|
|
12907
|
+
var BDT_EPOCH_MS8 = Date.UTC(2006, 0, 1);
|
|
12393
12908
|
var WEEK_MS = 6048e5;
|
|
12394
12909
|
var BDT_MINUS_GPST_MS = 14e3;
|
|
12395
12910
|
var BDS_GEO_PRNS = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 59, 60, 61, 62, 63]);
|
|
12396
12911
|
function almanacEpochMs(alm) {
|
|
12397
12912
|
if (alm.system === "C") {
|
|
12398
|
-
return
|
|
12913
|
+
return BDT_EPOCH_MS8 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
|
|
12399
12914
|
}
|
|
12400
12915
|
return GPS_EPOCH_MS23 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
|
|
12401
12916
|
}
|
|
@@ -12770,8 +13285,8 @@ function computeDop(satAzEls) {
|
|
|
12770
13285
|
for (const { az, el, prn } of sats) {
|
|
12771
13286
|
const cosEl = Math.cos(el);
|
|
12772
13287
|
const row = [cosEl * Math.sin(az), cosEl * Math.cos(az), Math.sin(el)];
|
|
12773
|
-
const
|
|
12774
|
-
for (const c of clocks) row.push(c ===
|
|
13288
|
+
const clock2 = dopClock(prn);
|
|
13289
|
+
for (const c of clocks) row.push(c === clock2 ? 1 : 0);
|
|
12775
13290
|
H3.push(row);
|
|
12776
13291
|
}
|
|
12777
13292
|
const HtH = Array.from({ length: m }, () => new Array(m).fill(0));
|
|
@@ -14997,7 +15512,7 @@ var P2_31 = 2 ** -31;
|
|
|
14997
15512
|
var P2_39 = 2 ** -39;
|
|
14998
15513
|
var D2R = Math.PI / 180;
|
|
14999
15514
|
var R2D = 180 / Math.PI;
|
|
15000
|
-
var
|
|
15515
|
+
var SEC_PER_WEEK14 = 604800;
|
|
15001
15516
|
var MAXSBSAGEF = 30;
|
|
15002
15517
|
var MAXSBSAGEL = 360;
|
|
15003
15518
|
var MAXBAND = 10;
|
|
@@ -15145,7 +15660,7 @@ var igpband2 = [
|
|
|
15145
15660
|
[{ coord: 60, arr: x5, bits: 1, bite: 72 }, { coord: 65, arr: x6, bits: 73, bite: 108 }, { coord: 70, arr: x6, bits: 109, bite: 144 }, { coord: 75, arr: x6, bits: 145, bite: 180 }, { coord: 85, arr: x7, bits: 181, bite: 192 }],
|
|
15146
15661
|
[{ coord: -60, arr: x5, bits: 1, bite: 72 }, { coord: -65, arr: x6, bits: 73, bite: 108 }, { coord: -70, arr: x6, bits: 109, bite: 144 }, { coord: -75, arr: x6, bits: 145, bite: 180 }, { coord: -85, arr: x8, bits: 181, bite: 192 }]
|
|
15147
15662
|
];
|
|
15148
|
-
var gpsSeconds = (week, tow) => week *
|
|
15663
|
+
var gpsSeconds = (week, tow) => week * SEC_PER_WEEK14 + tow;
|
|
15149
15664
|
function maskPrn(i) {
|
|
15150
15665
|
if (i >= 1 && i <= 37) return `G${two11(i)}`;
|
|
15151
15666
|
if (i >= 38 && i <= 61) return `R${two11(i - 37)}`;
|
|
@@ -15525,8 +16040,8 @@ var SbasProcessor = class {
|
|
|
15525
16040
|
const j = block * 15 + i;
|
|
15526
16041
|
if (j >= b.igp.length) continue;
|
|
15527
16042
|
const give = getBitU(msg, 22 + i * 13 + 9, 4);
|
|
15528
|
-
const
|
|
15529
|
-
b.igp[j].delay =
|
|
16043
|
+
const delay2 = getBitU(msg, 22 + i * 13, 9);
|
|
16044
|
+
b.igp[j].delay = delay2 === 511 ? 0 : delay2 * 0.125;
|
|
15530
16045
|
b.igp[j].give = give + 1 >= 16 ? 0 : give + 1;
|
|
15531
16046
|
b.igp[j].t0s = t0s;
|
|
15532
16047
|
}
|
|
@@ -15692,19 +16207,19 @@ var SbasProcessor = class {
|
|
|
15692
16207
|
if (w[3] < 0) return null;
|
|
15693
16208
|
} else return null;
|
|
15694
16209
|
const now = gpsSeconds(week, tow);
|
|
15695
|
-
let
|
|
16210
|
+
let delay2 = 0;
|
|
15696
16211
|
let varVert = 0;
|
|
15697
16212
|
for (let i = 0; i < 4; i++) {
|
|
15698
16213
|
const g = pts[i];
|
|
15699
16214
|
if (!g) continue;
|
|
15700
|
-
|
|
16215
|
+
delay2 += w[i] * g.delay;
|
|
15701
16216
|
const sigGive = Math.sqrt(varicorr(g.give));
|
|
15702
16217
|
const d = this.degr;
|
|
15703
16218
|
const eiono = d ? sbasIonoDeg(d, now - g.t0s) : 0;
|
|
15704
16219
|
const sig2 = d?.rssIono ? sigGive * sigGive + eiono * eiono : (sigGive + eiono) ** 2;
|
|
15705
16220
|
varVert += w[i] * sig2;
|
|
15706
16221
|
}
|
|
15707
|
-
return { delayM:
|
|
16222
|
+
return { delayM: delay2 * fp, varM2: varVert * fp * fp };
|
|
15708
16223
|
}
|
|
15709
16224
|
/** Find the four IGPs bracketing a pierce point (RTKLIB `searchigp`). */
|
|
15710
16225
|
searchIgp(latP, lonP) {
|
|
@@ -15792,10 +16307,10 @@ function applyOrbitClock(eph, corr, timeMs) {
|
|
|
15792
16307
|
const clockM = corr.clockC0 + (corr.clockC1 ?? 0) * age + (corr.clockC2 ?? 0) * age * age + (corr.highRateClock ?? 0);
|
|
15793
16308
|
return { x, y, z, clockOffsetS: clockM / C_LIGHT };
|
|
15794
16309
|
}
|
|
15795
|
-
function hasToOrbitClock(orbit,
|
|
16310
|
+
function hasToOrbitClock(orbit, clock2, refTimeMs, validitySeconds) {
|
|
15796
16311
|
if (orbit.deltaRadial == null || orbit.deltaInTrack == null || orbit.deltaCrossTrack == null)
|
|
15797
16312
|
return null;
|
|
15798
|
-
const clockC0 =
|
|
16313
|
+
const clockC0 = clock2 && clock2.deltaClock != null && !clock2.notUsable ? clock2.deltaClock : 0;
|
|
15799
16314
|
return {
|
|
15800
16315
|
prn: orbit.prn,
|
|
15801
16316
|
iod: orbit.gnssIod,
|
|
@@ -17171,7 +17686,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
17171
17686
|
let x9 = 0;
|
|
17172
17687
|
let y2 = 0;
|
|
17173
17688
|
let z2 = 0;
|
|
17174
|
-
const
|
|
17689
|
+
const clock3 = new Map(systems.map((s) => [s, 0]));
|
|
17175
17690
|
const residuals2 = {};
|
|
17176
17691
|
let iterations2 = 0;
|
|
17177
17692
|
let converged2 = false;
|
|
@@ -17191,7 +17706,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
17191
17706
|
const psr = pseudoranges.get(prn);
|
|
17192
17707
|
const eph = ephemerides.get(prn);
|
|
17193
17708
|
const sys = prn[0];
|
|
17194
|
-
const clk =
|
|
17709
|
+
const clk = clock3.get(sys);
|
|
17195
17710
|
const tTx = timeMs - psr / C_LIGHT * 1e3;
|
|
17196
17711
|
const dtsClock = satClockCorrection(eph, tTx);
|
|
17197
17712
|
const sat = computeSatPosition(eph, tTx - dtsClock * 1e3);
|
|
@@ -17283,13 +17798,13 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
17283
17798
|
y2 += dx[1];
|
|
17284
17799
|
z2 += dx[2];
|
|
17285
17800
|
for (const s of systems)
|
|
17286
|
-
|
|
17801
|
+
clock3.set(s, clock3.get(s) + dx[sysIndex.get(s)]);
|
|
17287
17802
|
if (Math.hypot(dx[0], dx[1], dx[2]) < convergenceM) {
|
|
17288
17803
|
converged2 = true;
|
|
17289
17804
|
break;
|
|
17290
17805
|
}
|
|
17291
17806
|
}
|
|
17292
|
-
return { x: x9, y: y2, z: z2, clock:
|
|
17807
|
+
return { x: x9, y: y2, z: z2, clock: clock3, residuals: residuals2, iterations: iterations2, converged: converged2 };
|
|
17293
17808
|
};
|
|
17294
17809
|
const REJECT_THRESHOLD_M = 50;
|
|
17295
17810
|
let candidates = all;
|
|
@@ -17314,7 +17829,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
17314
17829
|
candidates = remaining;
|
|
17315
17830
|
}
|
|
17316
17831
|
if (!inner) return null;
|
|
17317
|
-
const { x, y, z, clock, residuals, iterations, converged } = inner;
|
|
17832
|
+
const { x, y, z, clock: clock2, residuals, iterations, converged } = inner;
|
|
17318
17833
|
const used = [];
|
|
17319
17834
|
const azels = [];
|
|
17320
17835
|
const [rxLat, rxLon, rxHgt] = ecefToGeodetic(x, y, z);
|
|
@@ -17354,7 +17869,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
17354
17869
|
const pl = sbas ? sbasProtectionLevels(sbasRows) : null;
|
|
17355
17870
|
return {
|
|
17356
17871
|
position: [x, y, z],
|
|
17357
|
-
clockBias: Object.fromEntries(
|
|
17872
|
+
clockBias: Object.fromEntries(clock2),
|
|
17358
17873
|
usedSatellites: used,
|
|
17359
17874
|
rejectedSatellites: rejected,
|
|
17360
17875
|
residuals,
|
|
@@ -19895,6 +20410,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
19895
20410
|
parseNovatelRange,
|
|
19896
20411
|
parseRinexStream,
|
|
19897
20412
|
parseSbfAlmanac,
|
|
20413
|
+
parseSbfBdsCnav,
|
|
19898
20414
|
parseSbfBdsNav,
|
|
19899
20415
|
parseSbfCnav,
|
|
19900
20416
|
parseSbfGalNav,
|