gnss-js 2.8.2 → 2.10.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-6SWJTN6H.js → chunk-56HM5B6T.js} +19 -5
- package/dist/{chunk-5OWRCF56.js → chunk-7T5DLVZL.js} +43 -15
- package/dist/{chunk-CLNLOYBX.js → chunk-K3GLUWZI.js} +62 -1
- package/dist/{chunk-7GNRNKBR.js → chunk-N6GQUHM4.js} +27 -9
- package/dist/index.cjs +172 -46
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -4
- package/dist/msm-CcQJV3PC.d.ts +108 -0
- package/dist/msm-DWtoTvx2.d.cts +108 -0
- package/dist/orbit.cjs +46 -15
- package/dist/orbit.d.cts +39 -4
- package/dist/orbit.d.ts +39 -4
- package/dist/orbit.js +7 -1
- package/dist/positioning.cjs +109 -26
- package/dist/positioning.d.cts +19 -1
- package/dist/positioning.d.ts +19 -1
- package/dist/positioning.js +4 -2
- package/dist/rinex.cjs +20 -5
- package/dist/rinex.d.cts +10 -1
- package/dist/rinex.d.ts +10 -1
- package/dist/rinex.js +3 -1
- package/dist/rtcm3.cjs +27 -9
- package/dist/rtcm3.d.cts +6 -88
- package/dist/rtcm3.d.ts +6 -88
- package/dist/rtcm3.js +1 -1
- package/package.json +1 -1
package/dist/positioning.cjs
CHANGED
|
@@ -49,6 +49,7 @@ __export(positioning_exports, {
|
|
|
49
49
|
nlWavelength: () => nlWavelength,
|
|
50
50
|
postProcessRtk: () => postProcessRtk,
|
|
51
51
|
rcvAntennaRangeM: () => rcvAntennaRangeM,
|
|
52
|
+
resolveMsmRanges: () => resolveMsmRanges,
|
|
52
53
|
resolvePppAmbiguities: () => resolvePppAmbiguities,
|
|
53
54
|
satClockCorrection: () => satClockCorrection,
|
|
54
55
|
sbasIonoDeg: () => sbasIonoDeg,
|
|
@@ -254,6 +255,38 @@ function invertMatrix(A) {
|
|
|
254
255
|
return M.map((row) => row.slice(n));
|
|
255
256
|
}
|
|
256
257
|
|
|
258
|
+
// src/orbit/validity.ts
|
|
259
|
+
var H = 36e5;
|
|
260
|
+
var MIN = 6e4;
|
|
261
|
+
var EPHEMERIS_VALIDITY_MS = {
|
|
262
|
+
G: 2 * H,
|
|
263
|
+
J: 2 * H,
|
|
264
|
+
E: 2.5 * H,
|
|
265
|
+
C: 90 * MIN,
|
|
266
|
+
R: 15 * MIN,
|
|
267
|
+
I: 2 * H,
|
|
268
|
+
S: 6 * MIN
|
|
269
|
+
};
|
|
270
|
+
function tocDistanceMs(eph, tGpsMs) {
|
|
271
|
+
const t = eph.system === "R" || eph.system === "S" ? tGpsMs - getGpsLeap(new Date(tGpsMs)) * 1e3 : tGpsMs;
|
|
272
|
+
return Math.abs(eph.tocDate.getTime() - t);
|
|
273
|
+
}
|
|
274
|
+
function nearestValidEphemeris(ephs, tGpsMs) {
|
|
275
|
+
if (!ephs) return null;
|
|
276
|
+
let best = null;
|
|
277
|
+
let bestDt = Infinity;
|
|
278
|
+
for (const eph of ephs) {
|
|
279
|
+
const dt = tocDistanceMs(eph, tGpsMs);
|
|
280
|
+
const w = EPHEMERIS_VALIDITY_MS[eph.system];
|
|
281
|
+
if (w === void 0 || dt > w) continue;
|
|
282
|
+
if (dt < bestDt) {
|
|
283
|
+
bestDt = dt;
|
|
284
|
+
best = eph;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return best;
|
|
288
|
+
}
|
|
289
|
+
|
|
257
290
|
// src/orbit/index.ts
|
|
258
291
|
var GM_GPS = 3986005e8;
|
|
259
292
|
var GM_GAL = 3986004418e5;
|
|
@@ -452,20 +485,20 @@ function computeDop(satAzEls) {
|
|
|
452
485
|
const clocks = [...new Set(sats.map((s) => dopClock(s.prn)))];
|
|
453
486
|
const m = 3 + clocks.length;
|
|
454
487
|
if (n < Math.max(4, m)) return null;
|
|
455
|
-
const
|
|
488
|
+
const H3 = [];
|
|
456
489
|
for (const { az, el, prn } of sats) {
|
|
457
490
|
const cosEl = Math.cos(el);
|
|
458
491
|
const row = [cosEl * Math.sin(az), cosEl * Math.cos(az), Math.sin(el)];
|
|
459
492
|
const clock = dopClock(prn);
|
|
460
493
|
for (const c of clocks) row.push(c === clock ? 1 : 0);
|
|
461
|
-
|
|
494
|
+
H3.push(row);
|
|
462
495
|
}
|
|
463
496
|
const HtH = Array.from({ length: m }, () => new Array(m).fill(0));
|
|
464
497
|
for (let i = 0; i < m; i++) {
|
|
465
498
|
for (let j = 0; j < m; j++) {
|
|
466
499
|
let sum = 0;
|
|
467
500
|
for (let k = 0; k < n; k++) {
|
|
468
|
-
sum +=
|
|
501
|
+
sum += H3[k][i] * H3[k][j];
|
|
469
502
|
}
|
|
470
503
|
HtH[i][j] = sum;
|
|
471
504
|
}
|
|
@@ -501,18 +534,7 @@ function computeSatPosition(eph, timeMs) {
|
|
|
501
534
|
return keplerPosition(eph, tow);
|
|
502
535
|
}
|
|
503
536
|
function selectBest(ephs, timeMs) {
|
|
504
|
-
|
|
505
|
-
let bestDt = Infinity;
|
|
506
|
-
for (const eph of ephs) {
|
|
507
|
-
const dt = Math.abs(timeMs - eph.tocDate.getTime());
|
|
508
|
-
const maxAge = eph.system === "R" || eph.system === "S" ? 18e5 : 4 * 36e5;
|
|
509
|
-
if (dt > maxAge) continue;
|
|
510
|
-
if (dt < bestDt) {
|
|
511
|
-
bestDt = dt;
|
|
512
|
-
best = eph;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return best;
|
|
537
|
+
return nearestValidEphemeris(ephs, timeMs);
|
|
516
538
|
}
|
|
517
539
|
var GPS_EPOCH_MS = START_GPS_TIME.getTime();
|
|
518
540
|
var MS_PER_WEEK = 7 * 864e5;
|
|
@@ -1308,7 +1330,7 @@ function solveDgnss(rover, base, basePos, ephemerides, timeMs, opts = {}) {
|
|
|
1308
1330
|
let cov = null;
|
|
1309
1331
|
for (let iter = 0; iter < maxIterations; iter++) {
|
|
1310
1332
|
iterations = iter + 1;
|
|
1311
|
-
const
|
|
1333
|
+
const H3 = [];
|
|
1312
1334
|
const v = [];
|
|
1313
1335
|
const terms = /* @__PURE__ */ new Map();
|
|
1314
1336
|
const termOf = (g) => {
|
|
@@ -1324,11 +1346,11 @@ function solveDgnss(rover, base, basePos, ephemerides, timeMs, opts = {}) {
|
|
|
1324
1346
|
const tr = termOf(row.ref);
|
|
1325
1347
|
const pred = ts.rho - row.g.rhoB + ts.dTropo - (tr.rho - row.ref.rhoB + tr.dTropo);
|
|
1326
1348
|
v.push(row.z - pred);
|
|
1327
|
-
|
|
1349
|
+
H3.push([ts.u[0] - tr.u[0], ts.u[1] - tr.u[1], ts.u[2] - tr.u[2]]);
|
|
1328
1350
|
}
|
|
1329
|
-
const Ht = transpose(
|
|
1351
|
+
const Ht = transpose(H3);
|
|
1330
1352
|
const HtW = matMul(Ht, W);
|
|
1331
|
-
const N = matMul(HtW,
|
|
1353
|
+
const N = matMul(HtW, H3);
|
|
1332
1354
|
const b = matMul(
|
|
1333
1355
|
HtW,
|
|
1334
1356
|
v.map((s) => [s])
|
|
@@ -1344,7 +1366,7 @@ function solveDgnss(rover, base, basePos, ephemerides, timeMs, opts = {}) {
|
|
|
1344
1366
|
z += dx[2][0];
|
|
1345
1367
|
cov = Ninv;
|
|
1346
1368
|
rows.forEach((row, i) => {
|
|
1347
|
-
residuals[row.g.prn] = v[i] - (
|
|
1369
|
+
residuals[row.g.prn] = v[i] - (H3[i][0] * dx[0][0] + H3[i][1] * dx[1][0] + H3[i][2] * dx[2][0]);
|
|
1348
1370
|
});
|
|
1349
1371
|
if (Math.hypot(dx[0][0], dx[1][0], dx[2][0]) < convergenceM) {
|
|
1350
1372
|
converged = true;
|
|
@@ -1738,19 +1760,19 @@ var RtkFloatEngine = class {
|
|
|
1738
1760
|
const PPrior = this.P;
|
|
1739
1761
|
let xi = [...this.x];
|
|
1740
1762
|
let K = [];
|
|
1741
|
-
let
|
|
1763
|
+
let H3 = [];
|
|
1742
1764
|
for (let it = 0; it < Math.max(o.updateIterations, 1); it++) {
|
|
1743
|
-
|
|
1765
|
+
H3 = [];
|
|
1744
1766
|
const v = [];
|
|
1745
1767
|
for (const row of rows) {
|
|
1746
1768
|
const { pred, h } = predict(row, xi);
|
|
1747
1769
|
let corr = 0;
|
|
1748
1770
|
for (let j = 0; j < n; j++) corr += h[j] * (xPrior[j] - xi[j]);
|
|
1749
1771
|
v.push(row.z - pred - corr);
|
|
1750
|
-
|
|
1772
|
+
H3.push(h);
|
|
1751
1773
|
}
|
|
1752
|
-
const Ht = transpose(
|
|
1753
|
-
const S = matMul(matMul(
|
|
1774
|
+
const Ht = transpose(H3);
|
|
1775
|
+
const S = matMul(matMul(H3, PPrior), Ht);
|
|
1754
1776
|
for (let i = 0; i < rows.length; i++)
|
|
1755
1777
|
for (let j = 0; j < rows.length; j++) S[i][j] += R[i][j];
|
|
1756
1778
|
const Sinv = matInv(S);
|
|
@@ -1766,7 +1788,7 @@ var RtkFloatEngine = class {
|
|
|
1766
1788
|
xi = xPrior.map((s, i) => s + dx[i][0]);
|
|
1767
1789
|
}
|
|
1768
1790
|
this.x = xi;
|
|
1769
|
-
const KH = matMul(K,
|
|
1791
|
+
const KH = matMul(K, H3);
|
|
1770
1792
|
const IKH = zeros(n, n);
|
|
1771
1793
|
for (let i = 0; i < n; i++)
|
|
1772
1794
|
for (let j = 0; j < n; j++) IKH[i][j] = (i === j ? 1 : 0) - KH[i][j];
|
|
@@ -2113,6 +2135,66 @@ var ZeroBaselineEngine = class {
|
|
|
2113
2135
|
}
|
|
2114
2136
|
};
|
|
2115
2137
|
|
|
2138
|
+
// src/positioning/msm-resolve.ts
|
|
2139
|
+
var LIGHT_MS = C_LIGHT / 1e3;
|
|
2140
|
+
var MAX_FRACTION_MISFIT = 0.25;
|
|
2141
|
+
function predictedRange(eph, timeMs, rx) {
|
|
2142
|
+
let tau = 0.075;
|
|
2143
|
+
for (let i = 0; i < 2; i++) {
|
|
2144
|
+
const tEmit = timeMs - tau * 1e3;
|
|
2145
|
+
const p = computeSatPosition(eph, tEmit);
|
|
2146
|
+
if (!Number.isFinite(p.x)) return null;
|
|
2147
|
+
const rho = Math.hypot(p.x - rx[0], p.y - rx[1], p.z - rx[2]);
|
|
2148
|
+
tau = rho / C_LIGHT;
|
|
2149
|
+
if (i === 1) return rho - C_LIGHT * satClockCorrection(eph, tEmit);
|
|
2150
|
+
}
|
|
2151
|
+
return null;
|
|
2152
|
+
}
|
|
2153
|
+
function moduloRange(sat) {
|
|
2154
|
+
for (const s of sat.signals)
|
|
2155
|
+
if (s.pseudorange !== void 0) return s.pseudorange;
|
|
2156
|
+
for (const s of sat.signals)
|
|
2157
|
+
if (s.phase !== void 0 && s.wavelength > 0)
|
|
2158
|
+
return s.phase * s.wavelength;
|
|
2159
|
+
return null;
|
|
2160
|
+
}
|
|
2161
|
+
function resolveMsmRanges(epoch, opts) {
|
|
2162
|
+
if (!epoch.rangeModulo1ms) return epoch;
|
|
2163
|
+
const cand = [];
|
|
2164
|
+
for (const sat of epoch.observations) {
|
|
2165
|
+
const eph = opts.ephFor(sat.prn);
|
|
2166
|
+
const mod = moduloRange(sat);
|
|
2167
|
+
if (!eph || mod === null) continue;
|
|
2168
|
+
const pred = predictedRange(eph, opts.timeMs, opts.rxEcef);
|
|
2169
|
+
if (pred === null) continue;
|
|
2170
|
+
cand.push({ sat, k: (pred - mod) / LIGHT_MS });
|
|
2171
|
+
}
|
|
2172
|
+
const { rangeModulo1ms: _drop, ...rest } = epoch;
|
|
2173
|
+
if (cand.length === 0) return { ...rest, observations: [] };
|
|
2174
|
+
let sx = 0;
|
|
2175
|
+
let sy = 0;
|
|
2176
|
+
for (const c of cand) {
|
|
2177
|
+
sx += Math.cos(2 * Math.PI * c.k);
|
|
2178
|
+
sy += Math.sin(2 * Math.PI * c.k);
|
|
2179
|
+
}
|
|
2180
|
+
const b = Math.atan2(sy, sx) / (2 * Math.PI);
|
|
2181
|
+
const observations = [];
|
|
2182
|
+
for (const { sat, k } of cand) {
|
|
2183
|
+
const n = Math.round(k - b);
|
|
2184
|
+
if (Math.abs(k - b - n) > MAX_FRACTION_MISFIT) continue;
|
|
2185
|
+
const add = n * LIGHT_MS;
|
|
2186
|
+
observations.push({
|
|
2187
|
+
...sat,
|
|
2188
|
+
signals: sat.signals.map((s) => ({
|
|
2189
|
+
...s,
|
|
2190
|
+
...s.pseudorange !== void 0 ? { pseudorange: s.pseudorange + add } : {},
|
|
2191
|
+
...s.phase !== void 0 && s.wavelength > 0 ? { phase: s.phase + add / s.wavelength } : {}
|
|
2192
|
+
}))
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
return { ...rest, observations };
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2116
2198
|
// src/navbits/index.ts
|
|
2117
2199
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
2118
2200
|
var SEC_PER_WEEK = 7 * 86400;
|
|
@@ -4612,6 +4694,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
4612
4694
|
nlWavelength,
|
|
4613
4695
|
postProcessRtk,
|
|
4614
4696
|
rcvAntennaRangeM,
|
|
4697
|
+
resolveMsmRanges,
|
|
4615
4698
|
resolvePppAmbiguities,
|
|
4616
4699
|
satClockCorrection,
|
|
4617
4700
|
sbasIonoDeg,
|
package/dist/positioning.d.cts
CHANGED
|
@@ -2,6 +2,7 @@ import { E as Ephemeris } from './nav-DImXUdbp.cjs';
|
|
|
2
2
|
import { DopValues } from './orbit.cjs';
|
|
3
3
|
import { I as IonexGrid, C as ClkFile, S as Sp3File } from './clk-DGVBGRzA.cjs';
|
|
4
4
|
import { AntexFile } from './antex.cjs';
|
|
5
|
+
import { a as ObsEpoch } from './msm-DWtoTvx2.cjs';
|
|
5
6
|
import { a as HasOrbitCorrection, b as HasClockCorrection } from './has-BaXnQarR.cjs';
|
|
6
7
|
import './ephemeris-BAnBLLB9.cjs';
|
|
7
8
|
import './ecef-CF0uAysr.cjs';
|
|
@@ -613,6 +614,23 @@ declare class ZeroBaselineEngine {
|
|
|
613
614
|
private processReceiver;
|
|
614
615
|
}
|
|
615
616
|
|
|
617
|
+
interface MsmResolveOptions {
|
|
618
|
+
/** Epoch time, GPS-scale ms (as `obsEpochToDate` returns). */
|
|
619
|
+
timeMs: number;
|
|
620
|
+
/** Approximate receiver ECEF (m) — the station's 1005/1006, a sourcetable
|
|
621
|
+
* position, or a previous fix. Tens of km of error are tolerated. */
|
|
622
|
+
rxEcef: readonly [number, number, number];
|
|
623
|
+
/** Broadcast ephemeris for a PRN at this time, or null. */
|
|
624
|
+
ephFor: (prn: string) => Ephemeris | null;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Add the missing whole light-milliseconds to an MSM1–3 epoch's ranges.
|
|
628
|
+
* Returns the epoch with `rangeModulo1ms` cleared, keeping only satellites
|
|
629
|
+
* whose range could be resolved (an ephemeris, and a prediction consistent
|
|
630
|
+
* with the rest of the epoch). Epochs that aren't modulo-1-ms pass through.
|
|
631
|
+
*/
|
|
632
|
+
declare function resolveMsmRanges(epoch: ObsEpoch, opts: MsmResolveOptions): ObsEpoch;
|
|
633
|
+
|
|
616
634
|
/**
|
|
617
635
|
* Integer ambiguity resolution: LAMBDA decorrelation + MLAMBDA
|
|
618
636
|
* integer least-squares search.
|
|
@@ -1714,4 +1732,4 @@ declare function sbasProtectionLevels(sats: readonly {
|
|
|
1714
1732
|
*/
|
|
1715
1733
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
1716
1734
|
|
|
1717
|
-
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
1735
|
+
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type MsmResolveOptions, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolveMsmRanges, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { E as Ephemeris } from './nav-DImXUdbp.js';
|
|
|
2
2
|
import { DopValues } from './orbit.js';
|
|
3
3
|
import { I as IonexGrid, C as ClkFile, S as Sp3File } from './clk-DGVBGRzA.js';
|
|
4
4
|
import { AntexFile } from './antex.js';
|
|
5
|
+
import { a as ObsEpoch } from './msm-CcQJV3PC.js';
|
|
5
6
|
import { a as HasOrbitCorrection, b as HasClockCorrection } from './has-BaXnQarR.js';
|
|
6
7
|
import './ephemeris-BAnBLLB9.js';
|
|
7
8
|
import './ecef-CF0uAysr.js';
|
|
@@ -613,6 +614,23 @@ declare class ZeroBaselineEngine {
|
|
|
613
614
|
private processReceiver;
|
|
614
615
|
}
|
|
615
616
|
|
|
617
|
+
interface MsmResolveOptions {
|
|
618
|
+
/** Epoch time, GPS-scale ms (as `obsEpochToDate` returns). */
|
|
619
|
+
timeMs: number;
|
|
620
|
+
/** Approximate receiver ECEF (m) — the station's 1005/1006, a sourcetable
|
|
621
|
+
* position, or a previous fix. Tens of km of error are tolerated. */
|
|
622
|
+
rxEcef: readonly [number, number, number];
|
|
623
|
+
/** Broadcast ephemeris for a PRN at this time, or null. */
|
|
624
|
+
ephFor: (prn: string) => Ephemeris | null;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Add the missing whole light-milliseconds to an MSM1–3 epoch's ranges.
|
|
628
|
+
* Returns the epoch with `rangeModulo1ms` cleared, keeping only satellites
|
|
629
|
+
* whose range could be resolved (an ephemeris, and a prediction consistent
|
|
630
|
+
* with the rest of the epoch). Epochs that aren't modulo-1-ms pass through.
|
|
631
|
+
*/
|
|
632
|
+
declare function resolveMsmRanges(epoch: ObsEpoch, opts: MsmResolveOptions): ObsEpoch;
|
|
633
|
+
|
|
616
634
|
/**
|
|
617
635
|
* Integer ambiguity resolution: LAMBDA decorrelation + MLAMBDA
|
|
618
636
|
* integer least-squares search.
|
|
@@ -1714,4 +1732,4 @@ declare function sbasProtectionLevels(sats: readonly {
|
|
|
1714
1732
|
*/
|
|
1715
1733
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
1716
1734
|
|
|
1717
|
-
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
1735
|
+
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type MsmResolveOptions, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolveMsmRanges, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.js
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
nlWavelength,
|
|
29
29
|
postProcessRtk,
|
|
30
30
|
rcvAntennaRangeM,
|
|
31
|
+
resolveMsmRanges,
|
|
31
32
|
resolvePppAmbiguities,
|
|
32
33
|
satClockCorrection,
|
|
33
34
|
sbasIonoDeg,
|
|
@@ -40,9 +41,9 @@ import {
|
|
|
40
41
|
sunEcef,
|
|
41
42
|
toRtkEpoch,
|
|
42
43
|
wlWavelength
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-K3GLUWZI.js";
|
|
44
45
|
import "./chunk-WQX354KD.js";
|
|
45
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-7T5DLVZL.js";
|
|
46
47
|
import "./chunk-HVXYFUCB.js";
|
|
47
48
|
import "./chunk-CVCTRIWU.js";
|
|
48
49
|
import "./chunk-37QNKGTC.js";
|
|
@@ -82,6 +83,7 @@ export {
|
|
|
82
83
|
nlWavelength,
|
|
83
84
|
postProcessRtk,
|
|
84
85
|
rcvAntennaRangeM,
|
|
86
|
+
resolveMsmRanges,
|
|
85
87
|
resolvePppAmbiguities,
|
|
86
88
|
satClockCorrection,
|
|
87
89
|
sbasIonoDeg,
|
package/dist/rinex.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(rinex_exports, {
|
|
|
32
32
|
fmtD: () => fmtD,
|
|
33
33
|
fmtF: () => fmtF,
|
|
34
34
|
hdrLine: () => hdrLine,
|
|
35
|
+
modalIntervalS: () => modalIntervalS,
|
|
35
36
|
padL: () => padL,
|
|
36
37
|
padR: () => padR,
|
|
37
38
|
parseBiasSinex: () => parseBiasSinex,
|
|
@@ -2600,6 +2601,21 @@ function writeRinexObsBlob(header, epochs, obsTypes) {
|
|
|
2600
2601
|
comment: "Merged from multiple RINEX files"
|
|
2601
2602
|
});
|
|
2602
2603
|
}
|
|
2604
|
+
function modalIntervalS(epochs) {
|
|
2605
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2606
|
+
for (let i = 1; i < epochs.length; i++) {
|
|
2607
|
+
const d = Math.round(epochs[i].time - epochs[i - 1].time);
|
|
2608
|
+
if (d > 0) counts.set(d, (counts.get(d) ?? 0) + 1);
|
|
2609
|
+
}
|
|
2610
|
+
let best = null;
|
|
2611
|
+
let bestN = 0;
|
|
2612
|
+
for (const [d, n] of counts)
|
|
2613
|
+
if (n > bestN || n === bestN && best !== null && d < best) {
|
|
2614
|
+
best = d;
|
|
2615
|
+
bestN = n;
|
|
2616
|
+
}
|
|
2617
|
+
return best === null ? null : best / 1e3;
|
|
2618
|
+
}
|
|
2603
2619
|
async function writeModernObsBlob(header, epochs, obsTypes, opts) {
|
|
2604
2620
|
if (epochs.length === 0) return new Blob([], { type: "application/gzip" });
|
|
2605
2621
|
const sink = createGzipLineSink();
|
|
@@ -2646,11 +2662,9 @@ async function writeModernObsBlob(header, epochs, obsTypes, opts) {
|
|
|
2646
2662
|
"TIME OF LAST OBS"
|
|
2647
2663
|
)
|
|
2648
2664
|
);
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
sink.push(hdrLine(fmtF(interval, 10, 3), "INTERVAL"));
|
|
2653
|
-
}
|
|
2665
|
+
const interval = modalIntervalS(epochs);
|
|
2666
|
+
if (interval !== null && interval < 3600) {
|
|
2667
|
+
sink.push(hdrLine(fmtF(interval, 10, 3), "INTERVAL"));
|
|
2654
2668
|
}
|
|
2655
2669
|
if (header.glonassSlots && Object.keys(header.glonassSlots).length > 0) {
|
|
2656
2670
|
const entries = Object.entries(header.glonassSlots).sort(
|
|
@@ -2916,6 +2930,7 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
|
|
|
2916
2930
|
fmtD,
|
|
2917
2931
|
fmtF,
|
|
2918
2932
|
hdrLine,
|
|
2933
|
+
modalIntervalS,
|
|
2919
2934
|
padL,
|
|
2920
2935
|
padR,
|
|
2921
2936
|
parseBiasSinex,
|
package/dist/rinex.d.cts
CHANGED
|
@@ -258,6 +258,15 @@ interface CompactEpoch {
|
|
|
258
258
|
* the Float64Array index order for each system.
|
|
259
259
|
*/
|
|
260
260
|
declare function writeRinexObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>): Promise<Blob>;
|
|
261
|
+
/**
|
|
262
|
+
* The nominal observation interval (s): the most common spacing between
|
|
263
|
+
* consecutive epochs. The first difference alone mis-states it whenever the
|
|
264
|
+
* file opens with an irregular gap (a late second epoch, a burst). Null with
|
|
265
|
+
* fewer than two epochs.
|
|
266
|
+
*/
|
|
267
|
+
declare function modalIntervalS(epochs: readonly {
|
|
268
|
+
time: number;
|
|
269
|
+
}[]): number | null;
|
|
261
270
|
/** Shared RINEX 3/4 implementation (also used by obs-writer-v4.ts). */
|
|
262
271
|
declare function writeModernObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>, opts: {
|
|
263
272
|
version: string;
|
|
@@ -311,4 +320,4 @@ declare function createGzipLineSink(): {
|
|
|
311
320
|
*/
|
|
312
321
|
declare function stationHeaderLines(header: RinexHeader): string[];
|
|
313
322
|
|
|
314
|
-
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
|
323
|
+
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
package/dist/rinex.d.ts
CHANGED
|
@@ -258,6 +258,15 @@ interface CompactEpoch {
|
|
|
258
258
|
* the Float64Array index order for each system.
|
|
259
259
|
*/
|
|
260
260
|
declare function writeRinexObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>): Promise<Blob>;
|
|
261
|
+
/**
|
|
262
|
+
* The nominal observation interval (s): the most common spacing between
|
|
263
|
+
* consecutive epochs. The first difference alone mis-states it whenever the
|
|
264
|
+
* file opens with an irregular gap (a late second epoch, a burst). Null with
|
|
265
|
+
* fewer than two epochs.
|
|
266
|
+
*/
|
|
267
|
+
declare function modalIntervalS(epochs: readonly {
|
|
268
|
+
time: number;
|
|
269
|
+
}[]): number | null;
|
|
261
270
|
/** Shared RINEX 3/4 implementation (also used by obs-writer-v4.ts). */
|
|
262
271
|
declare function writeModernObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>, opts: {
|
|
263
272
|
version: string;
|
|
@@ -311,4 +320,4 @@ declare function createGzipLineSink(): {
|
|
|
311
320
|
*/
|
|
312
321
|
declare function stationHeaderLines(header: RinexHeader): string[];
|
|
313
322
|
|
|
314
|
-
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
|
323
|
+
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
package/dist/rinex.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
fmtD,
|
|
8
8
|
fmtF,
|
|
9
9
|
hdrLine,
|
|
10
|
+
modalIntervalS,
|
|
10
11
|
padL,
|
|
11
12
|
padR,
|
|
12
13
|
parseBiasSinex,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
writeRinexNav,
|
|
21
22
|
writeRinexNav4,
|
|
22
23
|
writeRinexObsBlob
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-56HM5B6T.js";
|
|
24
25
|
import {
|
|
25
26
|
SYSTEM_ORDER,
|
|
26
27
|
crxDecompress,
|
|
@@ -52,6 +53,7 @@ export {
|
|
|
52
53
|
fmtD,
|
|
53
54
|
fmtF,
|
|
54
55
|
hdrLine,
|
|
56
|
+
modalIntervalS,
|
|
55
57
|
padL,
|
|
56
58
|
padR,
|
|
57
59
|
parseBiasSinex,
|
package/dist/rtcm3.cjs
CHANGED
|
@@ -1287,12 +1287,14 @@ function satPrn(sys, satIdx1) {
|
|
|
1287
1287
|
const num = sys === "S" ? satIdx1 + 119 : satIdx1;
|
|
1288
1288
|
return `${prefix}${String(num).padStart(2, "0")}`;
|
|
1289
1289
|
}
|
|
1290
|
-
function decodeMsmFull(frame) {
|
|
1290
|
+
function decodeMsmFull(frame, opts = {}) {
|
|
1291
1291
|
const type = frame.messageType;
|
|
1292
1292
|
const sys = msmSystem(type);
|
|
1293
1293
|
if (!sys) return null;
|
|
1294
1294
|
const variant = type % 10;
|
|
1295
|
-
if (variant <
|
|
1295
|
+
if (variant < 1 || variant > 7) return null;
|
|
1296
|
+
const compact = variant <= 3;
|
|
1297
|
+
if (compact && !opts.compactMsm) return null;
|
|
1296
1298
|
const payload = frame.payload;
|
|
1297
1299
|
if (!payload || payload.length < 10) return null;
|
|
1298
1300
|
try {
|
|
@@ -1337,7 +1339,9 @@ function decodeMsmFull(frame) {
|
|
|
1337
1339
|
const rrmod = new Float64Array(numSat);
|
|
1338
1340
|
const extsat = new Int8Array(numSat);
|
|
1339
1341
|
const rdop = new Float64Array(numSat);
|
|
1340
|
-
if (
|
|
1342
|
+
if (compact) {
|
|
1343
|
+
for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
|
|
1344
|
+
} else if (variant === 4 || variant === 6) {
|
|
1341
1345
|
for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
|
|
1342
1346
|
for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
|
|
1343
1347
|
} else {
|
|
@@ -1363,7 +1367,18 @@ function decodeMsmFull(frame) {
|
|
|
1363
1367
|
psr.fill(-1e30);
|
|
1364
1368
|
cp.fill(-1e30);
|
|
1365
1369
|
dop.fill(-1e30);
|
|
1366
|
-
if (variant ===
|
|
1370
|
+
if (variant === 1) {
|
|
1371
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1372
|
+
} else if (variant === 2) {
|
|
1373
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1374
|
+
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
1375
|
+
for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
|
|
1376
|
+
} else if (variant === 3) {
|
|
1377
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1378
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1379
|
+
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
1380
|
+
for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
|
|
1381
|
+
} else if (variant === 4) {
|
|
1367
1382
|
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1368
1383
|
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1369
1384
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
@@ -1439,8 +1454,10 @@ function decodeMsmFull(frame) {
|
|
|
1439
1454
|
if (cnrVal > 0) {
|
|
1440
1455
|
signal.cn0 = cnrVal;
|
|
1441
1456
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1457
|
+
if (variant !== 1) {
|
|
1458
|
+
signal.lockTime = lockTimeSec(type, ll[cellIdx]);
|
|
1459
|
+
signal.halfCycle = hc[cellIdx] === 1;
|
|
1460
|
+
}
|
|
1444
1461
|
signals.push(signal);
|
|
1445
1462
|
cellIdx++;
|
|
1446
1463
|
}
|
|
@@ -1452,7 +1469,8 @@ function decodeMsmFull(frame) {
|
|
|
1452
1469
|
messageType: type,
|
|
1453
1470
|
epochMs,
|
|
1454
1471
|
system: sys,
|
|
1455
|
-
observations
|
|
1472
|
+
observations,
|
|
1473
|
+
...compact ? { rangeModulo1ms: true } : {}
|
|
1456
1474
|
};
|
|
1457
1475
|
} catch (err) {
|
|
1458
1476
|
reportDecodeError("msm", err);
|
|
@@ -1606,8 +1624,8 @@ function decodeLegacyObs(frame) {
|
|
|
1606
1624
|
}
|
|
1607
1625
|
return { messageType: type, epochMs, system, observations };
|
|
1608
1626
|
}
|
|
1609
|
-
function decodeObs(frame) {
|
|
1610
|
-
return decodeMsmFull(frame) ?? decodeLegacyObs(frame);
|
|
1627
|
+
function decodeObs(frame, opts = {}) {
|
|
1628
|
+
return decodeMsmFull(frame, opts) ?? decodeLegacyObs(frame);
|
|
1611
1629
|
}
|
|
1612
1630
|
|
|
1613
1631
|
// src/rtcm3/ssr.ts
|