gnss-js 1.33.0 → 1.34.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-PVOF4IGX.js → chunk-H73PZB5C.js} +113 -27
- package/dist/index.cjs +130 -43
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -1
- package/dist/positioning.cjs +114 -27
- package/dist/positioning.d.cts +54 -1
- package/dist/positioning.d.ts +54 -1
- package/dist/positioning.js +3 -1
- package/package.json +1 -1
|
@@ -461,15 +461,15 @@ function matMul(A, B) {
|
|
|
461
461
|
const n = A.length;
|
|
462
462
|
const k = B.length;
|
|
463
463
|
const m = B[0]?.length ?? 0;
|
|
464
|
-
const
|
|
464
|
+
const C2 = zeros(n, m);
|
|
465
465
|
for (let i = 0; i < n; i++) {
|
|
466
466
|
for (let l = 0; l < k; l++) {
|
|
467
467
|
const a = A[i][l];
|
|
468
468
|
if (a === 0) continue;
|
|
469
|
-
for (let j = 0; j < m; j++)
|
|
469
|
+
for (let j = 0; j < m; j++) C2[i][j] += a * B[l][j];
|
|
470
470
|
}
|
|
471
471
|
}
|
|
472
|
-
return
|
|
472
|
+
return C2;
|
|
473
473
|
}
|
|
474
474
|
function transpose(A) {
|
|
475
475
|
const n = A.length;
|
|
@@ -1649,6 +1649,24 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1649
1649
|
const clockSeeded = /* @__PURE__ */ new Set();
|
|
1650
1650
|
const ambIdx = /* @__PURE__ */ new Map();
|
|
1651
1651
|
const lastSeen = /* @__PURE__ */ new Map();
|
|
1652
|
+
const arcs = [];
|
|
1653
|
+
const arcSnap = /* @__PURE__ */ new Map();
|
|
1654
|
+
const flushArc = (prn, minEpochs = 10) => {
|
|
1655
|
+
const s = arcSnap.get(prn);
|
|
1656
|
+
arcSnap.delete(prn);
|
|
1657
|
+
if (!s || s.nEpochs < minEpochs) return;
|
|
1658
|
+
arcs.push({
|
|
1659
|
+
prn,
|
|
1660
|
+
aIF: s.aIF,
|
|
1661
|
+
mwCyc: s.mwCyc,
|
|
1662
|
+
f1: s.f1,
|
|
1663
|
+
f2: s.f2,
|
|
1664
|
+
meanElevDeg: s.elevSum / s.nEpochs,
|
|
1665
|
+
nEpochs: s.nEpochs,
|
|
1666
|
+
startMs: s.startMs,
|
|
1667
|
+
endMs: s.endMs
|
|
1668
|
+
});
|
|
1669
|
+
};
|
|
1652
1670
|
const mwState = /* @__PURE__ */ new Map();
|
|
1653
1671
|
const detectSlip = (o, ei) => {
|
|
1654
1672
|
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
@@ -1766,7 +1784,9 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1766
1784
|
tropoFixed: zhd * mh + corr.rangeM,
|
|
1767
1785
|
mw,
|
|
1768
1786
|
windupM: corr.phaseWindupM,
|
|
1769
|
-
slip
|
|
1787
|
+
slip,
|
|
1788
|
+
f1: o.f1,
|
|
1789
|
+
f2: o.f2
|
|
1770
1790
|
});
|
|
1771
1791
|
}
|
|
1772
1792
|
const zwd0 = x[IDX_ZWD];
|
|
@@ -1791,6 +1811,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1791
1811
|
for (const v of vis) {
|
|
1792
1812
|
const ci = clockOf(v.prn[0]);
|
|
1793
1813
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
1814
|
+
if (v.slip) flushArc(v.prn);
|
|
1794
1815
|
let ai = ambIdx.get(v.prn);
|
|
1795
1816
|
if (ai === void 0 || v.slip) {
|
|
1796
1817
|
const bInit = v.lIf - (common + v.windupM);
|
|
@@ -1824,6 +1845,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1824
1845
|
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
1825
1846
|
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
1826
1847
|
if (Math.abs(innov) > 0.15) {
|
|
1848
|
+
flushArc(v.prn);
|
|
1827
1849
|
x[ai] = v.lIf - (commonPh + v.windupM);
|
|
1828
1850
|
for (let j = 0; j < P.length; j++) {
|
|
1829
1851
|
P[ai][j] = 0;
|
|
@@ -1841,6 +1863,29 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1841
1863
|
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
1842
1864
|
}
|
|
1843
1865
|
}
|
|
1866
|
+
{
|
|
1867
|
+
const elevDeg = v.elRad * 180 / Math.PI;
|
|
1868
|
+
const mwMean = mwState.get(v.prn)?.mean ?? 0;
|
|
1869
|
+
const s = arcSnap.get(v.prn);
|
|
1870
|
+
if (s) {
|
|
1871
|
+
s.aIF = x[ai];
|
|
1872
|
+
s.mwCyc = mwMean;
|
|
1873
|
+
s.elevSum += elevDeg;
|
|
1874
|
+
s.nEpochs++;
|
|
1875
|
+
s.endMs = epoch.timeMs;
|
|
1876
|
+
} else {
|
|
1877
|
+
arcSnap.set(v.prn, {
|
|
1878
|
+
aIF: x[ai],
|
|
1879
|
+
mwCyc: mwMean,
|
|
1880
|
+
f1: v.f1,
|
|
1881
|
+
f2: v.f2,
|
|
1882
|
+
elevSum: elevDeg,
|
|
1883
|
+
nEpochs: 1,
|
|
1884
|
+
startMs: epoch.timeMs,
|
|
1885
|
+
endMs: epoch.timeMs
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1844
1889
|
lastSeen.set(v.prn, ei);
|
|
1845
1890
|
nSats++;
|
|
1846
1891
|
}
|
|
@@ -1874,6 +1919,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1874
1919
|
const idx = ambIdx.get(prn);
|
|
1875
1920
|
if (idx !== void 0) dropState(idx);
|
|
1876
1921
|
lastSeen.delete(prn);
|
|
1922
|
+
flushArc(prn);
|
|
1877
1923
|
}
|
|
1878
1924
|
}
|
|
1879
1925
|
const pos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
@@ -1913,6 +1959,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1913
1959
|
phaseResRms: nPhaseRes > 0 ? Math.sqrt(sumPhaseResSq / nPhaseRes) : 0
|
|
1914
1960
|
});
|
|
1915
1961
|
}
|
|
1962
|
+
for (const prn of [...arcSnap.keys()]) flushArc(prn);
|
|
1916
1963
|
const finalPos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
1917
1964
|
const llh = ecefToGeodetic(finalPos[0], finalPos[1], finalPos[2]);
|
|
1918
1965
|
const finalError3d = truth ? Math.hypot(
|
|
@@ -1927,7 +1974,8 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
1927
1974
|
ztdWet: x[IDX_ZWD],
|
|
1928
1975
|
epochsUsed: epochs.length,
|
|
1929
1976
|
convergenceSec,
|
|
1930
|
-
finalError3d
|
|
1977
|
+
finalError3d,
|
|
1978
|
+
arcs
|
|
1931
1979
|
};
|
|
1932
1980
|
}
|
|
1933
1981
|
|
|
@@ -2068,34 +2116,34 @@ function circMean(vals, weights) {
|
|
|
2068
2116
|
if (s === 0 && c === 0) return 0;
|
|
2069
2117
|
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
2070
2118
|
}
|
|
2071
|
-
function
|
|
2119
|
+
function decomposeFcb(entries, opts = {}) {
|
|
2072
2120
|
const maxIter = opts.maxIter ?? 50;
|
|
2073
2121
|
const tol = opts.tol ?? 1e-4;
|
|
2074
2122
|
const fixWindow = opts.fixWindow ?? 0.25;
|
|
2075
|
-
const sats = [...new Set(
|
|
2076
|
-
const stations = [...new Set(
|
|
2123
|
+
const sats = [...new Set(entries.map((e) => e.sat))].sort();
|
|
2124
|
+
const stations = [...new Set(entries.map((e) => e.station))].sort();
|
|
2077
2125
|
const refStation = stations[0] ?? "";
|
|
2078
2126
|
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
2079
2127
|
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
2080
|
-
const nInt = new Array(
|
|
2128
|
+
const nInt = new Array(entries.length).fill(0);
|
|
2081
2129
|
let iterations = 0;
|
|
2082
2130
|
for (let it = 0; it < maxIter; it++) {
|
|
2083
2131
|
iterations = it + 1;
|
|
2084
|
-
for (let i = 0; i <
|
|
2085
|
-
const
|
|
2132
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2133
|
+
const e = entries[i];
|
|
2086
2134
|
nInt[i] = Math.round(
|
|
2087
|
-
|
|
2135
|
+
e.value - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
2088
2136
|
);
|
|
2089
2137
|
}
|
|
2090
2138
|
let maxChange = 0;
|
|
2091
2139
|
for (const s of sats) {
|
|
2092
2140
|
const vals = [];
|
|
2093
2141
|
const w = [];
|
|
2094
|
-
for (let i = 0; i <
|
|
2095
|
-
const
|
|
2096
|
-
if (
|
|
2097
|
-
vals.push(
|
|
2098
|
-
w.push(
|
|
2142
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2143
|
+
const e = entries[i];
|
|
2144
|
+
if (e.sat !== s) continue;
|
|
2145
|
+
vals.push(e.value - nInt[i] - rcvBias.get(e.station));
|
|
2146
|
+
w.push(e.weight);
|
|
2099
2147
|
}
|
|
2100
2148
|
if (!vals.length) continue;
|
|
2101
2149
|
const nv = circMean(vals, w);
|
|
@@ -2105,11 +2153,11 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
2105
2153
|
for (const r of stations) {
|
|
2106
2154
|
const vals = [];
|
|
2107
2155
|
const w = [];
|
|
2108
|
-
for (let i = 0; i <
|
|
2109
|
-
const
|
|
2110
|
-
if (
|
|
2111
|
-
vals.push(
|
|
2112
|
-
w.push(
|
|
2156
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2157
|
+
const e = entries[i];
|
|
2158
|
+
if (e.station !== r) continue;
|
|
2159
|
+
vals.push(e.value - nInt[i] - satFcb.get(e.sat));
|
|
2160
|
+
w.push(e.weight);
|
|
2113
2161
|
}
|
|
2114
2162
|
if (!vals.length) continue;
|
|
2115
2163
|
rcvBias.set(r, circMean(vals, w));
|
|
@@ -2124,18 +2172,55 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
2124
2172
|
}
|
|
2125
2173
|
let sumSq = 0;
|
|
2126
2174
|
let fixed = 0;
|
|
2127
|
-
for (let i = 0; i <
|
|
2128
|
-
const
|
|
2175
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2176
|
+
const e = entries[i];
|
|
2129
2177
|
const resid = wrapHalf(
|
|
2130
|
-
|
|
2178
|
+
e.value - nInt[i] - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
2131
2179
|
);
|
|
2132
2180
|
sumSq += resid * resid;
|
|
2133
2181
|
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
2134
2182
|
}
|
|
2135
|
-
const residRms =
|
|
2136
|
-
const fixRate =
|
|
2183
|
+
const residRms = entries.length ? Math.sqrt(sumSq / entries.length) : 0;
|
|
2184
|
+
const fixRate = entries.length ? fixed / entries.length : 0;
|
|
2137
2185
|
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
2138
2186
|
}
|
|
2187
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
2188
|
+
return decomposeFcb(
|
|
2189
|
+
arcs.map((a) => ({
|
|
2190
|
+
station: a.station,
|
|
2191
|
+
sat: a.prn,
|
|
2192
|
+
value: a.wlFloat,
|
|
2193
|
+
weight: a.nObs
|
|
2194
|
+
})),
|
|
2195
|
+
opts
|
|
2196
|
+
);
|
|
2197
|
+
}
|
|
2198
|
+
var C = 299792458;
|
|
2199
|
+
function estimateNarrowlaneFcb(arcs, wl, opts = {}) {
|
|
2200
|
+
const entries = [];
|
|
2201
|
+
let wlRejected = 0;
|
|
2202
|
+
for (const a of arcs) {
|
|
2203
|
+
const satWl = wl.satFcb.get(a.prn);
|
|
2204
|
+
const rcvWl = wl.rcvBias.get(a.station);
|
|
2205
|
+
if (satWl === void 0 || rcvWl === void 0) continue;
|
|
2206
|
+
const wlFloat = a.mwCyc - satWl - rcvWl;
|
|
2207
|
+
const nWl = Math.round(wlFloat);
|
|
2208
|
+
if (Math.abs(wlFloat - nWl) > (opts.fixWindow ?? 0.25)) {
|
|
2209
|
+
wlRejected++;
|
|
2210
|
+
continue;
|
|
2211
|
+
}
|
|
2212
|
+
const lamNl = C / (a.f1 + a.f2);
|
|
2213
|
+
const n1Float = a.aIF / lamNl - a.f2 / (a.f1 - a.f2) * nWl;
|
|
2214
|
+
entries.push({
|
|
2215
|
+
station: a.station,
|
|
2216
|
+
sat: a.prn,
|
|
2217
|
+
value: n1Float,
|
|
2218
|
+
weight: a.nEpochs
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2221
|
+
const res = decomposeFcb(entries, { fixWindow: 0.15, ...opts });
|
|
2222
|
+
return { ...res, usedArcs: entries.length, wlRejected };
|
|
2223
|
+
}
|
|
2139
2224
|
|
|
2140
2225
|
// src/positioning/index.ts
|
|
2141
2226
|
var GM_GPS = 3986005e8;
|
|
@@ -2388,6 +2473,7 @@ export {
|
|
|
2388
2473
|
resolvePppAmbiguities,
|
|
2389
2474
|
extractWidelaneArcs,
|
|
2390
2475
|
estimateWidelaneFcb,
|
|
2476
|
+
estimateNarrowlaneFcb,
|
|
2391
2477
|
satClockCorrection,
|
|
2392
2478
|
ionoFree,
|
|
2393
2479
|
solveSpp
|
package/dist/index.cjs
CHANGED
|
@@ -149,6 +149,7 @@ __export(src_exports, {
|
|
|
149
149
|
ecefToAzEl: () => ecefToAzEl,
|
|
150
150
|
ecefToGeodetic: () => ecefToGeodetic,
|
|
151
151
|
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
152
|
+
estimateNarrowlaneFcb: () => estimateNarrowlaneFcb,
|
|
152
153
|
estimateWidelaneFcb: () => estimateWidelaneFcb,
|
|
153
154
|
euclidean3D: () => euclidean3D,
|
|
154
155
|
extractWidelaneArcs: () => extractWidelaneArcs,
|
|
@@ -1067,7 +1068,7 @@ function vincenty(lat1, lon1, lat2, lon2) {
|
|
|
1067
1068
|
let lambdaPrev;
|
|
1068
1069
|
let sinSigma, cosSigma, sigma;
|
|
1069
1070
|
let sinAlpha, cos2Alpha, cos2SigmaM;
|
|
1070
|
-
let
|
|
1071
|
+
let C2;
|
|
1071
1072
|
let iter = 0;
|
|
1072
1073
|
do {
|
|
1073
1074
|
const sinLambda2 = Math.sin(lambda);
|
|
@@ -1083,9 +1084,9 @@ function vincenty(lat1, lon1, lat2, lon2) {
|
|
|
1083
1084
|
sinAlpha = cosU1 * cosU2 * sinLambda2 / sinSigma;
|
|
1084
1085
|
cos2Alpha = 1 - sinAlpha ** 2;
|
|
1085
1086
|
cos2SigmaM = cos2Alpha !== 0 ? cosSigma - 2 * sinU1 * sinU2 / cos2Alpha : 0;
|
|
1086
|
-
|
|
1087
|
+
C2 = WGS84_FLATTENING / 16 * cos2Alpha * (4 + WGS84_FLATTENING * (4 - 3 * cos2Alpha));
|
|
1087
1088
|
lambdaPrev = lambda;
|
|
1088
|
-
lambda = lon2 - lon1 + (1 -
|
|
1089
|
+
lambda = lon2 - lon1 + (1 - C2) * WGS84_FLATTENING * sinAlpha * (sigma + C2 * sinSigma * (cos2SigmaM + C2 * cosSigma * (-1 + 2 * cos2SigmaM ** 2)));
|
|
1089
1090
|
} while (Math.abs(lambda - lambdaPrev) > 1e-12 && ++iter < 200);
|
|
1090
1091
|
if (iter >= 200) {
|
|
1091
1092
|
const cosLat1 = Math.cos(lat1), sinLat1 = Math.sin(lat1);
|
|
@@ -1189,11 +1190,11 @@ function geodeticToUtm(lat, lon) {
|
|
|
1189
1190
|
const ep2 = e2 / (1 - e2);
|
|
1190
1191
|
const N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - e2 * Math.sin(lat) ** 2);
|
|
1191
1192
|
const T = Math.tan(lat) ** 2;
|
|
1192
|
-
const
|
|
1193
|
+
const C2 = ep2 * Math.cos(lat) ** 2;
|
|
1193
1194
|
const A = Math.cos(lat) * (lon - lon0);
|
|
1194
1195
|
const M = WGS84_SEMI_MAJOR_AXIS * ((1 - e2 / 4 - 3 * e2 ** 2 / 64 - 5 * e2 ** 3 / 256) * lat - (3 * e2 / 8 + 3 * e2 ** 2 / 32 + 45 * e2 ** 3 / 1024) * Math.sin(2 * lat) + (15 * e2 ** 2 / 256 + 45 * e2 ** 3 / 1024) * Math.sin(4 * lat) - 35 * e2 ** 3 / 3072 * Math.sin(6 * lat));
|
|
1195
|
-
const easting = k0 * N * (A + (1 - T +
|
|
1196
|
-
let northing = k0 * (M + N * Math.tan(lat) * (A ** 2 / 2 + (5 - T + 9 *
|
|
1196
|
+
const easting = k0 * N * (A + (1 - T + C2) * A ** 3 / 6 + (5 - 18 * T + T ** 2 + 72 * C2 - 58 * ep2) * A ** 5 / 120) + 5e5;
|
|
1197
|
+
let northing = k0 * (M + N * Math.tan(lat) * (A ** 2 / 2 + (5 - T + 9 * C2 + 4 * C2 ** 2) * A ** 4 / 24 + (61 - 58 * T + T ** 2 + 600 * C2 - 330 * ep2) * A ** 6 / 720));
|
|
1197
1198
|
const hemisphere = latDeg >= 0 ? "N" : "S";
|
|
1198
1199
|
if (hemisphere === "S") {
|
|
1199
1200
|
northing += 1e7;
|
|
@@ -11857,15 +11858,15 @@ function matMul(A, B) {
|
|
|
11857
11858
|
const n = A.length;
|
|
11858
11859
|
const k = B.length;
|
|
11859
11860
|
const m = B[0]?.length ?? 0;
|
|
11860
|
-
const
|
|
11861
|
+
const C2 = zeros(n, m);
|
|
11861
11862
|
for (let i = 0; i < n; i++) {
|
|
11862
11863
|
for (let l = 0; l < k; l++) {
|
|
11863
11864
|
const a = A[i][l];
|
|
11864
11865
|
if (a === 0) continue;
|
|
11865
|
-
for (let j = 0; j < m; j++)
|
|
11866
|
+
for (let j = 0; j < m; j++) C2[i][j] += a * B[l][j];
|
|
11866
11867
|
}
|
|
11867
11868
|
}
|
|
11868
|
-
return
|
|
11869
|
+
return C2;
|
|
11869
11870
|
}
|
|
11870
11871
|
function transpose(A) {
|
|
11871
11872
|
const n = A.length;
|
|
@@ -13045,6 +13046,24 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13045
13046
|
const clockSeeded = /* @__PURE__ */ new Set();
|
|
13046
13047
|
const ambIdx = /* @__PURE__ */ new Map();
|
|
13047
13048
|
const lastSeen = /* @__PURE__ */ new Map();
|
|
13049
|
+
const arcs = [];
|
|
13050
|
+
const arcSnap = /* @__PURE__ */ new Map();
|
|
13051
|
+
const flushArc = (prn, minEpochs = 10) => {
|
|
13052
|
+
const s = arcSnap.get(prn);
|
|
13053
|
+
arcSnap.delete(prn);
|
|
13054
|
+
if (!s || s.nEpochs < minEpochs) return;
|
|
13055
|
+
arcs.push({
|
|
13056
|
+
prn,
|
|
13057
|
+
aIF: s.aIF,
|
|
13058
|
+
mwCyc: s.mwCyc,
|
|
13059
|
+
f1: s.f1,
|
|
13060
|
+
f2: s.f2,
|
|
13061
|
+
meanElevDeg: s.elevSum / s.nEpochs,
|
|
13062
|
+
nEpochs: s.nEpochs,
|
|
13063
|
+
startMs: s.startMs,
|
|
13064
|
+
endMs: s.endMs
|
|
13065
|
+
});
|
|
13066
|
+
};
|
|
13048
13067
|
const mwState = /* @__PURE__ */ new Map();
|
|
13049
13068
|
const detectSlip = (o, ei) => {
|
|
13050
13069
|
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
@@ -13162,7 +13181,9 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13162
13181
|
tropoFixed: zhd * mh + corr.rangeM,
|
|
13163
13182
|
mw,
|
|
13164
13183
|
windupM: corr.phaseWindupM,
|
|
13165
|
-
slip
|
|
13184
|
+
slip,
|
|
13185
|
+
f1: o.f1,
|
|
13186
|
+
f2: o.f2
|
|
13166
13187
|
});
|
|
13167
13188
|
}
|
|
13168
13189
|
const zwd0 = x[IDX_ZWD];
|
|
@@ -13187,6 +13208,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13187
13208
|
for (const v of vis) {
|
|
13188
13209
|
const ci = clockOf(v.prn[0]);
|
|
13189
13210
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
13211
|
+
if (v.slip) flushArc(v.prn);
|
|
13190
13212
|
let ai = ambIdx.get(v.prn);
|
|
13191
13213
|
if (ai === void 0 || v.slip) {
|
|
13192
13214
|
const bInit = v.lIf - (common + v.windupM);
|
|
@@ -13220,6 +13242,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13220
13242
|
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
13221
13243
|
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
13222
13244
|
if (Math.abs(innov) > 0.15) {
|
|
13245
|
+
flushArc(v.prn);
|
|
13223
13246
|
x[ai] = v.lIf - (commonPh + v.windupM);
|
|
13224
13247
|
for (let j = 0; j < P.length; j++) {
|
|
13225
13248
|
P[ai][j] = 0;
|
|
@@ -13237,6 +13260,29 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13237
13260
|
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
13238
13261
|
}
|
|
13239
13262
|
}
|
|
13263
|
+
{
|
|
13264
|
+
const elevDeg = v.elRad * 180 / Math.PI;
|
|
13265
|
+
const mwMean = mwState.get(v.prn)?.mean ?? 0;
|
|
13266
|
+
const s = arcSnap.get(v.prn);
|
|
13267
|
+
if (s) {
|
|
13268
|
+
s.aIF = x[ai];
|
|
13269
|
+
s.mwCyc = mwMean;
|
|
13270
|
+
s.elevSum += elevDeg;
|
|
13271
|
+
s.nEpochs++;
|
|
13272
|
+
s.endMs = epoch.timeMs;
|
|
13273
|
+
} else {
|
|
13274
|
+
arcSnap.set(v.prn, {
|
|
13275
|
+
aIF: x[ai],
|
|
13276
|
+
mwCyc: mwMean,
|
|
13277
|
+
f1: v.f1,
|
|
13278
|
+
f2: v.f2,
|
|
13279
|
+
elevSum: elevDeg,
|
|
13280
|
+
nEpochs: 1,
|
|
13281
|
+
startMs: epoch.timeMs,
|
|
13282
|
+
endMs: epoch.timeMs
|
|
13283
|
+
});
|
|
13284
|
+
}
|
|
13285
|
+
}
|
|
13240
13286
|
lastSeen.set(v.prn, ei);
|
|
13241
13287
|
nSats++;
|
|
13242
13288
|
}
|
|
@@ -13270,6 +13316,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13270
13316
|
const idx = ambIdx.get(prn);
|
|
13271
13317
|
if (idx !== void 0) dropState(idx);
|
|
13272
13318
|
lastSeen.delete(prn);
|
|
13319
|
+
flushArc(prn);
|
|
13273
13320
|
}
|
|
13274
13321
|
}
|
|
13275
13322
|
const pos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
@@ -13309,6 +13356,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13309
13356
|
phaseResRms: nPhaseRes > 0 ? Math.sqrt(sumPhaseResSq / nPhaseRes) : 0
|
|
13310
13357
|
});
|
|
13311
13358
|
}
|
|
13359
|
+
for (const prn of [...arcSnap.keys()]) flushArc(prn);
|
|
13312
13360
|
const finalPos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
13313
13361
|
const llh = ecefToGeodetic(finalPos[0], finalPos[1], finalPos[2]);
|
|
13314
13362
|
const finalError3d = truth ? Math.hypot(
|
|
@@ -13323,7 +13371,8 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13323
13371
|
ztdWet: x[IDX_ZWD],
|
|
13324
13372
|
epochsUsed: epochs.length,
|
|
13325
13373
|
convergenceSec,
|
|
13326
|
-
finalError3d
|
|
13374
|
+
finalError3d,
|
|
13375
|
+
arcs
|
|
13327
13376
|
};
|
|
13328
13377
|
}
|
|
13329
13378
|
|
|
@@ -13464,34 +13513,34 @@ function circMean(vals, weights) {
|
|
|
13464
13513
|
if (s === 0 && c === 0) return 0;
|
|
13465
13514
|
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
13466
13515
|
}
|
|
13467
|
-
function
|
|
13516
|
+
function decomposeFcb(entries, opts = {}) {
|
|
13468
13517
|
const maxIter = opts.maxIter ?? 50;
|
|
13469
13518
|
const tol = opts.tol ?? 1e-4;
|
|
13470
13519
|
const fixWindow = opts.fixWindow ?? 0.25;
|
|
13471
|
-
const sats = [...new Set(
|
|
13472
|
-
const stations = [...new Set(
|
|
13520
|
+
const sats = [...new Set(entries.map((e) => e.sat))].sort();
|
|
13521
|
+
const stations = [...new Set(entries.map((e) => e.station))].sort();
|
|
13473
13522
|
const refStation = stations[0] ?? "";
|
|
13474
13523
|
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
13475
13524
|
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
13476
|
-
const nInt = new Array(
|
|
13525
|
+
const nInt = new Array(entries.length).fill(0);
|
|
13477
13526
|
let iterations = 0;
|
|
13478
13527
|
for (let it = 0; it < maxIter; it++) {
|
|
13479
13528
|
iterations = it + 1;
|
|
13480
|
-
for (let i = 0; i <
|
|
13481
|
-
const
|
|
13529
|
+
for (let i = 0; i < entries.length; i++) {
|
|
13530
|
+
const e = entries[i];
|
|
13482
13531
|
nInt[i] = Math.round(
|
|
13483
|
-
|
|
13532
|
+
e.value - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
13484
13533
|
);
|
|
13485
13534
|
}
|
|
13486
13535
|
let maxChange = 0;
|
|
13487
13536
|
for (const s of sats) {
|
|
13488
13537
|
const vals = [];
|
|
13489
13538
|
const w = [];
|
|
13490
|
-
for (let i = 0; i <
|
|
13491
|
-
const
|
|
13492
|
-
if (
|
|
13493
|
-
vals.push(
|
|
13494
|
-
w.push(
|
|
13539
|
+
for (let i = 0; i < entries.length; i++) {
|
|
13540
|
+
const e = entries[i];
|
|
13541
|
+
if (e.sat !== s) continue;
|
|
13542
|
+
vals.push(e.value - nInt[i] - rcvBias.get(e.station));
|
|
13543
|
+
w.push(e.weight);
|
|
13495
13544
|
}
|
|
13496
13545
|
if (!vals.length) continue;
|
|
13497
13546
|
const nv = circMean(vals, w);
|
|
@@ -13501,11 +13550,11 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
13501
13550
|
for (const r of stations) {
|
|
13502
13551
|
const vals = [];
|
|
13503
13552
|
const w = [];
|
|
13504
|
-
for (let i = 0; i <
|
|
13505
|
-
const
|
|
13506
|
-
if (
|
|
13507
|
-
vals.push(
|
|
13508
|
-
w.push(
|
|
13553
|
+
for (let i = 0; i < entries.length; i++) {
|
|
13554
|
+
const e = entries[i];
|
|
13555
|
+
if (e.station !== r) continue;
|
|
13556
|
+
vals.push(e.value - nInt[i] - satFcb.get(e.sat));
|
|
13557
|
+
w.push(e.weight);
|
|
13509
13558
|
}
|
|
13510
13559
|
if (!vals.length) continue;
|
|
13511
13560
|
rcvBias.set(r, circMean(vals, w));
|
|
@@ -13520,18 +13569,55 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
13520
13569
|
}
|
|
13521
13570
|
let sumSq = 0;
|
|
13522
13571
|
let fixed = 0;
|
|
13523
|
-
for (let i = 0; i <
|
|
13524
|
-
const
|
|
13572
|
+
for (let i = 0; i < entries.length; i++) {
|
|
13573
|
+
const e = entries[i];
|
|
13525
13574
|
const resid = wrapHalf(
|
|
13526
|
-
|
|
13575
|
+
e.value - nInt[i] - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
13527
13576
|
);
|
|
13528
13577
|
sumSq += resid * resid;
|
|
13529
13578
|
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
13530
13579
|
}
|
|
13531
|
-
const residRms =
|
|
13532
|
-
const fixRate =
|
|
13580
|
+
const residRms = entries.length ? Math.sqrt(sumSq / entries.length) : 0;
|
|
13581
|
+
const fixRate = entries.length ? fixed / entries.length : 0;
|
|
13533
13582
|
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
13534
13583
|
}
|
|
13584
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
13585
|
+
return decomposeFcb(
|
|
13586
|
+
arcs.map((a) => ({
|
|
13587
|
+
station: a.station,
|
|
13588
|
+
sat: a.prn,
|
|
13589
|
+
value: a.wlFloat,
|
|
13590
|
+
weight: a.nObs
|
|
13591
|
+
})),
|
|
13592
|
+
opts
|
|
13593
|
+
);
|
|
13594
|
+
}
|
|
13595
|
+
var C = 299792458;
|
|
13596
|
+
function estimateNarrowlaneFcb(arcs, wl, opts = {}) {
|
|
13597
|
+
const entries = [];
|
|
13598
|
+
let wlRejected = 0;
|
|
13599
|
+
for (const a of arcs) {
|
|
13600
|
+
const satWl = wl.satFcb.get(a.prn);
|
|
13601
|
+
const rcvWl = wl.rcvBias.get(a.station);
|
|
13602
|
+
if (satWl === void 0 || rcvWl === void 0) continue;
|
|
13603
|
+
const wlFloat = a.mwCyc - satWl - rcvWl;
|
|
13604
|
+
const nWl = Math.round(wlFloat);
|
|
13605
|
+
if (Math.abs(wlFloat - nWl) > (opts.fixWindow ?? 0.25)) {
|
|
13606
|
+
wlRejected++;
|
|
13607
|
+
continue;
|
|
13608
|
+
}
|
|
13609
|
+
const lamNl = C / (a.f1 + a.f2);
|
|
13610
|
+
const n1Float = a.aIF / lamNl - a.f2 / (a.f1 - a.f2) * nWl;
|
|
13611
|
+
entries.push({
|
|
13612
|
+
station: a.station,
|
|
13613
|
+
sat: a.prn,
|
|
13614
|
+
value: n1Float,
|
|
13615
|
+
weight: a.nEpochs
|
|
13616
|
+
});
|
|
13617
|
+
}
|
|
13618
|
+
const res = decomposeFcb(entries, { fixWindow: 0.15, ...opts });
|
|
13619
|
+
return { ...res, usedArcs: entries.length, wlRejected };
|
|
13620
|
+
}
|
|
13535
13621
|
|
|
13536
13622
|
// src/positioning/index.ts
|
|
13537
13623
|
var GM_GPS3 = 3986005e8;
|
|
@@ -13943,9 +14029,9 @@ var MultipathAccumulator = class {
|
|
|
13943
14029
|
const bandMap = this.obsIndices.get(sys) ?? this.obsIndices.get("_v2");
|
|
13944
14030
|
if (!bandMap) return;
|
|
13945
14031
|
const bandData = /* @__PURE__ */ new Map();
|
|
13946
|
-
for (const [band, { C, L }] of bandMap) {
|
|
13947
|
-
if (
|
|
13948
|
-
const cVal = values[
|
|
14032
|
+
for (const [band, { C: C2, L }] of bandMap) {
|
|
14033
|
+
if (C2 === null) continue;
|
|
14034
|
+
const cVal = values[C2];
|
|
13949
14035
|
const lVal = values[L];
|
|
13950
14036
|
const freq = getFreq(this.gloChannels, prn, band);
|
|
13951
14037
|
if (cVal != null && cVal !== 0 && lVal != null && lVal !== 0 && freq) {
|
|
@@ -14157,13 +14243,13 @@ var CycleSlipAccumulator = class {
|
|
|
14157
14243
|
if (sys !== "R" && !FREQ[sys]) return;
|
|
14158
14244
|
const phaseM = /* @__PURE__ */ new Map();
|
|
14159
14245
|
const codeM = /* @__PURE__ */ new Map();
|
|
14160
|
-
for (const [band, { L, C }] of idxMap) {
|
|
14246
|
+
for (const [band, { L, C: C2 }] of idxMap) {
|
|
14161
14247
|
const freq = this.getFreqForPrn(prn, band);
|
|
14162
14248
|
if (!freq) continue;
|
|
14163
14249
|
const lVal = values[L];
|
|
14164
14250
|
if (lVal != null && lVal !== 0) phaseM.set(band, lVal * (C_LIGHT / freq));
|
|
14165
|
-
if (
|
|
14166
|
-
const cVal = values[
|
|
14251
|
+
if (C2 !== null) {
|
|
14252
|
+
const cVal = values[C2];
|
|
14167
14253
|
if (cVal != null && cVal !== 0) codeM.set(band, cVal);
|
|
14168
14254
|
}
|
|
14169
14255
|
}
|
|
@@ -14427,9 +14513,9 @@ var IonoAccumulator = class {
|
|
|
14427
14513
|
const bandMap = this.obsIndices.get(sys) ?? this.obsIndices.get("_v2");
|
|
14428
14514
|
if (!bandMap) return;
|
|
14429
14515
|
const bandData = /* @__PURE__ */ new Map();
|
|
14430
|
-
for (const [band, { C, L }] of bandMap) {
|
|
14431
|
-
if (
|
|
14432
|
-
const cVal = values[
|
|
14516
|
+
for (const [band, { C: C2, L }] of bandMap) {
|
|
14517
|
+
if (C2 === null) continue;
|
|
14518
|
+
const cVal = values[C2];
|
|
14433
14519
|
const lVal = values[L];
|
|
14434
14520
|
const freq = getFreq(this.gloChannels, prn, band);
|
|
14435
14521
|
if (cVal != null && cVal !== 0 && lVal != null && lVal !== 0 && freq) {
|
|
@@ -14437,7 +14523,7 @@ var IonoAccumulator = class {
|
|
|
14437
14523
|
C: cVal,
|
|
14438
14524
|
L: lVal,
|
|
14439
14525
|
f: freq,
|
|
14440
|
-
code: codes[
|
|
14526
|
+
code: codes[C2] ?? `C${band}`
|
|
14441
14527
|
});
|
|
14442
14528
|
}
|
|
14443
14529
|
}
|
|
@@ -16150,6 +16236,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
16150
16236
|
ecefToAzEl,
|
|
16151
16237
|
ecefToGeodetic,
|
|
16152
16238
|
ephInfoToEphemeris,
|
|
16239
|
+
estimateNarrowlaneFcb,
|
|
16153
16240
|
estimateWidelaneFcb,
|
|
16154
16241
|
euclidean3D,
|
|
16155
16242
|
extractWidelaneArcs,
|
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, 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';
|
|
20
|
+
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, 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, 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';
|
|
20
|
+
export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SatGeom, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, 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,7 @@ import {
|
|
|
146
146
|
RtkFloatEngine,
|
|
147
147
|
buildPppAntenna,
|
|
148
148
|
createPppCorrections,
|
|
149
|
+
estimateNarrowlaneFcb,
|
|
149
150
|
estimateWidelaneFcb,
|
|
150
151
|
extractWidelaneArcs,
|
|
151
152
|
gimSlantIonoDelayL1,
|
|
@@ -167,7 +168,7 @@ import {
|
|
|
167
168
|
sunEcef,
|
|
168
169
|
toRtkEpoch,
|
|
169
170
|
wlWavelength
|
|
170
|
-
} from "./chunk-
|
|
171
|
+
} from "./chunk-H73PZB5C.js";
|
|
171
172
|
import {
|
|
172
173
|
almanacEpochMs,
|
|
173
174
|
almanacSatPosition,
|
|
@@ -474,6 +475,7 @@ export {
|
|
|
474
475
|
ecefToAzEl,
|
|
475
476
|
ecefToGeodetic,
|
|
476
477
|
ephInfoToEphemeris,
|
|
478
|
+
estimateNarrowlaneFcb,
|
|
477
479
|
estimateWidelaneFcb,
|
|
478
480
|
euclidean3D,
|
|
479
481
|
extractWidelaneArcs,
|
package/dist/positioning.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(positioning_exports, {
|
|
|
24
24
|
RtkFloatEngine: () => RtkFloatEngine,
|
|
25
25
|
buildPppAntenna: () => buildPppAntenna,
|
|
26
26
|
createPppCorrections: () => createPppCorrections,
|
|
27
|
+
estimateNarrowlaneFcb: () => estimateNarrowlaneFcb,
|
|
27
28
|
estimateWidelaneFcb: () => estimateWidelaneFcb,
|
|
28
29
|
extractWidelaneArcs: () => extractWidelaneArcs,
|
|
29
30
|
gimSlantIonoDelayL1: () => gimSlantIonoDelayL1,
|
|
@@ -913,15 +914,15 @@ function matMul(A, B) {
|
|
|
913
914
|
const n = A.length;
|
|
914
915
|
const k = B.length;
|
|
915
916
|
const m = B[0]?.length ?? 0;
|
|
916
|
-
const
|
|
917
|
+
const C2 = zeros(n, m);
|
|
917
918
|
for (let i = 0; i < n; i++) {
|
|
918
919
|
for (let l = 0; l < k; l++) {
|
|
919
920
|
const a = A[i][l];
|
|
920
921
|
if (a === 0) continue;
|
|
921
|
-
for (let j = 0; j < m; j++)
|
|
922
|
+
for (let j = 0; j < m; j++) C2[i][j] += a * B[l][j];
|
|
922
923
|
}
|
|
923
924
|
}
|
|
924
|
-
return
|
|
925
|
+
return C2;
|
|
925
926
|
}
|
|
926
927
|
function transpose(A) {
|
|
927
928
|
const n = A.length;
|
|
@@ -2173,6 +2174,24 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2173
2174
|
const clockSeeded = /* @__PURE__ */ new Set();
|
|
2174
2175
|
const ambIdx = /* @__PURE__ */ new Map();
|
|
2175
2176
|
const lastSeen = /* @__PURE__ */ new Map();
|
|
2177
|
+
const arcs = [];
|
|
2178
|
+
const arcSnap = /* @__PURE__ */ new Map();
|
|
2179
|
+
const flushArc = (prn, minEpochs = 10) => {
|
|
2180
|
+
const s = arcSnap.get(prn);
|
|
2181
|
+
arcSnap.delete(prn);
|
|
2182
|
+
if (!s || s.nEpochs < minEpochs) return;
|
|
2183
|
+
arcs.push({
|
|
2184
|
+
prn,
|
|
2185
|
+
aIF: s.aIF,
|
|
2186
|
+
mwCyc: s.mwCyc,
|
|
2187
|
+
f1: s.f1,
|
|
2188
|
+
f2: s.f2,
|
|
2189
|
+
meanElevDeg: s.elevSum / s.nEpochs,
|
|
2190
|
+
nEpochs: s.nEpochs,
|
|
2191
|
+
startMs: s.startMs,
|
|
2192
|
+
endMs: s.endMs
|
|
2193
|
+
});
|
|
2194
|
+
};
|
|
2176
2195
|
const mwState = /* @__PURE__ */ new Map();
|
|
2177
2196
|
const detectSlip = (o, ei) => {
|
|
2178
2197
|
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
@@ -2290,7 +2309,9 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2290
2309
|
tropoFixed: zhd * mh + corr.rangeM,
|
|
2291
2310
|
mw,
|
|
2292
2311
|
windupM: corr.phaseWindupM,
|
|
2293
|
-
slip
|
|
2312
|
+
slip,
|
|
2313
|
+
f1: o.f1,
|
|
2314
|
+
f2: o.f2
|
|
2294
2315
|
});
|
|
2295
2316
|
}
|
|
2296
2317
|
const zwd0 = x[IDX_ZWD];
|
|
@@ -2315,6 +2336,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2315
2336
|
for (const v of vis) {
|
|
2316
2337
|
const ci = clockOf(v.prn[0]);
|
|
2317
2338
|
const common = v.range + x[ci] - v.satClkM + v.tropoFixed + zwd0 * v.mw;
|
|
2339
|
+
if (v.slip) flushArc(v.prn);
|
|
2318
2340
|
let ai = ambIdx.get(v.prn);
|
|
2319
2341
|
if (ai === void 0 || v.slip) {
|
|
2320
2342
|
const bInit = v.lIf - (common + v.windupM);
|
|
@@ -2348,6 +2370,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2348
2370
|
const commonPh = v.range + x[ci] - v.satClkM + v.tropoFixed + x[IDX_ZWD] * v.mw;
|
|
2349
2371
|
const innov = v.lIf - (commonPh + v.windupM + x[ai]);
|
|
2350
2372
|
if (Math.abs(innov) > 0.15) {
|
|
2373
|
+
flushArc(v.prn);
|
|
2351
2374
|
x[ai] = v.lIf - (commonPh + v.windupM);
|
|
2352
2375
|
for (let j = 0; j < P.length; j++) {
|
|
2353
2376
|
P[ai][j] = 0;
|
|
@@ -2365,6 +2388,29 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2365
2388
|
ekfUpdateScalar(x, P, h, innov, rPhase, 4);
|
|
2366
2389
|
}
|
|
2367
2390
|
}
|
|
2391
|
+
{
|
|
2392
|
+
const elevDeg = v.elRad * 180 / Math.PI;
|
|
2393
|
+
const mwMean = mwState.get(v.prn)?.mean ?? 0;
|
|
2394
|
+
const s = arcSnap.get(v.prn);
|
|
2395
|
+
if (s) {
|
|
2396
|
+
s.aIF = x[ai];
|
|
2397
|
+
s.mwCyc = mwMean;
|
|
2398
|
+
s.elevSum += elevDeg;
|
|
2399
|
+
s.nEpochs++;
|
|
2400
|
+
s.endMs = epoch.timeMs;
|
|
2401
|
+
} else {
|
|
2402
|
+
arcSnap.set(v.prn, {
|
|
2403
|
+
aIF: x[ai],
|
|
2404
|
+
mwCyc: mwMean,
|
|
2405
|
+
f1: v.f1,
|
|
2406
|
+
f2: v.f2,
|
|
2407
|
+
elevSum: elevDeg,
|
|
2408
|
+
nEpochs: 1,
|
|
2409
|
+
startMs: epoch.timeMs,
|
|
2410
|
+
endMs: epoch.timeMs
|
|
2411
|
+
});
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2368
2414
|
lastSeen.set(v.prn, ei);
|
|
2369
2415
|
nSats++;
|
|
2370
2416
|
}
|
|
@@ -2398,6 +2444,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2398
2444
|
const idx = ambIdx.get(prn);
|
|
2399
2445
|
if (idx !== void 0) dropState(idx);
|
|
2400
2446
|
lastSeen.delete(prn);
|
|
2447
|
+
flushArc(prn);
|
|
2401
2448
|
}
|
|
2402
2449
|
}
|
|
2403
2450
|
const pos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
@@ -2437,6 +2484,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2437
2484
|
phaseResRms: nPhaseRes > 0 ? Math.sqrt(sumPhaseResSq / nPhaseRes) : 0
|
|
2438
2485
|
});
|
|
2439
2486
|
}
|
|
2487
|
+
for (const prn of [...arcSnap.keys()]) flushArc(prn);
|
|
2440
2488
|
const finalPos = [x[IDX_X], x[IDX_Y], x[IDX_Z]];
|
|
2441
2489
|
const llh = ecefToGeodetic(finalPos[0], finalPos[1], finalPos[2]);
|
|
2442
2490
|
const finalError3d = truth ? Math.hypot(
|
|
@@ -2451,7 +2499,8 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
2451
2499
|
ztdWet: x[IDX_ZWD],
|
|
2452
2500
|
epochsUsed: epochs.length,
|
|
2453
2501
|
convergenceSec,
|
|
2454
|
-
finalError3d
|
|
2502
|
+
finalError3d,
|
|
2503
|
+
arcs
|
|
2455
2504
|
};
|
|
2456
2505
|
}
|
|
2457
2506
|
|
|
@@ -2592,34 +2641,34 @@ function circMean(vals, weights) {
|
|
|
2592
2641
|
if (s === 0 && c === 0) return 0;
|
|
2593
2642
|
return wrapHalf(Math.atan2(s, c) / (2 * Math.PI));
|
|
2594
2643
|
}
|
|
2595
|
-
function
|
|
2644
|
+
function decomposeFcb(entries, opts = {}) {
|
|
2596
2645
|
const maxIter = opts.maxIter ?? 50;
|
|
2597
2646
|
const tol = opts.tol ?? 1e-4;
|
|
2598
2647
|
const fixWindow = opts.fixWindow ?? 0.25;
|
|
2599
|
-
const sats = [...new Set(
|
|
2600
|
-
const stations = [...new Set(
|
|
2648
|
+
const sats = [...new Set(entries.map((e) => e.sat))].sort();
|
|
2649
|
+
const stations = [...new Set(entries.map((e) => e.station))].sort();
|
|
2601
2650
|
const refStation = stations[0] ?? "";
|
|
2602
2651
|
const satFcb = new Map(sats.map((s) => [s, 0]));
|
|
2603
2652
|
const rcvBias = new Map(stations.map((s) => [s, 0]));
|
|
2604
|
-
const nInt = new Array(
|
|
2653
|
+
const nInt = new Array(entries.length).fill(0);
|
|
2605
2654
|
let iterations = 0;
|
|
2606
2655
|
for (let it = 0; it < maxIter; it++) {
|
|
2607
2656
|
iterations = it + 1;
|
|
2608
|
-
for (let i = 0; i <
|
|
2609
|
-
const
|
|
2657
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2658
|
+
const e = entries[i];
|
|
2610
2659
|
nInt[i] = Math.round(
|
|
2611
|
-
|
|
2660
|
+
e.value - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
2612
2661
|
);
|
|
2613
2662
|
}
|
|
2614
2663
|
let maxChange = 0;
|
|
2615
2664
|
for (const s of sats) {
|
|
2616
2665
|
const vals = [];
|
|
2617
2666
|
const w = [];
|
|
2618
|
-
for (let i = 0; i <
|
|
2619
|
-
const
|
|
2620
|
-
if (
|
|
2621
|
-
vals.push(
|
|
2622
|
-
w.push(
|
|
2667
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2668
|
+
const e = entries[i];
|
|
2669
|
+
if (e.sat !== s) continue;
|
|
2670
|
+
vals.push(e.value - nInt[i] - rcvBias.get(e.station));
|
|
2671
|
+
w.push(e.weight);
|
|
2623
2672
|
}
|
|
2624
2673
|
if (!vals.length) continue;
|
|
2625
2674
|
const nv = circMean(vals, w);
|
|
@@ -2629,11 +2678,11 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
2629
2678
|
for (const r of stations) {
|
|
2630
2679
|
const vals = [];
|
|
2631
2680
|
const w = [];
|
|
2632
|
-
for (let i = 0; i <
|
|
2633
|
-
const
|
|
2634
|
-
if (
|
|
2635
|
-
vals.push(
|
|
2636
|
-
w.push(
|
|
2681
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2682
|
+
const e = entries[i];
|
|
2683
|
+
if (e.station !== r) continue;
|
|
2684
|
+
vals.push(e.value - nInt[i] - satFcb.get(e.sat));
|
|
2685
|
+
w.push(e.weight);
|
|
2637
2686
|
}
|
|
2638
2687
|
if (!vals.length) continue;
|
|
2639
2688
|
rcvBias.set(r, circMean(vals, w));
|
|
@@ -2648,18 +2697,55 @@ function estimateWidelaneFcb(arcs, opts = {}) {
|
|
|
2648
2697
|
}
|
|
2649
2698
|
let sumSq = 0;
|
|
2650
2699
|
let fixed = 0;
|
|
2651
|
-
for (let i = 0; i <
|
|
2652
|
-
const
|
|
2700
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2701
|
+
const e = entries[i];
|
|
2653
2702
|
const resid = wrapHalf(
|
|
2654
|
-
|
|
2703
|
+
e.value - nInt[i] - rcvBias.get(e.station) - satFcb.get(e.sat)
|
|
2655
2704
|
);
|
|
2656
2705
|
sumSq += resid * resid;
|
|
2657
2706
|
if (Math.abs(resid) <= fixWindow) fixed++;
|
|
2658
2707
|
}
|
|
2659
|
-
const residRms =
|
|
2660
|
-
const fixRate =
|
|
2708
|
+
const residRms = entries.length ? Math.sqrt(sumSq / entries.length) : 0;
|
|
2709
|
+
const fixRate = entries.length ? fixed / entries.length : 0;
|
|
2661
2710
|
return { satFcb, rcvBias, residRms, fixRate, refStation, iterations };
|
|
2662
2711
|
}
|
|
2712
|
+
function estimateWidelaneFcb(arcs, opts = {}) {
|
|
2713
|
+
return decomposeFcb(
|
|
2714
|
+
arcs.map((a) => ({
|
|
2715
|
+
station: a.station,
|
|
2716
|
+
sat: a.prn,
|
|
2717
|
+
value: a.wlFloat,
|
|
2718
|
+
weight: a.nObs
|
|
2719
|
+
})),
|
|
2720
|
+
opts
|
|
2721
|
+
);
|
|
2722
|
+
}
|
|
2723
|
+
var C = 299792458;
|
|
2724
|
+
function estimateNarrowlaneFcb(arcs, wl, opts = {}) {
|
|
2725
|
+
const entries = [];
|
|
2726
|
+
let wlRejected = 0;
|
|
2727
|
+
for (const a of arcs) {
|
|
2728
|
+
const satWl = wl.satFcb.get(a.prn);
|
|
2729
|
+
const rcvWl = wl.rcvBias.get(a.station);
|
|
2730
|
+
if (satWl === void 0 || rcvWl === void 0) continue;
|
|
2731
|
+
const wlFloat = a.mwCyc - satWl - rcvWl;
|
|
2732
|
+
const nWl = Math.round(wlFloat);
|
|
2733
|
+
if (Math.abs(wlFloat - nWl) > (opts.fixWindow ?? 0.25)) {
|
|
2734
|
+
wlRejected++;
|
|
2735
|
+
continue;
|
|
2736
|
+
}
|
|
2737
|
+
const lamNl = C / (a.f1 + a.f2);
|
|
2738
|
+
const n1Float = a.aIF / lamNl - a.f2 / (a.f1 - a.f2) * nWl;
|
|
2739
|
+
entries.push({
|
|
2740
|
+
station: a.station,
|
|
2741
|
+
sat: a.prn,
|
|
2742
|
+
value: n1Float,
|
|
2743
|
+
weight: a.nEpochs
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
const res = decomposeFcb(entries, { fixWindow: 0.15, ...opts });
|
|
2747
|
+
return { ...res, usedArcs: entries.length, wlRejected };
|
|
2748
|
+
}
|
|
2663
2749
|
|
|
2664
2750
|
// src/positioning/index.ts
|
|
2665
2751
|
var GM_GPS2 = 3986005e8;
|
|
@@ -2894,6 +2980,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
2894
2980
|
RtkFloatEngine,
|
|
2895
2981
|
buildPppAntenna,
|
|
2896
2982
|
createPppCorrections,
|
|
2983
|
+
estimateNarrowlaneFcb,
|
|
2897
2984
|
estimateWidelaneFcb,
|
|
2898
2985
|
extractWidelaneArcs,
|
|
2899
2986
|
gimSlantIonoDelayL1,
|
package/dist/positioning.d.cts
CHANGED
|
@@ -666,6 +666,26 @@ interface PppSolution {
|
|
|
666
666
|
convergenceSec: number | null;
|
|
667
667
|
/** Final 3D error vs ground truth (m), if given. */
|
|
668
668
|
finalError3d: number | null;
|
|
669
|
+
/** Per-arc converged float ambiguities — one per continuous satellite
|
|
670
|
+
* tracking arc — the raw material for ambiguity resolution (PPP-AR). */
|
|
671
|
+
arcs: PppArc[];
|
|
672
|
+
}
|
|
673
|
+
/** A converged carrier-phase arc: the float ionosphere-free ambiguity plus
|
|
674
|
+
* the wide-lane, for integer resolution / FCB estimation. */
|
|
675
|
+
interface PppArc {
|
|
676
|
+
prn: string;
|
|
677
|
+
/** Final float ionosphere-free ambiguity (m). */
|
|
678
|
+
aIF: number;
|
|
679
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane (cycles). */
|
|
680
|
+
mwCyc: number;
|
|
681
|
+
f1: number;
|
|
682
|
+
f2: number;
|
|
683
|
+
/** Mean satellite elevation over the arc (deg). */
|
|
684
|
+
meanElevDeg: number;
|
|
685
|
+
/** Epochs in the arc. */
|
|
686
|
+
nEpochs: number;
|
|
687
|
+
startMs: number;
|
|
688
|
+
endMs: number;
|
|
669
689
|
}
|
|
670
690
|
declare function solvePpp(epochs: PppEpoch[], sp3: Sp3File, opts: PppOptions): PppSolution;
|
|
671
691
|
|
|
@@ -879,6 +899,39 @@ interface WlFcbResult {
|
|
|
879
899
|
* integer/bias entanglement.
|
|
880
900
|
*/
|
|
881
901
|
declare function estimateWidelaneFcb(arcs: WlArc[], opts?: WlFcbOptions): WlFcbResult;
|
|
902
|
+
/** One converged arc (from `solvePpp`) tagged with its station, for NL FCB. */
|
|
903
|
+
interface NlArc {
|
|
904
|
+
station: string;
|
|
905
|
+
prn: string;
|
|
906
|
+
/** Float ionosphere-free ambiguity (m). */
|
|
907
|
+
aIF: number;
|
|
908
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane (cycles). */
|
|
909
|
+
mwCyc: number;
|
|
910
|
+
f1: number;
|
|
911
|
+
f2: number;
|
|
912
|
+
nEpochs: number;
|
|
913
|
+
}
|
|
914
|
+
interface NlFcbResult extends WlFcbResult {
|
|
915
|
+
/** Arcs whose wide-lane fixed and were used in the narrow-lane estimation. */
|
|
916
|
+
usedArcs: number;
|
|
917
|
+
/** Arcs dropped because the wide-lane did not round confidently. */
|
|
918
|
+
wlRejected: number;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Estimate per-satellite **narrow-lane** FCBs — the centimetre half of
|
|
922
|
+
* PPP-AR. Needs the wide-lane FCBs already solved (`wl`, from the same
|
|
923
|
+
* network) to fix each arc's N_WL, from which the float narrow-lane
|
|
924
|
+
* ambiguity is recovered:
|
|
925
|
+
*
|
|
926
|
+
* A_IF = λ_NL·N1 + λ_NL·(f2/(f1−f2))·N_WL
|
|
927
|
+
* ⇒ N1_float = A_IF/λ_NL − (f2/(f1−f2))·N_WL, λ_NL = c/(f1+f2)
|
|
928
|
+
*
|
|
929
|
+
* then decomposed across the network exactly like the wide-lane. The
|
|
930
|
+
* narrow-lane wavelength is ~10.7 cm, so this is far more sensitive to
|
|
931
|
+
* residual orbit/clock/troposphere/position error than the ~86 cm wide-lane
|
|
932
|
+
* — the fix rate is the honest measure of how close the network is to cm.
|
|
933
|
+
*/
|
|
934
|
+
declare function estimateNarrowlaneFcb(arcs: NlArc[], wl: WlFcbResult, opts?: WlFcbOptions): NlFcbResult;
|
|
882
935
|
|
|
883
936
|
/**
|
|
884
937
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
@@ -969,4 +1022,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
969
1022
|
*/
|
|
970
1023
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
971
1024
|
|
|
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 };
|
|
1025
|
+
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 NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, 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, estimateNarrowlaneFcb, 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
|
@@ -666,6 +666,26 @@ interface PppSolution {
|
|
|
666
666
|
convergenceSec: number | null;
|
|
667
667
|
/** Final 3D error vs ground truth (m), if given. */
|
|
668
668
|
finalError3d: number | null;
|
|
669
|
+
/** Per-arc converged float ambiguities — one per continuous satellite
|
|
670
|
+
* tracking arc — the raw material for ambiguity resolution (PPP-AR). */
|
|
671
|
+
arcs: PppArc[];
|
|
672
|
+
}
|
|
673
|
+
/** A converged carrier-phase arc: the float ionosphere-free ambiguity plus
|
|
674
|
+
* the wide-lane, for integer resolution / FCB estimation. */
|
|
675
|
+
interface PppArc {
|
|
676
|
+
prn: string;
|
|
677
|
+
/** Final float ionosphere-free ambiguity (m). */
|
|
678
|
+
aIF: number;
|
|
679
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane (cycles). */
|
|
680
|
+
mwCyc: number;
|
|
681
|
+
f1: number;
|
|
682
|
+
f2: number;
|
|
683
|
+
/** Mean satellite elevation over the arc (deg). */
|
|
684
|
+
meanElevDeg: number;
|
|
685
|
+
/** Epochs in the arc. */
|
|
686
|
+
nEpochs: number;
|
|
687
|
+
startMs: number;
|
|
688
|
+
endMs: number;
|
|
669
689
|
}
|
|
670
690
|
declare function solvePpp(epochs: PppEpoch[], sp3: Sp3File, opts: PppOptions): PppSolution;
|
|
671
691
|
|
|
@@ -879,6 +899,39 @@ interface WlFcbResult {
|
|
|
879
899
|
* integer/bias entanglement.
|
|
880
900
|
*/
|
|
881
901
|
declare function estimateWidelaneFcb(arcs: WlArc[], opts?: WlFcbOptions): WlFcbResult;
|
|
902
|
+
/** One converged arc (from `solvePpp`) tagged with its station, for NL FCB. */
|
|
903
|
+
interface NlArc {
|
|
904
|
+
station: string;
|
|
905
|
+
prn: string;
|
|
906
|
+
/** Float ionosphere-free ambiguity (m). */
|
|
907
|
+
aIF: number;
|
|
908
|
+
/** Arc-averaged Melbourne–Wübbena wide-lane (cycles). */
|
|
909
|
+
mwCyc: number;
|
|
910
|
+
f1: number;
|
|
911
|
+
f2: number;
|
|
912
|
+
nEpochs: number;
|
|
913
|
+
}
|
|
914
|
+
interface NlFcbResult extends WlFcbResult {
|
|
915
|
+
/** Arcs whose wide-lane fixed and were used in the narrow-lane estimation. */
|
|
916
|
+
usedArcs: number;
|
|
917
|
+
/** Arcs dropped because the wide-lane did not round confidently. */
|
|
918
|
+
wlRejected: number;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Estimate per-satellite **narrow-lane** FCBs — the centimetre half of
|
|
922
|
+
* PPP-AR. Needs the wide-lane FCBs already solved (`wl`, from the same
|
|
923
|
+
* network) to fix each arc's N_WL, from which the float narrow-lane
|
|
924
|
+
* ambiguity is recovered:
|
|
925
|
+
*
|
|
926
|
+
* A_IF = λ_NL·N1 + λ_NL·(f2/(f1−f2))·N_WL
|
|
927
|
+
* ⇒ N1_float = A_IF/λ_NL − (f2/(f1−f2))·N_WL, λ_NL = c/(f1+f2)
|
|
928
|
+
*
|
|
929
|
+
* then decomposed across the network exactly like the wide-lane. The
|
|
930
|
+
* narrow-lane wavelength is ~10.7 cm, so this is far more sensitive to
|
|
931
|
+
* residual orbit/clock/troposphere/position error than the ~86 cm wide-lane
|
|
932
|
+
* — the fix rate is the honest measure of how close the network is to cm.
|
|
933
|
+
*/
|
|
934
|
+
declare function estimateNarrowlaneFcb(arcs: NlArc[], wl: WlFcbResult, opts?: WlFcbOptions): NlFcbResult;
|
|
882
935
|
|
|
883
936
|
/**
|
|
884
937
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
@@ -969,4 +1022,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
969
1022
|
*/
|
|
970
1023
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
971
1024
|
|
|
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 };
|
|
1025
|
+
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 NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, 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, estimateNarrowlaneFcb, 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,7 @@ import {
|
|
|
3
3
|
RtkFloatEngine,
|
|
4
4
|
buildPppAntenna,
|
|
5
5
|
createPppCorrections,
|
|
6
|
+
estimateNarrowlaneFcb,
|
|
6
7
|
estimateWidelaneFcb,
|
|
7
8
|
extractWidelaneArcs,
|
|
8
9
|
gimSlantIonoDelayL1,
|
|
@@ -24,7 +25,7 @@ import {
|
|
|
24
25
|
sunEcef,
|
|
25
26
|
toRtkEpoch,
|
|
26
27
|
wlWavelength
|
|
27
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-H73PZB5C.js";
|
|
28
29
|
import "./chunk-MHGNKSSH.js";
|
|
29
30
|
import "./chunk-37QNKGTC.js";
|
|
30
31
|
import "./chunk-6FAL6P4G.js";
|
|
@@ -37,6 +38,7 @@ export {
|
|
|
37
38
|
RtkFloatEngine,
|
|
38
39
|
buildPppAntenna,
|
|
39
40
|
createPppCorrections,
|
|
41
|
+
estimateNarrowlaneFcb,
|
|
40
42
|
estimateWidelaneFcb,
|
|
41
43
|
extractWidelaneArcs,
|
|
42
44
|
gimSlantIonoDelayL1,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
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,
|