gnss-js 2.2.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.
@@ -302,6 +302,211 @@ function lambdaReduction(Q, n) {
302
302
  return Z;
303
303
  }
304
304
 
305
+ // src/positioning/ppp-antenna.ts
306
+ function parseAntexTime(s) {
307
+ const p = s.trim().split(/\s+/).map(Number);
308
+ if (p.length < 3 || p.some((v) => Number.isNaN(v))) return null;
309
+ return Date.UTC(
310
+ p[0],
311
+ (p[1] || 1) - 1,
312
+ p[2] || 1,
313
+ p[3] ?? 0,
314
+ p[4] ?? 0,
315
+ Math.floor(p[5] ?? 0)
316
+ );
317
+ }
318
+ function freqOf(entry, code) {
319
+ return entry.frequencies.find((f) => f.frequency === code);
320
+ }
321
+ function combineIf(fA, fB, f1, f2) {
322
+ const g = f1 * f1 / (f1 * f1 - f2 * f2);
323
+ const mm = 1e-3;
324
+ const pco = [
325
+ (g * fA.pcoN - (g - 1) * fB.pcoN) * mm,
326
+ (g * fA.pcoE - (g - 1) * fB.pcoE) * mm,
327
+ (g * fA.pcoU - (g - 1) * fB.pcoU) * mm
328
+ ];
329
+ const nz = Math.min(fA.pcvNoazi.length, fB.pcvNoazi.length);
330
+ const pcvNoazi = new Array(nz);
331
+ for (let i = 0; i < nz; i++) {
332
+ pcvNoazi[i] = (g * fA.pcvNoazi[i] - (g - 1) * fB.pcvNoazi[i]) * mm;
333
+ }
334
+ return { pco, pcvZen1Deg: 0, pcvDzenDeg: 0, pcvNoazi };
335
+ }
336
+ function buildPppAntenna(antex) {
337
+ const sats = /* @__PURE__ */ new Map();
338
+ const rcvs = /* @__PURE__ */ new Map();
339
+ for (const a of antex.antennas) {
340
+ if (a.isSatellite) {
341
+ const list = sats.get(a.serialNo) ?? [];
342
+ list.push(a);
343
+ sats.set(a.serialNo, list);
344
+ } else if (!rcvs.has(a.type)) {
345
+ rcvs.set(a.type, a);
346
+ }
347
+ }
348
+ const withZen = (entry, off) => ({
349
+ ...off,
350
+ pcvZen1Deg: entry.zen1,
351
+ pcvDzenDeg: entry.dzen
352
+ });
353
+ return {
354
+ satOffset(prn, dateMs, band1, band2, f1, f2) {
355
+ const list = sats.get(prn);
356
+ if (!list) return null;
357
+ const entry = list.find((e) => {
358
+ const from = parseAntexTime(e.validFrom);
359
+ const until = parseAntexTime(e.validUntil);
360
+ return (from == null || dateMs >= from) && (until == null || dateMs <= until);
361
+ });
362
+ if (!entry) return null;
363
+ const a = freqOf(entry, band1);
364
+ const b = freqOf(entry, band2);
365
+ if (!a || !b) return null;
366
+ return withZen(entry, combineIf(a, b, f1, f2));
367
+ },
368
+ rcvOffset(antType, band1, band2, f1, f2) {
369
+ const entry = rcvs.get(antType);
370
+ if (!entry) return null;
371
+ const a = freqOf(entry, band1);
372
+ const b = freqOf(entry, band2);
373
+ if (!a || !b) return null;
374
+ return withZen(entry, combineIf(a, b, f1, f2));
375
+ }
376
+ };
377
+ }
378
+ function cross(a, b) {
379
+ return [
380
+ a[1] * b[2] - a[2] * b[1],
381
+ a[2] * b[0] - a[0] * b[2],
382
+ a[0] * b[1] - a[1] * b[0]
383
+ ];
384
+ }
385
+ function norm(a) {
386
+ const n = Math.hypot(a[0], a[1], a[2]) || 1;
387
+ return [a[0] / n, a[1] / n, a[2] / n];
388
+ }
389
+ function dot(a, b) {
390
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
391
+ }
392
+ function satBodyFrame(satEcef, sunEcef2) {
393
+ const z = norm([-satEcef[0], -satEcef[1], -satEcef[2]]);
394
+ const eSun = norm([
395
+ sunEcef2[0] - satEcef[0],
396
+ sunEcef2[1] - satEcef[1],
397
+ sunEcef2[2] - satEcef[2]
398
+ ]);
399
+ const y = norm(cross(z, eSun));
400
+ const x = norm(cross(y, z));
401
+ return { x, y, z };
402
+ }
403
+ function satPcoToEcef(pcoBody, frame) {
404
+ return [
405
+ pcoBody[0] * frame.x[0] + pcoBody[1] * frame.y[0] + pcoBody[2] * frame.z[0],
406
+ pcoBody[0] * frame.x[1] + pcoBody[1] * frame.y[1] + pcoBody[2] * frame.z[1],
407
+ pcoBody[0] * frame.x[2] + pcoBody[1] * frame.y[2] + pcoBody[2] * frame.z[2]
408
+ ];
409
+ }
410
+ function enuToEcef(enu, latRad, lonRad) {
411
+ const sl = Math.sin(latRad);
412
+ const cl = Math.cos(latRad);
413
+ const so = Math.sin(lonRad);
414
+ const co = Math.cos(lonRad);
415
+ const [e, n, u] = enu;
416
+ return [
417
+ -so * e - sl * co * n + cl * co * u,
418
+ co * e - sl * so * n + cl * so * u,
419
+ cl * n + sl * u
420
+ ];
421
+ }
422
+ function interpPcv(off, angleDeg) {
423
+ const { pcvZen1Deg, pcvDzenDeg, pcvNoazi } = off;
424
+ if (pcvDzenDeg <= 0 || pcvNoazi.length < 2) return 0;
425
+ const x = (angleDeg - pcvZen1Deg) / pcvDzenDeg;
426
+ if (x <= 0) return pcvNoazi[0];
427
+ if (x >= pcvNoazi.length - 1) return pcvNoazi[pcvNoazi.length - 1];
428
+ const i = Math.floor(x);
429
+ const t = x - i;
430
+ return pcvNoazi[i] * (1 - t) + pcvNoazi[i + 1] * t;
431
+ }
432
+ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
433
+ const k = [
434
+ -losRcvToSat[0],
435
+ -losRcvToSat[1],
436
+ -losRcvToSat[2]
437
+ ];
438
+ const kx = satFrame.x;
439
+ const ky = satFrame.y;
440
+ const kdotx = dot(k, kx);
441
+ const kcrossY = cross(k, ky);
442
+ const dS = [
443
+ kx[0] - k[0] * kdotx - kcrossY[0],
444
+ kx[1] - k[1] * kdotx - kcrossY[1],
445
+ kx[2] - k[2] * kdotx - kcrossY[2]
446
+ ];
447
+ const north = enuToEcef([0, 1, 0], latRad, lonRad);
448
+ const east = enuToEcef([1, 0, 0], latRad, lonRad);
449
+ const kdotn = dot(k, north);
450
+ const kcrossE = cross(k, east);
451
+ const dR = [
452
+ north[0] - k[0] * kdotn + kcrossE[0],
453
+ north[1] - k[1] * kdotn + kcrossE[1],
454
+ north[2] - k[2] * kdotn + kcrossE[2]
455
+ ];
456
+ const nS = Math.hypot(dS[0], dS[1], dS[2]) || 1;
457
+ const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
458
+ let cosPhi = dot(dS, dR) / (nS * nR);
459
+ cosPhi = Math.max(-1, Math.min(1, cosPhi));
460
+ const zeta = cross(dS, dR);
461
+ const sign = dot(k, zeta) >= 0 ? 1 : -1;
462
+ const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
463
+ const prev = state.get(prn);
464
+ const wu = prev == null ? dphi : dphi + Math.round(prev - dphi);
465
+ state.set(prn, wu);
466
+ return wu;
467
+ }
468
+
469
+ // src/positioning/rtk-antenna.ts
470
+ function freqOf2(entry, code) {
471
+ return entry.frequencies.find((f) => f.frequency === code);
472
+ }
473
+ function buildRtkAntenna(antex) {
474
+ const rcvs = /* @__PURE__ */ new Map();
475
+ for (const a of antex.antennas) {
476
+ if (!a.isSatellite && !rcvs.has(a.type)) rcvs.set(a.type, a);
477
+ }
478
+ const mm = 1e-3;
479
+ return {
480
+ rcvOffset(antType, freq) {
481
+ const entry = rcvs.get(antType);
482
+ if (!entry) return null;
483
+ const f = freqOf2(entry, freq);
484
+ if (!f) return null;
485
+ return {
486
+ pco: [f.pcoN * mm, f.pcoE * mm, f.pcoU * mm],
487
+ pcvZen1Deg: entry.zen1,
488
+ pcvDzenDeg: entry.dzen,
489
+ pcvNoazi: f.pcvNoazi.map((v) => v * mm)
490
+ };
491
+ }
492
+ };
493
+ }
494
+ function rcvAntennaRangeM(off, losRcvToSat, latRad, lonRad, elRad, antDeltaEnu = [0, 0, 0]) {
495
+ const total = [
496
+ off.pco[0] + antDeltaEnu[0],
497
+ off.pco[1] + antDeltaEnu[1],
498
+ off.pco[2] + antDeltaEnu[2]
499
+ ];
500
+ const ecef = enuToEcef(total, latRad, lonRad);
501
+ let m = -dot(losRcvToSat, ecef);
502
+ const zenithDeg = 90 - elRad * 180 / Math.PI;
503
+ m += interpPcv(off, zenithDeg);
504
+ return m;
505
+ }
506
+ function antexFreqOfGroup(group) {
507
+ return `${group[0]}0${group[1]}`;
508
+ }
509
+
305
510
  // src/positioning/rtk.ts
