gnss-js 1.16.0 → 1.18.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/{chunk-R33A2VA7.js → chunk-2IM5VXNI.js} +193 -12
- package/dist/{chunk-YPOVPXNK.js → chunk-CG7SF45F.js} +75 -0
- package/dist/{chunk-6CX6EXRK.js → chunk-FEGLXNWA.js} +97 -23
- package/dist/{chunk-4LVD4DYL.js → chunk-IQ5OIMQD.js} +2 -0
- package/dist/chunk-Y5IWUPJQ.js +206 -0
- package/dist/cnav-CRns0ECn.d.cts +96 -0
- package/dist/cnav-CRns0ECn.d.ts +96 -0
- package/dist/index.cjs +577 -56
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +13 -4
- package/dist/novatel.cjs +192 -11
- package/dist/novatel.d.cts +36 -13
- package/dist/novatel.d.ts +36 -13
- package/dist/novatel.js +2 -2
- package/dist/sbf.cjs +288 -2
- package/dist/sbf.d.cts +82 -1
- package/dist/sbf.d.ts +82 -1
- package/dist/sbf.js +7 -1
- package/dist/ubx.cjs +291 -24
- package/dist/ubx.d.cts +73 -2
- package/dist/ubx.d.ts +73 -2
- package/dist/ubx.js +7 -2
- package/package.json +1 -1
package/dist/ubx.cjs
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/ubx/index.ts
|
|
21
21
|
var ubx_exports = {};
|
|
22
22
|
__export(ubx_exports, {
|
|
23
|
+
parseUbxCnav: () => parseUbxCnav,
|
|
24
|
+
parseUbxIonoUtc: () => parseUbxIonoUtc,
|
|
23
25
|
parseUbxNav: () => parseUbxNav,
|
|
24
26
|
parseUbxRawx: () => parseUbxRawx,
|
|
25
27
|
ubxFrames: () => ubxFrames
|
|
@@ -201,6 +203,30 @@ function decodeGpsLnavFrame(subframes, opts = {}) {
|
|
|
201
203
|
|
|
202
204
|
// src/ubx/nav.ts
|
|
203
205
|
var PREAMB_CNAV = 139;
|
|
206
|
+
function readLnavSubframe(view, f) {
|
|
207
|
+
const p = f.payload;
|
|
208
|
+
if (p.length < 8) return null;
|
|
209
|
+
const gnssId = p[0];
|
|
210
|
+
const svId = p[1];
|
|
211
|
+
let prn;
|
|
212
|
+
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
213
|
+
prn = `G${String(svId).padStart(2, "0")}`;
|
|
214
|
+
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
215
|
+
if (p.length === 44) return null;
|
|
216
|
+
prn = `J${String(svId).padStart(2, "0")}`;
|
|
217
|
+
} else {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
if (p.length < 8 + 40) return null;
|
|
221
|
+
const base = f.payloadStart + 8;
|
|
222
|
+
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) return null;
|
|
223
|
+
const buff = new Uint8Array(30);
|
|
224
|
+
for (let k = 0; k < 10; k++) {
|
|
225
|
+
const dwrd = view.getUint32(base + 4 * k, true);
|
|
226
|
+
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
227
|
+
}
|
|
228
|
+
return { prn, gnssId, svId, buff, id: getBitU(buff, 43, 3) };
|
|
229
|
+
}
|
|
204
230
|
function parseUbxNav(data, opts = {}) {
|
|
205
231
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
206
232
|
const ephemerides = [];
|
|
@@ -222,28 +248,9 @@ function parseUbxNav(data, opts = {}) {
|
|
|
222
248
|
const last = /* @__PURE__ */ new Map();
|
|
223
249
|
for (const f of ubxFrames(data)) {
|
|
224
250
|
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
const gnssId =
|
|
228
|
-
const svId = p[1];
|
|
229
|
-
let prn;
|
|
230
|
-
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
231
|
-
prn = `G${String(svId).padStart(2, "0")}`;
|
|
232
|
-
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
233
|
-
if (p.length === 44) continue;
|
|
234
|
-
prn = `J${String(svId).padStart(2, "0")}`;
|
|
235
|
-
} else {
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
if (p.length < 8 + 40) continue;
|
|
239
|
-
const base = f.payloadStart + 8;
|
|
240
|
-
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) continue;
|
|
241
|
-
const buff = new Uint8Array(30);
|
|
242
|
-
for (let k = 0; k < 10; k++) {
|
|
243
|
-
const dwrd = view.getUint32(base + 4 * k, true);
|
|
244
|
-
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
245
|
-
}
|
|
246
|
-
const id = getBitU(buff, 43, 3);
|
|
251
|
+
const lnav = readLnavSubframe(view, f);
|
|
252
|
+
if (!lnav) continue;
|
|
253
|
+
const { prn, gnssId, svId, buff, id } = lnav;
|
|
247
254
|
if (id < 1 || id > 5) {
|
|
248
255
|
badParity++;
|
|
249
256
|
continue;
|
|
@@ -273,8 +280,266 @@ function parseUbxNav(data, opts = {}) {
|
|
|
273
280
|
return { ephemerides, badParity };
|
|
274
281
|
}
|
|
275
282
|
|
|
276
|
-
// src/ubx/
|
|
283
|
+
// src/ubx/iono.ts
|
|
284
|
+
function parseUbxIonoUtc(data) {
|
|
285
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
286
|
+
const ionoCorrections = {};
|
|
287
|
+
let leapSeconds = null;
|
|
288
|
+
for (const f of ubxFrames(data)) {
|
|
289
|
+
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
290
|
+
const sf = readLnavSubframe(view, f);
|
|
291
|
+
if (!sf || sf.gnssId !== 0 || sf.id !== 4) continue;
|
|
292
|
+
const b = sf.buff;
|
|
293
|
+
if (getBitU(b, 48, 2) !== 1 || getBitU(b, 50, 6) !== 56) continue;
|
|
294
|
+
ionoCorrections["GPSA"] = [
|
|
295
|
+
getBitS(b, 56, 8) * 2 ** -30,
|
|
296
|
+
getBitS(b, 64, 8) * 2 ** -27,
|
|
297
|
+
getBitS(b, 72, 8) * 2 ** -24,
|
|
298
|
+
getBitS(b, 80, 8) * 2 ** -24
|
|
299
|
+
];
|
|
300
|
+
ionoCorrections["GPSB"] = [
|
|
301
|
+
getBitS(b, 88, 8) * 2 ** 11,
|
|
302
|
+
getBitS(b, 96, 8) * 2 ** 14,
|
|
303
|
+
getBitS(b, 104, 8) * 2 ** 16,
|
|
304
|
+
getBitS(b, 112, 8) * 2 ** 16
|
|
305
|
+
];
|
|
306
|
+
leapSeconds = getBitS(b, 192, 8);
|
|
307
|
+
}
|
|
308
|
+
return { ionoCorrections, leapSeconds };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/navbits/cnav.ts
|
|
277
312
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
313
|
+
var SEC_PER_WEEK2 = 7 * 86400;
|
|
314
|
+
var HALF_WEEK = 302400;
|
|
315
|
+
var CNAV_PREAMBLE = 139;
|
|
316
|
+
var CNAV_A_REF = 26559710;
|
|
317
|
+
var CNAV_OMEGA_DOT_REF = -26e-10;
|
|
318
|
+
function crc24q(buff, bitLen) {
|
|
319
|
+
let crc = 0;
|
|
320
|
+
for (let i = 0; i < bitLen; i++) {
|
|
321
|
+
crc ^= (buff[i >> 3] >> 7 - (i & 7) & 1) << 23;
|
|
322
|
+
const msb = crc & 8388608;
|
|
323
|
+
crc = crc << 1 & 16777215;
|
|
324
|
+
if (msb) crc ^= 8801531;
|
|
325
|
+
}
|
|
326
|
+
return crc;
|
|
327
|
+
}
|
|
328
|
+
function cnavCrcOk(msg) {
|
|
329
|
+
if (msg.length < 38) return false;
|
|
330
|
+
return crc24q(msg, 276) === getBitU(msg, 276, 24);
|
|
331
|
+
}
|
|
332
|
+
function getBitU33(b, pos) {
|
|
333
|
+
return getBitU(b, pos, 1) * 2 ** 32 + getBitU(b, pos + 1, 32);
|
|
334
|
+
}
|
|
335
|
+
function getBitS33(b, pos) {
|
|
336
|
+
const u = getBitU33(b, pos);
|
|
337
|
+
return u < 2 ** 32 ? u : u - 2 ** 33;
|
|
338
|
+
}
|
|
339
|
+
function decodeType10(b, tow) {
|
|
340
|
+
return {
|
|
341
|
+
tow,
|
|
342
|
+
week: getBitU(b, 38, 13),
|
|
343
|
+
health: getBitU(b, 51, 3),
|
|
344
|
+
top: getBitU(b, 54, 11) * 300,
|
|
345
|
+
uraEd: getBitS(b, 65, 5),
|
|
346
|
+
toe: getBitU(b, 70, 11) * 300,
|
|
347
|
+
deltaA: getBitS(b, 81, 26) * 2 ** -9,
|
|
348
|
+
aDot: getBitS(b, 107, 25) * 2 ** -21,
|
|
349
|
+
deltaN0: getBitS(b, 132, 17) * 2 ** -44 * GPS_PI,
|
|
350
|
+
deltaN0Dot: getBitS(b, 149, 23) * 2 ** -57 * GPS_PI,
|
|
351
|
+
m0: getBitS33(b, 172) * 2 ** -32 * GPS_PI,
|
|
352
|
+
e: getBitU33(b, 205) * 2 ** -34,
|
|
353
|
+
omega: getBitS33(b, 238) * 2 ** -32 * GPS_PI,
|
|
354
|
+
integrityFlag: getBitU(b, 271, 1) === 1,
|
|
355
|
+
l2cPhasing: getBitU(b, 272, 1) === 1
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
function decodeType11(b) {
|
|
359
|
+
return {
|
|
360
|
+
toe: getBitU(b, 38, 11) * 300,
|
|
361
|
+
omega0: getBitS33(b, 49) * 2 ** -32 * GPS_PI,
|
|
362
|
+
i0: getBitS33(b, 82) * 2 ** -32 * GPS_PI,
|
|
363
|
+
deltaOmegaDot: getBitS(b, 115, 17) * 2 ** -44 * GPS_PI,
|
|
364
|
+
i0Dot: getBitS(b, 132, 15) * 2 ** -44 * GPS_PI,
|
|
365
|
+
cis: getBitS(b, 147, 16) * 2 ** -30,
|
|
366
|
+
cic: getBitS(b, 163, 16) * 2 ** -30,
|
|
367
|
+
crs: getBitS(b, 179, 24) * 2 ** -8,
|
|
368
|
+
crc: getBitS(b, 203, 24) * 2 ** -8,
|
|
369
|
+
cus: getBitS(b, 227, 21) * 2 ** -30,
|
|
370
|
+
cuc: getBitS(b, 248, 21) * 2 ** -30
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
var isc = (b, pos) => {
|
|
374
|
+
const raw = getBitS(b, pos, 13);
|
|
375
|
+
return raw === -4096 ? null : raw * 2 ** -35;
|
|
376
|
+
};
|
|
377
|
+
function decodeClock(b, msgType) {
|
|
378
|
+
const clock = {
|
|
379
|
+
msgType,
|
|
380
|
+
top: getBitU(b, 38, 11) * 300,
|
|
381
|
+
uraNed0: getBitS(b, 49, 5),
|
|
382
|
+
uraNed1: getBitU(b, 54, 3),
|
|
383
|
+
uraNed2: getBitU(b, 57, 3),
|
|
384
|
+
toc: getBitU(b, 60, 11) * 300,
|
|
385
|
+
af0: getBitS(b, 71, 26) * 2 ** -35,
|
|
386
|
+
af1: getBitS(b, 97, 20) * 2 ** -48,
|
|
387
|
+
af2: getBitS(b, 117, 10) * 2 ** -60
|
|
388
|
+
};
|
|
389
|
+
if (msgType === 30) {
|
|
390
|
+
clock.tgd = isc(b, 127);
|
|
391
|
+
clock.iscL1ca = isc(b, 140);
|
|
392
|
+
clock.iscL2c = isc(b, 153);
|
|
393
|
+
clock.iscL5i5 = isc(b, 166);
|
|
394
|
+
clock.iscL5q5 = isc(b, 179);
|
|
395
|
+
clock.ionoAlpha = [
|
|
396
|
+
getBitS(b, 192, 8) * 2 ** -30,
|
|
397
|
+
getBitS(b, 200, 8) * 2 ** -27,
|
|
398
|
+
getBitS(b, 208, 8) * 2 ** -24,
|
|
399
|
+
getBitS(b, 216, 8) * 2 ** -24
|
|
400
|
+
];
|
|
401
|
+
clock.ionoBeta = [
|
|
402
|
+
getBitS(b, 224, 8) * 2 ** 11,
|
|
403
|
+
getBitS(b, 232, 8) * 2 ** 14,
|
|
404
|
+
getBitS(b, 240, 8) * 2 ** 16,
|
|
405
|
+
getBitS(b, 248, 8) * 2 ** 16
|
|
406
|
+
];
|
|
407
|
+
clock.wnOp = getBitU(b, 256, 8);
|
|
408
|
+
}
|
|
409
|
+
return clock;
|
|
410
|
+
}
|
|
411
|
+
function resolveWeek(week, towSec, sec) {
|
|
412
|
+
if (sec < towSec - HALF_WEEK) return week + 1;
|
|
413
|
+
if (sec > towSec + HALF_WEEK) return week - 1;
|
|
414
|
+
return week;
|
|
415
|
+
}
|
|
416
|
+
function gpsDate(week, sec) {
|
|
417
|
+
return new Date(GPS_EPOCH_MS2 + (week * SEC_PER_WEEK2 + sec) * 1e3);
|
|
418
|
+
}
|
|
419
|
+
var CnavAssembler = class {
|
|
420
|
+
sats = /* @__PURE__ */ new Map();
|
|
421
|
+
/**
|
|
422
|
+
* Push one 300-bit CNAV message (38+ bytes, bit 0 = first bit of
|
|
423
|
+
* the preamble). Returns the newly completed ephemeris, or null.
|
|
424
|
+
* Messages that are not MT10/MT11/MT30-37, or whose preamble/PRN
|
|
425
|
+
* are out of range, are ignored.
|
|
426
|
+
*/
|
|
427
|
+
push(msg) {
|
|
428
|
+
if (msg.length < 38 || getBitU(msg, 0, 8) !== CNAV_PREAMBLE) return null;
|
|
429
|
+
const prn = getBitU(msg, 8, 6);
|
|
430
|
+
if (prn < 1 || prn > 32) return null;
|
|
431
|
+
const type = getBitU(msg, 14, 6);
|
|
432
|
+
const tow = getBitU(msg, 20, 17) * 6;
|
|
433
|
+
let sat = this.sats.get(prn);
|
|
434
|
+
if (!sat) {
|
|
435
|
+
sat = {};
|
|
436
|
+
this.sats.set(prn, sat);
|
|
437
|
+
}
|
|
438
|
+
if (type === 10) sat.t10 = decodeType10(msg, tow);
|
|
439
|
+
else if (type === 11) sat.t11 = decodeType11(msg);
|
|
440
|
+
else if (type >= 30 && type <= 37) {
|
|
441
|
+
sat.clock = decodeClock(msg, type);
|
|
442
|
+
if (type === 30) sat.extras = sat.clock;
|
|
443
|
+
} else return null;
|
|
444
|
+
return this.tryEmit(prn, sat);
|
|
445
|
+
}
|
|
446
|
+
tryEmit(prn, sat) {
|
|
447
|
+
const { t10, t11, clock, extras } = sat;
|
|
448
|
+
if (!t10 || !t11 || !clock) return null;
|
|
449
|
+
if (t10.toe !== t11.toe || clock.toc !== t10.toe) return null;
|
|
450
|
+
const key = `${t10.week}:${t10.toe}:${clock.af0}:${clock.af1}`;
|
|
451
|
+
if (key === sat.lastKey) return null;
|
|
452
|
+
sat.lastKey = key;
|
|
453
|
+
const weekToe = resolveWeek(t10.week, t10.tow, t10.toe);
|
|
454
|
+
const a = CNAV_A_REF + t10.deltaA;
|
|
455
|
+
return {
|
|
456
|
+
system: "G",
|
|
457
|
+
prn: `G${String(prn).padStart(2, "0")}`,
|
|
458
|
+
week: t10.week,
|
|
459
|
+
health: t10.health,
|
|
460
|
+
uraEd: t10.uraEd,
|
|
461
|
+
uraNed0: clock.uraNed0,
|
|
462
|
+
uraNed1: clock.uraNed1,
|
|
463
|
+
uraNed2: clock.uraNed2,
|
|
464
|
+
top: t10.top,
|
|
465
|
+
toe: t10.toe,
|
|
466
|
+
toeDate: gpsDate(weekToe, t10.toe),
|
|
467
|
+
a,
|
|
468
|
+
deltaA: t10.deltaA,
|
|
469
|
+
aDot: t10.aDot,
|
|
470
|
+
deltaN0: t10.deltaN0,
|
|
471
|
+
deltaN0Dot: t10.deltaN0Dot,
|
|
472
|
+
m0: t10.m0,
|
|
473
|
+
e: t10.e,
|
|
474
|
+
omega: t10.omega,
|
|
475
|
+
omega0: t11.omega0,
|
|
476
|
+
i0: t11.i0,
|
|
477
|
+
omegaDot: CNAV_OMEGA_DOT_REF * GPS_PI + t11.deltaOmegaDot,
|
|
478
|
+
deltaOmegaDot: t11.deltaOmegaDot,
|
|
479
|
+
i0Dot: t11.i0Dot,
|
|
480
|
+
cis: t11.cis,
|
|
481
|
+
cic: t11.cic,
|
|
482
|
+
crs: t11.crs,
|
|
483
|
+
crc: t11.crc,
|
|
484
|
+
cus: t11.cus,
|
|
485
|
+
cuc: t11.cuc,
|
|
486
|
+
toc: clock.toc,
|
|
487
|
+
tocDate: gpsDate(weekToe, clock.toc),
|
|
488
|
+
af0: clock.af0,
|
|
489
|
+
af1: clock.af1,
|
|
490
|
+
af2: clock.af2,
|
|
491
|
+
clockMsgType: clock.msgType,
|
|
492
|
+
tgd: extras?.tgd ?? null,
|
|
493
|
+
iscL1ca: extras?.iscL1ca ?? null,
|
|
494
|
+
iscL2c: extras?.iscL2c ?? null,
|
|
495
|
+
iscL5i5: extras?.iscL5i5 ?? null,
|
|
496
|
+
iscL5q5: extras?.iscL5q5 ?? null,
|
|
497
|
+
...extras?.ionoAlpha && { ionoAlpha: extras.ionoAlpha },
|
|
498
|
+
...extras?.ionoBeta && { ionoBeta: extras.ionoBeta },
|
|
499
|
+
...extras?.wnOp !== void 0 && { wnOp: extras.wnOp },
|
|
500
|
+
integrityFlag: t10.integrityFlag,
|
|
501
|
+
l2cPhasing: t10.l2cPhasing,
|
|
502
|
+
tow: t10.tow
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
// src/ubx/cnav.ts
|
|
508
|
+
function parseUbxCnav(data) {
|
|
509
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
510
|
+
const assembler = new CnavAssembler();
|
|
511
|
+
const ephemerides = [];
|
|
512
|
+
let badCrc = 0;
|
|
513
|
+
let messages = 0;
|
|
514
|
+
for (const f of ubxFrames(data)) {
|
|
515
|
+
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
516
|
+
const p = f.payload;
|
|
517
|
+
if (p.length < 8 + 40) continue;
|
|
518
|
+
if (p[0] !== 0 || p[2] !== 3 && p[2] !== 4) continue;
|
|
519
|
+
const svId = p[1];
|
|
520
|
+
if (svId < 1 || svId > 32) continue;
|
|
521
|
+
messages++;
|
|
522
|
+
const msg = new Uint8Array(40);
|
|
523
|
+
const base = f.payloadStart + 8;
|
|
524
|
+
for (let k = 0; k < 10; k++) {
|
|
525
|
+
const w = view.getUint32(base + 4 * k, true);
|
|
526
|
+
msg[4 * k] = w >>> 24;
|
|
527
|
+
msg[4 * k + 1] = w >>> 16 & 255;
|
|
528
|
+
msg[4 * k + 2] = w >>> 8 & 255;
|
|
529
|
+
msg[4 * k + 3] = w & 255;
|
|
530
|
+
}
|
|
531
|
+
if (!cnavCrcOk(msg)) {
|
|
532
|
+
badCrc++;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
const eph = assembler.push(msg);
|
|
536
|
+
if (eph) ephemerides.push(eph);
|
|
537
|
+
}
|
|
538
|
+
return { ephemerides, badCrc, messages };
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/ubx/index.ts
|
|
542
|
+
var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
|
|
278
543
|
var MS_PER_WEEK = 7 * 864e5;
|
|
279
544
|
var SIGNALS = {
|
|
280
545
|
0: { 0: ["G", "1C"], 3: ["G", "2X"], 4: ["G", "2X"] },
|
|
@@ -357,7 +622,7 @@ function parseUbxRawx(data) {
|
|
|
357
622
|
if (!codes.includes(sig[1])) codes.push(sig[1]);
|
|
358
623
|
}
|
|
359
624
|
epochs.push({
|
|
360
|
-
timeMs:
|
|
625
|
+
timeMs: GPS_EPOCH_MS3 + week * MS_PER_WEEK + Math.round(rcvTow * 1e3),
|
|
361
626
|
leapS: leapValid ? leapS : null,
|
|
362
627
|
meas
|
|
363
628
|
});
|
|
@@ -367,6 +632,8 @@ function parseUbxRawx(data) {
|
|
|
367
632
|
}
|
|
368
633
|
// Annotate the CommonJS export names for ESM import in node:
|
|
369
634
|
0 && (module.exports = {
|
|
635
|
+
parseUbxCnav,
|
|
636
|
+
parseUbxIonoUtc,
|
|
370
637
|
parseUbxNav,
|
|
371
638
|
parseUbxRawx,
|
|
372
639
|
ubxFrames
|
package/dist/ubx.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { E as Ephemeris } from './nav-BAI1a9vK.cjs';
|
|
2
|
+
import { C as CnavEphemeris } from './cnav-CRns0ECn.cjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* u-blox UBX framing shared by the measurement and navigation decoders:
|
|
@@ -46,7 +47,9 @@ declare function ubxFrames(data: Uint8Array, stats?: {
|
|
|
46
47
|
*
|
|
47
48
|
* Other constellations in RXM-SFRBX (Galileo I/NAV, BDS D1/D2, GLONASS
|
|
48
49
|
* strings, SBAS) and GPS/QZSS CNAV are out of scope and skipped
|
|
49
|
-
* silently
|
|
50
|
+
* silently. LNAV subframes 4/5 are skipped here except that
|
|
51
|
+
* `parseUbxIonoUtc` (./iono.ts) decodes the subframe-4 page-18
|
|
52
|
+
* iono/UTC parameters through the shared `readLnavSubframe` helper.
|
|
50
53
|
*/
|
|
51
54
|
|
|
52
55
|
interface UbxNavOptions {
|
|
@@ -77,6 +80,74 @@ interface UbxNavResult {
|
|
|
77
80
|
*/
|
|
78
81
|
declare function parseUbxNav(data: Uint8Array, opts?: UbxNavOptions): UbxNavResult;
|
|
79
82
|
|
|
83
|
+
/**
|
|
84
|
+
* u-blox UBX ionosphere / UTC decoding: the GPS LNAV subframe 4
|
|
85
|
+
* page 18 broadcast (Klobuchar coefficients + GPS-UTC parameters)
|
|
86
|
+
* from RXM-SFRBX.
|
|
87
|
+
*
|
|
88
|
+
* Ported from RTKLIB demo5 (rtklibexplorer fork, src/rcvraw.c:
|
|
89
|
+
* decode_frame_ion / decode_frame_utc, Copyright (c) 2007-2020
|
|
90
|
+
* T. Takasu, BSD-2-Clause); frame extraction is shared with
|
|
91
|
+
* `parseUbxNav` through `readLnavSubframe` (./nav.ts).
|
|
92
|
+
*
|
|
93
|
+
* Scope is GPS satellites (gnssId 0) only: QZSS also broadcasts
|
|
94
|
+
* page-18-format iono parameters, but those are the separate
|
|
95
|
+
* wide-area/Japan-area QZSS coefficient set, not the GPS one a RINEX
|
|
96
|
+
* `GPSA`/`GPSB` header carries. Scale factors follow IS-GPS-200
|
|
97
|
+
* §20.3.3.5.1 (alpha_n in s/semicircle^n, beta_n in s/semicircle^n) —
|
|
98
|
+
* the same semicircle-based units the RINEX nav header prints, so the
|
|
99
|
+
* output matches `parseNavFile` on a converted header. Like
|
|
100
|
+
* `parseUbxNav`, the decoder never consults the system clock (nothing
|
|
101
|
+
* here needs a week reference).
|
|
102
|
+
*/
|
|
103
|
+
interface UbxIonoUtcResult {
|
|
104
|
+
/**
|
|
105
|
+
* Iono coefficient sets keyed like `NavHeader.ionoCorrections`:
|
|
106
|
+
* `GPSA` (alpha_0..3) and `GPSB` (beta_0..3). The page repeats
|
|
107
|
+
* (nominally every 12.5 min per satellite); the last broadcast in
|
|
108
|
+
* the stream wins.
|
|
109
|
+
*/
|
|
110
|
+
ionoCorrections: Record<string, number[]>;
|
|
111
|
+
/** GPS-UTC ΔtLS from the last page-18 broadcast, if any. */
|
|
112
|
+
leapSeconds: number | null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Decode every GPS LNAV subframe 4 page 18 (data ID 1, SV ID 56) in a
|
|
116
|
+
* UBX byte stream (RXM-SFRBX) into Klobuchar iono coefficients and the
|
|
117
|
+
* current leap-second count.
|
|
118
|
+
*/
|
|
119
|
+
declare function parseUbxIonoUtc(data: Uint8Array): UbxIonoUtcResult;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* u-blox UBX raw CNAV decoding: GPS L2C CNAV messages from RXM-SFRBX
|
|
123
|
+
* (class 0x02, id 0x13), gnssId 0 with sigId 3 (L2 CL) or 4 (L2 CM).
|
|
124
|
+
*
|
|
125
|
+
* Word packing: the u-blox interface description delivers the 300-bit
|
|
126
|
+
* CNAV message as 10 32-bit `dwrd` words (little-endian in the
|
|
127
|
+
* stream) with the message bits left-justified MSB-first — message
|
|
128
|
+
* bit 0 is bit 31 of dwrd[0], and the low 20 bits of dwrd[9] are
|
|
129
|
+
* padding. Verified empirically on a ZED-F9P capture: this unpacking
|
|
130
|
+
* yields a valid CRC-24Q (and the 0x8B preamble in the top byte of
|
|
131
|
+
* dwrd[0], the same property `readLnavSubframe` in ./nav uses to skip
|
|
132
|
+
* CNAV frames) on effectively every message. RTKLIB demo5 does not
|
|
133
|
+
* decode CNAV from u-blox receivers; the field decoding lives in
|
|
134
|
+
* `src/navbits/cnav.ts`, working from IS-GPS-200 directly.
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
interface UbxCnavResult {
|
|
138
|
+
/** Assembled CNAV ephemerides in stream order, repeats suppressed. */
|
|
139
|
+
ephemerides: CnavEphemeris[];
|
|
140
|
+
/** Raw messages whose CRC-24Q check failed (dropped). */
|
|
141
|
+
badCrc: number;
|
|
142
|
+
/** Total GPS L2C RXM-SFRBX messages seen (checksum-valid frames). */
|
|
143
|
+
messages: number;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Decode every GPS L2C CNAV message in a UBX byte stream (RXM-SFRBX,
|
|
147
|
+
* gnssId 0, sigId 3/4) and assemble them into ephemerides.
|
|
148
|
+
*/
|
|
149
|
+
declare function parseUbxCnav(data: Uint8Array): UbxCnavResult;
|
|
150
|
+
|
|
80
151
|
/**
|
|
81
152
|
* u-blox UBX raw-measurement decoding (RXM-RAWX) — the path from a
|
|
82
153
|
* receiver log to RINEX-grade observables.
|
|
@@ -133,4 +204,4 @@ interface UbxParseResult {
|
|
|
133
204
|
*/
|
|
134
205
|
declare function parseUbxRawx(data: Uint8Array): UbxParseResult;
|
|
135
206
|
|
|
136
|
-
export { type UbxFrame, type UbxMeasurement, type UbxNavOptions, type UbxNavResult, type UbxParseResult, type UbxRawxEpoch, parseUbxNav, parseUbxRawx, ubxFrames };
|
|
207
|
+
export { type UbxCnavResult, type UbxFrame, type UbxIonoUtcResult, type UbxMeasurement, type UbxNavOptions, type UbxNavResult, type UbxParseResult, type UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawx, ubxFrames };
|
package/dist/ubx.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { E as Ephemeris } from './nav-BAI1a9vK.js';
|
|
2
|
+
import { C as CnavEphemeris } from './cnav-CRns0ECn.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* u-blox UBX framing shared by the measurement and navigation decoders:
|
|
@@ -46,7 +47,9 @@ declare function ubxFrames(data: Uint8Array, stats?: {
|
|
|
46
47
|
*
|
|
47
48
|
* Other constellations in RXM-SFRBX (Galileo I/NAV, BDS D1/D2, GLONASS
|
|
48
49
|
* strings, SBAS) and GPS/QZSS CNAV are out of scope and skipped
|
|
49
|
-
* silently
|
|
50
|
+
* silently. LNAV subframes 4/5 are skipped here except that
|
|
51
|
+
* `parseUbxIonoUtc` (./iono.ts) decodes the subframe-4 page-18
|
|
52
|
+
* iono/UTC parameters through the shared `readLnavSubframe` helper.
|
|
50
53
|
*/
|
|
51
54
|
|
|
52
55
|
interface UbxNavOptions {
|
|
@@ -77,6 +80,74 @@ interface UbxNavResult {
|
|
|
77
80
|
*/
|
|
78
81
|
declare function parseUbxNav(data: Uint8Array, opts?: UbxNavOptions): UbxNavResult;
|
|
79
82
|
|
|
83
|
+
/**
|
|
84
|
+
* u-blox UBX ionosphere / UTC decoding: the GPS LNAV subframe 4
|
|
85
|
+
* page 18 broadcast (Klobuchar coefficients + GPS-UTC parameters)
|
|
86
|
+
* from RXM-SFRBX.
|
|
87
|
+
*
|
|
88
|
+
* Ported from RTKLIB demo5 (rtklibexplorer fork, src/rcvraw.c:
|
|
89
|
+
* decode_frame_ion / decode_frame_utc, Copyright (c) 2007-2020
|
|
90
|
+
* T. Takasu, BSD-2-Clause); frame extraction is shared with
|
|
91
|
+
* `parseUbxNav` through `readLnavSubframe` (./nav.ts).
|
|
92
|
+
*
|
|
93
|
+
* Scope is GPS satellites (gnssId 0) only: QZSS also broadcasts
|
|
94
|
+
* page-18-format iono parameters, but those are the separate
|
|
95
|
+
* wide-area/Japan-area QZSS coefficient set, not the GPS one a RINEX
|
|
96
|
+
* `GPSA`/`GPSB` header carries. Scale factors follow IS-GPS-200
|
|
97
|
+
* §20.3.3.5.1 (alpha_n in s/semicircle^n, beta_n in s/semicircle^n) —
|
|
98
|
+
* the same semicircle-based units the RINEX nav header prints, so the
|
|
99
|
+
* output matches `parseNavFile` on a converted header. Like
|
|
100
|
+
* `parseUbxNav`, the decoder never consults the system clock (nothing
|
|
101
|
+
* here needs a week reference).
|
|
102
|
+
*/
|
|
103
|
+
interface UbxIonoUtcResult {
|
|
104
|
+
/**
|
|
105
|
+
* Iono coefficient sets keyed like `NavHeader.ionoCorrections`:
|
|
106
|
+
* `GPSA` (alpha_0..3) and `GPSB` (beta_0..3). The page repeats
|
|
107
|
+
* (nominally every 12.5 min per satellite); the last broadcast in
|
|
108
|
+
* the stream wins.
|
|
109
|
+
*/
|
|
110
|
+
ionoCorrections: Record<string, number[]>;
|
|
111
|
+
/** GPS-UTC ΔtLS from the last page-18 broadcast, if any. */
|
|
112
|
+
leapSeconds: number | null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Decode every GPS LNAV subframe 4 page 18 (data ID 1, SV ID 56) in a
|
|
116
|
+
* UBX byte stream (RXM-SFRBX) into Klobuchar iono coefficients and the
|
|
117
|
+
* current leap-second count.
|
|
118
|
+
*/
|
|
119
|
+
declare function parseUbxIonoUtc(data: Uint8Array): UbxIonoUtcResult;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* u-blox UBX raw CNAV decoding: GPS L2C CNAV messages from RXM-SFRBX
|
|
123
|
+
* (class 0x02, id 0x13), gnssId 0 with sigId 3 (L2 CL) or 4 (L2 CM).
|
|
124
|
+
*
|
|
125
|
+
* Word packing: the u-blox interface description delivers the 300-bit
|
|
126
|
+
* CNAV message as 10 32-bit `dwrd` words (little-endian in the
|
|
127
|
+
* stream) with the message bits left-justified MSB-first — message
|
|
128
|
+
* bit 0 is bit 31 of dwrd[0], and the low 20 bits of dwrd[9] are
|
|
129
|
+
* padding. Verified empirically on a ZED-F9P capture: this unpacking
|
|
130
|
+
* yields a valid CRC-24Q (and the 0x8B preamble in the top byte of
|
|
131
|
+
* dwrd[0], the same property `readLnavSubframe` in ./nav uses to skip
|
|
132
|
+
* CNAV frames) on effectively every message. RTKLIB demo5 does not
|
|
133
|
+
* decode CNAV from u-blox receivers; the field decoding lives in
|
|
134
|
+
* `src/navbits/cnav.ts`, working from IS-GPS-200 directly.
|
|
135
|
+
*/
|
|
136
|
+
|
|
137
|
+
interface UbxCnavResult {
|
|
138
|
+
/** Assembled CNAV ephemerides in stream order, repeats suppressed. */
|
|
139
|
+
ephemerides: CnavEphemeris[];
|
|
140
|
+
/** Raw messages whose CRC-24Q check failed (dropped). */
|
|
141
|
+
badCrc: number;
|
|
142
|
+
/** Total GPS L2C RXM-SFRBX messages seen (checksum-valid frames). */
|
|
143
|
+
messages: number;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Decode every GPS L2C CNAV message in a UBX byte stream (RXM-SFRBX,
|
|
147
|
+
* gnssId 0, sigId 3/4) and assemble them into ephemerides.
|
|
148
|
+
*/
|
|
149
|
+
declare function parseUbxCnav(data: Uint8Array): UbxCnavResult;
|
|
150
|
+
|
|
80
151
|
/**
|
|
81
152
|
* u-blox UBX raw-measurement decoding (RXM-RAWX) — the path from a
|
|
82
153
|
* receiver log to RINEX-grade observables.
|
|
@@ -133,4 +204,4 @@ interface UbxParseResult {
|
|
|
133
204
|
*/
|
|
134
205
|
declare function parseUbxRawx(data: Uint8Array): UbxParseResult;
|
|
135
206
|
|
|
136
|
-
export { type UbxFrame, type UbxMeasurement, type UbxNavOptions, type UbxNavResult, type UbxParseResult, type UbxRawxEpoch, parseUbxNav, parseUbxRawx, ubxFrames };
|
|
207
|
+
export { type UbxCnavResult, type UbxFrame, type UbxIonoUtcResult, type UbxMeasurement, type UbxNavOptions, type UbxNavResult, type UbxParseResult, type UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawx, ubxFrames };
|
package/dist/ubx.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
+
parseUbxCnav,
|
|
3
|
+
parseUbxIonoUtc,
|
|
2
4
|
parseUbxNav,
|
|
3
5
|
parseUbxRawx,
|
|
4
6
|
ubxFrames
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-FEGLXNWA.js";
|
|
8
|
+
import "./chunk-Y5IWUPJQ.js";
|
|
9
|
+
import "./chunk-IQ5OIMQD.js";
|
|
7
10
|
export {
|
|
11
|
+
parseUbxCnav,
|
|
12
|
+
parseUbxIonoUtc,
|
|
8
13
|
parseUbxNav,
|
|
9
14
|
parseUbxRawx,
|
|
10
15
|
ubxFrames
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.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,
|