gnss-js 1.10.0 → 1.12.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.
@@ -2,12 +2,46 @@ import {
2
2
  computeDop,
3
3
  computeSatPosition,
4
4
  ecefToAzEl
5
- } from "./chunk-AK6LNWZX.js";
5
+ } from "./chunk-DMNFB7Q6.js";
6
+ import {
7
+ ecefToGeodetic
8
+ } from "./chunk-37QNKGTC.js";
6
9
  import {
7
10
  C_LIGHT,
8
11
  OMEGA_E
9
12
  } from "./chunk-FIEWO4J4.js";
10
13
 
14
+ // src/positioning/klobuchar.ts
15
+ function klobucharDelay(coeffs, latRad, lonRad, azRad, elRad, gpsTowSec) {
16
+ const { alpha, beta } = coeffs;
17
+ if (alpha.length < 4 || beta.length < 4) return 0;
18
+ const E = elRad / Math.PI;
19
+ const phiU = latRad / Math.PI;
20
+ const lambdaU = lonRad / Math.PI;
21
+ const psi = 0.0137 / (E + 0.11) - 0.022;
22
+ let phiI = phiU + psi * Math.cos(azRad);
23
+ if (phiI > 0.416) phiI = 0.416;
24
+ else if (phiI < -0.416) phiI = -0.416;
25
+ const lambdaI = lambdaU + psi * Math.sin(azRad) / Math.cos(phiI * Math.PI);
26
+ const phiM = phiI + 0.064 * Math.cos((lambdaI - 1.617) * Math.PI);
27
+ let t = 43200 * lambdaI + gpsTowSec;
28
+ t %= 86400;
29
+ if (t < 0) t += 86400;
30
+ let amp = 0;
31
+ let per = 0;
32
+ for (let n = 3; n >= 0; n--) {
33
+ amp = amp * phiM + alpha[n];
34
+ per = per * phiM + beta[n];
35
+ }
36
+ if (amp < 0) amp = 0;
37
+ if (per < 72e3) per = 72e3;
38
+ const F = 1 + 16 * Math.pow(0.53 - E, 3);
39
+ const x = 2 * Math.PI * (t - 50400) / per;
40
+ if (Math.abs(x) >= 1.57) return F * 5e-9;
41
+ const x2 = x * x;
42
+ return F * (5e-9 + amp * (1 - x2 / 2 + x2 * x2 / 24));
43
+ }
44
+
11
45
  // src/positioning/index.ts
12
46
  var GM_GPS = 3986005e8;
13
47
  var F_REL = -4442807633e-19;
@@ -34,6 +68,16 @@ function ionoFree(p1, p2, f1, f2) {
34
68
  const g = f1 * f1 / (f1 * f1 - f2 * f2);
35
69
  return g * p1 - (g - 1) * p2;
36
70
  }
71
+ var GPS_EPOCH_MS_SPP = Date.UTC(1980, 0, 6);
72
+ var PRIMARY_FREQ_HZ = {
73
+ G: 157542e4,
74
+ E: 157542e4,
75
+ J: 157542e4,
76
+ S: 157542e4,
77
+ C: 1561098e3,
78
+ R: 1602e6
79
+ };
80
+ var F_L1 = 157542e4;
37
81
  function tropoDelay(elevationRad) {
38
82
  const sinEl = Math.sin(elevationRad);
39
83
  return 2.47 / (sinEl + 0.0121);
@@ -68,8 +112,10 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
68
112
  troposphere = true,
69
113
  maxIterations = 15,
70
114
  convergenceM = 1e-4,
71
- tgd = true
115
+ tgd = true,
116
+ iono
72
117
  } = opts;
118
+ const gpsTow = (timeMs - GPS_EPOCH_MS_SPP) / 1e3 % 604800;
73
119
  const all = [...pseudoranges.keys()].filter((p) => ephemerides.has(p));
74
120
  const minSats = (list) => 3 + new Set(list.map((p) => p[0])).size;
75
121
  if (all.length < minSats(all)) return null;
@@ -93,6 +139,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
93
139
  const Htv = new Array(dim).fill(0);
94
140
  let rows = 0;
95
141
  for (const k of Object.keys(residuals2)) delete residuals2[k];
142
+ const positionSaneIter = x2 * x2 + y2 * y2 + z2 * z2 > 1e12;
143
+ const [rxLat, rxLon] = positionSaneIter ? ecefToGeodetic(x2, y2, z2) : [0, 0];
96
144
  for (const prn of prns) {
97
145
  const psr = pseudoranges.get(prn);
98
146
  const eph = ephemerides.get(prn);
@@ -111,17 +159,24 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
111
159
  const uy = (y2 - sy) / rho;
112
160
  const uz = (z2 - sz) / rho;
113
161
  let elev = Math.PI / 2;
162
+ let azim = 0;
114
163
  let weight = 1;
115
- const positionSane = x2 * x2 + y2 * y2 + z2 * z2 > 1e12;
164
+ const positionSane = positionSaneIter;
116
165
  if (positionSane) {
117
166
  const azel = ecefToAzEl(x2, y2, z2, sx, sy, sz);
118
167
  elev = azel.el;
168
+ azim = azel.az;
119
169
  if (iter >= 2 && elev < elevationMaskDeg * Math.PI / 180) continue;
120
170
  const sinEl = Math.max(Math.sin(elev), 0.1);
121
171
  weight = sinEl * sinEl;
122
172
  }
123
173
  const tropo = troposphere && positionSane ? tropoDelay(elev) : 0;
124
- const predicted = rho + clk - C_LIGHT * dts + tropo;
174
+ let ionoM = 0;
175
+ if (iono && positionSane) {
176
+ const f = PRIMARY_FREQ_HZ[sys] ?? F_L1;
177
+ ionoM = C_LIGHT * klobucharDelay(iono, rxLat, rxLon, azim, elev, gpsTow) * (F_L1 / f * (F_L1 / f));
178
+ }
179
+ const predicted = rho + clk - C_LIGHT * dts + tropo + ionoM;
125
180
  const v = psr - predicted;
126
181
  const h = new Array(dim).fill(0);
127
182
  h[0] = ux;
@@ -200,6 +255,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
200
255
  }
201
256
 
202
257
  export {
258
+ klobucharDelay,
203
259
  satClockCorrection,
204
260
  ionoFree,
205
261
  solveSpp