306
511
  var L1_CODES = {
307
512
  G: ["1C"],
@@ -367,8 +572,16 @@ function resolveEphemeris(src, prn, timeMs) {
367
572
  return selectEphemeris(src, prn, timeMs);
368
573
  return src.get(prn) ?? null;
369
574
  }
370
- function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, troposphere) {
575
+ var ZERO_DELTA = [0, 0, 0];
576
+ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, troposphere, antenna = null) {
371
577
  const out = [];
578
+ let baseLatRad = 0;
579
+ let baseLonRad = 0;
580
+ if (antenna?.base) {
581
+ const [latDeg, lonDeg] = ecefToGeodetic(basePos[0], basePos[1], basePos[2]);
582
+ baseLatRad = latDeg * Math.PI / 180;
583
+ baseLonRad = lonDeg * Math.PI / 180;
584
+ }
372
585
  for (const [prn, mR] of rover) {
373
586
  const sys = prn[0];
374
587
  if (!"GERCJ".includes(sys)) continue;
@@ -393,14 +606,43 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
393
606
  satB.z - basePos[2]
394
607
  ) / C_LIGHT;
395
608
  const [bx, by, bz] = sagnac(satB, travelB);
396
- const rhoB = Math.hypot(bx - basePos[0], by - basePos[1], bz - basePos[2]);
609
+ let rhoB = Math.hypot(bx - basePos[0], by - basePos[1], bz - basePos[2]);
397
610
  const elB = ecefToAzEl(basePos[0], basePos[1], basePos[2], bx, by, bz).el;
398
611
  if (elB < maskRad) continue;
612
+ const group = sys + mR.code;
613
+ let offR = null;
614
+ let roverDelta = ZERO_DELTA;
615
+ if (antenna) {
616
+ const antexFreq = antexFreqOfGroup(group);
617
+ if (antenna.base) {
618
+ const offB = antenna.model.rcvOffset(antenna.base.type, antexFreq);
619
+ if (offB) {
620
+ const inv = 1 / rhoB;
621
+ const losB = [
622
+ (bx - basePos[0]) * inv,
623
+ (by - basePos[1]) * inv,
624
+ (bz - basePos[2]) * inv
625
+ ];
626
+ rhoB += rcvAntennaRangeM(
627
+ offB,
628
+ losB,
629
+ baseLatRad,
630
+ baseLonRad,
631
+ elB,
632
+ antenna.base.deltaEnu
633
+ );
634
+ }
635
+ }
636
+ if (antenna.rover) {
637
+ offR = antenna.model.rcvOffset(antenna.rover.type, antexFreq);
638
+ roverDelta = antenna.rover.deltaEnu ?? ZERO_DELTA;
639
+ }
640
+ }
399
641
  const gloK = sys === "R" ? mR.gloChannel ?? mB.gloChannel ?? eph.freqNum ?? null : null;
400
642
  const freq = carrierFreqHz(sys, mR.code, gloK);
401
643
  out.push({
402
644
  prn,
403
- group: sys + mR.code,
645
+ group,
404
646
  lambda: freq > 0 ? C_LIGHT / freq : 0,
405
647
  satR,
406
648
  rhoB,
@@ -411,7 +653,9 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
411
653
  cpR: mR.cp ?? null,
412
654
  cpB: mB.cp ?? null,
413
655
  lockR: mR.lockTimeMs,
414
- lockB: mB.lockTimeMs
656
+ lockB: mB.lockTimeMs,
657
+ offR,
658
+ roverDelta
415
659
  });
416
660
  }
