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.
- package/dist/{chunk-AK6LNWZX.js → chunk-DMNFB7Q6.js} +57 -7
- package/dist/{chunk-77VUSDNI.js → chunk-HXF7XVW7.js} +499 -1
- package/dist/{chunk-ZTFKRZMM.js → chunk-LKFSXVIZ.js} +60 -4
- package/dist/index.cjs +623 -12
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +27 -5
- package/dist/orbit.cjs +59 -7
- package/dist/orbit.d.cts +12 -2
- package/dist/orbit.d.ts +12 -2
- package/dist/orbit.js +5 -1
- package/dist/positioning.cjs +101 -10
- package/dist/positioning.d.cts +44 -4
- package/dist/positioning.d.ts +44 -4
- package/dist/positioning.js +4 -2
- package/dist/rinex.cjs +508 -2
- package/dist/rinex.d.cts +129 -1
- package/dist/rinex.d.ts +129 -1
- package/dist/rinex.js +19 -3
- package/package.json +1 -1
|
@@ -2,12 +2,46 @@ import {
|
|
|
2
2
|
computeDop,
|
|
3
3
|
computeSatPosition,
|
|
4
4
|
ecefToAzEl
|
|
5
|
-
} from "./chunk-
|
|
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 =
|
|
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
|
-
|
|
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
|