gnss-js 2.1.0 → 2.3.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
@@ -116,6 +116,7 @@ __export(src_exports, {
116
116
  almanacEpochMs: () => almanacEpochMs,
117
117
  almanacSatPosition: () => almanacSatPosition,
118
118
  analyzeQuality: () => analyzeQuality,
119
+ antexFreqOfGroup: () => antexFreqOfGroup,
119
120
  applyHelmert: () => applyHelmert,
120
121
  applyIonoDcb: () => applyIonoDcb,
121
122
  applyOrbitClock: () => applyOrbitClock,
@@ -127,6 +128,7 @@ __export(src_exports, {
127
128
  buildGloChannelMap: () => buildGloChannelMap,
128
129
  buildObsIndices: () => buildObsIndices,
129
130
  buildPppAntenna: () => buildPppAntenna,
131
+ buildRtkAntenna: () => buildRtkAntenna,
130
132
  clampUnit: () => clampUnit,
131
133
  clkBias: () => clkBias,
132
134
  computeAllPositions: () => computeAllPositions,
@@ -309,6 +311,7 @@ __export(src_exports, {
309
311
  postProcessRtk: () => postProcessRtk,
310
312
  rad2deg: () => rad2deg,
311
313
  rangeRate: () => rangeRate,
314
+ rcvAntennaRangeM: () => rcvAntennaRangeM,
312
315
  readString: () => readString,
313
316
  reportDecodeError: () => reportDecodeError,
314
317
  resetGloFreqCache: () => resetGloFreqCache,
@@ -6572,7 +6575,8 @@ function updateStreamStats(stats, frames, rawBytes) {
6572
6575
  stats.satellites.set(obs.prn, {
6573
6576
  prn: obs.prn,
6574
6577
  system: obs.system,
6575
- cn0: bestCn0,
6578
+ cn0: bestCn0 > 0 ? bestCn0 : null,
6579
+ // null = no C/N0 reported
6576
6580
  lastSeen: now,
6577
6581
  signals
6578
6582
  });
@@ -13225,6 +13229,211 @@ function lambdaReduction(Q, n) {
13225
13229
  return Z2;
13226
13230
  }
13227
13231
 
13232
+ // src/positioning/ppp-antenna.ts
13233
+ function parseAntexTime(s) {
13234
+ const p = s.trim().split(/\s+/).map(Number);
13235
+ if (p.length < 3 || p.some((v) => Number.isNaN(v))) return null;
13236
+ return Date.UTC(
13237
+ p[0],
13238
+ (p[1] || 1) - 1,
13239
+ p[2] || 1,
13240
+ p[3] ?? 0,
13241
+ p[4] ?? 0,
13242
+ Math.floor(p[5] ?? 0)
13243
+ );
13244
+ }
13245
+ function freqOf(entry, code) {
13246
+ return entry.frequencies.find((f) => f.frequency === code);
13247
+ }
13248
+ function combineIf(fA, fB, f1, f2) {
13249
+ const g = f1 * f1 / (f1 * f1 - f2 * f2);
13250
+ const mm = 1e-3;
13251
+ const pco = [
13252
+ (g * fA.pcoN - (g - 1) * fB.pcoN) * mm,
13253
+ (g * fA.pcoE - (g - 1) * fB.pcoE) * mm,
13254
+ (g * fA.pcoU - (g - 1) * fB.pcoU) * mm
13255
+ ];
13256
+ const nz = Math.min(fA.pcvNoazi.length, fB.pcvNoazi.length);
13257
+ const pcvNoazi = new Array(nz);
13258
+ for (let i = 0; i < nz; i++) {
13259
+ pcvNoazi[i] = (g * fA.pcvNoazi[i] - (g - 1) * fB.pcvNoazi[i]) * mm;
13260
+ }
13261
+ return { pco, pcvZen1Deg: 0, pcvDzenDeg: 0, pcvNoazi };
13262
+ }
13263
+ function buildPppAntenna(antex) {
13264
+ const sats = /* @__PURE__ */ new Map();
13265
+ const rcvs = /* @__PURE__ */ new Map();
13266
+ for (const a of antex.antennas) {
13267
+ if (a.isSatellite) {
13268
+ const list = sats.get(a.serialNo) ?? [];
13269
+ list.push(a);
13270
+ sats.set(a.serialNo, list);
13271
+ } else if (!rcvs.has(a.type)) {
13272
+ rcvs.set(a.type, a);
13273
+ }
13274
+ }
13275
+ const withZen = (entry, off) => ({
13276
+ ...off,
13277
+ pcvZen1Deg: entry.zen1,
13278
+ pcvDzenDeg: entry.dzen
13279
+ });
13280
+ return {
13281
+ satOffset(prn, dateMs, band1, band2, f1, f2) {
13282
+ const list = sats.get(prn);
13283
+ if (!list) return null;
13284
+ const entry = list.find((e) => {
13285
+ const from = parseAntexTime(e.validFrom);
13286
+ const until = parseAntexTime(e.validUntil);
13287
+ return (from == null || dateMs >= from) && (until == null || dateMs <= until);
13288
+ });
13289
+ if (!entry) return null;
13290
+ const a = freqOf(entry, band1);
13291
+ const b = freqOf(entry, band2);
13292
+ if (!a || !b) return null;
13293
+ return withZen(entry, combineIf(a, b, f1, f2));
13294
+ },
13295
+ rcvOffset(antType, band1, band2, f1, f2) {
13296
+ const entry = rcvs.get(antType);
13297
+ if (!entry) return null;
13298
+ const a = freqOf(entry, band1);
13299
+ const b = freqOf(entry, band2);
13300
+ if (!a || !b) return null;
13301
+ return withZen(entry, combineIf(a, b, f1, f2));
13302
+ }
13303
+ };
13304
+ }
13305
+ function cross(a, b) {
13306
+ return [
13307
+ a[1] * b[2] - a[2] * b[1],
13308
+ a[2] * b[0] - a[0] * b[2],
13309
+ a[0] * b[1] - a[1] * b[0]
13310
+ ];
13311
+ }
13312
+ function norm(a) {
13313
+ const n = Math.hypot(a[0], a[1], a[2]) || 1;
13314
+ return [a[0] / n, a[1] / n, a[2] / n];
13315
+ }
13316
+ function dot(a, b) {
13317
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
13318
+ }
13319
+ function satBodyFrame(satEcef, sunEcef2) {
13320
+ const z = norm([-satEcef[0], -satEcef[1], -satEcef[2]]);
13321
+ const eSun = norm([
13322
+ sunEcef2[0] - satEcef[0],
13323
+ sunEcef2[1] - satEcef[1],
13324
+ sunEcef2[2] - satEcef[2]
13325
+ ]);
13326
+ const y = norm(cross(z, eSun));
13327
+ const x = norm(cross(y, z));
13328
+ return { x, y, z };
13329
+ }
13330
+ function satPcoToEcef(pcoBody, frame) {
13331
+ return [
13332
+ pcoBody[0] * frame.x[0] + pcoBody[1] * frame.y[0] + pcoBody[2] * frame.z[0],
13333
+ pcoBody[0] * frame.x[1] + pcoBody[1] * frame.y[1] + pcoBody[2] * frame.z[1],
13334
+ pcoBody[0] * frame.x[2] + pcoBody[1] * frame.y[2] + pcoBody[2] * frame.z[2]
13335
+ ];
13336
+ }
13337
+ function enuToEcef(enu, latRad, lonRad) {
13338
+ const sl = Math.sin(latRad);
13339
+ const cl = Math.cos(latRad);
13340
+ const so = Math.sin(lonRad);
13341
+ const co = Math.cos(lonRad);
13342
+ const [e, n, u] = enu;
13343
+ return [
13344
+ -so * e - sl * co * n + cl * co * u,
13345
+ co * e - sl * so * n + cl * so * u,
13346
+ cl * n + sl * u
13347
+ ];
13348
+ }
13349
+ function interpPcv(off, angleDeg) {
13350
+ const { pcvZen1Deg, pcvDzenDeg, pcvNoazi } = off;
13351
+ if (pcvDzenDeg <= 0 || pcvNoazi.length < 2) return 0;
13352
+ const x = (angleDeg - pcvZen1Deg) / pcvDzenDeg;
13353
+ if (x <= 0) return pcvNoazi[0];
13354
+ if (x >= pcvNoazi.length - 1) return pcvNoazi[pcvNoazi.length - 1];
13355
+ const i = Math.floor(x);
13356
+ const t = x - i;
13357
+ return pcvNoazi[i] * (1 - t) + pcvNoazi[i + 1] * t;
13358
+ }
13359
+ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
13360
+ const k = [
13361
+ -losRcvToSat[0],
13362
+ -losRcvToSat[1],
13363
+ -losRcvToSat[2]
13364
+ ];
13365
+ const kx = satFrame.x;
13366
+ const ky = satFrame.y;
13367
+ const kdotx = dot(k, kx);
13368
+ const kcrossY = cross(k, ky);
13369
+ const dS = [
13370
+ kx[0] - k[0] * kdotx - kcrossY[0],
13371
+ kx[1] - k[1] * kdotx - kcrossY[1],
13372
+ kx[2] - k[2] * kdotx - kcrossY[2]
13373
+ ];
13374
+ const north = enuToEcef([0, 1, 0], latRad, lonRad);
13375
+ const east = enuToEcef([1, 0, 0], latRad, lonRad);
13376
+ const kdotn = dot(k, north);
13377
+ const kcrossE = cross(k, east);
13378
+ const dR = [
13379
+ north[0] - k[0] * kdotn + kcrossE[0],
13380
+ north[1] - k[1] * kdotn + kcrossE[1],
13381
+ north[2] - k[2] * kdotn + kcrossE[2]
13382
+ ];
13383
+ const nS = Math.hypot(dS[0], dS[1], dS[2]) || 1;
13384
+ const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
13385
+ let cosPhi = dot(dS, dR) / (nS * nR);
13386
+ cosPhi = Math.max(-1, Math.min(1, cosPhi));
13387
+ const zeta = cross(dS, dR);
13388
+ const sign = dot(k, zeta) >= 0 ? 1 : -1;
13389
+ const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
13390
+ const prev = state.get(prn);
13391
+ const wu = prev == null ? dphi : dphi + Math.round(prev - dphi);
13392
+ state.set(prn, wu);
13393
+ return wu;
13394
+ }
13395
+
13396
+ // src/positioning/rtk-antenna.ts
13397
+ function freqOf2(entry, code) {
13398
+ return entry.frequencies.find((f) => f.frequency === code);
13399
+ }
13400
+ function buildRtkAntenna(antex) {
13401
+ const rcvs = /* @__PURE__ */ new Map();
13402
+ for (const a of antex.antennas) {
13403
+ if (!a.isSatellite && !rcvs.has(a.type)) rcvs.set(a.type, a);
13404
+ }
13405
+ const mm = 1e-3;
13406
+ return {
13407
+ rcvOffset(antType, freq) {
13408
+ const entry = rcvs.get(antType);
13409
+ if (!entry) return null;
13410
+ const f = freqOf2(entry, freq);
13411
+ if (!f) return null;
13412
+ return {
13413
+ pco: [f.pcoN * mm, f.pcoE * mm, f.pcoU * mm],
13414
+ pcvZen1Deg: entry.zen1,
13415
+ pcvDzenDeg: entry.dzen,
13416
+ pcvNoazi: f.pcvNoazi.map((v) => v * mm)
13417
+ };
13418
+ }
13419
+ };
13420
+ }
13421
+ function rcvAntennaRangeM(off, losRcvToSat, latRad, lonRad, elRad, antDeltaEnu = [0, 0, 0]) {
13422
+ const total = [
13423
+ off.pco[0] + antDeltaEnu[0],
13424
+ off.pco[1] + antDeltaEnu[1],
13425
+ off.pco[2] + antDeltaEnu[2]
13426
+ ];
13427
+ const ecef = enuToEcef(total, latRad, lonRad);
13428
+ let m = -dot(losRcvToSat, ecef);
13429
+ const zenithDeg = 90 - elRad * 180 / Math.PI;
13430
+ m += interpPcv(off, zenithDeg);
13431
+ return m;
13432
+ }
13433
+ function antexFreqOfGroup(group) {
13434
+ return `${group[0]}0${group[1]}`;
13435
+ }
13436
+
13228
13437
  // src/positioning/rtk.ts
13229
13438
  var L1_CODES = {
13230
13439
  G: ["1C"],
@@ -13290,8 +13499,16 @@ function resolveEphemeris(src, prn, timeMs) {
13290
13499
  return selectEphemeris(src, prn, timeMs);
13291
13500
  return src.get(prn) ?? null;
13292
13501
  }
13293
- function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, troposphere) {
13502
+ var ZERO_DELTA = [0, 0, 0];
13503
+ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, troposphere, antenna = null) {
13294
13504
  const out = [];
13505
+ let baseLatRad = 0;
13506
+ let baseLonRad = 0;
13507
+ if (antenna?.base) {
13508
+ const [latDeg, lonDeg] = ecefToGeodetic(basePos[0], basePos[1], basePos[2]);
13509
+ baseLatRad = latDeg * Math.PI / 180;
13510
+ baseLonRad = lonDeg * Math.PI / 180;
13511
+ }
13295
13512
  for (const [prn, mR] of rover) {
13296
13513
  const sys = prn[0];
13297
13514
  if (!"GERCJ".includes(sys)) continue;
@@ -13316,14 +13533,43 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
13316
13533
  satB.z - basePos[2]
13317
13534
  ) / C_LIGHT;
13318
13535
  const [bx, by, bz] = sagnac(satB, travelB);
13319
- const rhoB = Math.hypot(bx - basePos[0], by - basePos[1], bz - basePos[2]);
13536
+ let rhoB = Math.hypot(bx - basePos[0], by - basePos[1], bz - basePos[2]);
13320
13537
  const elB = ecefToAzEl(basePos[0], basePos[1], basePos[2], bx, by, bz).el;
13321
13538
  if (elB < maskRad) continue;
13539
+ const group = sys + mR.code;
13540
+ let offR = null;
13541
+ let roverDelta = ZERO_DELTA;
13542
+ if (antenna) {
13543
+ const antexFreq = antexFreqOfGroup(group);
13544
+ if (antenna.base) {
13545
+ const offB = antenna.model.rcvOffset(antenna.base.type, antexFreq);
13546
+ if (offB) {
13547
+ const inv = 1 / rhoB;
13548
+ const losB = [
13549
+ (bx - basePos[0]) * inv,
13550
+ (by - basePos[1]) * inv,
13551
+ (bz - basePos[2]) * inv
13552
+ ];
13553
+ rhoB += rcvAntennaRangeM(
13554
+ offB,
13555
+ losB,
13556
+ baseLatRad,
13557
+ baseLonRad,
13558
+ elB,
13559
+ antenna.base.deltaEnu
13560
+ );
13561
+ }
13562
+ }
13563
+ if (antenna.rover) {
13564
+ offR = antenna.model.rcvOffset(antenna.rover.type, antexFreq);
13565
+ roverDelta = antenna.rover.deltaEnu ?? ZERO_DELTA;
13566
+ }
13567
+ }
13322
13568
  const gloK = sys === "R" ? mR.gloChannel ?? mB.gloChannel ?? eph.freqNum ?? null : null;
13323
13569
  const freq = carrierFreqHz(sys, mR.code, gloK);
13324
13570
  out.push({
13325
13571
  prn,
13326
- group: sys + mR.code,
13572
+ group,
13327
13573
  lambda: freq > 0 ? C_LIGHT / freq : 0,
13328
13574
  satR,
13329
13575
  rhoB,
@@ -13334,7 +13580,9 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
13334
13580
  cpR: mR.cp ?? null,
13335
13581
  cpB: mB.cp ?? null,
13336
13582
  lockR: mR.lockTimeMs,
13337
- lockB: mB.lockTimeMs
13583
+ lockB: mB.lockTimeMs,
13584
+ offR,
13585
+ roverDelta
13338
13586
  });
13339
13587
  }
13340
13588
  return out;
@@ -13342,17 +13590,29 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
13342
13590
  function roverTerms(g, x, y, z, troposphere) {
13343
13591
  const travel = Math.hypot(g.satR.x - x, g.satR.y - y, g.satR.z - z) / C_LIGHT;
13344
13592
  const [sx, sy, sz] = sagnac(g.satR, travel);
13345
- const rho = Math.hypot(sx - x, sy - y, sz - z);
13593
+ let rho = Math.hypot(sx - x, sy - y, sz - z);
13346
13594
  const u = [
13347
13595
  (x - sx) / rho,
13348
13596
  (y - sy) / rho,
13349
13597
  (z - sz) / rho
13350
13598
  ];
13599
+ const needEl = troposphere || g.offR != null;
13600
+ const elR = needEl ? ecefToAzEl(x, y, z, sx, sy, sz).el : 0;
13351
13601
  let dTropo = 0;
13352
13602
  if (troposphere) {
13353
- const elR = ecefToAzEl(x, y, z, sx, sy, sz).el;
13354
13603
  dTropo = tropoDelay(Math.max(elR, 0.05)) - g.tropoB;
13355
13604
  }
13605
+ if (g.offR) {
13606
+ const [latDeg, lonDeg] = ecefToGeodetic(x, y, z);
13607
+ rho += rcvAntennaRangeM(
13608
+ g.offR,
13609
+ [-u[0], -u[1], -u[2]],
13610
+ latDeg * Math.PI / 180,
13611
+ lonDeg * Math.PI / 180,
13612
+ elR,
13613
+ g.roverDelta
13614
+ );
13615
+ }
13356
13616
  return { rho, u, dTropo };
13357
13617
  }
13358
13618
  function sdVariance(sigmaM, elRad) {
@@ -13591,7 +13851,8 @@ var RtkFloatEngine = class {
13591
13851
  arElevationMaskDeg: opts.arElevationMaskDeg ?? 0,
13592
13852
  glonassAr: opts.glonassAr ?? false,
13593
13853
  partialFixing: opts.partialFixing ?? true,
13594
- minFixAmbiguities: opts.minFixAmbiguities ?? 4
13854
+ minFixAmbiguities: opts.minFixAmbiguities ?? 4,
13855
+ antenna: opts.antenna ?? null
13595
13856
  };
13596
13857
  }
13597
13858
  /** Clear all filter state (position, ambiguities, lock history). */
@@ -13714,7 +13975,8 @@ var RtkFloatEngine = class {
13714
13975
  this.ephemerides,
13715
13976
  timeMs,
13716
13977
  o.elevationMaskDeg * Math.PI / 180,
13717
- o.troposphere
13978
+ o.troposphere,
13979
+ o.antenna
13718
13980
  );
13719
13981
  const byPrn = new Map(geom.map((g) => [g.prn, g]));
13720
13982
  const dtS = this.lastMs !== null ? (timeMs - this.lastMs) / 1e3 : 0;
@@ -14842,14 +15104,14 @@ var SbasProcessor = class {
14842
15104
  };
14843
15105
 
14844
15106
  // src/positioning/ssr-apply.ts
14845
- var cross = (a, b) => [
15107
+ var cross2 = (a, b) => [
14846
15108
  a[1] * b[2] - a[2] * b[1],
14847
15109
  a[2] * b[0] - a[0] * b[2],
14848
15110
  a[0] * b[1] - a[1] * b[0]
14849
15111
  ];
14850
- var norm = (a) => Math.hypot(a[0], a[1], a[2]);
15112
+ var norm2 = (a) => Math.hypot(a[0], a[1], a[2]);
14851
15113
  var unit = (a) => {
14852
- const n = norm(a);
15114
+ const n = norm2(a);
14853
15115
  return n > 0 ? [a[0] / n, a[1] / n, a[2] / n] : [0, 0, 0];
14854
15116
  };
14855
15117
  function applyOrbitClock(eph, corr, timeMs) {
@@ -14863,8 +15125,8 @@ function applyOrbitClock(eph, corr, timeMs) {
14863
15125
  const p = [s.x, s.y, s.z];
14864
15126
  const v = [s.vx, s.vy, s.vz];
14865
15127
  const er = unit(p);
14866
- const en = unit(cross(p, v));
14867
- const ea = cross(en, er);
15128
+ const en = unit(cross2(p, v));
15129
+ const ea = cross2(en, er);
14868
15130
  const dr = corr.radial + (corr.dotRadial ?? 0) * age;
14869
15131
  const da = corr.along + (corr.dotAlong ?? 0) * age;
14870
15132
  const dc = corr.cross + (corr.dotCross ?? 0) * age;
@@ -15074,170 +15336,6 @@ function solidEarthTide(rcv, sun, moon) {
15074
15336
  return disp;
15075
15337
  }
15076
15338
 
15077
- // src/positioning/ppp-antenna.ts
15078
- function parseAntexTime(s) {
15079
- const p = s.trim().split(/\s+/).map(Number);
15080
- if (p.length < 3 || p.some((v) => Number.isNaN(v))) return null;
15081
- return Date.UTC(
15082
- p[0],
15083
- (p[1] || 1) - 1,
15084
- p[2] || 1,
15085
- p[3] ?? 0,
15086
- p[4] ?? 0,
15087
- Math.floor(p[5] ?? 0)
15088
- );
15089
- }
15090
- function freqOf(entry, code) {
15091
- return entry.frequencies.find((f) => f.frequency === code);
15092
- }
15093
- function combineIf(fA, fB, f1, f2) {
15094
- const g = f1 * f1 / (f1 * f1 - f2 * f2);
15095
- const mm = 1e-3;
15096
- const pco = [
15097
- (g * fA.pcoN - (g - 1) * fB.pcoN) * mm,
15098
- (g * fA.pcoE - (g - 1) * fB.pcoE) * mm,
15099
- (g * fA.pcoU - (g - 1) * fB.pcoU) * mm
15100
- ];
15101
- const nz = Math.min(fA.pcvNoazi.length, fB.pcvNoazi.length);
15102
- const pcvNoazi = new Array(nz);
15103
- for (let i = 0; i < nz; i++) {
15104
- pcvNoazi[i] = (g * fA.pcvNoazi[i] - (g - 1) * fB.pcvNoazi[i]) * mm;
15105
- }
15106
- return { pco, pcvZen1Deg: 0, pcvDzenDeg: 0, pcvNoazi };
15107
- }
15108
- function buildPppAntenna(antex) {
15109
- const sats = /* @__PURE__ */ new Map();
15110
- const rcvs = /* @__PURE__ */ new Map();
15111
- for (const a of antex.antennas) {
15112
- if (a.isSatellite) {
15113
- const list = sats.get(a.serialNo) ?? [];
15114
- list.push(a);
15115
- sats.set(a.serialNo, list);
15116
- } else if (!rcvs.has(a.type)) {
15117
- rcvs.set(a.type, a);
15118
- }
15119
- }
15120
- const withZen = (entry, off) => ({
15121
- ...off,
15122
- pcvZen1Deg: entry.zen1,
15123
- pcvDzenDeg: entry.dzen
15124
- });
15125
- return {
15126
- satOffset(prn, dateMs, band1, band2, f1, f2) {
15127
- const list = sats.get(prn);
15128
- if (!list) return null;
15129
- const entry = list.find((e) => {
15130
- const from = parseAntexTime(e.validFrom);
15131
- const until = parseAntexTime(e.validUntil);
15132
- return (from == null || dateMs >= from) && (until == null || dateMs <= until);
15133
- });
15134
- if (!entry) return null;
15135
- const a = freqOf(entry, band1);
15136
- const b = freqOf(entry, band2);
15137
- if (!a || !b) return null;
15138
- return withZen(entry, combineIf(a, b, f1, f2));
15139
- },
15140
- rcvOffset(antType, band1, band2, f1, f2) {
15141
- const entry = rcvs.get(antType);
15142
- if (!entry) return null;
15143
- const a = freqOf(entry, band1);
15144
- const b = freqOf(entry, band2);
15145
- if (!a || !b) return null;
15146
- return withZen(entry, combineIf(a, b, f1, f2));
15147
- }
15148
- };
15149
- }
15150
- function cross2(a, b) {
15151
- return [
15152
- a[1] * b[2] - a[2] * b[1],
15153
- a[2] * b[0] - a[0] * b[2],
15154
- a[0] * b[1] - a[1] * b[0]
15155
- ];
15156
- }
15157
- function norm2(a) {
15158
- const n = Math.hypot(a[0], a[1], a[2]) || 1;
15159
- return [a[0] / n, a[1] / n, a[2] / n];
15160
- }
15161
- function dot(a, b) {
15162
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
15163
- }
15164
- function satBodyFrame(satEcef, sunEcef2) {
15165
- const z = norm2([-satEcef[0], -satEcef[1], -satEcef[2]]);
15166
- const eSun = norm2([
15167
- sunEcef2[0] - satEcef[0],
15168
- sunEcef2[1] - satEcef[1],
15169
- sunEcef2[2] - satEcef[2]
15170
- ]);
15171
- const y = norm2(cross2(z, eSun));
15172
- const x = norm2(cross2(y, z));
15173
- return { x, y, z };
15174
- }
15175
- function satPcoToEcef(pcoBody, frame) {
15176
- return [
15177
- pcoBody[0] * frame.x[0] + pcoBody[1] * frame.y[0] + pcoBody[2] * frame.z[0],
15178
- pcoBody[0] * frame.x[1] + pcoBody[1] * frame.y[1] + pcoBody[2] * frame.z[1],
15179
- pcoBody[0] * frame.x[2] + pcoBody[1] * frame.y[2] + pcoBody[2] * frame.z[2]
15180
- ];
15181
- }
15182
- function enuToEcef(enu, latRad, lonRad) {
15183
- const sl = Math.sin(latRad);
15184
- const cl = Math.cos(latRad);
15185
- const so = Math.sin(lonRad);
15186
- const co = Math.cos(lonRad);
15187
- const [e, n, u] = enu;
15188
- return [
15189
- -so * e - sl * co * n + cl * co * u,
15190
- co * e - sl * so * n + cl * so * u,
15191
- cl * n + sl * u
15192
- ];
15193
- }
15194
- function interpPcv(off, angleDeg) {
15195
- const { pcvZen1Deg, pcvDzenDeg, pcvNoazi } = off;
15196
- if (pcvDzenDeg <= 0 || pcvNoazi.length < 2) return 0;
15197
- const x = (angleDeg - pcvZen1Deg) / pcvDzenDeg;
15198
- if (x <= 0) return pcvNoazi[0];
15199
- if (x >= pcvNoazi.length - 1) return pcvNoazi[pcvNoazi.length - 1];
15200
- const i = Math.floor(x);
15201
- const t = x - i;
15202
- return pcvNoazi[i] * (1 - t) + pcvNoazi[i + 1] * t;
15203
- }
15204
- function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
15205
- const k = [
15206
- -losRcvToSat[0],
15207
- -losRcvToSat[1],
15208
- -losRcvToSat[2]
15209
- ];
15210
- const kx = satFrame.x;
15211
- const ky = satFrame.y;
15212
- const kdotx = dot(k, kx);
15213
- const kcrossY = cross2(k, ky);
15214
- const dS = [
15215
- kx[0] - k[0] * kdotx - kcrossY[0],
15216
- kx[1] - k[1] * kdotx - kcrossY[1],
15217
- kx[2] - k[2] * kdotx - kcrossY[2]
15218
- ];
15219
- const north = enuToEcef([0, 1, 0], latRad, lonRad);
15220
- const east = enuToEcef([1, 0, 0], latRad, lonRad);
15221
- const kdotn = dot(k, north);
15222
- const kcrossE = cross2(k, east);
15223
- const dR = [
15224
- north[0] - k[0] * kdotn + kcrossE[0],
15225
- north[1] - k[1] * kdotn + kcrossE[1],
15226
- north[2] - k[2] * kdotn + kcrossE[2]
15227
- ];
15228
- const nS = Math.hypot(dS[0], dS[1], dS[2]) || 1;
15229
- const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
15230
- let cosPhi = dot(dS, dR) / (nS * nR);
15231
- cosPhi = Math.max(-1, Math.min(1, cosPhi));
15232
- const zeta = cross2(dS, dR);
15233
- const sign = dot(k, zeta) >= 0 ? 1 : -1;
15234
- const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
15235
- const prev = state.get(prn);
15236
- const wu = prev == null ? dphi : dphi + Math.round(prev - dphi);
15237
- state.set(prn, wu);
15238
- return wu;
15239
- }
15240
-
15241
15339
  // src/positioning/ppp-corrections.ts
15242
15340
  function applyCorrections(corrections, geom, ctx) {
15243
15341
  if (corrections.evaluate) return corrections.evaluate(geom, ctx);
@@ -18988,6 +19086,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18988
19086
  almanacEpochMs,
18989
19087
  almanacSatPosition,
18990
19088
  analyzeQuality,
19089
+ antexFreqOfGroup,
18991
19090
  applyHelmert,
18992
19091
  applyIonoDcb,
18993
19092
  applyOrbitClock,
@@ -18999,6 +19098,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18999
19098
  buildGloChannelMap,
19000
19099
  buildObsIndices,
19001
19100
  buildPppAntenna,
19101
+ buildRtkAntenna,
19002
19102
  clampUnit,
19003
19103
  clkBias,
19004
19104
  computeAllPositions,
@@ -19181,6 +19281,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
19181
19281
  postProcessRtk,
19182
19282
  rad2deg,
19183
19283
  rangeRate,
19284
+ rcvAntennaRangeM,
19184
19285
  readString,
19185
19286
  reportDecodeError,
19186
19287
  resetGloFreqCache,
package/dist/index.d.cts CHANGED
@@ -19,7 +19,7 @@ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, Trimb
19
19
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
20
20
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
21
21
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
22
- export { AntennaOffset, AppliedOrbitClock, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, Degradation, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, OrbitClockCorrection, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEngine, PppEphemerisSource, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SatSample, SbasCorrectionSource, SbasIgp, SbasIonoDelay, SbasProcessor, SbasSatCorrection, Sp3EphemerisSource, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, applyOrbitClock, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
22
+ export { AntennaOffset, AppliedOrbitClock, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, Degradation, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, OrbitClockCorrection, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEngine, PppEphemerisSource, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkAntennaConfig, RtkAntennaModel, RtkAntennaOffset, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkReceiverAntenna, RtkTrackPoint, SatGeom, SatSample, SbasCorrectionSource, SbasIgp, SbasIonoDelay, SbasProcessor, SbasSatCorrection, Sp3EphemerisSource, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
23
23
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
24
24
  export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, IonoAccumulator, IonoDcbResult, IonoPoint, IonoRatePoint, IonoRateSeries, IonoResult, IonoSeries, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, SatDcbMap, analyzeQuality, applyIonoDcb, computeIonoRate, detrendIonoArcs, parseSinexBiasDcb } from './analysis.cjs';
25
25
  export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.cjs';
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, Trimb
19
19
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
20
20
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
21
21
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
22
- export { AntennaOffset, AppliedOrbitClock, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, Degradation, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, OrbitClockCorrection, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEngine, PppEphemerisSource, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SatSample, SbasCorrectionSource, SbasIgp, SbasIonoDelay, SbasProcessor, SbasSatCorrection, Sp3EphemerisSource, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, applyOrbitClock, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
22
+ export { AntennaOffset, AppliedOrbitClock, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, Degradation, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, OrbitClockCorrection, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEngine, PppEphemerisSource, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkAntennaConfig, RtkAntennaModel, RtkAntennaOffset, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkReceiverAntenna, RtkTrackPoint, SatGeom, SatSample, SbasCorrectionSource, SbasIgp, SbasIonoDelay, SbasProcessor, SbasSatCorrection, Sp3EphemerisSource, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
23
23
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
24
24
  export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, IonoAccumulator, IonoDcbResult, IonoPoint, IonoRatePoint, IonoRateSeries, IonoResult, IonoSeries, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, SatDcbMap, analyzeQuality, applyIonoDcb, computeIonoRate, detrendIonoArcs, parseSinexBiasDcb } from './analysis.js';
25
25
  export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.js';
package/dist/index.js CHANGED
@@ -77,7 +77,7 @@ import {
77
77
  setRtcm3DebugHandler,
78
78
  updateStationMeta,
79
79
  updateStreamStats
80
- } from "./chunk-WVTDVPKA.js";
80
+ } from "./chunk-XPQ4BU6W.js";
81
81
  import {
82
82
  parseUbxCnav,
83
83
  parseUbxIonoUtc,
@@ -174,8 +174,10 @@ import {
174
174
  RtkFloatEngine,
175
175
  SbasProcessor,
176
176
  Sp3EphemerisSource,
177
+ antexFreqOfGroup,
177
178
  applyOrbitClock,
178
179
  buildPppAntenna,
180
+ buildRtkAntenna,
179
181
  createPppCorrections,
180
182
  estimateNarrowlaneFcb,
181
183
  estimateNetworkFcbs,
@@ -194,6 +196,7 @@ import {
194
196
  niellMapping,
195
197
  nlWavelength,
196
198
  postProcessRtk,
199
+ rcvAntennaRangeM,
197
200
  resolvePppAmbiguities,
198
201
  satClockCorrection,
199
202
  sbasIonoDeg,
@@ -206,7 +209,7 @@ import {
206
209
  sunEcef,
207
210
  toRtkEpoch,
208
211
  wlWavelength
209
- } from "./chunk-DWUQRJ37.js";
212
+ } from "./chunk-TYJNN77C.js";
210
213
  import "./chunk-WQX354KD.js";
211
214
  import {
212
215
  almanacEpochMs,
@@ -486,6 +489,7 @@ export {
486
489
  almanacEpochMs,
487
490
  almanacSatPosition,
488
491
  analyzeQuality,
492
+ antexFreqOfGroup,
489
493
  applyHelmert,
490
494
  applyIonoDcb,
491
495
  applyOrbitClock,
@@ -497,6 +501,7 @@ export {
497
501
  buildGloChannelMap,
498
502
  buildObsIndices,
499
503
  buildPppAntenna,
504
+ buildRtkAntenna,
500
505
  clampUnit,
501
506
  clkBias,
502
507
  computeAllPositions,
@@ -679,6 +684,7 @@ export {
679
684
  postProcessRtk,
680
685
  rad2deg,
681
686
  rangeRate,
687
+ rcvAntennaRangeM,
682
688
  readString,
683
689
  reportDecodeError,
684
690
  resetGloFreqCache,