417
661
  return out;
@@ -419,17 +663,29 @@ function buildGeometry(rover, base, basePos, ephemerides, timeMs, maskRad, tropo
419
663
  function roverTerms(g, x, y, z, troposphere) {
420
664
  const travel = Math.hypot(g.satR.x - x, g.satR.y - y, g.satR.z - z) / C_LIGHT;
421
665
  const [sx, sy, sz] = sagnac(g.satR, travel);
422
- const rho = Math.hypot(sx - x, sy - y, sz - z);
666
+ let rho = Math.hypot(sx - x, sy - y, sz - z);
423
667
  const u = [
424
668
  (x - sx) / rho,
425
669
  (y - sy) / rho,
426
670
  (z - sz) / rho
427
671
  ];
672
+ const needEl = troposphere || g.offR != null;
673
+ const elR = needEl ? ecefToAzEl(x, y, z, sx, sy, sz).el : 0;
428
674
  let dTropo = 0;
429
675
  if (troposphere) {
430
- const elR = ecefToAzEl(x, y, z, sx, sy, sz).el;
431
676
  dTropo = tropoDelay(Math.max(elR, 0.05)) - g.tropoB;
432
677
  }
678
+ if (g.offR) {
679
+ const [latDeg, lonDeg] = ecefToGeodetic(x, y, z);
680
+ rho += rcvAntennaRangeM(
681
+ g.offR,
682
+ [-u[0], -u[1], -u[2]],
683
+ latDeg * Math.PI / 180,
684
+ lonDeg * Math.PI / 180,
685
+ elR,
686
+ g.roverDelta
687
+ );
688
+ }
433
689
  return { rho, u, dTropo };
434
690
  }
435
691
  function sdVariance(sigmaM, elRad) {
@@ -668,7 +924,8 @@ var RtkFloatEngine = class {
668
924
  arElevationMaskDeg: opts.arElevationMaskDeg ?? 0,
669
925
  glonassAr: opts.glonassAr ?? false,
670
926
  partialFixing: opts.partialFixing ?? true,
671
- minFixAmbiguities: opts.minFixAmbiguities ?? 4
927
+ minFixAmbiguities: opts.minFixAmbiguities ?? 4,
928
+ antenna: opts.antenna ?? null
672
929
  };
673
930
  }
674
931
  /** Clear all filter state (position, ambiguities, lock history). */
@@ -791,7 +1048,8 @@ var RtkFloatEngine = class {
791
1048
  this.ephemerides,
792
1049
  timeMs,
793
1050
  o.elevationMaskDeg * Math.PI / 180,
794
- o.troposphere
1051
+ o.troposphere,
1052
+ o.antenna
795
1053
  );
796
1054
  const byPrn = new Map(geom.map((g) => [g.prn, g]));
797
1055
  const dtS = this.lastMs !== null ? (timeMs - this.lastMs) / 1e3 : 0;
@@ -1919,14 +2177,14 @@ var SbasProcessor = class {
1919
2177
  };
1920
2178
 
1921
2179
  // src/positioning/ssr-apply.ts
1922
- var cross = (a, b) => [
2180
+ var cross2 = (a, b) => [
1923
2181
  a[1] * b[2] - a[2] * b[1],
1924
2182
  a[2] * b[0] - a[0] * b[2],
1925
2183
  a[0] * b[1] - a[1] * b[0]
1926
2184
  ];
1927
- var norm = (a) => Math.hypot(a[0], a[1], a[2]);
2185
+ var norm2 = (a) => Math.hypot(a[0], a[1], a[2]);
1928
2186
  var unit = (a) => {
1929
- const n = norm(a);
2187
+ const n = norm2(a);
1930
2188
  return n > 0 ? [a[0] / n, a[1] / n, a[2] / n] : [0, 0, 0];
1931
2189
  };
1932
2190
  function applyOrbitClock(eph, corr, timeMs) {
@@ -1940,8 +2198,8 @@ function applyOrbitClock(eph, corr, timeMs) {
1940
2198
  const p = [s.x, s.y, s.z];
1941
2199
  const v = [s.vx, s.vy, s.vz];
1942
2200
  const er = unit(p);
1943
- const en = unit(cross(p, v));
1944
- const ea = cross(en, er);
2201
+ const en = unit(cross2(p, v));
2202
+ const ea = cross2(en, er);
1945
2203
  const dr = corr.radial + (corr.dotRadial ?? 0) * age;
1946
2204
  const da = corr.along + (corr.dotAlong ?? 0) * age;
1947
2205
  const dc = corr.cross + (corr.dotCross ?? 0) * age;
@@ -2151,170 +2409,6 @@ function solidEarthTide(rcv, sun, moon) {
2151
2409
  return disp;
2152
2410
  }
2153
2411
 
2154
- // src/positioning/ppp-antenna.ts
2155
- function parseAntexTime(s) {
2156
- const p = s.trim().split(/\s+/).map(Number);
2157
- if (p.length < 3 || p.some((v) => Number.isNaN(v))) return null;
2158
- return Date.UTC(
2159
- p[0],
2160
- (p[1] || 1) - 1,
2161
- p[2] || 1,
2162
- p[3] ?? 0,
2163
- p[4] ?? 0,
2164
- Math.floor(p[5] ?? 0)
2165
- );
2166
- }
2167
- function freqOf(entry, code) {
2168
- return entry.frequencies.find((f) => f.frequency === code);
2169
- }
2170
- function combineIf(fA, fB, f1, f2) {
2171
- const g = f1 * f1 / (f1 * f1 - f2 * f2);
2172
- const mm = 1e-3;
2173
- const pco = [
2174
- (g * fA.pcoN - (g - 1) * fB.pcoN) * mm,
2175
- (g * fA.pcoE - (g - 1) * fB.pcoE) * mm,
2176
- (g * fA.pcoU - (g - 1) * fB.pcoU) * mm
2177
- ];
2178
- const nz = Math.min(fA.pcvNoazi.length, fB.pcvNoazi.length);
2179
- const pcvNoazi = new Array(nz);
2180
- for (let i = 0; i < nz; i++) {
2181
- pcvNoazi[i] = (g * fA.pcvNoazi[i] - (g - 1) * fB.pcvNoazi[i]) * mm;
2182
- }
2183
- return { pco, pcvZen1Deg: 0, pcvDzenDeg: 0, pcvNoazi };
2184
- }
2185
- function buildPppAntenna(antex) {
2186
- const sats = /* @__PURE__ */ new Map();
2187
- const rcvs = /* @__PURE__ */ new Map();
2188
- for (const a of antex.antennas) {
2189
- if (a.isSatellite) {
2190
- const list = sats.get(a.serialNo) ?? [];
2191
- list.push(a);
2192
- sats.set(a.serialNo, list);
2193
- } else if (!rcvs.has(a.type)) {
2194
- rcvs.set(a.type, a);
2195
- }
2196
- }
2197
- const withZen = (entry, off) => ({
2198
- ...off,
2199
- pcvZen1Deg: entry.zen1,
2200
- pcvDzenDeg: entry.dzen
2201
- });
2202
- return {
2203
- satOffset(prn, dateMs, band1, band2, f1, f2) {
2204
- const list = sats.get(prn);
2205
- if (!list) return null;
2206
- const entry = list.find((e) => {
2207
- const from = parseAntexTime(e.validFrom);
2208
- const until = parseAntexTime(e.validUntil);
2209
- return (from == null || dateMs >= from) && (until == null || dateMs <= until);
2210
- });
2211
- if (!entry) return null;
2212
- const a = freqOf(entry, band1);
2213
- const b = freqOf(entry, band2);
2214
- if (!a || !b) return null;
2215
- return withZen(entry, combineIf(a, b, f1, f2));
2216
- },
2217
- rcvOffset(antType, band1, band2, f1, f2) {
2218
- const entry = rcvs.get(antType);
2219
- if (!entry) return null;
2220
- const a = freqOf(entry, band1);
2221
- const b = freqOf(entry, band2);
2222
- if (!a || !b) return null;
2223
- return withZen(entry, combineIf(a, b, f1, f2));
2224
- }
2225
- };
2226
- }
2227
- function cross2(a, b) {
2228
- return [
2229
- a[1] * b[2] - a[2] * b[1],
2230
- a[2] * b[0] - a[0] * b[2],
2231
- a[0] * b[1] - a[1] * b[0]
2232
- ];
2233
- }
2234
- function norm2(a) {
2235
- const n = Math.hypot(a[0], a[1], a[2]) || 1;
2236
- return [a[0] / n, a[1] / n, a[2] / n];
2237
- }
2238
- function dot(a, b) {
2239
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
2240
- }
2241
- function satBodyFrame(satEcef, sunEcef2) {
2242
- const z = norm2([-satEcef[0], -satEcef[1], -satEcef[2]]);
2243
- const eSun = norm2([
2244
- sunEcef2[0] - satEcef[0],
2245
- sunEcef2[1] - satEcef[1],
2246
- sunEcef2[2] - satEcef[2]
2247
- ]);
2248
- const y = norm2(cross2(z, eSun));
2249
- const x = norm2(cross2(y, z));
2250
- return { x, y, z };
2251
- }
2252
- function satPcoToEcef(pcoBody, frame) {
2253
- return [
2254
- pcoBody[0] * frame.x[0] + pcoBody[1] * frame.y[0] + pcoBody[2] * frame.z[0],
2255
- pcoBody[0] * frame.x[1] + pcoBody[1] * frame.y[1] + pcoBody[2] * frame.z[1],
2256
- pcoBody[0] * frame.x[2] + pcoBody[1] * frame.y[2] + pcoBody[2] * frame.z[2]
2257
- ];
2258
- }
2259
- function enuToEcef(enu, latRad, lonRad) {
2260
- const sl = Math.sin(latRad);
2261
- const cl = Math.cos(latRad);
2262
- const so = Math.sin(lonRad);
2263
- const co = Math.cos(lonRad);
2264
- const [e, n, u] = enu;
2265
- return [
2266
- -so * e - sl * co * n + cl * co * u,
2267
- co * e - sl * so * n + cl * so * u,
2268
- cl * n + sl * u
2269
- ];
2270
- }
2271
- function interpPcv(off, angleDeg) {
2272
- const { pcvZen1Deg, pcvDzenDeg, pcvNoazi } = off;
2273
- if (pcvDzenDeg <= 0 || pcvNoazi.length < 2) return 0;
2274
- const x = (angleDeg - pcvZen1Deg) / pcvDzenDeg;
2275
- if (x <= 0) return pcvNoazi[0];
2276
- if (x >= pcvNoazi.length - 1) return pcvNoazi[pcvNoazi.length - 1];
2277
- const i = Math.floor(x);
2278
- const t = x - i;
2279
- return pcvNoazi[i] * (1 - t) + pcvNoazi[i + 1] * t;
2280
- }
2281
- function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
2282
- const k = [
2283
- -losRcvToSat[0],
2284
- -losRcvToSat[1],
2285
- -losRcvToSat[2]
2286
- ];
2287
- const kx = satFrame.x;
2288
- const ky = satFrame.y;
2289
- const kdotx = dot(k, kx);
2290
- const kcrossY = cross2(k, ky);
2291
- const dS = [
2292
- kx[0] - k[0] * kdotx - kcrossY[0],
2293
- kx[1] - k[1] * kdotx - kcrossY[1],
2294
- kx[2] - k[2] * kdotx - kcrossY[2]
2295
- ];
2296
- const north = enuToEcef([0, 1, 0], latRad, lonRad);
2297
- const east = enuToEcef([1, 0, 0], latRad, lonRad);
2298
- const kdotn = dot(k, north);
2299
- const kcrossE = cross2(k, east);
2300
- const dR = [
2301
- north[0] - k[0] * kdotn + kcrossE[0],
2302
- north[1] - k[1] * kdotn + kcrossE[1],
2303
- north[2] - k[2] * kdotn + kcrossE[2]
2304
- ];
2305
- const nS = Math.hypot(dS[0], dS[1], dS[2]) || 1;
2306
- const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
2307
- let cosPhi = dot(dS, dR) / (nS * nR);
2308
- cosPhi = Math.max(-1, Math.min(1, cosPhi));
2309
- const zeta = cross2(dS, dR);
2310
- const sign = dot(k, zeta) >= 0 ? 1 : -1;
2311
- const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
2312
- const prev = state.get(prn);
2313
- const wu = prev == null ? dphi : dphi + Math.round(prev - dphi);
2314
- state.set(prn, wu);
2315
- return wu;
2316
- }
2317
-
2318
2412
  // src/positioning/ppp-corrections.ts
2319
2413
  function applyCorrections(corrections, geom, ctx) {
2320
2414
  if (corrections.evaluate) return corrections.evaluate(geom, ctx);
@@ -3714,6 +3808,10 @@ export {
3714
3808
  gimSlantIonoDelayL1,
3715
3809
  lambdaSearch,
3716
3810
  lambdaReduction,
3811
+ buildPppAntenna,
3812
+ buildRtkAntenna,
3813
+ rcvAntennaRangeM,
3814
+ antexFreqOfGroup,
3717
3815
  toRtkEpoch,
3718
3816
  solveDgnss,
3719
3817
  RtkFloatEngine,
@@ -3728,7 +3826,6 @@ export {
3728
3826
  sunEcef,
3729
3827
  moonEcef,
3730
3828
  solidEarthTide,
3731
- buildPppAntenna,
3732
3829
  createPppCorrections,
3733
3830
  Sp3EphemerisSource,
3734
3831
  PppEngine,