gnss-js 1.15.0 → 1.16.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/index.cjs CHANGED
@@ -227,6 +227,7 @@ __export(src_exports, {
227
227
  parseSinexBiasDcb: () => parseSinexBiasDcb,
228
228
  parseSourcetable: () => parseSourcetable,
229
229
  parseSp3: () => parseSp3,
230
+ parseUbxNav: () => parseUbxNav,
230
231
  parseUbxRawx: () => parseUbxRawx,
231
232
  phiAltBOC: () => phiAltBOC,
232
233
  phiBOCc: () => phiBOCc,
@@ -240,6 +241,8 @@ __export(src_exports, {
240
241
  rhumbLine: () => rhumbLine,
241
242
  rtcm3Constellation: () => rtcm3Constellation,
242
243
  satClockCorrection: () => satClockCorrection,
244
+ sbfCrc16: () => crc16,
245
+ scanSbfFrames: () => scanSbfFrames,
243
246
  selectEphemeris: () => selectEphemeris,
244
247
  setGloFreqNumber: () => setGloFreqNumber,
245
248
  setRtcm3DebugHandler: () => setRtcm3DebugHandler,
@@ -249,6 +252,7 @@ __export(src_exports, {
249
252
  systemCmp: () => systemCmp,
250
253
  systemName: () => systemName,
251
254
  transformFrame: () => transformFrame,
255
+ ubxFrames: () => ubxFrames,
252
256
  updateStationMeta: () => updateStationMeta,
253
257
  updateStreamStats: () => updateStreamStats,
254
258
  verifyChecksum: () => verifyChecksum,
@@ -4598,8 +4602,255 @@ function updateStreamStats(stats, frames, rawBytes) {
4598
4602
  }
4599
4603
  }
4600
4604
 
4601
- // src/ubx/index.ts
4605
+ // src/ubx/frame.ts
4606
+ function* ubxFrames(data, stats = { badChecksums: 0 }) {
4607
+ let i = 0;
4608
+ while (i + 8 <= data.length) {
4609
+ if (data[i] !== 181 || data[i + 1] !== 98) {
4610
+ i++;
4611
+ continue;
4612
+ }
4613
+ const len = data[i + 4] | data[i + 5] << 8;
4614
+ const end = i + 6 + len + 2;
4615
+ if (end > data.length) break;
4616
+ let ckA = 0;
4617
+ let ckB = 0;
4618
+ for (let j = i + 2; j < i + 6 + len; j++) {
4619
+ ckA = ckA + data[j] & 255;
4620
+ ckB = ckB + ckA & 255;
4621
+ }
4622
+ if (ckA !== data[i + 6 + len] || ckB !== data[i + 7 + len]) {
4623
+ stats.badChecksums++;
4624
+ i++;
4625
+ continue;
4626
+ }
4627
+ yield {
4628
+ msgClass: data[i + 2],
4629
+ msgId: data[i + 3],
4630
+ payload: data.subarray(i + 6, i + 6 + len),
4631
+ payloadStart: i + 6
4632
+ };
4633
+ i = end;
4634
+ }
4635
+ }
4636
+
4637
+ // src/navbits/index.ts
4638
+ var GPS_PI = 3.1415926535898;
4602
4639
  var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
4640
+ var SEC_PER_WEEK = 7 * 86400;
4641
+ function getBitU(buff, pos, len) {
4642
+ let bits = 0;
4643
+ for (let i = pos; i < pos + len; i++) {
4644
+ bits = bits * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
4645
+ }
4646
+ return bits;
4647
+ }
4648
+ function getBitS(buff, pos, len) {
4649
+ const bits = getBitU(buff, pos, len);
4650
+ if (len <= 0 || bits < 2 ** (len - 1)) return bits;
4651
+ return bits - 2 ** len;
4652
+ }
4653
+ function setBitU(buff, pos, len, data) {
4654
+ let mask = 2 ** (len - 1);
4655
+ for (let i = pos; i < pos + len; i++, mask /= 2) {
4656
+ if (data >= mask) {
4657
+ buff[i >> 3] |= 1 << 7 - (i & 7);
4658
+ data -= mask;
4659
+ } else {
4660
+ buff[i >> 3] &= ~(1 << 7 - (i & 7));
4661
+ }
4662
+ }
4663
+ }
4664
+ function decodeGpsLnavFrame(subframes, opts = {}) {
4665
+ if (subframes.length < 90) return null;
4666
+ const b = subframes;
4667
+ let i = 24;
4668
+ const tow1 = getBitU(b, i, 17) * 6;
4669
+ i += 17 + 2;
4670
+ const id1 = getBitU(b, i, 3);
4671
+ i += 3 + 2;
4672
+ const week10 = getBitU(b, i, 10);
4673
+ i += 10;
4674
+ i += 2;
4675
+ i += 4;
4676
+ const svHealth = getBitU(b, i, 6);
4677
+ i += 6;
4678
+ const iodc0 = getBitU(b, i, 2);
4679
+ i += 2;
4680
+ i += 1 + 87;
4681
+ const tgdRaw = getBitS(b, i, 8);
4682
+ i += 8;
4683
+ const iodc1 = getBitU(b, i, 8);
4684
+ i += 8;
4685
+ const tocSec = getBitU(b, i, 16) * 16;
4686
+ i += 16;
4687
+ const af2 = getBitS(b, i, 8) * 2 ** -55;
4688
+ i += 8;
4689
+ const af1 = getBitS(b, i, 16) * 2 ** -43;
4690
+ i += 16;
4691
+ const af0 = getBitS(b, i, 22) * 2 ** -31;
4692
+ i = 240 + 24;
4693
+ i += 17 + 2;
4694
+ const id2 = getBitU(b, i, 3);
4695
+ i += 3 + 2;
4696
+ const iode = getBitU(b, i, 8);
4697
+ i += 8;
4698
+ const crs = getBitS(b, i, 16) * 2 ** -5;
4699
+ i += 16;
4700
+ const deltaN = getBitS(b, i, 16) * 2 ** -43 * GPS_PI;
4701
+ i += 16;
4702
+ const m0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
4703
+ i += 32;
4704
+ const cuc = getBitS(b, i, 16) * 2 ** -29;
4705
+ i += 16;
4706
+ const e = getBitU(b, i, 32) * 2 ** -33;
4707
+ i += 32;
4708
+ const cus = getBitS(b, i, 16) * 2 ** -29;
4709
+ i += 16;
4710
+ const sqrtA = getBitU(b, i, 32) * 2 ** -19;
4711
+ i += 32;
4712
+ const toes = getBitU(b, i, 16) * 16;
4713
+ i = 480 + 24;
4714
+ i += 17 + 2;
4715
+ const id3 = getBitU(b, i, 3);
4716
+ i += 3 + 2;
4717
+ const cic = getBitS(b, i, 16) * 2 ** -29;
4718
+ i += 16;
4719
+ const omega0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
4720
+ i += 32;
4721
+ const cis = getBitS(b, i, 16) * 2 ** -29;
4722
+ i += 16;
4723
+ const i0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
4724
+ i += 32;
4725
+ const crc = getBitS(b, i, 16) * 2 ** -5;
4726
+ i += 16;
4727
+ const omega = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
4728
+ i += 32;
4729
+ const omegaDot = getBitS(b, i, 24) * 2 ** -43 * GPS_PI;
4730
+ i += 24;
4731
+ const iode3 = getBitU(b, i, 8);
4732
+ i += 8;
4733
+ const idot = getBitS(b, i, 14) * 2 ** -43 * GPS_PI;
4734
+ const iodc = iodc0 * 256 + iodc1;
4735
+ if (id1 !== 1 || id2 !== 2 || id3 !== 3) return null;
4736
+ if (iode3 !== iode || iode !== (iodc & 255)) return null;
4737
+ const ref = opts.refWeek ?? Math.floor((Date.now() - GPS_EPOCH_MS) / 1e3 / SEC_PER_WEEK);
4738
+ let week = week10 + 1024 * Math.round((ref - week10) / 1024);
4739
+ if (toes < tow1 - 302400) week++;
4740
+ else if (toes > tow1 + 302400) week--;
4741
+ const prn = opts.prn ?? "G00";
4742
+ const tocDate = new Date(
4743
+ GPS_EPOCH_MS + (week * SEC_PER_WEEK + tocSec) * 1e3
4744
+ );
4745
+ return {
4746
+ system: prn[0] === "J" ? "J" : "G",
4747
+ prn,
4748
+ tocDate,
4749
+ // Same seconds-of-week convention as parseNavFile (rinex/nav.ts).
4750
+ toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK,
4751
+ af0,
4752
+ af1,
4753
+ af2,
4754
+ iode,
4755
+ crs,
4756
+ deltaN,
4757
+ m0,
4758
+ cuc,
4759
+ e,
4760
+ cus,
4761
+ sqrtA,
4762
+ toe: toes,
4763
+ cic,
4764
+ omega0,
4765
+ cis,
4766
+ i0,
4767
+ crc,
4768
+ omega,
4769
+ omegaDot,
4770
+ idot,
4771
+ week,
4772
+ svHealth,
4773
+ tgd: tgdRaw === -128 ? 0 : tgdRaw * 2 ** -31
4774
+ // IS-GPS-200: -128 reserved
4775
+ };
4776
+ }
4777
+
4778
+ // src/ubx/nav.ts
4779
+ var PREAMB_CNAV = 139;
4780
+ function parseUbxNav(data, opts = {}) {
4781
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
4782
+ const ephemerides = [];
4783
+ let badParity = 0;
4784
+ let refWeek = opts.refWeek;
4785
+ if (refWeek === void 0) {
4786
+ for (const f of ubxFrames(data)) {
4787
+ if (f.msgClass === 2 && f.msgId === 21 && f.payload.length >= 16) {
4788
+ const week = view.getUint16(f.payloadStart + 8, true);
4789
+ if (week > 0) {
4790
+ refWeek = week;
4791
+ break;
4792
+ }
4793
+ }
4794
+ }
4795
+ }
4796
+ if (refWeek === void 0) return { ephemerides, badParity };
4797
+ const subframes = /* @__PURE__ */ new Map();
4798
+ const last = /* @__PURE__ */ new Map();
4799
+ for (const f of ubxFrames(data)) {
4800
+ if (f.msgClass !== 2 || f.msgId !== 19) continue;
4801
+ const p = f.payload;
4802
+ if (p.length < 8) continue;
4803
+ const gnssId = p[0];
4804
+ const svId = p[1];
4805
+ let prn;
4806
+ if (gnssId === 0 && svId >= 1 && svId <= 32) {
4807
+ prn = `G${String(svId).padStart(2, "0")}`;
4808
+ } else if (gnssId === 5 && svId >= 1 && svId <= 10) {
4809
+ if (p.length === 44) continue;
4810
+ prn = `J${String(svId).padStart(2, "0")}`;
4811
+ } else {
4812
+ continue;
4813
+ }
4814
+ if (p.length < 8 + 40) continue;
4815
+ const base = f.payloadStart + 8;
4816
+ if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) continue;
4817
+ const buff = new Uint8Array(30);
4818
+ for (let k = 0; k < 10; k++) {
4819
+ const dwrd = view.getUint32(base + 4 * k, true);
4820
+ setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
4821
+ }
4822
+ const id = getBitU(buff, 43, 3);
4823
+ if (id < 1 || id > 5) {
4824
+ badParity++;
4825
+ continue;
4826
+ }
4827
+ if (id > 3) continue;
4828
+ const key = gnssId * 256 + svId;
4829
+ let sf = subframes.get(key);
4830
+ if (!sf) {
4831
+ sf = { buf: new Uint8Array(90), have: 0 };
4832
+ subframes.set(key, sf);
4833
+ }
4834
+ sf.buf.set(buff, (id - 1) * 30);
4835
+ sf.have |= 1 << id - 1;
4836
+ if (id !== 3 || sf.have !== 7) continue;
4837
+ const eph = decodeGpsLnavFrame(sf.buf, { prn, refWeek });
4838
+ if (!eph) {
4839
+ badParity++;
4840
+ continue;
4841
+ }
4842
+ const prev = last.get(prn);
4843
+ if (prev && prev.iode === eph.iode && prev.tocDate.getTime() === eph.tocDate.getTime()) {
4844
+ continue;
4845
+ }
4846
+ last.set(prn, eph);
4847
+ ephemerides.push(eph);
4848
+ }
4849
+ return { ephemerides, badParity };
4850
+ }
4851
+
4852
+ // src/ubx/index.ts
4853
+ var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
4603
4854
  var MS_PER_WEEK2 = 7 * 864e5;
4604
4855
  var SIGNALS = {
4605
4856
  0: { 0: ["G", "1C"], 3: ["G", "2X"], 4: ["G", "2X"] },
@@ -4639,33 +4890,14 @@ function parseUbxRawx(data) {
4639
4890
  const epochs = [];
4640
4891
  const messageCounts = {};
4641
4892
  const obsCodes = {};
4642
- let badChecksums = 0;
4643
- let i = 0;
4644
- while (i + 8 <= data.length) {
4645
- if (data[i] !== 181 || data[i + 1] !== 98) {
4646
- i++;
4647
- continue;
4648
- }
4649
- const cls = data[i + 2];
4650
- const id = data[i + 3];
4651
- const len = data[i + 4] | data[i + 5] << 8;
4652
- const end = i + 6 + len + 2;
4653
- if (end > data.length) break;
4654
- let ckA = 0;
4655
- let ckB = 0;
4656
- for (let j = i + 2; j < i + 6 + len; j++) {
4657
- ckA = ckA + data[j] & 255;
4658
- ckB = ckB + ckA & 255;
4659
- }
4660
- if (ckA !== data[i + 6 + len] || ckB !== data[i + 7 + len]) {
4661
- badChecksums++;
4662
- i++;
4663
- continue;
4664
- }
4893
+ const stats = { badChecksums: 0 };
4894
+ for (const frame of ubxFrames(data, stats)) {
4895
+ const { msgClass: cls, msgId: id } = frame;
4896
+ const len = frame.payload.length;
4665
4897
  const key = `${cls.toString(16).padStart(2, "0")}-${id.toString(16).padStart(2, "0")}`;
4666
4898
  messageCounts[key] = (messageCounts[key] ?? 0) + 1;
4667
4899
  if (cls === 2 && id === 21 && len >= 16) {
4668
- const p = i + 6;
4900
+ const p = frame.payloadStart;
4669
4901
  const rcvTow = view.getFloat64(p, true);
4670
4902
  const week = view.getUint16(p + 8, true);
4671
4903
  const leapS = view.getInt8(p + 10);
@@ -4701,14 +4933,13 @@ function parseUbxRawx(data) {
4701
4933
  if (!codes.includes(sig[1])) codes.push(sig[1]);
4702
4934
  }
4703
4935
  epochs.push({
4704
- timeMs: GPS_EPOCH_MS + week * MS_PER_WEEK2 + Math.round(rcvTow * 1e3),
4936
+ timeMs: GPS_EPOCH_MS2 + week * MS_PER_WEEK2 + Math.round(rcvTow * 1e3),
4705
4937
  leapS: leapValid ? leapS : null,
4706
4938
  meas
4707
4939
  });
4708
4940
  }
4709
- i = end;
4710
4941
  }
4711
- return { epochs, messageCounts, obsCodes, badChecksums };
4942
+ return { epochs, messageCounts, obsCodes, badChecksums: stats.badChecksums };
4712
4943
  }
4713
4944
 
4714
4945
  // src/sbf/frame.ts
@@ -4773,10 +5004,10 @@ function svidToPrn(svid) {
4773
5004
 
4774
5005
  // src/sbf/nav.ts
4775
5006
  var PI2 = Math.PI;
4776
- var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
5007
+ var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
4777
5008
  var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
4778
- var SEC_PER_WEEK = 7 * 86400;
4779
- var MS_PER_WEEK3 = SEC_PER_WEEK * 1e3;
5009
+ var SEC_PER_WEEK2 = 7 * 86400;
5010
+ var MS_PER_WEEK3 = SEC_PER_WEEK2 * 1e3;
4780
5011
  var F4_DNU = -2e10;
4781
5012
  var U4_DNU = 4294967295;
4782
5013
  function adjustWeek(refWeek, wn, mod) {
@@ -4785,8 +5016,8 @@ function adjustWeek(refWeek, wn, mod) {
4785
5016
  if (offset < -(mod / 2 - 1)) offset += mod;
4786
5017
  return refWeek - offset;
4787
5018
  }
4788
- var gpsMs = (week, sec) => GPS_EPOCH_MS2 + week * MS_PER_WEEK3 + sec * 1e3;
4789
- var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
5019
+ var gpsMs = (week, sec) => GPS_EPOCH_MS3 + week * MS_PER_WEEK3 + sec * 1e3;
5020
+ var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK2;
4790
5021
  function decodeGpsQzsNav(view, b, sys) {
4791
5022
  const svid = view.getUint8(b + 14);
4792
5023
  const prn = sys === "G" ? svid : svid - 180;
@@ -4935,7 +5166,7 @@ function decodeGloNav(view, b) {
4935
5166
  const tocDate = new Date(toeGpsMs - leapMs);
4936
5167
  const tofGpsMs = gpsMs(wnc, 0) + view.getUint32(b + 8, true);
4937
5168
  const tofLeapMs = getGpsLeap(new Date(tofGpsMs)) * 1e3;
4938
- const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS2) / 1e3 % SEC_PER_WEEK;
5169
+ const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS3) / 1e3 % SEC_PER_WEEK2;
4939
5170
  return {
4940
5171
  system: "R",
4941
5172
  prn,
@@ -5082,7 +5313,7 @@ function parseSbfAlmanac(data) {
5082
5313
 
5083
5314
  // src/sbf/index.ts
5084
5315
  var CLIGHT = 299792458;
5085
- var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
5316
+ var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
5086
5317
  var MS_PER_WEEK4 = 7 * 864e5;
5087
5318
  var M3_SYS = ["G", "R", "E", "C", "S", "J", "I"];
5088
5319
  var M3_PR_BASE = [19e6, 19e6, 22e6, 2e7, 34e6, 34e6, 34e6];
@@ -5736,7 +5967,7 @@ function parseSbfMeas(data) {
5736
5967
  const tow = view.getUint32(i + 8, true);
5737
5968
  const wnc = view.getUint16(i + 12, true);
5738
5969
  if (tow !== 4294967295 && wnc !== 65535) {
5739
- ensureEpoch(GPS_EPOCH_MS3 + wnc * MS_PER_WEEK4 + tow);
5970
+ ensureEpoch(GPS_EPOCH_MS4 + wnc * MS_PER_WEEK4 + tow);
5740
5971
  if (id === 4109) decodeMeas3Ranges(i, tow);
5741
5972
  else if (id === 4110) decodeMeas3CN0(i, len);
5742
5973
  else if (id === 4111) decodeMeas3Doppler(i, len);
@@ -5792,136 +6023,6 @@ function* oem4Frames(data, view, stats) {
5792
6023
  }
5793
6024
  }
5794
6025
 
5795
- // src/navbits/index.ts
5796
- var GPS_PI = 3.1415926535898;
5797
- var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
5798
- var SEC_PER_WEEK2 = 7 * 86400;
5799
- function getBitU(buff, pos, len) {
5800
- let bits = 0;
5801
- for (let i = pos; i < pos + len; i++) {
5802
- bits = bits * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
5803
- }
5804
- return bits;
5805
- }
5806
- function getBitS(buff, pos, len) {
5807
- const bits = getBitU(buff, pos, len);
5808
- if (len <= 0 || bits < 2 ** (len - 1)) return bits;
5809
- return bits - 2 ** len;
5810
- }
5811
- function decodeGpsLnavFrame(subframes, opts = {}) {
5812
- if (subframes.length < 90) return null;
5813
- const b = subframes;
5814
- let i = 24;
5815
- const tow1 = getBitU(b, i, 17) * 6;
5816
- i += 17 + 2;
5817
- const id1 = getBitU(b, i, 3);
5818
- i += 3 + 2;
5819
- const week10 = getBitU(b, i, 10);
5820
- i += 10;
5821
- i += 2;
5822
- i += 4;
5823
- const svHealth = getBitU(b, i, 6);
5824
- i += 6;
5825
- const iodc0 = getBitU(b, i, 2);
5826
- i += 2;
5827
- i += 1 + 87;
5828
- const tgdRaw = getBitS(b, i, 8);
5829
- i += 8;
5830
- const iodc1 = getBitU(b, i, 8);
5831
- i += 8;
5832
- const tocSec = getBitU(b, i, 16) * 16;
5833
- i += 16;
5834
- const af2 = getBitS(b, i, 8) * 2 ** -55;
5835
- i += 8;
5836
- const af1 = getBitS(b, i, 16) * 2 ** -43;
5837
- i += 16;
5838
- const af0 = getBitS(b, i, 22) * 2 ** -31;
5839
- i = 240 + 24;
5840
- i += 17 + 2;
5841
- const id2 = getBitU(b, i, 3);
5842
- i += 3 + 2;
5843
- const iode = getBitU(b, i, 8);
5844
- i += 8;
5845
- const crs = getBitS(b, i, 16) * 2 ** -5;
5846
- i += 16;
5847
- const deltaN = getBitS(b, i, 16) * 2 ** -43 * GPS_PI;
5848
- i += 16;
5849
- const m0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
5850
- i += 32;
5851
- const cuc = getBitS(b, i, 16) * 2 ** -29;
5852
- i += 16;
5853
- const e = getBitU(b, i, 32) * 2 ** -33;
5854
- i += 32;
5855
- const cus = getBitS(b, i, 16) * 2 ** -29;
5856
- i += 16;
5857
- const sqrtA = getBitU(b, i, 32) * 2 ** -19;
5858
- i += 32;
5859
- const toes = getBitU(b, i, 16) * 16;
5860
- i = 480 + 24;
5861
- i += 17 + 2;
5862
- const id3 = getBitU(b, i, 3);
5863
- i += 3 + 2;
5864
- const cic = getBitS(b, i, 16) * 2 ** -29;
5865
- i += 16;
5866
- const omega0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
5867
- i += 32;
5868
- const cis = getBitS(b, i, 16) * 2 ** -29;
5869
- i += 16;
5870
- const i0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
5871
- i += 32;
5872
- const crc = getBitS(b, i, 16) * 2 ** -5;
5873
- i += 16;
5874
- const omega = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
5875
- i += 32;
5876
- const omegaDot = getBitS(b, i, 24) * 2 ** -43 * GPS_PI;
5877
- i += 24;
5878
- const iode3 = getBitU(b, i, 8);
5879
- i += 8;
5880
- const idot = getBitS(b, i, 14) * 2 ** -43 * GPS_PI;
5881
- const iodc = iodc0 * 256 + iodc1;
5882
- if (id1 !== 1 || id2 !== 2 || id3 !== 3) return null;
5883
- if (iode3 !== iode || iode !== (iodc & 255)) return null;
5884
- const ref = opts.refWeek ?? Math.floor((Date.now() - GPS_EPOCH_MS4) / 1e3 / SEC_PER_WEEK2);
5885
- let week = week10 + 1024 * Math.round((ref - week10) / 1024);
5886
- if (toes < tow1 - 302400) week++;
5887
- else if (toes > tow1 + 302400) week--;
5888
- const prn = opts.prn ?? "G00";
5889
- const tocDate = new Date(
5890
- GPS_EPOCH_MS4 + (week * SEC_PER_WEEK2 + tocSec) * 1e3
5891
- );
5892
- return {
5893
- system: prn[0] === "J" ? "J" : "G",
5894
- prn,
5895
- tocDate,
5896
- // Same seconds-of-week convention as parseNavFile (rinex/nav.ts).
5897
- toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK2,
5898
- af0,
5899
- af1,
5900
- af2,
5901
- iode,
5902
- crs,
5903
- deltaN,
5904
- m0,
5905
- cuc,
5906
- e,
5907
- cus,
5908
- sqrtA,
5909
- toe: toes,
5910
- cic,
5911
- omega0,
5912
- cis,
5913
- i0,
5914
- crc,
5915
- omega,
5916
- omegaDot,
5917
- idot,
5918
- week,
5919
- svHealth,
5920
- tgd: tgdRaw === -128 ? 0 : tgdRaw * 2 ** -31
5921
- // IS-GPS-200: -128 reserved
5922
- };
5923
- }
5924
-
5925
6026
  // src/novatel/nav.ts
5926
6027
  var ID_RAWEPHEM = 41;
5927
6028
  var ID_GLOEPHEMERIS = 723;
@@ -9748,6 +9849,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
9748
9849
  parseSinexBiasDcb,
9749
9850
  parseSourcetable,
9750
9851
  parseSp3,
9852
+ parseUbxNav,
9751
9853
  parseUbxRawx,
9752
9854
  phiAltBOC,
9753
9855
  phiBOCc,
@@ -9761,6 +9863,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
9761
9863
  rhumbLine,
9762
9864
  rtcm3Constellation,
9763
9865
  satClockCorrection,
9866
+ sbfCrc16,
9867
+ scanSbfFrames,
9764
9868
  selectEphemeris,
9765
9869
  setGloFreqNumber,
9766
9870
  setRtcm3DebugHandler,
@@ -9770,6 +9874,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
9770
9874
  systemCmp,
9771
9875
  systemName,
9772
9876
  transformFrame,
9877
+ ubxFrames,
9773
9878
  updateStationMeta,
9774
9879
  updateStreamStats,
9775
9880
  verifyChecksum,
package/dist/index.d.cts CHANGED
@@ -9,8 +9,8 @@ export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResul
9
9
  export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.cjs';
10
10
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
11
11
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
12
- export { UbxMeasurement, UbxParseResult, UbxRawxEpoch, parseUbxRawx } from './ubx.cjs';
13
- export { SbfAlmanac, SbfAlmanacResult, SbfGlonassAlmanac, SbfKeplerAlmanac, SbfMeasEpoch, SbfMeasurement, SbfNavResult, SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav } from './sbf.cjs';
12
+ export { UbxFrame, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawxEpoch, parseUbxNav, parseUbxRawx, ubxFrames } from './ubx.cjs';
13
+ export { SbfAlmanac, SbfAlmanacResult, SbfGlonassAlmanac, SbfKeplerAlmanac, SbfMeasEpoch, SbfMeasurement, SbfNavResult, SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav, sbfCrc16, scanSbfFrames } from './sbf.cjs';
14
14
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.cjs';
15
15
  export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
16
16
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
package/dist/index.d.ts CHANGED
@@ -9,8 +9,8 @@ export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResul
9
9
  export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.js';
10
10
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
11
11
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
12
- export { UbxMeasurement, UbxParseResult, UbxRawxEpoch, parseUbxRawx } from './ubx.js';
13
- export { SbfAlmanac, SbfAlmanacResult, SbfGlonassAlmanac, SbfKeplerAlmanac, SbfMeasEpoch, SbfMeasurement, SbfNavResult, SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav } from './sbf.js';
12
+ export { UbxFrame, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawxEpoch, parseUbxNav, parseUbxRawx, ubxFrames } from './ubx.js';
13
+ export { SbfAlmanac, SbfAlmanacResult, SbfGlonassAlmanac, SbfKeplerAlmanac, SbfMeasEpoch, SbfMeasurement, SbfNavResult, SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav, sbfCrc16, scanSbfFrames } from './sbf.js';
14
14
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.js';
15
15
  export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
16
16
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
package/dist/index.js CHANGED
@@ -34,20 +34,25 @@ import {
34
34
  phiBPSK
35
35
  } from "./chunk-2K3FCJBX.js";
36
36
  import {
37
- parseUbxRawx
38
- } from "./chunk-5IXK25MX.js";
37
+ parseUbxNav,
38
+ parseUbxRawx,
39
+ ubxFrames
40
+ } from "./chunk-6CX6EXRK.js";
39
41
  import {
42
+ crc16,
40
43
  parseSbfAlmanac,
41
44
  parseSbfMeas,
42
- parseSbfNav
43
- } from "./chunk-BEQSEJMU.js";
45
+ parseSbfNav,
46
+ scanSbfFrames
47
+ } from "./chunk-YPOVPXNK.js";
44
48
  import {
45
49
  OEM4_HLEN,
46
50
  crc32,
47
51
  oem4Frames,
48
52
  parseNovatelNav,
49
53
  parseNovatelRange
50
- } from "./chunk-I4UV45NT.js";
54
+ } from "./chunk-R33A2VA7.js";
55
+ import "./chunk-4LVD4DYL.js";
51
56
  import {
52
57
  connectToMountpoint,
53
58
  fetchSourcetable,
@@ -487,6 +492,7 @@ export {
487
492
  parseSinexBiasDcb,
488
493
  parseSourcetable,
489
494
  parseSp3,
495
+ parseUbxNav,
490
496
  parseUbxRawx,
491
497
  phiAltBOC,
492
498
  phiBOCc,
@@ -500,6 +506,8 @@ export {
500
506
  rhumbLine,
501
507
  rtcm3Constellation,
502
508
  satClockCorrection,
509
+ crc16 as sbfCrc16,
510
+ scanSbfFrames,
503
511
  selectEphemeris,
504
512
  setGloFreqNumber,
505
513
  setRtcm3DebugHandler,
@@ -509,6 +517,7 @@ export {
509
517
  systemCmp,
510
518
  systemName,
511
519
  transformFrame,
520
+ ubxFrames,
512
521
  updateStationMeta,
513
522
  updateStreamStats,
514
523
  verifyChecksum,
package/dist/novatel.js CHANGED
@@ -4,7 +4,8 @@ import {
4
4
  oem4Frames,
5
5
  parseNovatelNav,
6
6
  parseNovatelRange
7
- } from "./chunk-I4UV45NT.js";
7
+ } from "./chunk-R33A2VA7.js";
8
+ import "./chunk-4LVD4DYL.js";
8
9
  import "./chunk-HVXYFUCB.js";
9
10
  import "./chunk-LEEU5OIO.js";
10
11
  export {
package/dist/sbf.cjs CHANGED
@@ -22,7 +22,9 @@ var sbf_exports = {};
22
22
  __export(sbf_exports, {
23
23
  parseSbfAlmanac: () => parseSbfAlmanac,
24
24
  parseSbfMeas: () => parseSbfMeas,
25
- parseSbfNav: () => parseSbfNav
25
+ parseSbfNav: () => parseSbfNav,
26
+ sbfCrc16: () => crc16,
27
+ scanSbfFrames: () => scanSbfFrames
26
28
  });
27
29
  module.exports = __toCommonJS(sbf_exports);
28
30
 
@@ -1153,5 +1155,7 @@ function parseSbfMeas(data) {
1153
1155
  0 && (module.exports = {
1154
1156
  parseSbfAlmanac,
1155
1157
  parseSbfMeas,
1156
- parseSbfNav
1158
+ parseSbfNav,
1159
+ sbfCrc16,
1160
+ scanSbfFrames
1157
1161
  });
package/dist/sbf.d.cts CHANGED
@@ -1,5 +1,22 @@
1
1
  import { E as Ephemeris } from './nav-BAI1a9vK.cjs';
2
2
 
3
+ /**
4
+ * Septentrio SBF framing shared by the measurement and navigation
5
+ * decoders: 0x24 0x40 sync, CRC16-CCITT (poly 0x1021, init 0) as U2,
6
+ * block ID U2 (number in bits 0..12, revision in 13..15), total length
7
+ * U2 (multiple of 4, includes the 8-byte header). The CRC covers block
8
+ * ID through payload end.
9
+ */
10
+ declare function crc16(data: Uint8Array, start: number, end: number): number;
11
+ /**
12
+ * Scan a byte stream for valid SBF frames and invoke `onBlock` for each
13
+ * one, passing the block number (revision bits stripped), the frame
14
+ * start offset and the total frame length. Frames with bad CRC are
15
+ * counted and a resync continues at the next byte; the count of bad
16
+ * frames is returned.
17
+ */
18
+ declare function scanSbfFrames(data: Uint8Array, view: DataView, onBlock: (id: number, offset: number, len: number) => void): number;
19
+
3
20
  /**
4
21
  * Septentrio SBF decoded navigation and almanac blocks.
5
22
  *
@@ -197,4 +214,4 @@ interface SbfParseResult {
197
214
  */
198
215
  declare function parseSbfMeas(data: Uint8Array): SbfParseResult;
199
216
 
200
- export { type SbfAlmanac, type SbfAlmanacResult, type SbfGlonassAlmanac, type SbfKeplerAlmanac, type SbfMeasEpoch, type SbfMeasurement, type SbfNavResult, type SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav };
217
+ export { type SbfAlmanac, type SbfAlmanacResult, type SbfGlonassAlmanac, type SbfKeplerAlmanac, type SbfMeasEpoch, type SbfMeasurement, type SbfNavResult, type SbfParseResult, parseSbfAlmanac, parseSbfMeas, parseSbfNav, crc16 as sbfCrc16, scanSbfFrames };