gnss-js 1.63.0 → 1.64.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.
@@ -563,6 +563,192 @@ function decodeEphemeris(frame) {
563
563
  }
564
564
  }
565
565
 
566
+ // src/rtcm3/igs-ssr.ts
567
+ var UPDATE_INTERVAL_S = [
568
+ 1,
569
+ 2,
570
+ 5,
571
+ 10,
572
+ 15,
573
+ 30,
574
+ 60,
575
+ 120,
576
+ 240,
577
+ 300,
578
+ 600,
579
+ 900,
580
+ 1800,
581
+ 3600,
582
+ 7200,
583
+ 10800
584
+ ];
585
+ var SYSTEM_BY_BASE = {
586
+ 20: "G",
587
+ 40: "R",
588
+ 60: "E",
589
+ 80: "J",
590
+ 100: "C",
591
+ 120: "S"
592
+ };
593
+ var KIND_BY_OFFSET = {
594
+ 1: "orbit",
595
+ 2: "clock",
596
+ 3: "combined",
597
+ 4: "highRateClock",
598
+ 5: "codeBias",
599
+ 6: "phaseBias",
600
+ 7: "ura"
601
+ };
602
+ var two = (n) => n.toString().padStart(2, "0");
603
+ function prnFor(system, id) {
604
+ if (system === "J") return `J${two(id)}`;
605
+ if (system === "S") return `S${two(19 + id)}`;
606
+ return `${system}${two(id)}`;
607
+ }
608
+ function ssrUraMm(v) {
609
+ if (v === 0) return null;
610
+ const cls = v >> 3 & 7;
611
+ const val = v & 7;
612
+ return 3 ** cls * (1 + val / 4) - 1;
613
+ }
614
+ function decodeIgsSsr(frame) {
615
+ if (frame.messageType !== 4076) return null;
616
+ const r = new BitReader(frame.payload);
617
+ r.readU(12);
618
+ const version = r.readU(3);
619
+ const im = r.readU(8);
620
+ if (im === 201) return decodeIono(r, version, im);
621
+ const base = Math.floor(im / 20) * 20;
622
+ const system = SYSTEM_BY_BASE[base];
623
+ const kind = KIND_BY_OFFSET[im - base];
624
+ if (!system || !kind) return null;
625
+ const epochS = r.readU(20);
626
+ const updateIntervalS = UPDATE_INTERVAL_S[r.readU(4)];
627
+ const multipleMessage = r.readU(1) === 1;
628
+ const iodSsr = r.readU(4);
629
+ const providerId = r.readU(16);
630
+ const solutionId = r.readU(4);
631
+ const hasDatum = kind === "orbit" || kind === "combined";
632
+ const referenceDatum = hasDatum ? r.readU(1) : void 0;
633
+ let dispersiveConsistency;
634
+ let mwConsistency;
635
+ if (kind === "phaseBias") {
636
+ dispersiveConsistency = r.readU(1) === 1;
637
+ mwConsistency = r.readU(1) === 1;
638
+ }
639
+ const nsat = r.readU(6);
640
+ const readOrbit = (s) => {
641
+ s.iode = r.readU(8);
642
+ s.deltaRadial = r.readS(22) * 1e-4;
643
+ s.deltaAlongTrack = r.readS(20) * 4e-4;
644
+ s.deltaCrossTrack = r.readS(20) * 4e-4;
645
+ s.dotRadial = r.readS(21) * 1e-6;
646
+ s.dotAlongTrack = r.readS(19) * 4e-6;
647
+ s.dotCrossTrack = r.readS(19) * 4e-6;
648
+ };
649
+ const readClock = (s) => {
650
+ s.c0 = r.readS(22) * 1e-4;
651
+ s.c1 = r.readS(21) * 1e-6;
652
+ s.c2 = r.readS(27) * 2e-8;
653
+ };
654
+ const satellites = [];
655
+ for (let i = 0; i < nsat; i++) {
656
+ const id = r.readU(6);
657
+ const sat = { prn: prnFor(system, id) };
658
+ if (kind === "orbit" || kind === "combined") readOrbit(sat);
659
+ if (kind === "clock" || kind === "combined") readClock(sat);
660
+ else if (kind === "ura")
661
+ sat.uraMm = ssrUraMm(r.readU(6));
662
+ else if (kind === "highRateClock")
663
+ sat.highRateClock = r.readS(22) * 1e-4;
664
+ else if (kind === "codeBias") {
665
+ const n = r.readU(5);
666
+ const biases = [];
667
+ for (let b = 0; b < n; b++) {
668
+ const signal = r.readU(5);
669
+ biases.push({
670
+ signal,
671
+ signalName: `#${signal}`,
672
+ biasM: r.readS(14) * 0.01
673
+ // IDF025 0.01 m
674
+ });
675
+ }
676
+ sat.codeBiases = biases;
677
+ } else if (kind === "phaseBias") {
678
+ const n = r.readU(5);
679
+ r.readU(9);
680
+ r.readS(8);
681
+ const biases = [];
682
+ for (let b = 0; b < n; b++) {
683
+ const signal = r.readU(5);
684
+ const integer = r.readU(1) === 1;
685
+ const wideLaneGroup = r.readU(2);
686
+ const discontinuity = r.readU(4);
687
+ const biasM = r.readS(20) * 1e-4;
688
+ biases.push({ signal, integer, wideLaneGroup, discontinuity, biasM });
689
+ }
690
+ sat.phaseBiases = biases;
691
+ }
692
+ satellites.push(sat);
693
+ }
694
+ return {
695
+ messageType: 4076,
696
+ version,
697
+ igsMessageNumber: im,
698
+ system,
699
+ kind,
700
+ epochS,
701
+ updateIntervalS,
702
+ multipleMessage,
703
+ referenceDatum,
704
+ iodSsr,
705
+ providerId,
706
+ solutionId,
707
+ dispersiveConsistency,
708
+ mwConsistency,
709
+ satellites
710
+ };
711
+ }
712
+ function decodeIono(r, version, im) {
713
+ const epochS = r.readU(20);
714
+ const updateIntervalS = UPDATE_INTERVAL_S[r.readU(4)];
715
+ const multipleMessage = r.readU(1) === 1;
716
+ const iodSsr = r.readU(4);
717
+ const providerId = r.readU(16);
718
+ const solutionId = r.readU(4);
719
+ const qualityTecu = r.readU(9) * 0.05;
720
+ const nLayers = r.readU(2) + 1;
721
+ const layers = [];
722
+ for (let l = 0; l < nLayers; l++) {
723
+ const heightKm = r.readU(8) * 10;
724
+ const degree = r.readU(4) + 1;
725
+ const order = r.readU(4) + 1;
726
+ const N = degree;
727
+ const M = order;
728
+ const nCoef = (N + 1) * (N + 1) - (N - M) * (N - M + 1);
729
+ const nCos = nCoef;
730
+ let nSin = 0;
731
+ for (let m = 1; m <= M; m++) nSin += N - m + 1;
732
+ for (let i = 0; i < nCos + nSin; i++) r.readS(16);
733
+ layers.push({ heightKm, degree, order, coefficientCount: nCos + nSin });
734
+ }
735
+ return {
736
+ messageType: 4076,
737
+ version,
738
+ igsMessageNumber: im,
739
+ system: "I",
740
+ kind: "ionosphere",
741
+ epochS,
742
+ updateIntervalS,
743
+ multipleMessage,
744
+ iodSsr,
745
+ providerId,
746
+ solutionId,
747
+ satellites: [],
748
+ iono: { qualityTecu, layers }
749
+ };
750
+ }
751
+
566
752
  // src/rtcm3/legacy-obs.ts
