gnss-js 1.31.0 → 1.32.1
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-EVFD4UNZ.js → chunk-KD2KJGLQ.js} +144 -6
- package/dist/index.cjs +146 -6
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -1
- package/dist/positioning.cjs +146 -6
- package/dist/positioning.d.cts +88 -1
- package/dist/positioning.d.ts +88 -1
- package/dist/positioning.js +5 -1
- package/package.json +1 -1
|
@@ -1788,8 +1788,6 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1788
1788
|
P[ci][ci] = CLK_VAR;
|
|
1789
1789
|
}
|
|
1790
1790
|
let nSats = 0;
|
|
1791
|
-
let sumPhaseResSq = 0;
|
|
1792
|
-
let nPhaseRes = 0;
|
|
1793
1791
|
for (const v of vis) {
|
|
1794
1792
|
const ci = clockOf(v.prn[0]);
|
|
1795
1793
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
@@ -1840,15 +1838,37 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1840
1838
|
h[ci] = 1;
|
|
1841
1839
|
h[IDX_ZWD] = v.mw;
|
|
1842
1840
|
h[ai] = 1;
|
|
1843
|
-
|
|
1844
|
-
sumPhaseResSq += innov * innov;
|
|
1845
|
-
nPhaseRes++;
|
|
1846
|
-
}
|
|
1841
|
+
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
1847
1842
|
}
|
|
1848
1843
|
}
|
|
1849
1844
|
lastSeen.set(v.prn, ei);
|
|
1850
1845
|
nSats++;
|
|
1851
1846
|
}
|
|
1847
|
+
let sumPhaseResSq = 0;
|
|
1848
|
+
let nPhaseRes = 0;
|
|
1849
|
+
{
|
|
1850
|
+
const bySysRes = /* @__PURE__ */ new Map();
|
|
1851
|
+
for (const v of vis) {
|
|
1852
|
+
const ai = ambIdx.get(v.prn);
|
|
1853
|
+
if (ai === void 0) continue;
|
|
1854
|
+
const sys = v.prn[0];
|
|
1855
|
+
const ci = clockOf(sys);
|
|
1856
|
+
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
1857
|
+
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
1858
|
+
if (Math.abs(innov) >= 0.15) continue;
|
|
1859
|
+
const arr = bySysRes.get(sys);
|
|
1860
|
+
if (arr) arr.push(innov);
|
|
1861
|
+
else bySysRes.set(sys, [innov]);
|
|
1862
|
+
}
|
|
1863
|
+
for (const res of bySysRes.values()) {
|
|
1864
|
+
const mean = res.reduce((a, b) => a + b, 0) / res.length;
|
|
1865
|
+
for (const r of res) {
|
|
1866
|
+
const d = r - mean;
|
|
1867
|
+
sumPhaseResSq += d * d;
|
|
1868
|
+
nPhaseRes++;
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1852
1872
|
for (const [prn, seen] of [...lastSeen]) {
|
|
1853
1873
|
if (ei - seen > 20) {
|
|
1854
1874
|
const idx = ambIdx.get(prn);
|
|
@@ -2001,6 +2021,122 @@ function resolvePppAmbiguities(sats, Qaif, opts = {}) {
|
|
|
2001
2021
|
};
|
|
2002
2022
|
}
|
|
2003
2023
|
|
|
2024
|
+
// src/positioning/ppp-fcb.ts
|
|
2025
|
+
function extractWidelaneArcs(station, epochs, opts = {}) {
|
|
2026
|
+
const slipCyc = opts.slipCyc ?? 4;
|
|
2027
|
+
const gapMs = opts.gapMs ?? 12e4;
|
|
2028
|
+
const minObs = opts.minObs ?? 20;
|
|
2029
|
+
const state = /* @__PURE__ */ new Map();
|
|
2030
|
+
const out = [];
|
|
2031
|
+
const flush = (prn) => {
|
|
2032
|
+
const s = state.get(prn);
|
|
2033
|
+
if (s && s.n >= minObs)
|
|
2034
|
+
out.push({ station, prn, wlFloat: s.sum / s.n, nObs: s.n });
|
|
2035
|
+
};
|
|
2036
|
+
for (const ep of epochs) {
|
|
2037
|
+
for (const o of ep.obs) {
|
|
2038
|
+
if (!o.c1 || !o.c2 || !o.l1 || !o.l2) continue;
|
|
2039
|
+
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
2040
|
+
const codeNl = (o.f1 * o.c1 + o.f2 * o.c2) / (o.f1 + o.f2);
|
|
2041
|
+
const mw = o.l1 - o.l2 - codeNl / lamW;
|
|
2042
|
+
const s = state.get(o.prn);
|
|
2043
|
+
if (!s || ep.timeMs - s.lastT > gapMs || Math.abs(mw - s.mean) > slipCyc) {
|
|
2044
|
+
if (s) flush(o.prn);
|
|
2045
|
+
state.set(o.prn, { sum: mw, n: 1, mean: mw, lastT: ep.timeMs });
|
|
2046
|
+
} else {
|
|
2047
|
+
s.sum += mw;
|
|
2048
|
+
s.n += 1;
|
|
2049
|
+
s.mean = s.sum / s.n;
|
|
2050
|
+
s.lastT = ep.timeMs;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
for (const prn of state.keys()) flush(prn);
|
|
2055
|
+
return out;
|
|
2056
|
+
}
|
|
2057
|
+
function wrapHalf(x) {
|
|
2058
|
+
return x - Math.round(x);
|
|
2059
|
+
}
|
|
2060
|
+
function circMean(vals, weights) {
|
|
2061
|
+
let s = 0;
|
|
2062
|
+
let c = 0;
|
|
2063
|
+
for (let i = 0; i < vals.length; i++) {
|
|
2064
|
+
const a = 2 * Math.PI * vals[i];
|
|
2065
|
+
s += weights[i] * Math.sin(a);
|
|
2066
|
+
c += weights[i] * Math.cos(a);
|
|
2067
|
+
}
|
|
2068
|
+
if (s === 0 && c === 0) return 0;
|
|
2069
|
+
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
2070
|
+
}
|
|
2071
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
2072
|
+
const maxIter = opts.maxIter ?? 50;
|
|
2073
|
+
const tol = opts.tol ?? 1e-4;
|
|
2074
|
+
const fixWindow = opts.fixWindow ?? 0.25;
|
|
2075
|
+
const sats = [...new Set(arcs.map((a) => a.prn))].sort();
|
|
2076
|
+
const stations = [...new Set(arcs.map((a) => a.station))].sort();
|
|
2077
|
+
const refStation = stations[0] ?? "";
|
|
2078
|
+
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
2079
|
+
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
2080
|
+
const nInt = new Array(arcs.length).fill(0);
|
|
2081
|
+
let iterations = 0;
|
|
2082
|
+
for (let it = 0; it < maxIter; it++) {
|
|
2083
|
+
iterations = it + 1;
|
|
2084
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2085
|
+
const a = arcs[i];
|
|
2086
|
+
nInt[i] = Math.round(
|
|
2087
|
+
a.wlFloat - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
2088
|
+
);
|
|
2089
|
+
}
|
|
2090
|
+
let maxChange = 0;
|
|
2091
|
+
for (const s of sats) {
|
|
2092
|
+
const vals = [];
|
|
2093
|
+
const w = [];
|
|
2094
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2095
|
+
const a = arcs[i];
|
|
2096
|
+
if (a.prn !== s) continue;
|
|
2097
|
+
vals.push(a.wlFloat - nInt[i] - rcvBias.get(a.station));
|
|
2098
|
+
w.push(a.nObs);
|
|
2099
|
+
}
|
|
2100
|
+
if (!vals.length) continue;
|
|
2101
|
+
const nv = circMean(vals, w);
|
|
2102
|
+
maxChange = Math.max(maxChange, Math.abs(wrapHalf(nv - satFcb.get(s))));
|
|
2103
|
+
satFcb.set(s, nv);
|
|
2104
|
+
}
|
|
2105
|
+
for (const r of stations) {
|
|
2106
|
+
const vals = [];
|
|
2107
|
+
const w = [];
|
|
2108
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2109
|
+
const a = arcs[i];
|
|
2110
|
+
if (a.station !== r) continue;
|
|
2111
|
+
vals.push(a.wlFloat - nInt[i] - satFcb.get(a.prn));
|
|
2112
|
+
w.push(a.nObs);
|
|
2113
|
+
}
|
|
2114
|
+
if (!vals.length) continue;
|
|
2115
|
+
rcvBias.set(r, circMean(vals, w));
|
|
2116
|
+
}
|
|
2117
|
+
const shift = rcvBias.get(refStation);
|
|
2118
|
+
if (shift !== 0) {
|
|
2119
|
+
for (const r of stations)
|
|
2120
|
+
rcvBias.set(r, wrapHalf(rcvBias.get(r) - shift));
|
|
2121
|
+
for (const s of sats) satFcb.set(s, wrapHalf(satFcb.get(s) + shift));
|
|
2122
|
+
}
|
|
2123
|
+
if (maxChange < tol) break;
|
|
2124
|
+
}
|
|
2125
|
+
let sumSq = 0;
|
|
2126
|
+
let fixed = 0;
|
|
2127
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2128
|
+
const a = arcs[i];
|
|
2129
|
+
const resid = wrapHalf(
|
|
2130
|
+
a.wlFloat - nInt[i] - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
2131
|
+
);
|
|
2132
|
+
sumSq += resid * resid;
|
|
2133
|
+
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
2134
|
+
}
|
|
2135
|
+
const residRms = arcs.length ? Math.sqrt(sumSq / arcs.length) : 0;
|
|
2136
|
+
const fixRate = arcs.length ? fixed / arcs.length : 0;
|
|
2137
|
+
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2004
2140
|
// src/positioning/index.ts
|
|
2005
2141
|
var GM_GPS = 3986005e8;
|
|
2006
2142
|
var F_REL = -4442807633e-19;
|
|
@@ -2250,6 +2386,8 @@ export {
|
|
|
2250
2386
|
wlWavelength,
|
|
2251
2387
|
nlWavelength,
|
|
2252
2388
|
resolvePppAmbiguities,
|
|
2389
|
+
extractWidelaneArcs,
|
|
2390
|
+
estimateWidelaneFcb,
|
|
2253
2391
|
satClockCorrection,
|
|
2254
2392
|
ionoFree,
|
|
2255
2393
|
solveSpp
|
package/dist/index.cjs
CHANGED
|
@@ -149,7 +149,9 @@ __export(src_exports, {
|
|
|
149
149
|
ecefToAzEl: () => ecefToAzEl,
|
|
150
150
|
ecefToGeodetic: () => ecefToGeodetic,
|
|
151
151
|
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
152
|
+
estimateWidelaneFcb: () => estimateWidelaneFcb,
|
|
152
153
|
euclidean3D: () => euclidean3D,
|
|
154
|
+
extractWidelaneArcs: () => extractWidelaneArcs,
|
|
153
155
|
fetchSourcetable: () => fetchSourcetable,
|
|
154
156
|
findSatBias: () => findSatBias,
|
|
155
157
|
fmtD: () => fmtD,
|
|
@@ -13182,8 +13184,6 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13182
13184
|
P[ci][ci] = CLK_VAR;
|
|
13183
13185
|
}
|
|
13184
13186
|
let nSats = 0;
|
|
13185
|
-
let sumPhaseResSq = 0;
|
|
13186
|
-
let nPhaseRes = 0;
|
|
13187
13187
|
for (const v of vis) {
|
|
13188
13188
|
const ci = clockOf(v.prn[0]);
|
|
13189
13189
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
@@ -13234,15 +13234,37 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13234
13234
|
h[ci] = 1;
|
|
13235
13235
|
h[IDX_ZWD] = v.mw;
|
|
13236
13236
|
h[ai] = 1;
|
|
13237
|
-
|
|
13238
|
-
sumPhaseResSq += innov * innov;
|
|
13239
|
-
nPhaseRes++;
|
|
13240
|
-
}
|
|
13237
|
+
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
13241
13238
|
}
|
|
13242
13239
|
}
|
|
13243
13240
|
lastSeen.set(v.prn, ei);
|
|
13244
13241
|
nSats++;
|
|
13245
13242
|
}
|
|
13243
|
+
let sumPhaseResSq = 0;
|
|
13244
|
+
let nPhaseRes = 0;
|
|
13245
|
+
{
|
|
13246
|
+
const bySysRes = /* @__PURE__ */ new Map();
|
|
13247
|
+
for (const v of vis) {
|
|
13248
|
+
const ai = ambIdx.get(v.prn);
|
|
13249
|
+
if (ai === void 0) continue;
|
|
13250
|
+
const sys = v.prn[0];
|
|
13251
|
+
const ci = clockOf(sys);
|
|
13252
|
+
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
13253
|
+
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
13254
|
+
if (Math.abs(innov) >= 0.15) continue;
|
|
13255
|
+
const arr = bySysRes.get(sys);
|
|
13256
|
+
if (arr) arr.push(innov);
|
|
13257
|
+
else bySysRes.set(sys, [innov]);
|
|
13258
|
+
}
|
|
13259
|
+
for (const res of bySysRes.values()) {
|
|
13260
|
+
const mean = res.reduce((a, b) => a + b, 0) / res.length;
|
|
13261
|
+
for (const r of res) {
|
|
13262
|
+
const d = r - mean;
|
|
13263
|
+
sumPhaseResSq += d * d;
|
|
13264
|
+
nPhaseRes++;
|
|
13265
|
+
}
|
|
13266
|
+
}
|
|
13267
|
+
}
|
|
13246
13268
|
for (const [prn, seen] of [...lastSeen]) {
|
|
13247
13269
|
if (ei - seen > 20) {
|
|
13248
13270
|
const idx = ambIdx.get(prn);
|
|
@@ -13395,6 +13417,122 @@ function resolvePppAmbiguities(sats, Qaif, opts = {}) {
|
|
|
13395
13417
|
};
|
|
13396
13418
|
}
|
|
13397
13419
|
|
|
13420
|
+
// src/positioning/ppp-fcb.ts
|
|
13421
|
+
function extractWidelaneArcs(station, epochs, opts = {}) {
|
|
13422
|
+
const slipCyc = opts.slipCyc ?? 4;
|
|
13423
|
+
const gapMs = opts.gapMs ?? 12e4;
|
|
13424
|
+
const minObs = opts.minObs ?? 20;
|
|
13425
|
+
const state = /* @__PURE__ */ new Map();
|
|
13426
|
+
const out = [];
|
|
13427
|
+
const flush = (prn) => {
|
|
13428
|
+
const s = state.get(prn);
|
|
13429
|
+
if (s && s.n >= minObs)
|
|
13430
|
+
out.push({ station, prn, wlFloat: s.sum / s.n, nObs: s.n });
|
|
13431
|
+
};
|
|
13432
|
+
for (const ep of epochs) {
|
|
13433
|
+
for (const o of ep.obs) {
|
|
13434
|
+
if (!o.c1 || !o.c2 || !o.l1 || !o.l2) continue;
|
|
13435
|
+
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
13436
|
+
const codeNl = (o.f1 * o.c1 + o.f2 * o.c2) / (o.f1 + o.f2);
|
|
13437
|
+
const mw = o.l1 - o.l2 - codeNl / lamW;
|
|
13438
|
+
const s = state.get(o.prn);
|
|
13439
|
+
if (!s || ep.timeMs - s.lastT > gapMs || Math.abs(mw - s.mean) > slipCyc) {
|
|
13440
|
+
if (s) flush(o.prn);
|
|
13441
|
+
state.set(o.prn, { sum: mw, n: 1, mean: mw, lastT: ep.timeMs });
|
|
13442
|
+
} else {
|
|
13443
|
+
s.sum += mw;
|
|
13444
|
+
s.n += 1;
|
|
13445
|
+
s.mean = s.sum / s.n;
|
|
13446
|
+
s.lastT = ep.timeMs;
|
|
13447
|
+
}
|
|
13448
|
+
}
|
|
13449
|
+
}
|
|
13450
|
+
for (const prn of state.keys()) flush(prn);
|
|
13451
|
+
return out;
|
|
13452
|
+
}
|
|
13453
|
+
function wrapHalf(x) {
|
|
13454
|
+
return x - Math.round(x);
|
|
13455
|
+
}
|
|
13456
|
+
function circMean(vals, weights) {
|
|
13457
|
+
let s = 0;
|
|
13458
|
+
let c = 0;
|
|
13459
|
+
for (let i = 0; i < vals.length; i++) {
|
|
13460
|
+
const a = 2 * Math.PI * vals[i];
|
|
13461
|
+
s += weights[i] * Math.sin(a);
|
|
13462
|
+
c += weights[i] * Math.cos(a);
|
|
13463
|
+
}
|
|
13464
|
+
if (s === 0 && c === 0) return 0;
|
|
13465
|
+
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
13466
|
+
}
|
|
13467
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
13468
|
+
const maxIter = opts.maxIter ?? 50;
|
|
13469
|
+
const tol = opts.tol ?? 1e-4;
|
|
13470
|
+
const fixWindow = opts.fixWindow ?? 0.25;
|
|
13471
|
+
const sats = [...new Set(arcs.map((a) => a.prn))].sort();
|
|
13472
|
+
const stations = [...new Set(arcs.map((a) => a.station))].sort();
|
|
13473
|
+
const refStation = stations[0] ?? "";
|
|
13474
|
+
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
13475
|
+
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
13476
|
+
const nInt = new Array(arcs.length).fill(0);
|
|
13477
|
+
let iterations = 0;
|
|
13478
|
+
for (let it = 0; it < maxIter; it++) {
|
|
13479
|
+
iterations = it + 1;
|
|
13480
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
13481
|
+
const a = arcs[i];
|
|
13482
|
+
nInt[i] = Math.round(
|
|
13483
|
+
a.wlFloat - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
13484
|
+
);
|
|
13485
|
+
}
|
|
13486
|
+
let maxChange = 0;
|
|
13487
|
+
for (const s of sats) {
|
|
13488
|
+
const vals = [];
|
|
13489
|
+
const w = [];
|
|
13490
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
13491
|
+
const a = arcs[i];
|
|
13492
|
+
if (a.prn !== s) continue;
|
|
13493
|
+
vals.push(a.wlFloat - nInt[i] - rcvBias.get(a.station));
|
|
13494
|
+
w.push(a.nObs);
|
|
13495
|
+
}
|
|
13496
|
+
if (!vals.length) continue;
|
|
13497
|
+
const nv = circMean(vals, w);
|
|
13498
|
+
maxChange = Math.max(maxChange, Math.abs(wrapHalf(nv - satFcb.get(s))));
|
|
13499
|
+
satFcb.set(s, nv);
|
|
13500
|
+
}
|
|
13501
|
+
for (const r of stations) {
|
|
13502
|
+
const vals = [];
|
|
13503
|
+
const w = [];
|
|
13504
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
13505
|
+
const a = arcs[i];
|
|
13506
|
+
if (a.station !== r) continue;
|
|
13507
|
+
vals.push(a.wlFloat - nInt[i] - satFcb.get(a.prn));
|
|
13508
|
+
w.push(a.nObs);
|
|
13509
|
+
}
|
|
13510
|
+
if (!vals.length) continue;
|
|
13511
|
+
rcvBias.set(r, circMean(vals, w));
|
|
13512
|
+
}
|
|
13513
|
+
const shift = rcvBias.get(refStation);
|
|
13514
|
+
if (shift !== 0) {
|
|
13515
|
+
for (const r of stations)
|
|
13516
|
+
rcvBias.set(r, wrapHalf(rcvBias.get(r) - shift));
|
|
13517
|
+
for (const s of sats) satFcb.set(s, wrapHalf(satFcb.get(s) + shift));
|
|
13518
|
+
}
|
|
13519
|
+
if (maxChange < tol) break;
|
|
13520
|
+
}
|
|
13521
|
+
let sumSq = 0;
|
|
13522
|
+
let fixed = 0;
|
|
13523
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
13524
|
+
const a = arcs[i];
|
|
13525
|
+
const resid = wrapHalf(
|
|
13526
|
+
a.wlFloat - nInt[i] - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
13527
|
+
);
|
|
13528
|
+
sumSq += resid * resid;
|
|
13529
|
+
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
13530
|
+
}
|
|
13531
|
+
const residRms = arcs.length ? Math.sqrt(sumSq / arcs.length) : 0;
|
|
13532
|
+
const fixRate = arcs.length ? fixed / arcs.length : 0;
|
|
13533
|
+
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
13534
|
+
}
|
|
13535
|
+
|
|
13398
13536
|
// src/positioning/index.ts
|
|
13399
13537
|
var GM_GPS3 = 3986005e8;
|
|
13400
13538
|
var F_REL = -4442807633e-19;
|
|
@@ -16012,7 +16150,9 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
16012
16150
|
ecefToAzEl,
|
|
16013
16151
|
ecefToGeodetic,
|
|
16014
16152
|
ephInfoToEphemeris,
|
|
16153
|
+
estimateWidelaneFcb,
|
|
16015
16154
|
euclidean3D,
|
|
16155
|
+
extractWidelaneArcs,
|
|
16016
16156
|
fetchSourcetable,
|
|
16017
16157
|
findSatBias,
|
|
16018
16158
|
fmtD,
|
package/dist/index.d.cts
CHANGED
|
@@ -17,7 +17,7 @@ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, Trimb
|
|
|
17
17
|
export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
|
|
18
18
|
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';
|
|
19
19
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
|
|
20
|
-
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, PppAntennaModel, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, buildPppAntenna, createPppCorrections, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
|
|
20
|
+
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, PppAntennaModel, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateWidelaneFcb, extractWidelaneArcs, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
|
|
21
21
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
|
|
22
22
|
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';
|
|
23
23
|
export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, Trimb
|
|
|
17
17
|
export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
|
|
18
18
|
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';
|
|
19
19
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
|
|
20
|
-
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, PppAntennaModel, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, buildPppAntenna, createPppCorrections, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
|
|
20
|
+
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, PppAntennaModel, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateWidelaneFcb, extractWidelaneArcs, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
|
|
21
21
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
|
|
22
22
|
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';
|
|
23
23
|
export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.js';
|
package/dist/index.js
CHANGED
|
@@ -146,6 +146,8 @@ import {
|
|
|
146
146
|
RtkFloatEngine,
|
|
147
147
|
buildPppAntenna,
|
|
148
148
|
createPppCorrections,
|
|
149
|
+
estimateWidelaneFcb,
|
|
150
|
+
extractWidelaneArcs,
|
|
149
151
|
gimSlantIonoDelayL1,
|
|
150
152
|
gimVerticalTec,
|
|
151
153
|
gmst,
|
|
@@ -165,7 +167,7 @@ import {
|
|
|
165
167
|
sunEcef,
|
|
166
168
|
toRtkEpoch,
|
|
167
169
|
wlWavelength
|
|
168
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-KD2KJGLQ.js";
|
|
169
171
|
import {
|
|
170
172
|
almanacEpochMs,
|
|
171
173
|
almanacSatPosition,
|
|
@@ -472,7 +474,9 @@ export {
|
|
|
472
474
|
ecefToAzEl,
|
|
473
475
|
ecefToGeodetic,
|
|
474
476
|
ephInfoToEphemeris,
|
|
477
|
+
estimateWidelaneFcb,
|
|
475
478
|
euclidean3D,
|
|
479
|
+
extractWidelaneArcs,
|
|
476
480
|
fetchSourcetable,
|
|
477
481
|
findSatBias,
|
|
478
482
|
fmtD,
|
package/dist/positioning.cjs
CHANGED
|
@@ -24,6 +24,8 @@ __export(positioning_exports, {
|
|
|
24
24
|
RtkFloatEngine: () => RtkFloatEngine,
|
|
25
25
|
buildPppAntenna: () => buildPppAntenna,
|
|
26
26
|
createPppCorrections: () => createPppCorrections,
|
|
27
|
+
estimateWidelaneFcb: () => estimateWidelaneFcb,
|
|
28
|
+
extractWidelaneArcs: () => extractWidelaneArcs,
|
|
27
29
|
gimSlantIonoDelayL1: () => gimSlantIonoDelayL1,
|
|
28
30
|
gimVerticalTec: () => gimVerticalTec,
|
|
29
31
|
gmst: () => gmst,
|
|
@@ -2310,8 +2312,6 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2310
2312
|
P[ci][ci] = CLK_VAR;
|
|
2311
2313
|
}
|
|
2312
2314
|
let nSats = 0;
|
|
2313
|
-
let sumPhaseResSq = 0;
|
|
2314
|
-
let nPhaseRes = 0;
|
|
2315
2315
|
for (const v of vis) {
|
|
2316
2316
|
const ci = clockOf(v.prn[0]);
|
|
2317
2317
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
@@ -2362,15 +2362,37 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2362
2362
|
h[ci] = 1;
|
|
2363
2363
|
h[IDX_ZWD] = v.mw;
|
|
2364
2364
|
h[ai] = 1;
|
|
2365
|
-
|
|
2366
|
-
sumPhaseResSq += innov * innov;
|
|
2367
|
-
nPhaseRes++;
|
|
2368
|
-
}
|
|
2365
|
+
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
2369
2366
|
}
|
|
2370
2367
|
}
|
|
2371
2368
|
lastSeen.set(v.prn, ei);
|
|
2372
2369
|
nSats++;
|
|
2373
2370
|
}
|
|
2371
|
+
let sumPhaseResSq = 0;
|
|
2372
|
+
let nPhaseRes = 0;
|
|
2373
|
+
{
|
|
2374
|
+
const bySysRes = /* @__PURE__ */ new Map();
|
|
2375
|
+
for (const v of vis) {
|
|
2376
|
+
const ai = ambIdx.get(v.prn);
|
|
2377
|
+
if (ai === void 0) continue;
|
|
2378
|
+
const sys = v.prn[0];
|
|
2379
|
+
const ci = clockOf(sys);
|
|
2380
|
+
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
2381
|
+
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
2382
|
+
if (Math.abs(innov) >= 0.15) continue;
|
|
2383
|
+
const arr = bySysRes.get(sys);
|
|
2384
|
+
if (arr) arr.push(innov);
|
|
2385
|
+
else bySysRes.set(sys, [innov]);
|
|
2386
|
+
}
|
|
2387
|
+
for (const res of bySysRes.values()) {
|
|
2388
|
+
const mean = res.reduce((a, b) => a + b, 0) / res.length;
|
|
2389
|
+
for (const r of res) {
|
|
2390
|
+
const d = r - mean;
|
|
2391
|
+
sumPhaseResSq += d * d;
|
|
2392
|
+
nPhaseRes++;
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2374
2396
|
for (const [prn, seen] of [...lastSeen]) {
|
|
2375
2397
|
if (ei - seen > 20) {
|
|
2376
2398
|
const idx = ambIdx.get(prn);
|
|
@@ -2523,6 +2545,122 @@ function resolvePppAmbiguities(sats, Qaif, opts = {}) {
|
|
|
2523
2545
|
};
|
|
2524
2546
|
}
|
|
2525
2547
|
|
|
2548
|
+
// src/positioning/ppp-fcb.ts
|
|
2549
|
+
function extractWidelaneArcs(station, epochs, opts = {}) {
|
|
2550
|
+
const slipCyc = opts.slipCyc ?? 4;
|
|
2551
|
+
const gapMs = opts.gapMs ?? 12e4;
|
|
2552
|
+
const minObs = opts.minObs ?? 20;
|
|
2553
|
+
const state = /* @__PURE__ */ new Map();
|
|
2554
|
+
const out = [];
|
|
2555
|
+
const flush = (prn) => {
|
|
2556
|
+
const s = state.get(prn);
|
|
2557
|
+
if (s && s.n >= minObs)
|
|
2558
|
+
out.push({ station, prn, wlFloat: s.sum / s.n, nObs: s.n });
|
|
2559
|
+
};
|
|
2560
|
+
for (const ep of epochs) {
|
|
2561
|
+
for (const o of ep.obs) {
|
|
2562
|
+
if (!o.c1 || !o.c2 || !o.l1 || !o.l2) continue;
|
|
2563
|
+
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
2564
|
+
const codeNl = (o.f1 * o.c1 + o.f2 * o.c2) / (o.f1 + o.f2);
|
|
2565
|
+
const mw = o.l1 - o.l2 - codeNl / lamW;
|
|
2566
|
+
const s = state.get(o.prn);
|
|
2567
|
+
if (!s || ep.timeMs - s.lastT > gapMs || Math.abs(mw - s.mean) > slipCyc) {
|
|
2568
|
+
if (s) flush(o.prn);
|
|
2569
|
+
state.set(o.prn, { sum: mw, n: 1, mean: mw, lastT: ep.timeMs });
|
|
2570
|
+
} else {
|
|
2571
|
+
s.sum += mw;
|
|
2572
|
+
s.n += 1;
|
|
2573
|
+
s.mean = s.sum / s.n;
|
|
2574
|
+
s.lastT = ep.timeMs;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
for (const prn of state.keys()) flush(prn);
|
|
2579
|
+
return out;
|
|
2580
|
+
}
|
|
2581
|
+
function wrapHalf(x) {
|
|
2582
|
+
return x - Math.round(x);
|
|
2583
|
+
}
|
|
2584
|
+
function circMean(vals, weights) {
|
|
2585
|
+
let s = 0;
|
|
2586
|
+
let c = 0;
|
|
2587
|
+
for (let i = 0; i < vals.length; i++) {
|
|
2588
|
+
const a = 2 * Math.PI * vals[i];
|
|
2589
|
+
s += weights[i] * Math.sin(a);
|
|
2590
|
+
c += weights[i] * Math.cos(a);
|
|
2591
|
+
}
|
|
2592
|
+
if (s === 0 && c === 0) return 0;
|
|
2593
|
+
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
2594
|
+
}
|
|
2595
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
2596
|
+
const maxIter = opts.maxIter ?? 50;
|
|
2597
|
+
const tol = opts.tol ?? 1e-4;
|
|
2598
|
+
const fixWindow = opts.fixWindow ?? 0.25;
|
|
2599
|
+
const sats = [...new Set(arcs.map((a) => a.prn))].sort();
|
|
2600
|
+
const stations = [...new Set(arcs.map((a) => a.station))].sort();
|
|
2601
|
+
const refStation = stations[0] ?? "";
|
|
2602
|
+
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
2603
|
+
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
2604
|
+
const nInt = new Array(arcs.length).fill(0);
|
|
2605
|
+
let iterations = 0;
|
|
2606
|
+
for (let it = 0; it < maxIter; it++) {
|
|
2607
|
+
iterations = it + 1;
|
|
2608
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2609
|
+
const a = arcs[i];
|
|
2610
|
+
nInt[i] = Math.round(
|
|
2611
|
+
a.wlFloat - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
2612
|
+
);
|
|
2613
|
+
}
|
|
2614
|
+
let maxChange = 0;
|
|
2615
|
+
for (const s of sats) {
|
|
2616
|
+
const vals = [];
|
|
2617
|
+
const w = [];
|
|
2618
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2619
|
+
const a = arcs[i];
|
|
2620
|
+
if (a.prn !== s) continue;
|
|
2621
|
+
vals.push(a.wlFloat - nInt[i] - rcvBias.get(a.station));
|
|
2622
|
+
w.push(a.nObs);
|
|
2623
|
+
}
|
|
2624
|
+
if (!vals.length) continue;
|
|
2625
|
+
const nv = circMean(vals, w);
|
|
2626
|
+
maxChange = Math.max(maxChange, Math.abs(wrapHalf(nv - satFcb.get(s))));
|
|
2627
|
+
satFcb.set(s, nv);
|
|
2628
|
+
}
|
|
2629
|
+
for (const r of stations) {
|
|
2630
|
+
const vals = [];
|
|
2631
|
+
const w = [];
|
|
2632
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2633
|
+
const a = arcs[i];
|
|
2634
|
+
if (a.station !== r) continue;
|
|
2635
|
+
vals.push(a.wlFloat - nInt[i] - satFcb.get(a.prn));
|
|
2636
|
+
w.push(a.nObs);
|
|
2637
|
+
}
|
|
2638
|
+
if (!vals.length) continue;
|
|
2639
|
+
rcvBias.set(r, circMean(vals, w));
|
|
2640
|
+
}
|
|
2641
|
+
const shift = rcvBias.get(refStation);
|
|
2642
|
+
if (shift !== 0) {
|
|
2643
|
+
for (const r of stations)
|
|
2644
|
+
rcvBias.set(r, wrapHalf(rcvBias.get(r) - shift));
|
|
2645
|
+
for (const s of sats) satFcb.set(s, wrapHalf(satFcb.get(s) + shift));
|
|
2646
|
+
}
|
|
2647
|
+
if (maxChange < tol) break;
|
|
2648
|
+
}
|
|
2649
|
+
let sumSq = 0;
|
|
2650
|
+
let fixed = 0;
|
|
2651
|
+
for (let i = 0; i < arcs.length; i++) {
|
|
2652
|
+
const a = arcs[i];
|
|
2653
|
+
const resid = wrapHalf(
|
|
2654
|
+
a.wlFloat - nInt[i] - rcvBias.get(a.station) - satFcb.get(a.prn)
|
|
2655
|
+
);
|
|
2656
|
+
sumSq += resid * resid;
|
|
2657
|
+
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
2658
|
+
}
|
|
2659
|
+
const residRms = arcs.length ? Math.sqrt(sumSq / arcs.length) : 0;
|
|
2660
|
+
const fixRate = arcs.length ? fixed / arcs.length : 0;
|
|
2661
|
+
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2526
2664
|
// src/positioning/index.ts
|
|
2527
2665
|
var GM_GPS2 = 3986005e8;
|
|
2528
2666
|
var F_REL = -4442807633e-19;
|
|
@@ -2756,6 +2894,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
2756
2894
|
RtkFloatEngine,
|
|
2757
2895
|
buildPppAntenna,
|
|
2758
2896
|
createPppCorrections,
|
|
2897
|
+
estimateWidelaneFcb,
|
|
2898
|
+
extractWidelaneArcs,
|
|
2759
2899
|
gimSlantIonoDelayL1,
|
|
2760
2900
|
gimVerticalTec,
|
|
2761
2901
|
gmst,
|
package/dist/positioning.d.cts
CHANGED
|
@@ -793,6 +793,93 @@ interface ArResult {
|
|
|
793
793
|
*/
|
|
794
794
|
declare function resolvePppAmbiguities(sats: ArSat[], Qaif: Float64Array, opts?: ArOptions): ArResult;
|
|
795
795
|
|
|
796
|
+
/**
|
|
797
|
+
* Wide-lane fractional-cycle bias (FCB) estimation for PPP-AR — the
|
|
798
|
+
* self-contained route to integer ambiguities that needs no external
|
|
799
|
+
* phase-bias product, only a small network of stations.
|
|
800
|
+
*
|
|
801
|
+
* A single receiver cannot resolve ambiguities because its Melbourne–Wübbena
|
|
802
|
+
* wide-lane float is `Ñ_wl = N (integer) + b_rcv + b_sat`, and the integer
|
|
803
|
+
* and the satellite fractional bias `b_sat` are entangled. Across a *network*
|
|
804
|
+
* they separate: every station sees the same `b_sat` for a given satellite
|
|
805
|
+
* but its own integers and receiver bias, so the fractional part common to
|
|
806
|
+
* all stations *is* the satellite FCB. This is the classic Ge/Gendt method.
|
|
807
|
+
*
|
|
808
|
+
* The estimator alternates:
|
|
809
|
+
* 1. round each arc to its integer N = round(Ñ_wl − b_rcv − b_sat);
|
|
810
|
+
* 2. update each satellite FCB = circular-mean over stations of
|
|
811
|
+
* (Ñ_wl − N − b_rcv);
|
|
812
|
+
* 3. update each receiver bias = circular-mean over satellites of
|
|
813
|
+
* (Ñ_wl − N − b_sat);
|
|
814
|
+
* 4. pin the datum (b_rcv of a reference station ≡ 0) — receiver and
|
|
815
|
+
* satellite biases otherwise trade off by an arbitrary constant.
|
|
816
|
+
*
|
|
817
|
+
* The output `satFcb` feeds `resolvePppAmbiguities`' `wlBiasCyc`.
|
|
818
|
+
*/
|
|
819
|
+
/** Minimal per-satellite observation for wide-lane extraction. */
|
|
820
|
+
interface WlObs {
|
|
821
|
+
prn: string;
|
|
822
|
+
f1: number;
|
|
823
|
+
f2: number;
|
|
824
|
+
/** Code on f1/f2 (m) and carrier phase on f1/f2 (cycles). */
|
|
825
|
+
c1: number;
|
|
826
|
+
c2: number;
|
|
827
|
+
l1: number;
|
|
828
|
+
l2: number;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Extract arc-averaged Melbourne–Wübbena wide-lanes for one station from its
|
|
832
|
+
* epoch stream. The MW combination
|
|
833
|
+
* MW = (L1 − L2) − [(f1·C1 + f2·C2)/(f1+f2)] / (c/(f1−f2)) [cycles]
|
|
834
|
+
* is geometry-, clock- and (first-order) ionosphere-free, so it holds the
|
|
835
|
+
* wide-lane ambiguity plus biases and is near-constant within an arc. Arcs
|
|
836
|
+
* are split on a running-mean jump (cycle slip) or a time gap.
|
|
837
|
+
*/
|
|
838
|
+
declare function extractWidelaneArcs(station: string, epochs: {
|
|
839
|
+
timeMs: number;
|
|
840
|
+
obs: WlObs[];
|
|
841
|
+
}[], opts?: {
|
|
842
|
+
slipCyc?: number;
|
|
843
|
+
gapMs?: number;
|
|
844
|
+
minObs?: number;
|
|
845
|
+
}): WlArc[];
|
|
846
|
+
/** One continuous wide-lane arc at a station. */
|
|
847
|
+
interface WlArc {
|
|
848
|
+
station: string;
|
|
849
|
+
prn: string;
|
|
850
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane float (cycles). */
|
|
851
|
+
wlFloat: number;
|
|
852
|
+
/** Number of epochs averaged (used as the weight). */
|
|
853
|
+
nObs: number;
|
|
854
|
+
}
|
|
855
|
+
interface WlFcbOptions {
|
|
856
|
+
/** Max iterations. Default 50. */
|
|
857
|
+
maxIter?: number;
|
|
858
|
+
/** Convergence threshold on the largest bias change (cycles). Default 1e-4. */
|
|
859
|
+
tol?: number;
|
|
860
|
+
/** Fix-rate acceptance window |resid| (cycles). Default 0.25. */
|
|
861
|
+
fixWindow?: number;
|
|
862
|
+
}
|
|
863
|
+
interface WlFcbResult {
|
|
864
|
+
/** Per-satellite wide-lane FCB (cycles, wrapped to [−0.5, 0.5)). */
|
|
865
|
+
satFcb: Map<string, number>;
|
|
866
|
+
/** Per-station wide-lane bias (cycles); the reference station is 0. */
|
|
867
|
+
rcvBias: Map<string, number>;
|
|
868
|
+
/** RMS of the post-fit arc residuals Ñ_wl − N − b_rcv − b_sat (cycles). */
|
|
869
|
+
residRms: number;
|
|
870
|
+
/** Fraction of arcs whose residual lies within `fixWindow` of an integer. */
|
|
871
|
+
fixRate: number;
|
|
872
|
+
/** Reference station pinning the datum. */
|
|
873
|
+
refStation: string;
|
|
874
|
+
iterations: number;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Estimate per-satellite wide-lane FCBs from a network of stations' arc
|
|
878
|
+
* wide-lane floats. Needs ≥2 stations sharing satellites to break the
|
|
879
|
+
* integer/bias entanglement.
|
|
880
|
+
*/
|
|
881
|
+
declare function estimateWidelaneFcb(arcs: WlArc[], opts?: WlFcbOptions): WlFcbResult;
|
|
882
|
+
|
|
796
883
|
/**
|
|
797
884
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
798
885
|
* ephemerides.
|
|
@@ -882,4 +969,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
882
969
|
*/
|
|
883
970
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
884
971
|
|
|
885
|
-
export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, buildPppAntenna, createPppCorrections, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
972
|
+
export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, buildPppAntenna, createPppCorrections, estimateWidelaneFcb, extractWidelaneArcs, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.d.ts
CHANGED
|
@@ -793,6 +793,93 @@ interface ArResult {
|
|
|
793
793
|
*/
|
|
794
794
|
declare function resolvePppAmbiguities(sats: ArSat[], Qaif: Float64Array, opts?: ArOptions): ArResult;
|
|
795
795
|
|
|
796
|
+
/**
|
|
797
|
+
* Wide-lane fractional-cycle bias (FCB) estimation for PPP-AR — the
|
|
798
|
+
* self-contained route to integer ambiguities that needs no external
|
|
799
|
+
* phase-bias product, only a small network of stations.
|
|
800
|
+
*
|
|
801
|
+
* A single receiver cannot resolve ambiguities because its Melbourne–Wübbena
|
|
802
|
+
* wide-lane float is `Ñ_wl = N (integer) + b_rcv + b_sat`, and the integer
|
|
803
|
+
* and the satellite fractional bias `b_sat` are entangled. Across a *network*
|
|
804
|
+
* they separate: every station sees the same `b_sat` for a given satellite
|
|
805
|
+
* but its own integers and receiver bias, so the fractional part common to
|
|
806
|
+
* all stations *is* the satellite FCB. This is the classic Ge/Gendt method.
|
|
807
|
+
*
|
|
808
|
+
* The estimator alternates:
|
|
809
|
+
* 1. round each arc to its integer N = round(Ñ_wl − b_rcv − b_sat);
|
|
810
|
+
* 2. update each satellite FCB = circular-mean over stations of
|
|
811
|
+
* (Ñ_wl − N − b_rcv);
|
|
812
|
+
* 3. update each receiver bias = circular-mean over satellites of
|
|
813
|
+
* (Ñ_wl − N − b_sat);
|
|
814
|
+
* 4. pin the datum (b_rcv of a reference station ≡ 0) — receiver and
|
|
815
|
+
* satellite biases otherwise trade off by an arbitrary constant.
|
|
816
|
+
*
|
|
817
|
+
* The output `satFcb` feeds `resolvePppAmbiguities`' `wlBiasCyc`.
|
|
818
|
+
*/
|
|
819
|
+
/** Minimal per-satellite observation for wide-lane extraction. */
|
|
820
|
+
interface WlObs {
|
|
821
|
+
prn: string;
|
|
822
|
+
f1: number;
|
|
823
|
+
f2: number;
|
|
824
|
+
/** Code on f1/f2 (m) and carrier phase on f1/f2 (cycles). */
|
|
825
|
+
c1: number;
|
|
826
|
+
c2: number;
|
|
827
|
+
l1: number;
|
|
828
|
+
l2: number;
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Extract arc-averaged Melbourne–Wübbena wide-lanes for one station from its
|
|
832
|
+
* epoch stream. The MW combination
|
|
833
|
+
* MW = (L1 − L2) − [(f1·C1 + f2·C2)/(f1+f2)] / (c/(f1−f2)) [cycles]
|
|
834
|
+
* is geometry-, clock- and (first-order) ionosphere-free, so it holds the
|
|
835
|
+
* wide-lane ambiguity plus biases and is near-constant within an arc. Arcs
|
|
836
|
+
* are split on a running-mean jump (cycle slip) or a time gap.
|
|
837
|
+
*/
|
|
838
|
+
declare function extractWidelaneArcs(station: string, epochs: {
|
|
839
|
+
timeMs: number;
|
|
840
|
+
obs: WlObs[];
|
|
841
|
+
}[], opts?: {
|
|
842
|
+
slipCyc?: number;
|
|
843
|
+
gapMs?: number;
|
|
844
|
+
minObs?: number;
|
|
845
|
+
}): WlArc[];
|
|
846
|
+
/** One continuous wide-lane arc at a station. */
|
|
847
|
+
interface WlArc {
|
|
848
|
+
station: string;
|
|
849
|
+
prn: string;
|
|
850
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane float (cycles). */
|
|
851
|
+
wlFloat: number;
|
|
852
|
+
/** Number of epochs averaged (used as the weight). */
|
|
853
|
+
nObs: number;
|
|
854
|
+
}
|
|
855
|
+
interface WlFcbOptions {
|
|
856
|
+
/** Max iterations. Default 50. */
|
|
857
|
+
maxIter?: number;
|
|
858
|
+
/** Convergence threshold on the largest bias change (cycles). Default 1e-4. */
|
|
859
|
+
tol?: number;
|
|
860
|
+
/** Fix-rate acceptance window |resid| (cycles). Default 0.25. */
|
|
861
|
+
fixWindow?: number;
|
|
862
|
+
}
|
|
863
|
+
interface WlFcbResult {
|
|
864
|
+
/** Per-satellite wide-lane FCB (cycles, wrapped to [−0.5, 0.5)). */
|
|
865
|
+
satFcb: Map<string, number>;
|
|
866
|
+
/** Per-station wide-lane bias (cycles); the reference station is 0. */
|
|
867
|
+
rcvBias: Map<string, number>;
|
|
868
|
+
/** RMS of the post-fit arc residuals Ñ_wl − N − b_rcv − b_sat (cycles). */
|
|
869
|
+
residRms: number;
|
|
870
|
+
/** Fraction of arcs whose residual lies within `fixWindow` of an integer. */
|
|
871
|
+
fixRate: number;
|
|
872
|
+
/** Reference station pinning the datum. */
|
|
873
|
+
refStation: string;
|
|
874
|
+
iterations: number;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Estimate per-satellite wide-lane FCBs from a network of stations' arc
|
|
878
|
+
* wide-lane floats. Needs ≥2 stations sharing satellites to break the
|
|
879
|
+
* integer/bias entanglement.
|
|
880
|
+
*/
|
|
881
|
+
declare function estimateWidelaneFcb(arcs: WlArc[], opts?: WlFcbOptions): WlFcbResult;
|
|
882
|
+
|
|
796
883
|
/**
|
|
797
884
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
798
885
|
* ephemerides.
|
|
@@ -882,4 +969,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
882
969
|
*/
|
|
883
970
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
884
971
|
|
|
885
|
-
export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, buildPppAntenna, createPppCorrections, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
972
|
+
export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, buildPppAntenna, createPppCorrections, estimateWidelaneFcb, extractWidelaneArcs, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.js
CHANGED
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
RtkFloatEngine,
|
|
4
4
|
buildPppAntenna,
|
|
5
5
|
createPppCorrections,
|
|
6
|
+
estimateWidelaneFcb,
|
|
7
|
+
extractWidelaneArcs,
|
|
6
8
|
gimSlantIonoDelayL1,
|
|
7
9
|
gimVerticalTec,
|
|
8
10
|
gmst,
|
|
@@ -22,7 +24,7 @@ import {
|
|
|
22
24
|
sunEcef,
|
|
23
25
|
toRtkEpoch,
|
|
24
26
|
wlWavelength
|
|
25
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-KD2KJGLQ.js";
|
|
26
28
|
import "./chunk-MHGNKSSH.js";
|
|
27
29
|
import "./chunk-37QNKGTC.js";
|
|
28
30
|
import "./chunk-6FAL6P4G.js";
|
|
@@ -35,6 +37,8 @@ export {
|
|
|
35
37
|
RtkFloatEngine,
|
|
36
38
|
buildPppAntenna,
|
|
37
39
|
createPppCorrections,
|
|
40
|
+
estimateWidelaneFcb,
|
|
41
|
+
extractWidelaneArcs,
|
|
38
42
|
gimSlantIonoDelayL1,
|
|
39
43
|
gimVerticalTec,
|
|
40
44
|
gmst,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.32.1",
|
|
4
4
|
"description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|