gnss-js 2.0.0 → 2.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/{chunk-2CMAFEHI.js → chunk-DWUQRJ37.js} +284 -139
- package/dist/has-BaXnQarR.d.cts +123 -0
- package/dist/has-BaXnQarR.d.ts +123 -0
- package/dist/index.cjs +292 -143
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +9 -1
- package/dist/positioning.cjs +286 -137
- package/dist/positioning.d.cts +161 -2
- package/dist/positioning.d.ts +161 -2
- package/dist/positioning.js +9 -1
- package/dist/sbf.d.cts +2 -123
- package/dist/sbf.d.ts +2 -123
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,6 +79,7 @@ __export(src_exports, {
|
|
|
79
79
|
MultipathAccumulator: () => MultipathAccumulator,
|
|
80
80
|
OEM4_HLEN: () => OEM4_HLEN,
|
|
81
81
|
OMEGA_E: () => OMEGA_E,
|
|
82
|
+
PppEngine: () => PppEngine,
|
|
82
83
|
REFERENCE_FRAMES: () => REFERENCE_FRAMES,
|
|
83
84
|
RINEX_CODES: () => RINEX_CODES,
|
|
84
85
|
RTCM2_MESSAGE_NAMES: () => RTCM2_MESSAGE_NAMES,
|
|
@@ -106,6 +107,7 @@ __export(src_exports, {
|
|
|
106
107
|
SYS_SHORT: () => SYS_SHORT,
|
|
107
108
|
SbasProcessor: () => SbasProcessor,
|
|
108
109
|
Scale: () => Scale,
|
|
110
|
+
Sp3EphemerisSource: () => Sp3EphemerisSource,
|
|
109
111
|
WGS84_ECCENTRICITY_SQUARED: () => WGS84_ECCENTRICITY_SQUARED,
|
|
110
112
|
WGS84_FLATTENING: () => WGS84_FLATTENING,
|
|
111
113
|
WGS84_SEMI_MAJOR_AXIS: () => WGS84_SEMI_MAJOR_AXIS,
|
|
@@ -116,6 +118,7 @@ __export(src_exports, {
|
|
|
116
118
|
analyzeQuality: () => analyzeQuality,
|
|
117
119
|
applyHelmert: () => applyHelmert,
|
|
118
120
|
applyIonoDcb: () => applyIonoDcb,
|
|
121
|
+
applyOrbitClock: () => applyOrbitClock,
|
|
119
122
|
biasMetres: () => biasMetres,
|
|
120
123
|
binexCrc16: () => binexCrc16,
|
|
121
124
|
binexCrc32: () => binexCrc32,
|
|
@@ -240,6 +243,7 @@ __export(src_exports, {
|
|
|
240
243
|
glonassPosition: () => glonassPosition,
|
|
241
244
|
gmst: () => gmst,
|
|
242
245
|
greatCircleMidpoint: () => greatCircleMidpoint,
|
|
246
|
+
hasToOrbitClock: () => hasToOrbitClock,
|
|
243
247
|
hdrLine: () => hdrLine,
|
|
244
248
|
horizonDistance: () => horizonDistance,
|
|
245
249
|
ionoFree: () => ionoFree,
|
|
@@ -4069,7 +4073,7 @@ function parseBiasSinex(text) {
|
|
|
4069
4073
|
const endMs = parseEpoch(line.slice(50, 64), Infinity);
|
|
4070
4074
|
const tail = line.slice(65).trim().split(/\s+/);
|
|
4071
4075
|
if (tail.length < 2) continue;
|
|
4072
|
-
const
|
|
4076
|
+
const unit2 = tail[0];
|
|
4073
4077
|
const value = Number(tail[1]);
|
|
4074
4078
|
if (!Number.isFinite(value)) continue;
|
|
4075
4079
|
records.push({
|
|
@@ -4081,7 +4085,7 @@ function parseBiasSinex(text) {
|
|
|
4081
4085
|
startMs,
|
|
4082
4086
|
endMs,
|
|
4083
4087
|
value,
|
|
4084
|
-
unit
|
|
4088
|
+
unit: unit2
|
|
4085
4089
|
});
|
|
4086
4090
|
}
|
|
4087
4091
|
const bySat = /* @__PURE__ */ new Map();
|
|
@@ -9115,14 +9119,14 @@ function parseOrbitBlock(c, masks) {
|
|
|
9115
9119
|
const gnssIod = c.u(IOD_BITS[sys.system]);
|
|
9116
9120
|
const rad = c.s(13);
|
|
9117
9121
|
const inT = c.s(12);
|
|
9118
|
-
const
|
|
9122
|
+
const cross3 = c.s(12);
|
|
9119
9123
|
corrections.push({
|
|
9120
9124
|
system: sys.system,
|
|
9121
9125
|
prn,
|
|
9122
9126
|
gnssIod,
|
|
9123
9127
|
deltaRadial: rad === -4096 ? null : rad * 25e-4,
|
|
9124
9128
|
deltaInTrack: inT === -2048 ? null : inT * 8e-3,
|
|
9125
|
-
deltaCrossTrack:
|
|
9129
|
+
deltaCrossTrack: cross3 === -2048 ? null : cross3 * 8e-3
|
|
9126
9130
|
});
|
|
9127
9131
|
}
|
|
9128
9132
|
}
|
|
@@ -14837,6 +14841,55 @@ var SbasProcessor = class {
|
|
|
14837
14841
|
}
|
|
14838
14842
|
};
|
|
14839
14843
|
|
|
14844
|
+
// src/positioning/ssr-apply.ts
|
|
14845
|
+
var cross = (a, b) => [
|
|
14846
|
+
a[1] * b[2] - a[2] * b[1],
|
|
14847
|
+
a[2] * b[0] - a[0] * b[2],
|
|
14848
|
+
a[0] * b[1] - a[1] * b[0]
|
|
14849
|
+
];
|
|
14850
|
+
var norm = (a) => Math.hypot(a[0], a[1], a[2]);
|
|
14851
|
+
var unit = (a) => {
|
|
14852
|
+
const n = norm(a);
|
|
14853
|
+
return n > 0 ? [a[0] / n, a[1] / n, a[2] / n] : [0, 0, 0];
|
|
14854
|
+
};
|
|
14855
|
+
function applyOrbitClock(eph, corr, timeMs) {
|
|
14856
|
+
if (eph.system === "R" || eph.system === "S") return null;
|
|
14857
|
+
if (eph.iode !== corr.iod) return null;
|
|
14858
|
+
const age = (timeMs - corr.refTimeMs) / 1e3;
|
|
14859
|
+
if (corr.validitySeconds != null && (age < -1 || age > corr.validitySeconds))
|
|
14860
|
+
return null;
|
|
14861
|
+
const s = computeSatPosition(eph, timeMs);
|
|
14862
|
+
if (!Number.isFinite(s.x)) return null;
|
|
14863
|
+
const p = [s.x, s.y, s.z];
|
|
14864
|
+
const v = [s.vx, s.vy, s.vz];
|
|
14865
|
+
const er = unit(p);
|
|
14866
|
+
const en = unit(cross(p, v));
|
|
14867
|
+
const ea = cross(en, er);
|
|
14868
|
+
const dr = corr.radial + (corr.dotRadial ?? 0) * age;
|
|
14869
|
+
const da = corr.along + (corr.dotAlong ?? 0) * age;
|
|
14870
|
+
const dc = corr.cross + (corr.dotCross ?? 0) * age;
|
|
14871
|
+
const x = s.x + dr * er[0] + da * ea[0] + dc * en[0];
|
|
14872
|
+
const y = s.y + dr * er[1] + da * ea[1] + dc * en[1];
|
|
14873
|
+
const z = s.z + dr * er[2] + da * ea[2] + dc * en[2];
|
|
14874
|
+
const clockM = corr.clockC0 + (corr.clockC1 ?? 0) * age + (corr.clockC2 ?? 0) * age * age + (corr.highRateClock ?? 0);
|
|
14875
|
+
return { x, y, z, clockOffsetS: clockM / C_LIGHT };
|
|
14876
|
+
}
|
|
14877
|
+
function hasToOrbitClock(orbit, clock, refTimeMs, validitySeconds) {
|
|
14878
|
+
if (orbit.deltaRadial == null || orbit.deltaInTrack == null || orbit.deltaCrossTrack == null)
|
|
14879
|
+
return null;
|
|
14880
|
+
const clockC0 = clock && clock.deltaClock != null && !clock.notUsable ? clock.deltaClock : 0;
|
|
14881
|
+
return {
|
|
14882
|
+
prn: orbit.prn,
|
|
14883
|
+
iod: orbit.gnssIod,
|
|
14884
|
+
refTimeMs,
|
|
14885
|
+
radial: orbit.deltaRadial,
|
|
14886
|
+
along: orbit.deltaInTrack,
|
|
14887
|
+
cross: orbit.deltaCrossTrack,
|
|
14888
|
+
clockC0,
|
|
14889
|
+
validitySeconds
|
|
14890
|
+
};
|
|
14891
|
+
}
|
|
14892
|
+
|
|
14840
14893
|
// src/positioning/ppp-tropo.ts
|
|
14841
14894
|
var HYD_AVG_A = [
|
|
14842
14895
|
0.0012769934,
|
|
@@ -15094,14 +15147,14 @@ function buildPppAntenna(antex) {
|
|
|
15094
15147
|
}
|
|
15095
15148
|
};
|
|
15096
15149
|
}
|
|
15097
|
-
function
|
|
15150
|
+
function cross2(a, b) {
|
|
15098
15151
|
return [
|
|
15099
15152
|
a[1] * b[2] - a[2] * b[1],
|
|
15100
15153
|
a[2] * b[0] - a[0] * b[2],
|
|
15101
15154
|
a[0] * b[1] - a[1] * b[0]
|
|
15102
15155
|
];
|
|
15103
15156
|
}
|
|
15104
|
-
function
|
|
15157
|
+
function norm2(a) {
|
|
15105
15158
|
const n = Math.hypot(a[0], a[1], a[2]) || 1;
|
|
15106
15159
|
return [a[0] / n, a[1] / n, a[2] / n];
|
|
15107
15160
|
}
|
|
@@ -15109,14 +15162,14 @@ function dot(a, b) {
|
|
|
15109
15162
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
15110
15163
|
}
|
|
15111
15164
|
function satBodyFrame(satEcef, sunEcef2) {
|
|
15112
|
-
const z =
|
|
15113
|
-
const eSun =
|
|
15165
|
+
const z = norm2([-satEcef[0], -satEcef[1], -satEcef[2]]);
|
|
15166
|
+
const eSun = norm2([
|
|
15114
15167
|
sunEcef2[0] - satEcef[0],
|
|
15115
15168
|
sunEcef2[1] - satEcef[1],
|
|
15116
15169
|
sunEcef2[2] - satEcef[2]
|
|
15117
15170
|
]);
|
|
15118
|
-
const y =
|
|
15119
|
-
const x =
|
|
15171
|
+
const y = norm2(cross2(z, eSun));
|
|
15172
|
+
const x = norm2(cross2(y, z));
|
|
15120
15173
|
return { x, y, z };
|
|
15121
15174
|
}
|
|
15122
15175
|
function satPcoToEcef(pcoBody, frame) {
|
|
@@ -15157,7 +15210,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15157
15210
|
const kx = satFrame.x;
|
|
15158
15211
|
const ky = satFrame.y;
|
|
15159
15212
|
const kdotx = dot(k, kx);
|
|
15160
|
-
const kcrossY =
|
|
15213
|
+
const kcrossY = cross2(k, ky);
|
|
15161
15214
|
const dS = [
|
|
15162
15215
|
kx[0] - k[0] * kdotx - kcrossY[0],
|
|
15163
15216
|
kx[1] - k[1] * kdotx - kcrossY[1],
|
|
@@ -15166,7 +15219,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15166
15219
|
const north = enuToEcef([0, 1, 0], latRad, lonRad);
|
|
15167
15220
|
const east = enuToEcef([1, 0, 0], latRad, lonRad);
|
|
15168
15221
|
const kdotn = dot(k, north);
|
|
15169
|
-
const kcrossE =
|
|
15222
|
+
const kcrossE = cross2(k, east);
|
|
15170
15223
|
const dR = [
|
|
15171
15224
|
north[0] - k[0] * kdotn + kcrossE[0],
|
|
15172
15225
|
north[1] - k[1] * kdotn + kcrossE[1],
|
|
@@ -15176,7 +15229,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15176
15229
|
const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
|
|
15177
15230
|
let cosPhi = dot(dS, dR) / (nS * nR);
|
|
15178
15231
|
cosPhi = Math.max(-1, Math.min(1, cosPhi));
|
|
15179
|
-
const zeta =
|
|
15232
|
+
const zeta = cross2(dS, dR);
|
|
15180
15233
|
const sign = dot(k, zeta) >= 0 ? 1 : -1;
|
|
15181
15234
|
const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
|
|
15182
15235
|
const prev = state.get(prn);
|
|
@@ -15314,13 +15367,35 @@ function ifCoeffs(f1, f2) {
|
|
|
15314
15367
|
const lambdaIf = C_LIGHT / (f1 + f2);
|
|
15315
15368
|
return { g, lambdaIf };
|
|
15316
15369
|
}
|
|
15370
|
+
var Sp3EphemerisSource = class {
|
|
15371
|
+
constructor(sp3, clk) {
|
|
15372
|
+
this.sp3 = sp3;
|
|
15373
|
+
this.clk = clk;
|
|
15374
|
+
}
|
|
15375
|
+
satState(prn, tEmitMs) {
|
|
15376
|
+
const p = sp3Position(this.sp3, prn, tEmitMs);
|
|
15377
|
+
if (!p || p.clk == null) return null;
|
|
15378
|
+
const pPlus = sp3Position(this.sp3, prn, tEmitMs + 500);
|
|
15379
|
+
const pMinus = sp3Position(this.sp3, prn, tEmitMs - 500);
|
|
15380
|
+
let vx = 0;
|
|
15381
|
+
let vy = 0;
|
|
15382
|
+
let vz = 0;
|
|
15383
|
+
if (pPlus && pMinus) {
|
|
15384
|
+
vx = pPlus.x - pMinus.x;
|
|
15385
|
+
vy = pPlus.y - pMinus.y;
|
|
15386
|
+
vz = pPlus.z - pMinus.z;
|
|
15387
|
+
}
|
|
15388
|
+
const clkS = (this.clk ? clkBias(this.clk, prn, tEmitMs) : null) ?? p.clk;
|
|
15389
|
+
return { x: p.x, y: p.y, z: p.z, vx, vy, vz, clkS };
|
|
15390
|
+
}
|
|
15391
|
+
};
|
|
15317
15392
|
function sagnacRotate(x, y, z, travelS) {
|
|
15318
15393
|
const theta = OMEGA_E * travelS;
|
|
15319
15394
|
const c = Math.cos(theta);
|
|
15320
15395
|
const s = Math.sin(theta);
|
|
15321
15396
|
return [x * c + y * s, -x * s + y * c, z];
|
|
15322
15397
|
}
|
|
15323
|
-
function satStateAtEmission(
|
|
15398
|
+
function satStateAtEmission(source, prn, recvTimeMs, rcv) {
|
|
15324
15399
|
let travelS = 0.075;
|
|
15325
15400
|
let sx = 0;
|
|
15326
15401
|
let sy = 0;
|
|
@@ -15329,18 +15404,11 @@ function satStateAtEmission(sp3, prn, recvTimeMs, rcv, clk) {
|
|
|
15329
15404
|
let velDotPos = 0;
|
|
15330
15405
|
for (let iter = 0; iter < 3; iter++) {
|
|
15331
15406
|
const tEmit = recvTimeMs - travelS * 1e3;
|
|
15332
|
-
const
|
|
15333
|
-
if (!
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
const vx = (pPlus.x - pMinus.x) / 1;
|
|
15338
|
-
const vy = (pPlus.y - pMinus.y) / 1;
|
|
15339
|
-
const vz = (pPlus.z - pMinus.z) / 1;
|
|
15340
|
-
velDotPos = p.x * vx + p.y * vy + p.z * vz;
|
|
15341
|
-
}
|
|
15342
|
-
clkS = (clk && clkBias(clk, prn, tEmit)) ?? p.clk;
|
|
15343
|
-
const [rx, ry, rz] = sagnacRotate(p.x, p.y, p.z, travelS);
|
|
15407
|
+
const s = source.satState(prn, tEmit);
|
|
15408
|
+
if (!s) return null;
|
|
15409
|
+
velDotPos = s.x * s.vx + s.y * s.vy + s.z * s.vz;
|
|
15410
|
+
clkS = s.clkS;
|
|
15411
|
+
const [rx, ry, rz] = sagnacRotate(s.x, s.y, s.z, travelS);
|
|
15344
15412
|
sx = rx;
|
|
15345
15413
|
sy = ry;
|
|
15346
15414
|
sz = rz;
|
|
@@ -15362,39 +15430,72 @@ var IDX_ZWD = 3;
|
|
|
15362
15430
|
var NBASE = 4;
|
|
15363
15431
|
var CLK_VAR = 1e10;
|
|
15364
15432
|
var POS_VAR = 60 * 60;
|
|
15365
|
-
|
|
15366
|
-
|
|
15367
|
-
|
|
15368
|
-
|
|
15369
|
-
|
|
15370
|
-
|
|
15371
|
-
|
|
15372
|
-
|
|
15373
|
-
|
|
15374
|
-
|
|
15375
|
-
|
|
15376
|
-
|
|
15377
|
-
|
|
15378
|
-
|
|
15379
|
-
|
|
15380
|
-
|
|
15381
|
-
|
|
15382
|
-
|
|
15383
|
-
|
|
15384
|
-
|
|
15385
|
-
|
|
15386
|
-
|
|
15387
|
-
|
|
15388
|
-
|
|
15389
|
-
|
|
15390
|
-
|
|
15391
|
-
|
|
15392
|
-
|
|
15393
|
-
|
|
15394
|
-
|
|
15395
|
-
|
|
15433
|
+
var PppEngine = class {
|
|
15434
|
+
source;
|
|
15435
|
+
opts;
|
|
15436
|
+
elevMask;
|
|
15437
|
+
codeSigma;
|
|
15438
|
+
phaseSigma;
|
|
15439
|
+
ztdQ;
|
|
15440
|
+
kinematic;
|
|
15441
|
+
corrections;
|
|
15442
|
+
truth;
|
|
15443
|
+
// Filter state (reset() initialises; mutated in place across epochs).
|
|
15444
|
+
x;
|
|
15445
|
+
P;
|
|
15446
|
+
clkIdx;
|
|
15447
|
+
clockSeeded;
|
|
15448
|
+
ambIdx;
|
|
15449
|
+
lastSeen;
|
|
15450
|
+
arcs;
|
|
15451
|
+
arcSnap;
|
|
15452
|
+
mwState;
|
|
15453
|
+
series;
|
|
15454
|
+
ei = 0;
|
|
15455
|
+
t0 = 0;
|
|
15456
|
+
convergenceSec = null;
|
|
15457
|
+
convergedStreak = 0;
|
|
15458
|
+
constructor(opts, source) {
|
|
15459
|
+
this.opts = opts;
|
|
15460
|
+
this.source = source;
|
|
15461
|
+
this.elevMask = (opts.elevationMaskDeg ?? 10) * Math.PI / 180;
|
|
15462
|
+
this.codeSigma = opts.codeSigma ?? 3;
|
|
15463
|
+
this.phaseSigma = opts.phaseSigma ?? 0.01;
|
|
15464
|
+
this.ztdQ = opts.ztdProcessNoise ?? 1e-8;
|
|
15465
|
+
this.kinematic = opts.mode === "kinematic";
|
|
15466
|
+
this.corrections = opts.corrections;
|
|
15467
|
+
this.truth = opts.groundTruth;
|
|
15468
|
+
this.reset();
|
|
15469
|
+
}
|
|
15470
|
+
/** Reinitialise the filter (fresh session). */
|
|
15471
|
+
reset() {
|
|
15472
|
+
const { opts } = this;
|
|
15473
|
+
this.x = [opts.aprioriPos[0], opts.aprioriPos[1], opts.aprioriPos[2], 0.1];
|
|
15474
|
+
const P = [];
|
|
15475
|
+
for (let i = 0; i < NBASE; i++) P.push(new Array(NBASE).fill(0));
|
|
15476
|
+
P[IDX_X][IDX_X] = 100 * 100;
|
|
15477
|
+
P[IDX_Y][IDX_Y] = 100 * 100;
|
|
15478
|
+
P[IDX_Z][IDX_Z] = 100 * 100;
|
|
15479
|
+
P[IDX_ZWD][IDX_ZWD] = 0.5 * 0.5;
|
|
15480
|
+
this.P = P;
|
|
15481
|
+
this.clkIdx = /* @__PURE__ */ new Map();
|
|
15482
|
+
this.clockSeeded = /* @__PURE__ */ new Set();
|
|
15483
|
+
this.ambIdx = /* @__PURE__ */ new Map();
|
|
15484
|
+
this.lastSeen = /* @__PURE__ */ new Map();
|
|
15485
|
+
this.arcs = [];
|
|
15486
|
+
this.arcSnap = /* @__PURE__ */ new Map();
|
|
15487
|
+
this.mwState = /* @__PURE__ */ new Map();
|
|
15488
|
+
this.series = [];
|
|
15489
|
+
this.ei = 0;
|
|
15490
|
+
this.t0 = 0;
|
|
15491
|
+
this.convergenceSec = null;
|
|
15492
|
+
this.convergedStreak = 0;
|
|
15493
|
+
}
|
|
15494
|
+
flushArc(prn, minEpochs = 10) {
|
|
15495
|
+
const s = this.arcSnap.get(prn);
|
|
15496
|
+
this.arcSnap.delete(prn);
|
|
15396
15497
|
if (!s || s.nEpochs < minEpochs) return;
|
|
15397
|
-
arcs.push({
|
|
15498
|
+
this.arcs.push({
|
|
15398
15499
|
prn,
|
|
15399
15500
|
aIF: s.aIF,
|
|
15400
15501
|
mwCyc: s.mwCyc,
|
|
@@ -15405,64 +15506,88 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15405
15506
|
startMs: s.startMs,
|
|
15406
15507
|
endMs: s.endMs
|
|
15407
15508
|
});
|
|
15408
|
-
}
|
|
15409
|
-
|
|
15410
|
-
|
|
15509
|
+
}
|
|
15510
|
+
/** Detect a cycle slip via the Melbourne–Wübbena wide-lane ambiguity. */
|
|
15511
|
+
detectSlip(o, ei) {
|
|
15411
15512
|
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
15412
15513
|
const lw = o.l1 - o.l2;
|
|
15413
15514
|
const pn = (o.f1 * o.c1 + o.f2 * o.c2) / (o.f1 + o.f2);
|
|
15414
15515
|
const mw = lw - pn / lamW;
|
|
15415
|
-
const st = mwState.get(o.prn);
|
|
15516
|
+
const st = this.mwState.get(o.prn);
|
|
15416
15517
|
let slip = o.slip;
|
|
15417
15518
|
if (!st || ei - st.lastEi > 2)
|
|
15418
15519
|
slip = true;
|
|
15419
15520
|
else if (Math.abs(mw - st.mean) > 4) slip = true;
|
|
15420
|
-
if (slip) mwState.set(o.prn, { mean: mw, n: 1, lastEi: ei });
|
|
15521
|
+
if (slip) this.mwState.set(o.prn, { mean: mw, n: 1, lastEi: ei });
|
|
15421
15522
|
else {
|
|
15422
15523
|
const n = st.n + 1;
|
|
15423
|
-
mwState.set(o.prn, {
|
|
15524
|
+
this.mwState.set(o.prn, {
|
|
15424
15525
|
mean: st.mean + (mw - st.mean) / Math.min(n, 100),
|
|
15425
15526
|
n,
|
|
15426
15527
|
lastEi: ei
|
|
15427
15528
|
});
|
|
15428
15529
|
}
|
|
15429
15530
|
return slip;
|
|
15430
|
-
}
|
|
15431
|
-
|
|
15432
|
-
const idx = x.length;
|
|
15433
|
-
x.push(initVal);
|
|
15434
|
-
for (const row of P) row.push(0);
|
|
15435
|
-
P.push(new Array(x.length).fill(0));
|
|
15436
|
-
P[idx][idx] = initVar;
|
|
15531
|
+
}
|
|
15532
|
+
growState(initVal, initVar) {
|
|
15533
|
+
const idx = this.x.length;
|
|
15534
|
+
this.x.push(initVal);
|
|
15535
|
+
for (const row of this.P) row.push(0);
|
|
15536
|
+
this.P.push(new Array(this.x.length).fill(0));
|
|
15537
|
+
this.P[idx][idx] = initVar;
|
|
15437
15538
|
return idx;
|
|
15438
|
-
}
|
|
15439
|
-
|
|
15440
|
-
x.splice(idx, 1);
|
|
15441
|
-
P.splice(idx, 1);
|
|
15442
|
-
for (const row of P) row.splice(idx, 1);
|
|
15443
|
-
for (const [prn, i] of ambIdx) {
|
|
15444
|
-
if (i === idx) ambIdx.delete(prn);
|
|
15445
|
-
else if (i > idx) ambIdx.set(prn, i - 1);
|
|
15539
|
+
}
|
|
15540
|
+
dropState(idx) {
|
|
15541
|
+
this.x.splice(idx, 1);
|
|
15542
|
+
this.P.splice(idx, 1);
|
|
15543
|
+
for (const row of this.P) row.splice(idx, 1);
|
|
15544
|
+
for (const [prn, i] of this.ambIdx) {
|
|
15545
|
+
if (i === idx) this.ambIdx.delete(prn);
|
|
15546
|
+
else if (i > idx) this.ambIdx.set(prn, i - 1);
|
|
15446
15547
|
}
|
|
15447
|
-
for (const [sys, i] of clkIdx) {
|
|
15448
|
-
if (i > idx) clkIdx.set(sys, i - 1);
|
|
15548
|
+
for (const [sys, i] of this.clkIdx) {
|
|
15549
|
+
if (i > idx) this.clkIdx.set(sys, i - 1);
|
|
15449
15550
|
}
|
|
15450
|
-
}
|
|
15451
|
-
|
|
15452
|
-
|
|
15551
|
+
}
|
|
15552
|
+
/** State index of a constellation's receiver clock, creating it lazily. */
|
|
15553
|
+
clockOf(sys) {
|
|
15554
|
+
let i = this.clkIdx.get(sys);
|
|
15453
15555
|
if (i === void 0) {
|
|
15454
|
-
i = growState(0, CLK_VAR);
|
|
15455
|
-
clkIdx.set(sys, i);
|
|
15556
|
+
i = this.growState(0, CLK_VAR);
|
|
15557
|
+
this.clkIdx.set(sys, i);
|
|
15456
15558
|
}
|
|
15457
15559
|
return i;
|
|
15458
|
-
}
|
|
15459
|
-
|
|
15460
|
-
|
|
15461
|
-
|
|
15462
|
-
|
|
15463
|
-
|
|
15464
|
-
|
|
15465
|
-
|
|
15560
|
+
}
|
|
15561
|
+
/** Process one epoch, carrying the filter forward; returns its result. */
|
|
15562
|
+
process(epoch) {
|
|
15563
|
+
const {
|
|
15564
|
+
source,
|
|
15565
|
+
opts,
|
|
15566
|
+
elevMask,
|
|
15567
|
+
codeSigma,
|
|
15568
|
+
phaseSigma,
|
|
15569
|
+
ztdQ,
|
|
15570
|
+
kinematic,
|
|
15571
|
+
corrections,
|
|
15572
|
+
truth,
|
|
15573
|
+
x,
|
|
15574
|
+
P,
|
|
15575
|
+
clkIdx,
|
|
15576
|
+
clockSeeded,
|
|
15577
|
+
ambIdx,
|
|
15578
|
+
lastSeen,
|
|
15579
|
+
arcSnap,
|
|
15580
|
+
mwState,
|
|
15581
|
+
series
|
|
15582
|
+
} = this;
|
|
15583
|
+
const flushArc = this.flushArc.bind(this);
|
|
15584
|
+
const detectSlip = this.detectSlip.bind(this);
|
|
15585
|
+
const growState = this.growState.bind(this);
|
|
15586
|
+
const dropState = this.dropState.bind(this);
|
|
15587
|
+
const clockOf = this.clockOf.bind(this);
|
|
15588
|
+
const ei = this.ei;
|
|
15589
|
+
if (ei === 0) this.t0 = epoch.timeMs;
|
|
15590
|
+
const t0 = this.t0;
|
|
15466
15591
|
if (kinematic && ei > 0) {
|
|
15467
15592
|
for (const p of [IDX_X, IDX_Y, IDX_Z]) {
|
|
15468
15593
|
for (let j = 0; j < x.length; j++) {
|
|
@@ -15483,7 +15608,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15483
15608
|
for (const o of epoch.obs) {
|
|
15484
15609
|
if (o.c1 === 0 || o.c2 === 0 || o.l1 === 0 || o.l2 === 0) continue;
|
|
15485
15610
|
const slip = detectSlip(o, ei);
|
|
15486
|
-
const sat = satStateAtEmission(
|
|
15611
|
+
const sat = satStateAtEmission(source, o.prn, epoch.timeMs, rcv);
|
|
15487
15612
|
if (!sat) continue;
|
|
15488
15613
|
const [elRad, azRad] = getAer(
|
|
15489
15614
|
sat.state.x,
|
|
@@ -15503,7 +15628,9 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15503
15628
|
const lam1 = C_LIGHT / o.f1;
|
|
15504
15629
|
const lam2 = C_LIGHT / o.f2;
|
|
15505
15630
|
if (o.c1 === 0 || o.c2 === 0 || o.l1 === 0 || o.l2 === 0) continue;
|
|
15506
|
-
const
|
|
15631
|
+
const b1 = source.codeBias?.(o.prn, o.code1 ?? "", epoch.timeMs) ?? 0;
|
|
15632
|
+
const b2 = source.codeBias?.(o.prn, o.code2 ?? "", epoch.timeMs) ?? 0;
|
|
15633
|
+
const pIf = g * (o.c1 - b1) - (g - 1) * (o.c2 - b2);
|
|
15507
15634
|
const lIf = g * (o.l1 * lam1) - (g - 1) * (o.l2 * lam2);
|
|
15508
15635
|
if (!Number.isFinite(pIf) || !Number.isFinite(lIf)) continue;
|
|
15509
15636
|
const trop = opts.troposphere ?? true ? niellMapping(elRad, latRad, heightM, epoch.timeMs) : { zhd: 0, mh: 0, mw: 0 };
|
|
@@ -15690,16 +15817,16 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15690
15817
|
pos[2] - truth[2]
|
|
15691
15818
|
);
|
|
15692
15819
|
if (error3d < 0.1) {
|
|
15693
|
-
convergedStreak++;
|
|
15694
|
-
if (convergedStreak >= 10 && convergenceSec == null) {
|
|
15695
|
-
convergenceSec = (epoch.timeMs - t0) / 1e3;
|
|
15820
|
+
this.convergedStreak++;
|
|
15821
|
+
if (this.convergedStreak >= 10 && this.convergenceSec == null) {
|
|
15822
|
+
this.convergenceSec = (epoch.timeMs - t0) / 1e3;
|
|
15696
15823
|
}
|
|
15697
15824
|
} else {
|
|
15698
|
-
convergedStreak = 0;
|
|
15699
|
-
convergenceSec = null;
|
|
15825
|
+
this.convergedStreak = 0;
|
|
15826
|
+
this.convergenceSec = null;
|
|
15700
15827
|
}
|
|
15701
15828
|
}
|
|
15702
|
-
|
|
15829
|
+
const result = {
|
|
15703
15830
|
timeMs: epoch.timeMs,
|
|
15704
15831
|
enu,
|
|
15705
15832
|
error3d,
|
|
@@ -15708,50 +15835,68 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15708
15835
|
ztdWet: x[IDX_ZWD],
|
|
15709
15836
|
ztdHydrostatic: epochZhd,
|
|
15710
15837
|
phaseResRms: nPhaseRes > 0 ? Math.sqrt(sumPhaseResSq / nPhaseRes) : 0
|
|
15711
|
-
}
|
|
15712
|
-
|
|
15713
|
-
|
|
15714
|
-
|
|
15715
|
-
|
|
15716
|
-
|
|
15717
|
-
|
|
15718
|
-
|
|
15719
|
-
|
|
15720
|
-
|
|
15721
|
-
|
|
15722
|
-
|
|
15723
|
-
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
|
|
15838
|
+
};
|
|
15839
|
+
series.push(result);
|
|
15840
|
+
this.ei = ei + 1;
|
|
15841
|
+
return result;
|
|
15842
|
+
}
|
|
15843
|
+
/** Finalise the session: capture the AR state, flush open arcs, assemble. */
|
|
15844
|
+
solution() {
|
|
15845
|
+
const { opts, x, P, ambIdx, arcSnap, mwState, arcs, series, truth } = this;
|
|
15846
|
+
const flushArc = this.flushArc.bind(this);
|
|
15847
|
+
let finalState;
|
|
15848
|
+
if (opts.exposeState) {
|
|
15849
|
+
const ambs = [];
|
|
15850
|
+
for (const [prn, index] of ambIdx) {
|
|
15851
|
+
const s = arcSnap.get(prn);
|
|
15852
|
+
if (!s || s.nEpochs < 10) continue;
|
|
15853
|
+
ambs.push({
|
|
15854
|
+
prn,
|
|
15855
|
+
index,
|
|
15856
|
+
aIF: x[index],
|
|
15857
|
+
mwCyc: mwState.get(prn)?.mean ?? s.mwCyc,
|
|
15858
|
+
f1: s.f1,
|
|
15859
|
+
f2: s.f2,
|
|
15860
|
+
elevDeg: s.elevSum / s.nEpochs
|
|
15861
|
+
});
|
|
15862
|
+
}
|
|
15863
|
+
finalState = {
|
|
15864
|
+
position: [x[IDX_X], x[IDX_Y], x[IDX_Z]],
|
|
15865
|
+
covariance: P.map((row) => row.slice()),
|
|
15866
|
+
ambiguities: ambs
|
|
15867
|
+
};
|
|
15728
15868
|
}
|
|
15729
|
-
|
|
15730
|
-
|
|
15731
|
-
|
|
15732
|
-
|
|
15869
|
+
for (const prn of [...arcSnap.keys()]) flushArc(prn);
|
|
15870
|
+
const finalPos = [
|
|
15871
|
+
x[IDX_X],
|
|
15872
|
+
x[IDX_Y],
|
|
15873
|
+
x[IDX_Z]
|
|
15874
|
+
];
|
|
15875
|
+
const llh = ecefToGeodetic(finalPos[0], finalPos[1], finalPos[2]);
|
|
15876
|
+
const finalError3d = truth ? Math.hypot(
|
|
15877
|
+
finalPos[0] - truth[0],
|
|
15878
|
+
finalPos[1] - truth[1],
|
|
15879
|
+
finalPos[2] - truth[2]
|
|
15880
|
+
) : null;
|
|
15881
|
+
return {
|
|
15882
|
+
position: finalPos,
|
|
15883
|
+
llh,
|
|
15884
|
+
series,
|
|
15885
|
+
ztdWet: x[IDX_ZWD],
|
|
15886
|
+
ztdHydrostatic: series.length ? series[series.length - 1].ztdHydrostatic : 0,
|
|
15887
|
+
epochsUsed: series.length,
|
|
15888
|
+
convergenceSec: this.convergenceSec,
|
|
15889
|
+
finalError3d,
|
|
15890
|
+
arcs,
|
|
15891
|
+
finalState
|
|
15733
15892
|
};
|
|
15734
15893
|
}
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
const
|
|
15738
|
-
const
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
finalPos[2] - truth[2]
|
|
15742
|
-
) : null;
|
|
15743
|
-
return {
|
|
15744
|
-
position: finalPos,
|
|
15745
|
-
llh,
|
|
15746
|
-
series,
|
|
15747
|
-
ztdWet: x[IDX_ZWD],
|
|
15748
|
-
ztdHydrostatic: series.length ? series[series.length - 1].ztdHydrostatic : 0,
|
|
15749
|
-
epochsUsed: epochs.length,
|
|
15750
|
-
convergenceSec,
|
|
15751
|
-
finalError3d,
|
|
15752
|
-
arcs,
|
|
15753
|
-
finalState
|
|
15754
|
-
};
|
|
15894
|
+
};
|
|
15895
|
+
function solvePpp(epochs, sp3OrSource, opts) {
|
|
15896
|
+
const source = "satState" in sp3OrSource ? sp3OrSource : new Sp3EphemerisSource(sp3OrSource, opts.clk);
|
|
15897
|
+
const eng = new PppEngine(opts, source);
|
|
15898
|
+
for (const epoch of epochs) eng.process(epoch);
|
|
15899
|
+
return eng.solution();
|
|
15755
15900
|
}
|
|
15756
15901
|
|
|
15757
15902
|
// src/positioning/ppp-ar.ts
|
|
@@ -18806,6 +18951,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18806
18951
|
MultipathAccumulator,
|
|
18807
18952
|
OEM4_HLEN,
|
|
18808
18953
|
OMEGA_E,
|
|
18954
|
+
PppEngine,
|
|
18809
18955
|
REFERENCE_FRAMES,
|
|
18810
18956
|
RINEX_CODES,
|
|
18811
18957
|
RTCM2_MESSAGE_NAMES,
|
|
@@ -18833,6 +18979,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18833
18979
|
SYS_SHORT,
|
|
18834
18980
|
SbasProcessor,
|
|
18835
18981
|
Scale,
|
|
18982
|
+
Sp3EphemerisSource,
|
|
18836
18983
|
WGS84_ECCENTRICITY_SQUARED,
|
|
18837
18984
|
WGS84_FLATTENING,
|
|
18838
18985
|
WGS84_SEMI_MAJOR_AXIS,
|
|
@@ -18843,6 +18990,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18843
18990
|
analyzeQuality,
|
|
18844
18991
|
applyHelmert,
|
|
18845
18992
|
applyIonoDcb,
|
|
18993
|
+
applyOrbitClock,
|
|
18846
18994
|
biasMetres,
|
|
18847
18995
|
binexCrc16,
|
|
18848
18996
|
binexCrc32,
|
|
@@ -18967,6 +19115,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18967
19115
|
glonassPosition,
|
|
18968
19116
|
gmst,
|
|
18969
19117
|
greatCircleMidpoint,
|
|
19118
|
+
hasToOrbitClock,
|
|
18970
19119
|
hdrLine,
|
|
18971
19120
|
horizonDistance,
|
|
18972
19121
|
ionoFree,
|