gnss-js 1.0.1 → 1.1.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.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  CycleSlipAccumulator,
4
4
  MultipathAccumulator,
5
5
  analyzeQuality
6
- } from "./chunk-SO3POWWR.js";
6
+ } from "./chunk-G3N4S3DM.js";
7
7
  import {
8
8
  frequencyLabel,
9
9
  parseAntex
@@ -48,7 +48,7 @@ import {
48
48
  phiBOCc,
49
49
  phiBOCs,
50
50
  phiBPSK
51
- } from "./chunk-HKN3PUGN.js";
51
+ } from "./chunk-5SPJH4MG.js";
52
52
  import {
53
53
  Scale,
54
54
  getBdsTime,
@@ -116,31 +116,6 @@ import {
116
116
  vincenty
117
117
  } from "./chunk-MIIM4LDY.js";
118
118
  import "./chunk-5S5MONFK.js";
119
- import {
120
- DAYS_MJD2000_MJD,
121
- DAYS_MJD_JULIAN,
122
- MILLISECONDS_GPS_TAI,
123
- MILLISECONDS_IN_DAY,
124
- MILLISECONDS_IN_HOUR,
125
- MILLISECONDS_IN_MINUTE,
126
- MILLISECONDS_IN_SECOND,
127
- MILLISECONDS_IN_WEEK,
128
- MILLISECONDS_TT_TAI,
129
- RINEX_CODES,
130
- SECONDS_IN_DAY,
131
- SECONDS_IN_HOUR,
132
- SECONDS_IN_MINUTE,
133
- SECONDS_IN_WEEK,
134
- START_BDS_TIME,
135
- START_GAL_TIME,
136
- START_GLO_LEAP,
137
- START_GPS_TIME,
138
- START_JULIAN_TAI,
139
- START_MJD_UNIX_SECONDS,
140
- START_NTP_TIME,
141
- START_TAI_TIME,
142
- START_UNIX_TIME
143
- } from "./chunk-LEEU5OIO.js";
144
119
  import {
145
120
  EMPTY_WARNINGS,
146
121
  WarningAccumulator,
@@ -159,7 +134,7 @@ import {
159
134
  parseRinexStream,
160
135
  systemCmp,
161
136
  systemName
162
- } from "./chunk-HBLU2EJ4.js";
137
+ } from "./chunk-OZCYOM5D.js";
163
138
  import {
164
139
  BitReader,
165
140
  RTCM3_MESSAGE_NAMES,
@@ -170,11 +145,14 @@ import {
170
145
  decodeMsmFull,
171
146
  msmEpochToDate,
172
147
  readString,
148
+ reportDecodeError,
173
149
  resetGloFreqCache,
174
150
  rtcm3Constellation,
151
+ setGloFreqNumber,
152
+ setRtcm3DebugHandler,
175
153
  updateStationMeta,
176
154
  updateStreamStats
177
- } from "./chunk-WP2JFDLA.js";
155
+ } from "./chunk-JDO3LEPC.js";
178
156
  import {
179
157
  ARC_GAP_FACTOR,
180
158
  BAND_LABELS,
@@ -196,7 +174,7 @@ import {
196
174
  formatUTCTime,
197
175
  getFreq,
198
176
  gloFreq
199
- } from "./chunk-LWNTWBHB.js";
177
+ } from "./chunk-W5WKEV7U.js";
200
178
  import {
201
179
  computeAllPositions,
202
180
  computeDop,
@@ -207,7 +185,7 @@ import {
207
185
  keplerPosition,
208
186
  navTimesFromEph,
209
187
  selectEphemeris
210
- } from "./chunk-4YN353Q7.js";
188
+ } from "./chunk-PGHDJFQK.js";
211
189
  import {
212
190
  clampUnit,
213
191
  ecefToGeodetic,
@@ -221,6 +199,31 @@ import {
221
199
  WGS84_SEMI_MAJOR_AXIS,
222
200
  WGS84_SEMI_MINOR_AXIS
223
201
  } from "./chunk-6FAL6P4G.js";
202
+ import {
203
+ DAYS_MJD2000_MJD,
204
+ DAYS_MJD_JULIAN,
205
+ MILLISECONDS_GPS_TAI,
206
+ MILLISECONDS_IN_DAY,
207
+ MILLISECONDS_IN_HOUR,
208
+ MILLISECONDS_IN_MINUTE,
209
+ MILLISECONDS_IN_SECOND,
210
+ MILLISECONDS_IN_WEEK,
211
+ MILLISECONDS_TT_TAI,
212
+ RINEX_CODES,
213
+ SECONDS_IN_DAY,
214
+ SECONDS_IN_HOUR,
215
+ SECONDS_IN_MINUTE,
216
+ SECONDS_IN_WEEK,
217
+ START_BDS_TIME,
218
+ START_GAL_TIME,
219
+ START_GLO_LEAP,
220
+ START_GPS_TIME,
221
+ START_JULIAN_TAI,
222
+ START_MJD_UNIX_SECONDS,
223
+ START_NTP_TIME,
224
+ START_TAI_TIME,
225
+ START_UNIX_TIME
226
+ } from "./chunk-LEEU5OIO.js";
224
227
  import {
225
228
  connectToMountpoint,
226
229
  fetchSourcetable,
@@ -413,10 +416,13 @@ export {
413
416
  phiBPSK,
414
417
  rad2deg,
415
418
  readString,
419
+ reportDecodeError,
416
420
  resetGloFreqCache,
417
421
  rhumbLine,
418
422
  rtcm3Constellation,
419
423
  selectEphemeris,
424
+ setGloFreqNumber,
425
+ setRtcm3DebugHandler,
420
426
  systemCmp,
421
427
  systemName,
422
428
  updateStationMeta,
package/dist/orbit.cjs CHANGED
@@ -71,12 +71,18 @@ function ecefToGeodetic(x, y, z) {
71
71
  return [lat, lon, alt];
72
72
  }
73
73
 
74
+ // src/constants/time.ts
75
+ var START_GPS_TIME = /* @__PURE__ */ new Date("1980-01-06T00:00:00Z");
76
+ var START_BDS_TIME = /* @__PURE__ */ new Date("2006-01-01T00:00:14Z");
77
+
74
78
  // src/orbit/index.ts
75
79
  var GM_GPS = 3986005e8;
76
80
  var GM_GAL = 3986004418e5;
77
81
  var GM_BDS = 3986004418e5;
78
82
  var GM_GLO = 39860044e7;
79
83
  var OMEGA_E = 72921151467e-15;
84
+ var BDS_GEO_MAX_INCLINATION_RAD = 0.1;
85
+ var BDS_GEO_MIN_SEMIMAJOR_AXIS_M = 4e7;
80
86
  var AE_GLO = 6378136;
81
87
  var J2_GLO = 108263e-8;
82
88
  var TWO_PI = 2 * Math.PI;
@@ -114,7 +120,7 @@ function keplerPosition(eph, t) {
114
120
  const ik = eph.i0 + dik + eph.idot * tk;
115
121
  const xp = rk * Math.cos(uk);
116
122
  const yp = rk * Math.sin(uk);
117
- const isBdsGeo = eph.system === "C" && Math.abs(eph.i0) < 0.1 && a > 4e7;
123
+ const isBdsGeo = eph.system === "C" && Math.abs(eph.i0) < BDS_GEO_MAX_INCLINATION_RAD && a > BDS_GEO_MIN_SEMIMAJOR_AXIS_M;
118
124
  if (isBdsGeo) {
119
125
  const omegak2 = eph.omega0 + eph.omegaDot * tk - OMEGA_E * eph.toe;
120
126
  const cosO2 = Math.cos(omegak2);
@@ -295,9 +301,10 @@ function computeSatPosition(eph, timeMs) {
295
301
  if (eph.system === "R" || eph.system === "S") {
296
302
  return glonassPosition(eph, timeMs / 1e3);
297
303
  }
298
- const GPS_EPOCH = Date.UTC(1980, 0, 6);
304
+ const GPS_EPOCH = START_GPS_TIME.getTime();
299
305
  const gpsSeconds = (timeMs - GPS_EPOCH) / 1e3;
300
- const tow = gpsSeconds % (7 * 86400);
306
+ let tow = gpsSeconds % (7 * 86400);
307
+ if (eph.system === "C") tow = (tow - 14 + 604800) % 604800;
301
308
  return keplerPosition(eph, tow);
302
309
  }
303
310
  function navTimesFromEph(ephs) {
@@ -379,8 +386,8 @@ function selectBest(ephs, timeMs) {
379
386
  }
380
387
  return best;
381
388
  }
382
- var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
383
- var BDS_EPOCH_MS = Date.UTC(2006, 0, 1);
389
+ var GPS_EPOCH_MS = START_GPS_TIME.getTime();
390
+ var BDS_EPOCH_MS = START_BDS_TIME.getTime();
384
391
  var GAL_EPOCH_MS = GPS_EPOCH_MS;
385
392
  function ephInfoToEphemeris(info) {
386
393
  const sys = info.prn.charAt(0);
@@ -421,6 +428,9 @@ function ephInfoToEphemeris(info) {
421
428
  }
422
429
  if (info.sqrtA === void 0 || info.eccentricity === void 0 || info.inclination === void 0 || info.omega0 === void 0 || info.argPerigee === void 0 || info.meanAnomaly === void 0 || info.toe === void 0 || info.week === void 0)
423
430
  return null;
431
+ if (info.eccentricity < 0 || info.eccentricity >= 1 || info.sqrtA < 3e3 || info.sqrtA > 9e3 || info.toe < 0 || info.toe > 604800) {
432
+ return null;
433
+ }
424
434
  let epochMs;
425
435
  const tocSec = info.toc ?? info.toe;
426
436
  if (sys === "C") {
package/dist/orbit.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris } from './nav-BAI1a9vK.cjs';
2
- import { E as EphemerisInfo } from './ephemeris-C10stHhM.cjs';
2
+ import { E as EphemerisInfo } from './ephemeris-Ohl6NAfw.cjs';
3
3
  export { e as ecefToGeodetic, g as geodeticToEcef } from './ecef-CF0uAysr.cjs';
4
4
 
5
5
  /**
package/dist/orbit.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris } from './nav-BAI1a9vK.js';
2
- import { E as EphemerisInfo } from './ephemeris-C10stHhM.js';
2
+ import { E as EphemerisInfo } from './ephemeris-Ohl6NAfw.js';
3
3
  export { e as ecefToGeodetic, g as geodeticToEcef } from './ecef-CF0uAysr.js';
4
4
 
5
5
  /**
package/dist/orbit.js CHANGED
@@ -8,12 +8,13 @@ import {
8
8
  keplerPosition,
9
9
  navTimesFromEph,
10
10
  selectEphemeris
11
- } from "./chunk-4YN353Q7.js";
11
+ } from "./chunk-PGHDJFQK.js";
12
12
  import {
13
13
  ecefToGeodetic,
14
14
  geodeticToEcef
15
15
  } from "./chunk-37QNKGTC.js";
16
16
  import "./chunk-6FAL6P4G.js";
17
+ import "./chunk-LEEU5OIO.js";
17
18
  export {
18
19
  computeAllPositions,
19
20
  computeDop,
package/dist/rinex.js CHANGED
@@ -16,8 +16,8 @@ import {
16
16
  parseRinexStream,
17
17
  systemCmp,
18
18
  systemName
19
- } from "./chunk-HBLU2EJ4.js";
20
- import "./chunk-LWNTWBHB.js";
19
+ } from "./chunk-OZCYOM5D.js";
20
+ import "./chunk-W5WKEV7U.js";
21
21
  export {
22
22
  EMPTY_WARNINGS,
23
23
  SYSTEM_ORDER,
package/dist/rtcm3.cjs CHANGED
@@ -29,14 +29,24 @@ __export(rtcm3_exports, {
29
29
  decodeMsmFull: () => decodeMsmFull,
30
30
  msmEpochToDate: () => msmEpochToDate,
31
31
  readString: () => readString,
32
+ reportDecodeError: () => reportDecodeError,
32
33
  resetGloFreqCache: () => resetGloFreqCache,
33
34
  rtcm3Constellation: () => rtcm3Constellation,
35
+ setGloFreqNumber: () => setGloFreqNumber,
36
+ setRtcm3DebugHandler: () => setRtcm3DebugHandler,
34
37
  updateStationMeta: () => updateStationMeta,
35
38
  updateStreamStats: () => updateStreamStats
36
39
  });
37
40
  module.exports = __toCommonJS(rtcm3_exports);
38
41
 
39
42
  // src/rtcm3/decoder.ts
43
+ var debugHandler = null;
44
+ function setRtcm3DebugHandler(fn) {
45
+ debugHandler = fn;
46
+ }
47
+ function reportDecodeError(context, error) {
48
+ if (debugHandler) debugHandler(context, error);
49
+ }
40
50
  var BitReader = class {
41
51
  data;
42
52
  bitPos = 0;
@@ -571,38 +581,66 @@ function decodeEphemeris(frame) {
571
581
  default:
572
582
  return null;
573
583
  }
574
- } catch {
584
+ } catch (err) {
585
+ reportDecodeError("ephemeris", err);
575
586
  return null;
576
587
  }
577
588
  }
578
589
 
579
590
  // src/constants/gnss.ts
580
591
  var C_LIGHT = 299792458;
592
+ var FREQ = {
593
+ G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
594
+ // R bands 4/6 are the CDMA L1OC/L2OC center frequencies
595
+ R: { "3": 1202025e3, "4": 1600995e3, "6": 124806e4 },
596
+ E: {
597
+ "1": 157542e4,
598
+ "5": 117645e4,
599
+ "6": 127875e4,
600
+ "7": 120714e4,
601
+ "8": 1191795e3
602
+ },
603
+ C: {
604
+ "1": 157542e4,
605
+ "2": 1561098e3,
606
+ "5": 117645e4,
607
+ "6": 126852e4,
608
+ "7": 120714e4
609
+ },
610
+ J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
611
+ I: { "5": 117645e4, "9": 2492028e3 },
612
+ S: { "1": 157542e4, "5": 117645e4 }
613
+ };
581
614
  var GLO_F1_BASE = 1602e6;
582
615
  var GLO_F1_STEP = 562500;
583
616
  var GLO_F2_BASE = 1246e6;
584
617
  var GLO_F2_STEP = 437500;
585
618
 
619
+ // src/constants/time.ts
620
+ var MILLISECONDS_IN_WEEK = 6048e5;
621
+ var START_GPS_TIME = /* @__PURE__ */ new Date("1980-01-06T00:00:00Z");
622
+ var START_BDS_TIME = /* @__PURE__ */ new Date("2006-01-01T00:00:14Z");
623
+
586
624
  // src/rtcm3/msm.ts
587
- var GPS_L1 = 157542e4;
588
- var GPS_L2 = 12276e5;
589
- var GPS_L5 = 117645e4;
590
- var GLO_L1a = 1600995e3;
591
- var GLO_L2a = 124806e4;
592
- var GLO_L3 = 1202025e3;
593
- var GAL_E1 = 157542e4;
594
- var GAL_E5a = 117645e4;
595
- var GAL_E5b = 120714e4;
596
- var GAL_E5 = 1191795e3;
597
- var GAL_E6 = 127875e4;
598
- var BDS_B1 = 1561098e3;
599
- var BDS_B3 = 126852e4;
600
- var BDS_B2 = 120714e4;
601
- var BDS_B1C = 157542e4;
602
- var BDS_B2a = 117645e4;
603
- var BDS_B2b = 120714e4;
604
- var QZSS_L6 = 127875e4;
605
- var NAVIC_S = 2492028e3;
625
+ var GPS_L1 = FREQ.G["1"];
626
+ var GPS_L2 = FREQ.G["2"];
627
+ var GPS_L5 = FREQ.G["5"];
628
+ var GLO_L1a = FREQ.R["4"];
629
+ var GLO_L2a = FREQ.R["6"];
630
+ var GLO_L3 = FREQ.R["3"];
631
+ var GAL_E1 = FREQ.E["1"];
632
+ var GAL_E5a = FREQ.E["5"];
633
+ var GAL_E5b = FREQ.E["7"];
634
+ var GAL_E5 = FREQ.E["8"];
635
+ var GAL_E6 = FREQ.E["6"];
636
+ var BDS_B1 = FREQ.C["2"];
637
+ var BDS_B3 = FREQ.C["6"];
638
+ var BDS_B2 = FREQ.C["7"];
639
+ var BDS_B1C = FREQ.C["1"];
640
+ var BDS_B2a = FREQ.C["5"];
641
+ var BDS_B2b = FREQ.C["7"];
642
+ var QZSS_L6 = FREQ.J["6"];
643
+ var NAVIC_S = FREQ.I["9"];
606
644
  var EMPTY = { code: "", freq: 0 };
607
645
  function sd(code, freq) {
608
646
  return { code, freq };
@@ -854,40 +892,6 @@ function signalTable(sys) {
854
892
  return GPS_SIGNALS;
855
893
  }
856
894
  }
857
- var BitReader2 = class {
858
- data;
859
- pos;
860
- constructor(data, startBit = 0) {
861
- this.data = data;
862
- this.pos = startBit;
863
- }
864
- /** Read unsigned value of numBits bits (max 53) */
865
- u(numBits) {
866
- let val = 0;
867
- for (let i = 0; i < numBits; i++) {
868
- const byteIdx = this.pos + i >>> 3;
869
- const bitIdx = 7 - (this.pos + i & 7);
870
- const bit = byteIdx < this.data.length ? this.data[byteIdx] >>> bitIdx & 1 : 0;
871
- val = val * 2 + bit;
872
- }
873
- this.pos += numBits;
874
- return val;
875
- }
876
- /** Read signed value (two's complement) */
877
- s(numBits) {
878
- const raw = this.u(numBits);
879
- const half = 2 ** (numBits - 1);
880
- return raw >= half ? raw - 2 ** numBits : raw;
881
- }
882
- /** Skip bits */
883
- skip(n) {
884
- this.pos += n;
885
- }
886
- /** Current bit position */
887
- get position() {
888
- return this.pos;
889
- }
890
- };
891
895
  var gloFreqNum = new Int8Array(64).fill(-128);
892
896
  function gloWavelength(satIdx, freqMarker) {
893
897
  const k = gloFreqNum[satIdx];
@@ -922,28 +926,9 @@ function lockTimeSec(msmType, lti) {
922
926
  if (variant <= 5) {
923
927
  return LTI_TABLE_4BIT[lti] ?? 0;
924
928
  }
925
- if (lti < 64) return lti;
926
- if (lti < 96) return (lti - 64) * 2 + 64;
927
- if (lti < 128) return (lti - 96) * 4 + 128;
928
- if (lti < 160) return (lti - 128) * 8 + 256;
929
- if (lti < 192) return (lti - 160) * 16 + 512;
930
- if (lti < 224) return (lti - 192) * 32 + 1024;
931
- if (lti < 256) return (lti - 224) * 64 + 2048;
932
- if (lti < 288) return (lti - 256) * 128 + 4096;
933
- if (lti < 320) return (lti - 288) * 256 + 8192;
934
- if (lti < 352) return (lti - 320) * 512 + 16384;
935
- if (lti < 384) return (lti - 352) * 1024 + 32768;
936
- if (lti < 416) return (lti - 384) * 2048 + 65536;
937
- if (lti < 448) return (lti - 416) * 4096 + 131072;
938
- if (lti < 480) return (lti - 448) * 8192 + 262144;
939
- if (lti < 512) return (lti - 480) * 16384 + 524288;
940
- if (lti < 544) return (lti - 512) * 32768 + 1048576;
941
- if (lti < 576) return (lti - 544) * 65536 + 2097152;
942
- if (lti < 608) return (lti - 576) * 131072 + 4194304;
943
- if (lti < 640) return (lti - 608) * 262144 + 8388608;
944
- if (lti < 672) return (lti - 640) * 524288 + 16777216;
945
- if (lti < 704) return (lti - 672) * 1048576 + 33554432;
946
- return (lti - 704) * 2097152 + 67108864;
929
+ if (lti < 64) return lti / 1e3;
930
+ const n = Math.min(20, Math.floor((lti - 64) / 32));
931
+ return ((lti - 64 - 32 * n) * 2 ** (n + 1) + 2 ** (n + 6)) / 1e3;
947
932
  }
948
933
  function msmSystem(type) {
949
934
  if (type >= 1071 && type <= 1077) return "G";
@@ -969,10 +954,10 @@ function decodeMsmFull(frame) {
969
954
  const payload = frame.payload;
970
955
  if (!payload || payload.length < 10) return null;
971
956
  try {
972
- const bits = new BitReader2(payload);
957
+ const bits = new BitReader(payload);
973
958
  bits.skip(12);
974
959
  bits.skip(12);
975
- const epochMs = bits.u(30);
960
+ const epochMs = bits.readU(30);
976
961
  bits.skip(1);
977
962
  bits.skip(3);
978
963
  bits.skip(7);
@@ -980,8 +965,8 @@ function decodeMsmFull(frame) {
980
965
  bits.skip(2);
981
966
  bits.skip(1);
982
967
  bits.skip(3);
983
- const satMaskHi = bits.u(32) >>> 0;
984
- const satMaskLo = bits.u(32) >>> 0;
968
+ const satMaskHi = bits.readU(32) >>> 0;
969
+ const satMaskLo = bits.readU(32) >>> 0;
985
970
  const satIndices = [];
986
971
  for (let i = 0; i < 32; i++) {
987
972
  if (satMaskHi & 1 << 31 - i) satIndices.push(i + 1);
@@ -991,7 +976,7 @@ function decodeMsmFull(frame) {
991
976
  }
992
977
  const numSat = satIndices.length;
993
978
  if (numSat === 0) return null;
994
- const sigMask = bits.u(32) >>> 0;
979
+ const sigMask = bits.readU(32) >>> 0;
995
980
  const sigIndices = [];
996
981
  for (let i = 0; i < 32; i++) {
997
982
  if (sigMask & 1 << 31 - i) sigIndices.push(i);
@@ -1001,7 +986,7 @@ function decodeMsmFull(frame) {
1001
986
  const numCells = numSat * numSig;
1002
987
  const cellMask = [];
1003
988
  for (let i = 0; i < numCells; i++) {
1004
- cellMask.push(bits.u(1) === 1);
989
+ cellMask.push(bits.readU(1) === 1);
1005
990
  }
1006
991
  let activeCells = 0;
1007
992
  for (const c of cellMask) if (c) activeCells++;
@@ -1011,13 +996,13 @@ function decodeMsmFull(frame) {
1011
996
  const extsat = new Int8Array(numSat);
1012
997
  const rdop = new Float64Array(numSat);
1013
998
  if (variant === 4 || variant === 6) {
1014
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
1015
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
999
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
1000
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
1016
1001
  } else {
1017
- for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
1018
- for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
1019
- for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
1020
- for (let j = 0; j < numSat; j++) rdop[j] = bits.s(14) * 1;
1002
+ for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
1003
+ for (let j = 0; j < numSat; j++) extsat[j] = bits.readU(4);
1004
+ for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
1005
+ for (let j = 0; j < numSat; j++) rdop[j] = bits.readS(14) * 1;
1021
1006
  }
1022
1007
  if (sys === "R") {
1023
1008
  for (let j = 0; j < numSat; j++) {
@@ -1037,31 +1022,31 @@ function decodeMsmFull(frame) {
1037
1022
  cp.fill(-1e30);
1038
1023
  dop.fill(-1e30);
1039
1024
  if (variant === 4) {
1040
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
1041
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
1042
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
1043
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1044
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
1025
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
1026
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
1027
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
1028
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1029
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
1045
1030
  } else if (variant === 5) {
1046
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
1047
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
1048
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
1049
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1050
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
1051
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
1031
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
1032
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
1033
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
1034
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1035
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(6);
1036
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
1052
1037
  } else if (variant === 6) {
1053
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
1054
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
1055
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
1056
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1057
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
1038
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
1039
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
1040
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
1041
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1042
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
1058
1043
  } else {
1059
- for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
1060
- for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
1061
- for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
1062
- for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
1063
- for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
1064
- for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
1044
+ for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(20) / 2 ** 29;
1045
+ for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(24) / 2 ** 31;
1046
+ for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(10);
1047
+ for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
1048
+ for (let i = 0; i < activeCells; i++) cnr[i] = bits.readU(10) / 16;
1049
+ for (let i = 0; i < activeCells; i++) dop[i] = bits.readS(15) * 1e-4;
1065
1050
  }
1066
1051
  const sigTable = signalTable(sys);
1067
1052
  const observations = [];
@@ -1095,11 +1080,11 @@ function decodeMsmFull(frame) {
1095
1080
  wavelength
1096
1081
  };
1097
1082
  const psrVal = psr[cellIdx];
1098
- if (psrVal > -1 / (1 << 10)) {
1083
+ if (psrVal > -(2 ** -10)) {
1099
1084
  signal.pseudorange = psrVal * C_LIGHT / 1e3 + roughRange_m;
1100
1085
  }
1101
1086
  const cpVal = cp[cellIdx];
1102
- if (cpVal > -1 / (1 << 8) && wavelength > 0) {
1087
+ if (cpVal > -(2 ** -8) && wavelength > 0) {
1103
1088
  signal.phase = cpVal * C_LIGHT / 1e3 / wavelength + roughRange_m / wavelength;
1104
1089
  }
1105
1090
  if (variant === 5 || variant === 7) {
@@ -1127,12 +1112,13 @@ function decodeMsmFull(frame) {
1127
1112
  system: sys,
1128
1113
  observations
1129
1114
  };
1130
- } catch {
1115
+ } catch (err) {
1116
+ reportDecodeError("msm", err);
1131
1117
  return null;
1132
1118
  }
1133
1119
  }
1134
- var GPS_EPOCH = Date.UTC(1980, 0, 6);
1135
- var MS_PER_WEEK = 6048e5;
1120
+ var GPS_EPOCH = START_GPS_TIME.getTime();
1121
+ var MS_PER_WEEK = MILLISECONDS_IN_WEEK;
1136
1122
  function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1137
1123
  const refMs = refTime.getTime();
1138
1124
  if (sys === "R") {
@@ -1147,11 +1133,12 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1147
1133
  return new Date(t2);
1148
1134
  }
1149
1135
  if (sys === "C") {
1150
- const BDS_EPOCH = Date.UTC(2006, 0, 1) - 14e3;
1136
+ const BDS_EPOCH = START_BDS_TIME.getTime();
1151
1137
  const weeksSinceEpoch2 = Math.floor((refMs - BDS_EPOCH) / MS_PER_WEEK);
1152
1138
  let t2 = BDS_EPOCH + weeksSinceEpoch2 * MS_PER_WEEK + epochMs;
1153
1139
  if (t2 - refMs > MS_PER_WEEK / 2) t2 -= MS_PER_WEEK;
1154
1140
  else if (refMs - t2 > MS_PER_WEEK / 2) t2 += MS_PER_WEEK;
1141
+ t2 -= 18e3;
1155
1142
  return new Date(t2);
1156
1143
  }
1157
1144
  const weeksSinceEpoch = Math.floor((refMs - GPS_EPOCH) / MS_PER_WEEK);
@@ -1161,6 +1148,11 @@ function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
1161
1148
  t -= 18e3;
1162
1149
  return new Date(t);
1163
1150
  }
1151
+ function setGloFreqNumber(slot, k) {
1152
+ if (slot >= 1 && slot <= 64 && k >= -7 && k <= 13) {
1153
+ gloFreqNum[slot - 1] = k;
1154
+ }
1155
+ }
1164
1156
  function resetGloFreqCache() {
1165
1157
  gloFreqNum.fill(-128);
1166
1158
  }
@@ -1294,7 +1286,8 @@ function updateStationMeta(meta, frame) {
1294
1286
  default:
1295
1287
  return false;
1296
1288
  }
1297
- } catch {
1289
+ } catch (err) {
1290
+ reportDecodeError("station", err);
1298
1291
  return false;
1299
1292
  }
1300
1293
  }
@@ -1482,6 +1475,9 @@ function updateStreamStats(stats, frames, rawBytes) {
1482
1475
  const eph = decodeEphemeris(frame);
1483
1476
  if (eph) {
1484
1477
  stats.ephemerides.set(eph.prn, eph);
1478
+ if (eph.freqChannel !== void 0 && eph.prn.startsWith("R")) {
1479
+ setGloFreqNumber(parseInt(eph.prn.slice(1), 10), eph.freqChannel);
1480
+ }
1485
1481
  }
1486
1482
  updateStationMeta(stats.stationMeta, frame);
1487
1483
  }
@@ -1505,8 +1501,11 @@ function updateStreamStats(stats, frames, rawBytes) {
1505
1501
  decodeMsmFull,
1506
1502
  msmEpochToDate,
1507
1503
  readString,
1504
+ reportDecodeError,
1508
1505
  resetGloFreqCache,
1509
1506
  rtcm3Constellation,
1507
+ setGloFreqNumber,
1508
+ setRtcm3DebugHandler,
1510
1509
  updateStationMeta,
1511
1510
  updateStreamStats
1512
1511
  });
package/dist/rtcm3.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-C10stHhM.cjs';
2
- export { B as BitReader, R as Rtcm3Decoder, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.cjs';
1
+ import { b as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-Ohl6NAfw.cjs';
2
+ export { B as BitReader, R as Rtcm3DebugHandler, a as Rtcm3Decoder, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
3
3
 
4
4
  /**
5
5
  * Full RTCM3 MSM4-7 decoder — extracts pseudorange, carrier phase,
@@ -63,6 +63,12 @@ declare function decodeMsmFull(frame: Rtcm3Frame): MsmEpoch | null;
63
63
  * Requires an approximate reference time to resolve the current week.
64
64
  */
65
65
  declare function msmEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
66
+ /**
67
+ * Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
68
+ * e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
69
+ * this the wavelength — and hence carrier phase — stays unknown.
70
+ */
71
+ declare function setGloFreqNumber(slot: number, k: number): void;
66
72
  /**
67
73
  * Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
68
74
  */
@@ -140,4 +146,4 @@ declare function rtcm3Constellation(msgType: number): string | null;
140
146
  declare function createStreamStats(): StreamStats;
141
147
  declare function updateStreamStats(stats: StreamStats, frames: Rtcm3Frame[], rawBytes: number): void;
142
148
 
143
- export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats };
149
+ export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats };
package/dist/rtcm3.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-C10stHhM.js';
2
- export { B as BitReader, R as Rtcm3Decoder, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.js';
1
+ import { b as Rtcm3Frame, E as EphemerisInfo } from './ephemeris-Ohl6NAfw.js';
2
+ export { B as BitReader, R as Rtcm3DebugHandler, a as Rtcm3Decoder, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
3
3
 
4
4
  /**
5
5
  * Full RTCM3 MSM4-7 decoder — extracts pseudorange, carrier phase,
@@ -63,6 +63,12 @@ declare function decodeMsmFull(frame: Rtcm3Frame): MsmEpoch | null;
63
63
  * Requires an approximate reference time to resolve the current week.
64
64
  */
65
65
  declare function msmEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
66
+ /**
67
+ * Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
68
+ * e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
69
+ * this the wavelength — and hence carrier phase — stays unknown.
70
+ */
71
+ declare function setGloFreqNumber(slot: number, k: number): void;
66
72
  /**
67
73
  * Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
68
74
  */
@@ -140,4 +146,4 @@ declare function rtcm3Constellation(msgType: number): string | null;
140
146
  declare function createStreamStats(): StreamStats;
141
147
  declare function updateStreamStats(stats: StreamStats, frames: Rtcm3Frame[], rawBytes: number): void;
142
148
 
143
- export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats };
149
+ export { EphemerisInfo, type MessageTypeStats, type MsmEpoch, type MsmSatObs, type MsmSignal, RTCM3_MESSAGE_NAMES, Rtcm3Frame, type SatCn0, type SignalCn0, type StationMeta, type StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats };