gnss-js 1.19.0 → 1.21.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-2IM5VXNI.js → chunk-7RKLWE6R.js} +23 -2
- package/dist/{chunk-QXZZNXE3.js → chunk-B5LU4746.js} +1 -1
- package/dist/{chunk-JW2ICDR7.js → chunk-DLXTTHRK.js} +2 -4
- package/dist/{chunk-OMVL3X7V.js → chunk-JNFV5BYB.js} +186 -8
- package/dist/chunk-K3V3NHWL.js +2541 -0
- package/dist/{chunk-K73SERD5.js → chunk-NOQAAUGY.js} +2 -4
- package/dist/{chunk-6NCMACDO.js → chunk-WZDFZ76K.js} +149 -8
- package/dist/index.cjs +1675 -57
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +23 -8
- package/dist/nav-BYmYoh9A.d.cts +137 -0
- package/dist/nav-CN8rxL4h.d.ts +137 -0
- package/dist/novatel.cjs +230 -15
- package/dist/novatel.d.cts +8 -1
- package/dist/novatel.d.ts +8 -1
- package/dist/novatel.js +2 -2
- package/dist/orbit.cjs +190 -8
- package/dist/orbit.d.cts +90 -1
- package/dist/orbit.d.ts +90 -1
- package/dist/orbit.js +9 -1
- package/dist/positioning.d.cts +1 -0
- package/dist/positioning.d.ts +1 -0
- package/dist/positioning.js +2 -2
- package/dist/rinex.js +2 -3
- package/dist/sbf.cjs +1433 -11
- package/dist/sbf.d.cts +286 -136
- package/dist/sbf.d.ts +286 -136
- package/dist/sbf.js +10 -3
- package/dist/ubx.js +2 -3
- package/package.json +1 -1
- package/dist/chunk-5S5HMAKW.js +0 -1123
- package/dist/chunk-IQ5OIMQD.js +0 -148
package/dist/novatel.cjs
CHANGED
|
@@ -202,6 +202,202 @@ function decodeGpsLnavFrame(subframes, opts = {}) {
|
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
// src/navbits/cnav.ts
|
|
206
|
+
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
207
|
+
var SEC_PER_WEEK2 = 7 * 86400;
|
|
208
|
+
var HALF_WEEK = 302400;
|
|
209
|
+
var CNAV_PREAMBLE = 139;
|
|
210
|
+
var CNAV_A_REF = 26559710;
|
|
211
|
+
var CNAV_OMEGA_DOT_REF = -26e-10;
|
|
212
|
+
function crc24q(buff, bitLen) {
|
|
213
|
+
let crc = 0;
|
|
214
|
+
for (let i = 0; i < bitLen; i++) {
|
|
215
|
+
crc ^= (buff[i >> 3] >> 7 - (i & 7) & 1) << 23;
|
|
216
|
+
const msb = crc & 8388608;
|
|
217
|
+
crc = crc << 1 & 16777215;
|
|
218
|
+
if (msb) crc ^= 8801531;
|
|
219
|
+
}
|
|
220
|
+
return crc;
|
|
221
|
+
}
|
|
222
|
+
function cnavCrcOk(msg) {
|
|
223
|
+
if (msg.length < 38) return false;
|
|
224
|
+
return crc24q(msg, 276) === getBitU(msg, 276, 24);
|
|
225
|
+
}
|
|
226
|
+
function getBitU33(b, pos) {
|
|
227
|
+
return getBitU(b, pos, 1) * 2 ** 32 + getBitU(b, pos + 1, 32);
|
|
228
|
+
}
|
|
229
|
+
function getBitS33(b, pos) {
|
|
230
|
+
const u = getBitU33(b, pos);
|
|
231
|
+
return u < 2 ** 32 ? u : u - 2 ** 33;
|
|
232
|
+
}
|
|
233
|
+
function decodeType10(b, tow) {
|
|
234
|
+
return {
|
|
235
|
+
tow,
|
|
236
|
+
week: getBitU(b, 38, 13),
|
|
237
|
+
health: getBitU(b, 51, 3),
|
|
238
|
+
top: getBitU(b, 54, 11) * 300,
|
|
239
|
+
uraEd: getBitS(b, 65, 5),
|
|
240
|
+
toe: getBitU(b, 70, 11) * 300,
|
|
241
|
+
deltaA: getBitS(b, 81, 26) * 2 ** -9,
|
|
242
|
+
aDot: getBitS(b, 107, 25) * 2 ** -21,
|
|
243
|
+
deltaN0: getBitS(b, 132, 17) * 2 ** -44 * GPS_PI,
|
|
244
|
+
deltaN0Dot: getBitS(b, 149, 23) * 2 ** -57 * GPS_PI,
|
|
245
|
+
m0: getBitS33(b, 172) * 2 ** -32 * GPS_PI,
|
|
246
|
+
e: getBitU33(b, 205) * 2 ** -34,
|
|
247
|
+
omega: getBitS33(b, 238) * 2 ** -32 * GPS_PI,
|
|
248
|
+
integrityFlag: getBitU(b, 271, 1) === 1,
|
|
249
|
+
l2cPhasing: getBitU(b, 272, 1) === 1
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function decodeType11(b) {
|
|
253
|
+
return {
|
|
254
|
+
toe: getBitU(b, 38, 11) * 300,
|
|
255
|
+
omega0: getBitS33(b, 49) * 2 ** -32 * GPS_PI,
|
|
256
|
+
i0: getBitS33(b, 82) * 2 ** -32 * GPS_PI,
|
|
257
|
+
deltaOmegaDot: getBitS(b, 115, 17) * 2 ** -44 * GPS_PI,
|
|
258
|
+
i0Dot: getBitS(b, 132, 15) * 2 ** -44 * GPS_PI,
|
|
259
|
+
cis: getBitS(b, 147, 16) * 2 ** -30,
|
|
260
|
+
cic: getBitS(b, 163, 16) * 2 ** -30,
|
|
261
|
+
crs: getBitS(b, 179, 24) * 2 ** -8,
|
|
262
|
+
crc: getBitS(b, 203, 24) * 2 ** -8,
|
|
263
|
+
cus: getBitS(b, 227, 21) * 2 ** -30,
|
|
264
|
+
cuc: getBitS(b, 248, 21) * 2 ** -30
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
var isc = (b, pos) => {
|
|
268
|
+
const raw = getBitS(b, pos, 13);
|
|
269
|
+
return raw === -4096 ? null : raw * 2 ** -35;
|
|
270
|
+
};
|
|
271
|
+
function decodeClock(b, msgType) {
|
|
272
|
+
const clock = {
|
|
273
|
+
msgType,
|
|
274
|
+
top: getBitU(b, 38, 11) * 300,
|
|
275
|
+
uraNed0: getBitS(b, 49, 5),
|
|
276
|
+
uraNed1: getBitU(b, 54, 3),
|
|
277
|
+
uraNed2: getBitU(b, 57, 3),
|
|
278
|
+
toc: getBitU(b, 60, 11) * 300,
|
|
279
|
+
af0: getBitS(b, 71, 26) * 2 ** -35,
|
|
280
|
+
af1: getBitS(b, 97, 20) * 2 ** -48,
|
|
281
|
+
af2: getBitS(b, 117, 10) * 2 ** -60
|
|
282
|
+
};
|
|
283
|
+
if (msgType === 30) {
|
|
284
|
+
clock.tgd = isc(b, 127);
|
|
285
|
+
clock.iscL1ca = isc(b, 140);
|
|
286
|
+
clock.iscL2c = isc(b, 153);
|
|
287
|
+
clock.iscL5i5 = isc(b, 166);
|
|
288
|
+
clock.iscL5q5 = isc(b, 179);
|
|
289
|
+
clock.ionoAlpha = [
|
|
290
|
+
getBitS(b, 192, 8) * 2 ** -30,
|
|
291
|
+
getBitS(b, 200, 8) * 2 ** -27,
|
|
292
|
+
getBitS(b, 208, 8) * 2 ** -24,
|
|
293
|
+
getBitS(b, 216, 8) * 2 ** -24
|
|
294
|
+
];
|
|
295
|
+
clock.ionoBeta = [
|
|
296
|
+
getBitS(b, 224, 8) * 2 ** 11,
|
|
297
|
+
getBitS(b, 232, 8) * 2 ** 14,
|
|
298
|
+
getBitS(b, 240, 8) * 2 ** 16,
|
|
299
|
+
getBitS(b, 248, 8) * 2 ** 16
|
|
300
|
+
];
|
|
301
|
+
clock.wnOp = getBitU(b, 256, 8);
|
|
302
|
+
}
|
|
303
|
+
return clock;
|
|
304
|
+
}
|
|
305
|
+
function resolveWeek(week, towSec, sec) {
|
|
306
|
+
if (sec < towSec - HALF_WEEK) return week + 1;
|
|
307
|
+
if (sec > towSec + HALF_WEEK) return week - 1;
|
|
308
|
+
return week;
|
|
309
|
+
}
|
|
310
|
+
function gpsDate(week, sec) {
|
|
311
|
+
return new Date(GPS_EPOCH_MS2 + (week * SEC_PER_WEEK2 + sec) * 1e3);
|
|
312
|
+
}
|
|
313
|
+
var CnavAssembler = class {
|
|
314
|
+
sats = /* @__PURE__ */ new Map();
|
|
315
|
+
/**
|
|
316
|
+
* Push one 300-bit CNAV message (38+ bytes, bit 0 = first bit of
|
|
317
|
+
* the preamble). Returns the newly completed ephemeris, or null.
|
|
318
|
+
* Messages that are not MT10/MT11/MT30-37, or whose preamble/PRN
|
|
319
|
+
* are out of range, are ignored.
|
|
320
|
+
*/
|
|
321
|
+
push(msg) {
|
|
322
|
+
if (msg.length < 38 || getBitU(msg, 0, 8) !== CNAV_PREAMBLE) return null;
|
|
323
|
+
const prn = getBitU(msg, 8, 6);
|
|
324
|
+
if (prn < 1 || prn > 32) return null;
|
|
325
|
+
const type = getBitU(msg, 14, 6);
|
|
326
|
+
const tow = getBitU(msg, 20, 17) * 6;
|
|
327
|
+
let sat = this.sats.get(prn);
|
|
328
|
+
if (!sat) {
|
|
329
|
+
sat = {};
|
|
330
|
+
this.sats.set(prn, sat);
|
|
331
|
+
}
|
|
332
|
+
if (type === 10) sat.t10 = decodeType10(msg, tow);
|
|
333
|
+
else if (type === 11) sat.t11 = decodeType11(msg);
|
|
334
|
+
else if (type >= 30 && type <= 37) {
|
|
335
|
+
sat.clock = decodeClock(msg, type);
|
|
336
|
+
if (type === 30) sat.extras = sat.clock;
|
|
337
|
+
} else return null;
|
|
338
|
+
return this.tryEmit(prn, sat);
|
|
339
|
+
}
|
|
340
|
+
tryEmit(prn, sat) {
|
|
341
|
+
const { t10, t11, clock, extras } = sat;
|
|
342
|
+
if (!t10 || !t11 || !clock) return null;
|
|
343
|
+
if (t10.toe !== t11.toe || clock.toc !== t10.toe) return null;
|
|
344
|
+
const key = `${t10.week}:${t10.toe}:${clock.af0}:${clock.af1}`;
|
|
345
|
+
if (key === sat.lastKey) return null;
|
|
346
|
+
sat.lastKey = key;
|
|
347
|
+
const weekToe = resolveWeek(t10.week, t10.tow, t10.toe);
|
|
348
|
+
const a = CNAV_A_REF + t10.deltaA;
|
|
349
|
+
return {
|
|
350
|
+
system: "G",
|
|
351
|
+
prn: `G${String(prn).padStart(2, "0")}`,
|
|
352
|
+
week: t10.week,
|
|
353
|
+
health: t10.health,
|
|
354
|
+
uraEd: t10.uraEd,
|
|
355
|
+
uraNed0: clock.uraNed0,
|
|
356
|
+
uraNed1: clock.uraNed1,
|
|
357
|
+
uraNed2: clock.uraNed2,
|
|
358
|
+
top: t10.top,
|
|
359
|
+
toe: t10.toe,
|
|
360
|
+
toeDate: gpsDate(weekToe, t10.toe),
|
|
361
|
+
a,
|
|
362
|
+
deltaA: t10.deltaA,
|
|
363
|
+
aDot: t10.aDot,
|
|
364
|
+
deltaN0: t10.deltaN0,
|
|
365
|
+
deltaN0Dot: t10.deltaN0Dot,
|
|
366
|
+
m0: t10.m0,
|
|
367
|
+
e: t10.e,
|
|
368
|
+
omega: t10.omega,
|
|
369
|
+
omega0: t11.omega0,
|
|
370
|
+
i0: t11.i0,
|
|
371
|
+
omegaDot: CNAV_OMEGA_DOT_REF * GPS_PI + t11.deltaOmegaDot,
|
|
372
|
+
deltaOmegaDot: t11.deltaOmegaDot,
|
|
373
|
+
i0Dot: t11.i0Dot,
|
|
374
|
+
cis: t11.cis,
|
|
375
|
+
cic: t11.cic,
|
|
376
|
+
crs: t11.crs,
|
|
377
|
+
crc: t11.crc,
|
|
378
|
+
cus: t11.cus,
|
|
379
|
+
cuc: t11.cuc,
|
|
380
|
+
toc: clock.toc,
|
|
381
|
+
tocDate: gpsDate(weekToe, clock.toc),
|
|
382
|
+
af0: clock.af0,
|
|
383
|
+
af1: clock.af1,
|
|
384
|
+
af2: clock.af2,
|
|
385
|
+
clockMsgType: clock.msgType,
|
|
386
|
+
tgd: extras?.tgd ?? null,
|
|
387
|
+
iscL1ca: extras?.iscL1ca ?? null,
|
|
388
|
+
iscL2c: extras?.iscL2c ?? null,
|
|
389
|
+
iscL5i5: extras?.iscL5i5 ?? null,
|
|
390
|
+
iscL5q5: extras?.iscL5q5 ?? null,
|
|
391
|
+
...extras?.ionoAlpha && { ionoAlpha: extras.ionoAlpha },
|
|
392
|
+
...extras?.ionoBeta && { ionoBeta: extras.ionoBeta },
|
|
393
|
+
...extras?.wnOp !== void 0 && { wnOp: extras.wnOp },
|
|
394
|
+
integrityFlag: t10.integrityFlag,
|
|
395
|
+
l2cPhasing: t10.l2cPhasing,
|
|
396
|
+
tow: t10.tow
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
205
401
|
// src/constants/time.ts
|
|
206
402
|
var MILLISECONDS_IN_SECOND = 1e3;
|
|
207
403
|
var MILLISECONDS_GPS_TAI = 19e3;
|
|
@@ -291,21 +487,22 @@ function getUtcDate(date) {
|
|
|
291
487
|
|
|
292
488
|
// src/novatel/nav.ts
|
|
293
489
|
var ID_IONUTC = 8;
|
|
490
|
+
var ID_RAWCNAVFRAME = 1066;
|
|
294
491
|
var ID_RAWEPHEM = 41;
|
|
295
492
|
var ID_GLOEPHEMERIS = 723;
|
|
296
493
|
var ID_GALEPHEMERIS = 1122;
|
|
297
494
|
var ID_QZSSEPHEMERIS = 1336;
|
|
298
495
|
var ID_GPSEPHEM = 7;
|
|
299
496
|
var ID_BDSEPHEMERIS = 1696;
|
|
300
|
-
var
|
|
497
|
+
var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
|
|
301
498
|
var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
|
|
302
|
-
var
|
|
499
|
+
var SEC_PER_WEEK3 = 7 * 86400;
|
|
303
500
|
var SEC_PER_DAY = 86400;
|
|
304
|
-
var MS_PER_WEEK =
|
|
305
|
-
var gpsMs = (week, sec) =>
|
|
306
|
-
var sowOf = (dateMs) => dateMs / 1e3 %
|
|
501
|
+
var MS_PER_WEEK = SEC_PER_WEEK3 * 1e3;
|
|
502
|
+
var gpsMs = (week, sec) => GPS_EPOCH_MS3 + week * MS_PER_WEEK + sec * 1e3;
|
|
503
|
+
var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK3;
|
|
307
504
|
function nearWeekMs(refMs, sow) {
|
|
308
|
-
const refWeek = Math.floor((refMs -
|
|
505
|
+
const refWeek = Math.floor((refMs - GPS_EPOCH_MS3) / MS_PER_WEEK);
|
|
309
506
|
let ms = gpsMs(refWeek, sow);
|
|
310
507
|
if (ms < refMs - MS_PER_WEEK / 2) ms += MS_PER_WEEK;
|
|
311
508
|
else if (ms > refMs + MS_PER_WEEK / 2) ms -= MS_PER_WEEK;
|
|
@@ -332,9 +529,9 @@ function decodeGloEphemeris(view, p) {
|
|
|
332
529
|
tof += Math.floor(tow / SEC_PER_DAY) * SEC_PER_DAY;
|
|
333
530
|
if (tof < tow - 43200) tof += SEC_PER_DAY;
|
|
334
531
|
else if (tof > tow + 43200) tof -= SEC_PER_DAY;
|
|
335
|
-
const toeGpsMs =
|
|
336
|
-
const tofGpsMs =
|
|
337
|
-
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() -
|
|
532
|
+
const toeGpsMs = GPS_EPOCH_MS3 + (week * SEC_PER_WEEK3 + tow) * 1e3;
|
|
533
|
+
const tofGpsMs = GPS_EPOCH_MS3 + (week * SEC_PER_WEEK3 + tof) * 1e3;
|
|
534
|
+
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS3) / 1e3;
|
|
338
535
|
return {
|
|
339
536
|
system: "R",
|
|
340
537
|
prn: `R${String(slot).padStart(2, "0")}`,
|
|
@@ -342,7 +539,7 @@ function decodeGloEphemeris(view, p) {
|
|
|
342
539
|
tauN: -view.getFloat64(p + 100, true),
|
|
343
540
|
// RINEX stores −τ_n
|
|
344
541
|
gammaN: view.getFloat64(p + 116, true),
|
|
345
|
-
messageFrameTime: (tofUtcSec %
|
|
542
|
+
messageFrameTime: (tofUtcSec % SEC_PER_WEEK3 + SEC_PER_WEEK3) % SEC_PER_WEEK3,
|
|
346
543
|
x: view.getFloat64(p + 28, true) / 1e3,
|
|
347
544
|
y: view.getFloat64(p + 36, true) / 1e3,
|
|
348
545
|
z: view.getFloat64(p + 44, true) / 1e3,
|
|
@@ -399,7 +596,7 @@ function decodeGalEphemeris(view, p, headerMs) {
|
|
|
399
596
|
omega: view.getFloat64(p + 60, true),
|
|
400
597
|
omegaDot: view.getFloat64(p + 140, true),
|
|
401
598
|
idot: view.getFloat64(p + 124, true),
|
|
402
|
-
week: Math.floor((toeMs -
|
|
599
|
+
week: Math.floor((toeMs - GPS_EPOCH_MS3) / MS_PER_WEEK),
|
|
403
600
|
// RINEX Galileo SVH bit layout (E1B DVS/HS in bits 0-2, E5a in
|
|
404
601
|
// 3-5, E5b in 6-8) — same packing as RTKLIB.
|
|
405
602
|
svHealth: svhE5b << 7 | dvsE5b << 6 | svhE5a << 4 | dvsE5a << 3 | svhE1b << 1 | dvsE1b,
|
|
@@ -497,6 +694,9 @@ function parseNovatelNav(data) {
|
|
|
497
694
|
const ephemerides = [];
|
|
498
695
|
const ionoCorrections = {};
|
|
499
696
|
let leapSeconds = null;
|
|
697
|
+
const cnav = [];
|
|
698
|
+
const cnavAssembler = new CnavAssembler();
|
|
699
|
+
let cnavBadCrc = 0;
|
|
500
700
|
const lastKep = /* @__PURE__ */ new Map();
|
|
501
701
|
const lastGlo = /* @__PURE__ */ new Map();
|
|
502
702
|
const pushKepler = (key, eph) => {
|
|
@@ -527,6 +727,14 @@ function parseNovatelNav(data) {
|
|
|
527
727
|
} else if (frame.id === ID_QZSSEPHEMERIS && frame.msgLen >= 204) {
|
|
528
728
|
const eph = decodeGpsQzssEphemeris(view, frame.payload, "J");
|
|
529
729
|
if (eph) pushKepler(eph.prn, eph);
|
|
730
|
+
} else if (frame.id === ID_RAWCNAVFRAME && frame.msgLen >= 50) {
|
|
731
|
+
const msg = data.subarray(frame.payload + 12, frame.payload + 50);
|
|
732
|
+
if (!cnavCrcOk(msg)) {
|
|
733
|
+
cnavBadCrc++;
|
|
734
|
+
} else {
|
|
735
|
+
const eph = cnavAssembler.push(msg);
|
|
736
|
+
if (eph) cnav.push(eph);
|
|
737
|
+
}
|
|
530
738
|
} else if (frame.id === ID_IONUTC && frame.msgLen >= 108) {
|
|
531
739
|
const p = frame.payload;
|
|
532
740
|
const alpha = [];
|
|
@@ -549,11 +757,18 @@ function parseNovatelNav(data) {
|
|
|
549
757
|
ephemerides.push(eph);
|
|
550
758
|
}
|
|
551
759
|
}
|
|
552
|
-
return {
|
|
760
|
+
return {
|
|
761
|
+
ephemerides,
|
|
762
|
+
ionoCorrections,
|
|
763
|
+
leapSeconds,
|
|
764
|
+
cnav,
|
|
765
|
+
cnavBadCrc,
|
|
766
|
+
badCrc: stats.badCrc
|
|
767
|
+
};
|
|
553
768
|
}
|
|
554
769
|
|
|
555
770
|
// src/novatel/index.ts
|
|
556
|
-
var
|
|
771
|
+
var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
|
|
557
772
|
var MS_PER_WEEK2 = 7 * 864e5;
|
|
558
773
|
var HDR = 28;
|
|
559
774
|
var ID_RANGE = 43;
|
|
@@ -723,7 +938,7 @@ function parseNovatelRange(data) {
|
|
|
723
938
|
if (!codes.includes(code)) codes.push(code);
|
|
724
939
|
}
|
|
725
940
|
epochs.push({
|
|
726
|
-
timeMs:
|
|
941
|
+
timeMs: GPS_EPOCH_MS4 + week * MS_PER_WEEK2 + towMs,
|
|
727
942
|
meas
|
|
728
943
|
});
|
|
729
944
|
}
|
|
@@ -775,7 +990,7 @@ function parseNovatelRange(data) {
|
|
|
775
990
|
if (!codes.includes(code)) codes.push(code);
|
|
776
991
|
}
|
|
777
992
|
epochs.push({
|
|
778
|
-
timeMs:
|
|
993
|
+
timeMs: GPS_EPOCH_MS4 + week * MS_PER_WEEK2 + towMs,
|
|
779
994
|
meas
|
|
780
995
|
});
|
|
781
996
|
}
|
package/dist/novatel.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as Ephemeris } from './nav-DImXUdbp.cjs';
|
|
1
|
+
import { E as Ephemeris, C as CnavEphemeris } from './nav-DImXUdbp.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* NovAtel OEM4/6/7 binary framing shared by the measurement and
|
|
@@ -75,6 +75,13 @@ interface NovatelNavResult {
|
|
|
75
75
|
ionoCorrections: Record<string, number[]>;
|
|
76
76
|
/** GPS−UTC leap seconds (Δt_LS) from IONUTC, null when unseen. */
|
|
77
77
|
leapSeconds: number | null;
|
|
78
|
+
/**
|
|
79
|
+
* GPS CNAV ephemerides assembled from RAWCNAVFRAME (1066) raw
|
|
80
|
+
* L2C/L5 messages, repeats suppressed by the shared assembler.
|
|
81
|
+
*/
|
|
82
|
+
cnav: CnavEphemeris[];
|
|
83
|
+
/** RAWCNAVFRAME messages whose CRC-24Q check failed (dropped). */
|
|
84
|
+
cnavBadCrc: number;
|
|
78
85
|
/** Frames whose CRC failed (corruption indicator). */
|
|
79
86
|
badCrc: number;
|
|
80
87
|
}
|
package/dist/novatel.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as Ephemeris } from './nav-DImXUdbp.js';
|
|
1
|
+
import { E as Ephemeris, C as CnavEphemeris } from './nav-DImXUdbp.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* NovAtel OEM4/6/7 binary framing shared by the measurement and
|
|
@@ -75,6 +75,13 @@ interface NovatelNavResult {
|
|
|
75
75
|
ionoCorrections: Record<string, number[]>;
|
|
76
76
|
/** GPS−UTC leap seconds (Δt_LS) from IONUTC, null when unseen. */
|
|
77
77
|
leapSeconds: number | null;
|
|
78
|
+
/**
|
|
79
|
+
* GPS CNAV ephemerides assembled from RAWCNAVFRAME (1066) raw
|
|
80
|
+
* L2C/L5 messages, repeats suppressed by the shared assembler.
|
|
81
|
+
*/
|
|
82
|
+
cnav: CnavEphemeris[];
|
|
83
|
+
/** RAWCNAVFRAME messages whose CRC-24Q check failed (dropped). */
|
|
84
|
+
cnavBadCrc: number;
|
|
78
85
|
/** Frames whose CRC failed (corruption indicator). */
|
|
79
86
|
badCrc: number;
|
|
80
87
|
}
|
package/dist/novatel.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
oem4Frames,
|
|
5
5
|
parseNovatelNav,
|
|
6
6
|
parseNovatelRange
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-7RKLWE6R.js";
|
|
8
|
+
import "./chunk-WZDFZ76K.js";
|
|
9
9
|
import "./chunk-HVXYFUCB.js";
|
|
10
10
|
import "./chunk-LEEU5OIO.js";
|
|
11
11
|
export {
|
package/dist/orbit.cjs
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/orbit/index.ts
|
|
21
21
|
var orbit_exports = {};
|
|
22
22
|
__export(orbit_exports, {
|
|
23
|
+
almanacEpochMs: () => almanacEpochMs,
|
|
24
|
+
almanacSatPosition: () => almanacSatPosition,
|
|
23
25
|
computeAllPositions: () => computeAllPositions,
|
|
24
26
|
computeDop: () => computeDop,
|
|
25
27
|
computeLiveSkyPositions: () => computeLiveSkyPositions,
|
|
@@ -31,6 +33,8 @@ __export(orbit_exports, {
|
|
|
31
33
|
ecefToGeodetic: () => ecefToGeodetic,
|
|
32
34
|
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
33
35
|
geodeticToEcef: () => geodeticToEcef,
|
|
36
|
+
glonassAlmanacEpochMs: () => glonassAlmanacEpochMs,
|
|
37
|
+
glonassAlmanacPosition: () => glonassAlmanacPosition,
|
|
34
38
|
glonassPosition: () => glonassPosition,
|
|
35
39
|
keplerPosition: () => keplerPosition,
|
|
36
40
|
maskRadForAzimuth: () => maskRadForAzimuth,
|
|
@@ -170,10 +174,184 @@ function getGpsLeap(date) {
|
|
|
170
174
|
return leap_seconds - 19;
|
|
171
175
|
}
|
|
172
176
|
|
|
173
|
-
// src/orbit/
|
|
177
|
+
// src/orbit/almanac.ts
|
|
174
178
|
var GM_GPS = 3986005e8;
|
|
175
179
|
var GM_GAL = 3986004418e5;
|
|
176
180
|
var GM_BDS = 3986004418e5;
|
|
181
|
+
var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
|
|
182
|
+
var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
|
|
183
|
+
var WEEK_MS = 6048e5;
|
|
184
|
+
var BDT_MINUS_GPST_MS = 14e3;
|
|
185
|
+
var BDS_GEO_PRNS = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 59, 60, 61, 62, 63]);
|
|
186
|
+
function almanacEpochMs(alm) {
|
|
187
|
+
if (alm.system === "C") {
|
|
188
|
+
return BDT_EPOCH_MS + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
|
|
189
|
+
}
|
|
190
|
+
return GPS_EPOCH_MS + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
|
|
191
|
+
}
|
|
192
|
+
function almanacSatPosition(alm, timeMs) {
|
|
193
|
+
const GM = alm.system === "E" ? GM_GAL : alm.system === "C" ? GM_BDS : GM_GPS;
|
|
194
|
+
const a = alm.sqrtA * alm.sqrtA;
|
|
195
|
+
const n0 = Math.sqrt(GM / (a * a * a));
|
|
196
|
+
const tk = (timeMs - almanacEpochMs(alm)) / 1e3;
|
|
197
|
+
const Mk = alm.m0 + n0 * tk;
|
|
198
|
+
let Ek = Mk;
|
|
199
|
+
for (let i = 0; i < 12; i++) {
|
|
200
|
+
const dE = (Mk - (Ek - alm.e * Math.sin(Ek))) / (1 - alm.e * Math.cos(Ek));
|
|
201
|
+
Ek += dE;
|
|
202
|
+
if (Math.abs(dE) < 1e-12) break;
|
|
203
|
+
}
|
|
204
|
+
const sinE = Math.sin(Ek);
|
|
205
|
+
const cosE = Math.cos(Ek);
|
|
206
|
+
const vk = Math.atan2(Math.sqrt(1 - alm.e * alm.e) * sinE, cosE - alm.e);
|
|
207
|
+
const uk = vk + alm.omega;
|
|
208
|
+
const rk = a * (1 - alm.e * cosE);
|
|
209
|
+
const ik = alm.i0OrDeltaI;
|
|
210
|
+
const xp = rk * Math.cos(uk);
|
|
211
|
+
const yp = rk * Math.sin(uk);
|
|
212
|
+
const clockBias = alm.af0 + alm.af1 * tk;
|
|
213
|
+
const isGeo = alm.system === "C" && BDS_GEO_PRNS.has(Number(alm.prn.slice(1)));
|
|
214
|
+
if (isGeo) {
|
|
215
|
+
const omegak2 = alm.omega0 + alm.omegaDot * tk - OMEGA_E * alm.toaSec;
|
|
216
|
+
const cosO2 = Math.cos(omegak2);
|
|
217
|
+
const sinO2 = Math.sin(omegak2);
|
|
218
|
+
const cosI2 = Math.cos(ik);
|
|
219
|
+
const sinI2 = Math.sin(ik);
|
|
220
|
+
const xg = xp * cosO2 - yp * cosI2 * sinO2;
|
|
221
|
+
const yg = xp * sinO2 + yp * cosI2 * cosO2;
|
|
222
|
+
const zg = yp * sinI2;
|
|
223
|
+
const phi = OMEGA_E * tk;
|
|
224
|
+
const cosPhi = Math.cos(phi);
|
|
225
|
+
const sinPhi = Math.sin(phi);
|
|
226
|
+
const COS5 = Math.cos(-5 * Math.PI / 180);
|
|
227
|
+
const SIN5 = Math.sin(-5 * Math.PI / 180);
|
|
228
|
+
return {
|
|
229
|
+
prn: alm.prn,
|
|
230
|
+
x: xg * cosPhi + yg * sinPhi * COS5 + zg * sinPhi * SIN5,
|
|
231
|
+
y: -xg * sinPhi + yg * cosPhi * COS5 + zg * cosPhi * SIN5,
|
|
232
|
+
z: -yg * SIN5 + zg * COS5,
|
|
233
|
+
clockBias
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
const omegak = alm.omega0 + (alm.omegaDot - OMEGA_E) * tk - OMEGA_E * alm.toaSec;
|
|
237
|
+
const cosO = Math.cos(omegak);
|
|
238
|
+
const sinO = Math.sin(omegak);
|
|
239
|
+
const cosI = Math.cos(ik);
|
|
240
|
+
const sinI = Math.sin(ik);
|
|
241
|
+
return {
|
|
242
|
+
prn: alm.prn,
|
|
243
|
+
x: xp * cosO - yp * cosI * sinO,
|
|
244
|
+
y: xp * sinO + yp * cosI * cosO,
|
|
245
|
+
z: yp * sinI,
|
|
246
|
+
clockBias
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// src/orbit/almanac-glo.ts
|
|
251
|
+
var C20 = -108263e-8;
|
|
252
|
+
var J = -1.5 * C20;
|
|
253
|
+
var AE = 6378.136;
|
|
254
|
+
var MU = 398600.44;
|
|
255
|
+
var OMEGA_Z = 7292115e-11;
|
|
256
|
+
var I_MEAN = 63 * Math.PI / 180;
|
|
257
|
+
var T_MEAN = 43200;
|
|
258
|
+
var GLO_1996_UTC_MS = Date.UTC(1996, 0, 1) - 108e5;
|
|
259
|
+
var DAY_MS = 864e5;
|
|
260
|
+
var FOUR_YEARS_DAYS = 1461;
|
|
261
|
+
function glonassAlmanacEpochMs(alm) {
|
|
262
|
+
const utcMs = GLO_1996_UTC_MS + ((alm.n4 - 1) * FOUR_YEARS_DAYS + (alm.nDay - 1)) * DAY_MS + alm.tLambda * 1e3;
|
|
263
|
+
return utcMs + getGpsLeap(new Date(utcMs)) * 1e3;
|
|
264
|
+
}
|
|
265
|
+
function c20Deltas(lam, tau, B, h, l, n, sinI, cosI) {
|
|
266
|
+
const sin2i = sinI * sinI;
|
|
267
|
+
const cos2i = cosI * cosI;
|
|
268
|
+
const s1 = Math.sin(lam);
|
|
269
|
+
const c1 = Math.cos(lam);
|
|
270
|
+
const s2 = Math.sin(2 * lam);
|
|
271
|
+
const c2 = Math.cos(2 * lam);
|
|
272
|
+
const s3 = Math.sin(3 * lam);
|
|
273
|
+
const c3 = Math.cos(3 * lam);
|
|
274
|
+
const s4 = Math.sin(4 * lam);
|
|
275
|
+
const c4 = Math.cos(4 * lam);
|
|
276
|
+
const daOverA = 2 * B * (1 - 1.5 * sin2i) * (l * c1 + h * s1) + B * sin2i * (0.5 * h * s1 - 0.5 * l * c1 + c2 + 3.5 * l * c3 + 3.5 * h * s3);
|
|
277
|
+
const dh = B * (1 - 1.5 * sin2i) * (l * n * tau + s1 + 1.5 * l * s2 - 1.5 * h * c2) - 0.25 * B * sin2i * (s1 - 7 / 3 * s3 + 5 * l * s2 - 8.5 * l * s4 + 8.5 * h * c4 + h * c2) + B * cos2i * (l * n * tau - 0.5 * l * s2);
|
|
278
|
+
const dl = B * (1 - 1.5 * sin2i) * (-h * n * tau + c1 + 1.5 * l * c2 + 1.5 * h * s2) - 0.25 * B * sin2i * (-c1 - 7 / 3 * c3 - 5 * h * s2 - 8.5 * l * c4 - 8.5 * h * s4 + l * c2) + B * cos2i * (-h * n * tau + 0.5 * h * s2);
|
|
279
|
+
const nodeBracket = n * tau + 3.5 * l * s1 - 2.5 * h * c1 - 0.5 * s2 - 7 / 6 * l * s3 + 7 / 6 * h * c3;
|
|
280
|
+
const dOmega = -B * cosI * nodeBracket;
|
|
281
|
+
const di = 0.5 * B * sinI * cosI * (-l * c1 + h * s1 + c2 + 7 / 3 * l * c3 + 7 / 3 * h * s3);
|
|
282
|
+
const dLambda = 2 * B * (1 - 1.5 * sin2i) * (n * tau + 1.75 * l * s1 - 1.75 * h * c1) + 3 * B * sin2i * (-(7 / 24) * h * c1 - 7 / 24 * l * s1 - 49 / 72 * h * c3 + 49 / 72 * l * s3 + 0.25 * s2) + B * cos2i * nodeBracket;
|
|
283
|
+
return { daOverA, dh, dl, dOmega, di, dLambda };
|
|
284
|
+
}
|
|
285
|
+
function glonassAlmanacPosition(alm, timeMs) {
|
|
286
|
+
const i = I_MEAN + alm.deltaI;
|
|
287
|
+
const sinI = Math.sin(i);
|
|
288
|
+
const cosI = Math.cos(i);
|
|
289
|
+
const sin2i = sinI * sinI;
|
|
290
|
+
const e = alm.epsilon;
|
|
291
|
+
const oneMinusE2 = 1 - e * e;
|
|
292
|
+
const Tdr = T_MEAN + alm.deltaT;
|
|
293
|
+
const n = 2 * Math.PI / Tdr;
|
|
294
|
+
const cosW = Math.cos(alm.omega);
|
|
295
|
+
let a = Math.cbrt((Tdr / (2 * Math.PI)) ** 2 * MU);
|
|
296
|
+
for (let k = 0; k < 10; k++) {
|
|
297
|
+
const p = a * oneMinusE2;
|
|
298
|
+
const tOsc = Tdr / (1 + 1.5 * C20 * (AE / p) ** 2 * ((2 - 2.5 * sin2i) * (Math.pow(oneMinusE2, 1.5) / (1 + e * cosW) ** 2) + (1 + e * cosW) ** 3 / oneMinusE2));
|
|
299
|
+
const aNext = Math.cbrt((tOsc / (2 * Math.PI)) ** 2 * MU);
|
|
300
|
+
const converged = Math.abs(aNext - a) < 1e-3;
|
|
301
|
+
a = aNext;
|
|
302
|
+
if (converged) break;
|
|
303
|
+
}
|
|
304
|
+
const tStar = (timeMs - glonassAlmanacEpochMs(alm)) / 1e3;
|
|
305
|
+
const W = Math.floor(tStar / Tdr);
|
|
306
|
+
const nodeShift = Tdr * W + alm.deltaTDot * W * W;
|
|
307
|
+
const omegaDot = 1.5 * C20 * n * (AE / a) ** 2 * cosI * oneMinusE2 ** -2;
|
|
308
|
+
const lambdaK = alm.lambda + (omegaDot - OMEGA_Z) * nodeShift;
|
|
309
|
+
const tau = tStar - nodeShift;
|
|
310
|
+
const h = e * Math.sin(alm.omega);
|
|
311
|
+
const l = e * cosW;
|
|
312
|
+
const E0 = 2 * Math.atan(Math.sqrt((1 - e) / (1 + e)) * Math.tan(-alm.omega / 2));
|
|
313
|
+
const M = E0 - e * Math.sin(E0);
|
|
314
|
+
const B = J * (AE / a) ** 2;
|
|
315
|
+
const d1 = c20Deltas(M + alm.omega, 0, B, h, l, n, sinI, cosI);
|
|
316
|
+
const d2 = c20Deltas(M + alm.omega + n * tau, tau, B, h, l, n, sinI, cosI);
|
|
317
|
+
const hi = h + (d2.dh - d1.dh);
|
|
318
|
+
const li = l + (d2.dl - d1.dl);
|
|
319
|
+
const epsI = Math.hypot(hi, li);
|
|
320
|
+
const omegaI = epsI === 0 ? 0 : Math.atan2(hi, li);
|
|
321
|
+
const aI = a + a * (d2.daOverA - d1.daOverA);
|
|
322
|
+
const iI = i + (d2.di - d1.di);
|
|
323
|
+
const omegaG = lambdaK + (d2.dOmega - d1.dOmega) - OMEGA_Z * tau;
|
|
324
|
+
const lambdaStar = M + alm.omega + n * tau + (d2.dLambda - d1.dLambda);
|
|
325
|
+
const Mi = lambdaStar - omegaI;
|
|
326
|
+
let E = Mi;
|
|
327
|
+
for (let k = 0; k < 30; k++) {
|
|
328
|
+
const next = Mi + epsI * Math.sin(E);
|
|
329
|
+
const converged = Math.abs(next - E) < 1e-12;
|
|
330
|
+
E = next;
|
|
331
|
+
if (converged) break;
|
|
332
|
+
}
|
|
333
|
+
const v = 2 * Math.atan(Math.sqrt((1 + epsI) / (1 - epsI)) * Math.tan(E / 2));
|
|
334
|
+
const u = v + omegaI;
|
|
335
|
+
const rKm = aI * (1 - epsI * Math.cos(E));
|
|
336
|
+
const cosU = Math.cos(u);
|
|
337
|
+
const sinU = Math.sin(u);
|
|
338
|
+
const cosO = Math.cos(omegaG);
|
|
339
|
+
const sinO = Math.sin(omegaG);
|
|
340
|
+
const cosIi = Math.cos(iI);
|
|
341
|
+
const sinIi = Math.sin(iI);
|
|
342
|
+
return {
|
|
343
|
+
prn: alm.prn,
|
|
344
|
+
x: 1e3 * rKm * (cosU * cosO - sinU * sinO * cosIi),
|
|
345
|
+
y: 1e3 * rKm * (cosU * sinO + sinU * cosO * cosIi),
|
|
346
|
+
z: 1e3 * rKm * sinU * sinIi,
|
|
347
|
+
clockBias: -alm.tau
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// src/orbit/index.ts
|
|
352
|
+
var GM_GPS2 = 3986005e8;
|
|
353
|
+
var GM_GAL2 = 3986004418e5;
|
|
354
|
+
var GM_BDS2 = 3986004418e5;
|
|
177
355
|
var GM_GLO = 39860044e7;
|
|
178
356
|
var BDS_GEO_MAX_INCLINATION_RAD = 0.1;
|
|
179
357
|
var BDS_GEO_MIN_SEMIMAJOR_AXIS_M = 4e7;
|
|
@@ -181,9 +359,9 @@ var AE_GLO = 6378136;
|
|
|
181
359
|
var J2_GLO = 108263e-8;
|
|
182
360
|
var TWO_PI = 2 * Math.PI;
|
|
183
361
|
function gmForSystem(sys) {
|
|
184
|
-
if (sys === "E") return
|
|
185
|
-
if (sys === "C") return
|
|
186
|
-
return
|
|
362
|
+
if (sys === "E") return GM_GAL2;
|
|
363
|
+
if (sys === "C") return GM_BDS2;
|
|
364
|
+
return GM_GPS2;
|
|
187
365
|
}
|
|
188
366
|
var geoVelocityPass = false;
|
|
189
367
|
function keplerPosition(eph, t) {
|
|
@@ -519,10 +697,10 @@ function selectBest(ephs, timeMs) {
|
|
|
519
697
|
}
|
|
520
698
|
return best;
|
|
521
699
|
}
|
|
522
|
-
var
|
|
700
|
+
var GPS_EPOCH_MS2 = START_GPS_TIME.getTime();
|
|
523
701
|
var MS_PER_WEEK = 7 * 864e5;
|
|
524
702
|
var BDS_EPOCH_MS = START_BDS_TIME.getTime();
|
|
525
|
-
var GAL_EPOCH_MS =
|
|
703
|
+
var GAL_EPOCH_MS = GPS_EPOCH_MS2 + 1024 * MS_PER_WEEK;
|
|
526
704
|
function ephInfoToEphemeris(info) {
|
|
527
705
|
const sys = info.prn.charAt(0);
|
|
528
706
|
if (sys === "R") {
|
|
@@ -573,8 +751,8 @@ function ephInfoToEphemeris(info) {
|
|
|
573
751
|
} else if (sys === "E") {
|
|
574
752
|
epochMs = GAL_EPOCH_MS;
|
|
575
753
|
} else {
|
|
576
|
-
epochMs =
|
|
577
|
-
const weeksNow = (info.lastReceived -
|
|
754
|
+
epochMs = GPS_EPOCH_MS2;
|
|
755
|
+
const weeksNow = (info.lastReceived - GPS_EPOCH_MS2) / MS_PER_WEEK;
|
|
578
756
|
week += 1024 * Math.round((weeksNow - week) / 1024);
|
|
579
757
|
}
|
|
580
758
|
const tocDate = new Date(epochMs + week * MS_PER_WEEK + tocSec * 1e3);
|
|
@@ -755,6 +933,8 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
755
933
|
}
|
|
756
934
|
// Annotate the CommonJS export names for ESM import in node:
|
|
757
935
|
0 && (module.exports = {
|
|
936
|
+
almanacEpochMs,
|
|
937
|
+
almanacSatPosition,
|
|
758
938
|
computeAllPositions,
|
|
759
939
|
computeDop,
|
|
760
940
|
computeLiveSkyPositions,
|
|
@@ -766,6 +946,8 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
766
946
|
ecefToGeodetic,
|
|
767
947
|
ephInfoToEphemeris,
|
|
768
948
|
geodeticToEcef,
|
|
949
|
+
glonassAlmanacEpochMs,
|
|
950
|
+
glonassAlmanacPosition,
|
|
769
951
|
glonassPosition,
|
|
770
952
|
keplerPosition,
|
|
771
953
|
maskRadForAzimuth,
|