567
753
  var PRUNIT_GPS = 299792.458;
568
754
  var PRUNIT_GLO = 599584.916;
@@ -579,7 +765,7 @@ function legacyLockSec(i) {
579
765
  if (i < 127) return 32 * i - 3096;
580
766
  return 937;
581
767
  }
582
- var two = (n) => n.toString().padStart(2, "0");
768
+ var two2 = (n) => n.toString().padStart(2, "0");
583
769
  function decodeLegacyObs(frame) {
584
770
  const type = frame.messageType;
585
771
  const gps = type >= 1001 && type <= 1004;
@@ -665,7 +851,7 @@ function decodeLegacyObs(frame) {
665
851
  signals.push(sig);
666
852
  }
667
853
  observations.push({
668
- prn: `${system}${two(satId)}`,
854
+ prn: `${system}${two2(satId)}`,
669
855
  system,
670
856
  signals
671
857
  });
@@ -1207,6 +1393,144 @@ function resetGloFreqCache() {
1207
1393
  gloFreqNum.fill(-128);
1208
1394
  }
1209
1395
 
1396
+ // src/rtcm3/ssr.ts
1397
+ var UPDATE_INTERVAL_S2 = [
1398
+ 1,
1399
+ 2,
1400
+ 5,
1401
+ 10,
1402
+ 15,
1403
+ 30,
1404
+ 60,
1405
+ 120,
1406
+ 240,
1407
+ 300,
1408
+ 600,
1409
+ 900,
1410
+ 1800,
1411
+ 3600,
1412
+ 7200,
1413
+ 10800
1414
+ ];
1415
+ var GPS_SIGNAL = {
1416
+ 0: "L1 C/A",
1417
+ 1: "L1 P",
1418
+ 2: "L1 Z-tracking",
1419
+ 5: "L2 C/A",
1420
+ 6: "L2 semi-codeless",
1421
+ 7: "L2C(M)",
1422
+ 8: "L2C(L)",
1423
+ 9: "L2C(M+L)",
1424
+ 10: "L2 P",
1425
+ 11: "L2 Z-tracking",
1426
+ 14: "L5 I",
1427
+ 15: "L5 Q"
1428
+ };
1429
+ var GLO_SIGNAL = {
1430
+ 0: "G1 C/A",
1431
+ 1: "G1 P",
1432
+ 2: "G2 C/A",
1433
+ 3: "G2 P"
1434
+ };
1435
+ var SSR_KIND = {
1436
+ 1057: { system: "G", kind: "orbit" },
1437
+ 1058: { system: "G", kind: "clock" },
1438
+ 1059: { system: "G", kind: "codeBias" },
1439
+ 1060: { system: "G", kind: "combined" },
1440
+ 1061: { system: "G", kind: "ura" },
1441
+ 1062: { system: "G", kind: "highRateClock" },
1442
+ 1063: { system: "R", kind: "orbit" },
1443
+ 1064: { system: "R", kind: "clock" },
1444
+ 1065: { system: "R", kind: "codeBias" },
1445
+ 1066: { system: "R", kind: "combined" },
1446
+ 1067: { system: "R", kind: "ura" },
1447
+ 1068: { system: "R", kind: "highRateClock" }
1448
+ };
1449
+ function ssrUraMm2(v) {
1450
+ if (v === 0) return null;
1451
+ const cls = v >> 3 & 7;
1452
+ const val = v & 7;
1453
+ return 3 ** cls * (1 + val / 4) - 1;
1454
+ }
1455
+ var two3 = (n) => n.toString().padStart(2, "0");
1456
+ function decodeSsr(frame) {
1457
+ const spec = SSR_KIND[frame.messageType];
1458
+ if (!spec) return null;
1459
+ const { system, kind } = spec;
1460
+ const gps = system === "G";
1461
+ const r = new BitReader(frame.payload);
1462
+ r.readU(12);
1463
+ const epochS = r.readU(gps ? 20 : 17);
1464
+ const updateIntervalS = UPDATE_INTERVAL_S2[r.readU(4)];
1465
+ const multipleMessage = r.readU(1) === 1;
1466
+ const hasDatum = kind === "orbit" || kind === "combined";
1467
+ const referenceDatum = hasDatum ? r.readU(1) : void 0;
1468
+ const iodSsr = r.readU(4);
1469
+ const providerId = r.readU(16);
1470
+ const solutionId = r.readU(4);
1471
+ const nsat = r.readU(6);
1472
+ const sigName = gps ? GPS_SIGNAL : GLO_SIGNAL;
1473
+ const satellites = [];
1474
+ const readOrbit = (sat) => {
1475
+ sat.deltaRadial = r.readS(22) * 1e-4;
1476
+ sat.deltaAlongTrack = r.readS(20) * 4e-4;
1477
+ sat.deltaCrossTrack = r.readS(20) * 4e-4;
1478
+ sat.dotRadial = r.readS(21) * 1e-6;
1479
+ sat.dotAlongTrack = r.readS(19) * 4e-6;
1480
+ sat.dotCrossTrack = r.readS(19) * 4e-6;
1481
+ };
1482
+ const readClock = (sat) => {
1483
+ sat.c0 = r.readS(22) * 1e-4;
1484
+ sat.c1 = r.readS(21) * 1e-6;
1485
+ sat.c2 = r.readS(27) * 2e-8;
1486
+ };
1487
+ for (let i = 0; i < nsat; i++) {
1488
+ const satId = gps ? r.readU(6) : r.readU(5);
1489
+ const sat = { prn: `${system}${two3(satId)}` };
1490
+ if (kind === "orbit" || kind === "combined") {
1491
+ sat.iode = r.readU(8);
1492
+ readOrbit(sat);
1493
+ }
1494
+ if (kind === "combined") readClock(sat);
1495
+ else if (kind === "clock") readClock(sat);
1496
+ else if (kind === "ura")
1497
+ sat.uraMm = ssrUraMm2(r.readU(6));
1498
+ else if (kind === "highRateClock")
1499
+ sat.highRateClock = r.readS(22) * 1e-4;
1500
+ else if (kind === "codeBias") {
1501
+ const ncb = r.readU(5);
1502
+ const biases = [];
1503
+ for (let c = 0; c < ncb; c++) {
1504
+ const signal = r.readU(5);
1505
+ const biasM = r.readS(14) * 0.01;
1506
+ biases.push({
1507
+ signal,
1508
+ signalName: sigName[signal] ?? `#${signal}`,
1509
+ biasM
1510
+ });
1511
+ }
1512
+ sat.codeBiases = biases;
1513
+ }
1514
+ satellites.push(sat);
1515
+ }
1516
+ return {
1517
+ messageType: frame.messageType,
1518
+ system,
1519
+ kind,
1520
+ epochS,
1521
+ updateIntervalS,
1522
+ multipleMessage,
1523
+ referenceDatum,
1524
+ iodSsr,
1525
+ providerId,
1526
+ solutionId,
1527
+ satellites
1528
+ };
1529
+ }
1530
+ function isSsrMessage(messageType) {
1531
+ return messageType in SSR_KIND;
1532
+ }
1533
+
1210
1534
  // src/rtcm3/station.ts
1211
1535
  function createStationMeta() {
1212
1536
  return {
@@ -1557,11 +1881,14 @@ export {
1557
1881
  Rtcm3Decoder,
1558
1882
  readString,
1559
1883
  decodeEphemeris,
1884
+ decodeIgsSsr,
1560
1885
  decodeLegacyObs,
1561
1886
  decodeMsmFull,
1562
1887
  msmEpochToDate,
1563
1888
  setGloFreqNumber,
1564
1889
  resetGloFreqCache,
1890
+ decodeSsr,
1891
+ isSsrMessage,
1565
1892
  createStationMeta,
1566
1893
  updateStationMeta,
1567
1894
  RTCM3_MESSAGE_NAMES,