gnss-js 1.66.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -132
- package/dist/{chunk-2CMAFEHI.js → chunk-DWUQRJ37.js} +284 -139
- package/dist/{chunk-REULRNJ5.js → chunk-WVTDVPKA.js} +151 -188
- package/dist/{ephemeris-Ohl6NAfw.d.cts → ephemeris-BAnBLLB9.d.cts} +0 -1
- package/dist/{ephemeris-Ohl6NAfw.d.ts → ephemeris-BAnBLLB9.d.ts} +0 -1
- package/dist/has-BaXnQarR.d.cts +123 -0
- package/dist/has-BaXnQarR.d.ts +123 -0
- package/dist/index.cjs +444 -331
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +14 -4
- package/dist/orbit.d.cts +1 -1
- package/dist/orbit.d.ts +1 -1
- package/dist/positioning.cjs +286 -137
- package/dist/positioning.d.cts +162 -3
- package/dist/positioning.d.ts +162 -3
- package/dist/positioning.js +9 -1
- package/dist/rtcm3.cjs +181 -217
- package/dist/rtcm3.d.cts +28 -15
- package/dist/rtcm3.d.ts +28 -15
- package/dist/rtcm3.js +5 -3
- package/dist/sbf.d.cts +2 -123
- package/dist/sbf.d.ts +2 -123
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,6 +79,7 @@ __export(src_exports, {
|
|
|
79
79
|
MultipathAccumulator: () => MultipathAccumulator,
|
|
80
80
|
OEM4_HLEN: () => OEM4_HLEN,
|
|
81
81
|
OMEGA_E: () => OMEGA_E,
|
|
82
|
+
PppEngine: () => PppEngine,
|
|
82
83
|
REFERENCE_FRAMES: () => REFERENCE_FRAMES,
|
|
83
84
|
RINEX_CODES: () => RINEX_CODES,
|
|
84
85
|
RTCM2_MESSAGE_NAMES: () => RTCM2_MESSAGE_NAMES,
|
|
@@ -106,6 +107,7 @@ __export(src_exports, {
|
|
|
106
107
|
SYS_SHORT: () => SYS_SHORT,
|
|
107
108
|
SbasProcessor: () => SbasProcessor,
|
|
108
109
|
Scale: () => Scale,
|
|
110
|
+
Sp3EphemerisSource: () => Sp3EphemerisSource,
|
|
109
111
|
WGS84_ECCENTRICITY_SQUARED: () => WGS84_ECCENTRICITY_SQUARED,
|
|
110
112
|
WGS84_FLATTENING: () => WGS84_FLATTENING,
|
|
111
113
|
WGS84_SEMI_MAJOR_AXIS: () => WGS84_SEMI_MAJOR_AXIS,
|
|
@@ -116,6 +118,7 @@ __export(src_exports, {
|
|
|
116
118
|
analyzeQuality: () => analyzeQuality,
|
|
117
119
|
applyHelmert: () => applyHelmert,
|
|
118
120
|
applyIonoDcb: () => applyIonoDcb,
|
|
121
|
+
applyOrbitClock: () => applyOrbitClock,
|
|
119
122
|
biasMetres: () => biasMetres,
|
|
120
123
|
binexCrc16: () => binexCrc16,
|
|
121
124
|
binexCrc32: () => binexCrc32,
|
|
@@ -149,6 +152,7 @@ __export(src_exports, {
|
|
|
149
152
|
decodeIgsSsr: () => decodeIgsSsr,
|
|
150
153
|
decodeLegacyObs: () => decodeLegacyObs,
|
|
151
154
|
decodeMsmFull: () => decodeMsmFull,
|
|
155
|
+
decodeObs: () => decodeObs,
|
|
152
156
|
decodeSbfNavigation: () => decodeSbfNavigation,
|
|
153
157
|
decodeSsr: () => decodeSsr,
|
|
154
158
|
decodeSystemParams: () => decodeSystemParams,
|
|
@@ -239,6 +243,7 @@ __export(src_exports, {
|
|
|
239
243
|
glonassPosition: () => glonassPosition,
|
|
240
244
|
gmst: () => gmst,
|
|
241
245
|
greatCircleMidpoint: () => greatCircleMidpoint,
|
|
246
|
+
hasToOrbitClock: () => hasToOrbitClock,
|
|
242
247
|
hdrLine: () => hdrLine,
|
|
243
248
|
horizonDistance: () => horizonDistance,
|
|
244
249
|
ionoFree: () => ionoFree,
|
|
@@ -252,11 +257,11 @@ __export(src_exports, {
|
|
|
252
257
|
looksLikeRtcm2: () => looksLikeRtcm2,
|
|
253
258
|
maskRadForAzimuth: () => maskRadForAzimuth,
|
|
254
259
|
moonEcef: () => moonEcef,
|
|
255
|
-
msmEpochToDate: () => msmEpochToDate,
|
|
256
260
|
navTimesFromEph: () => navTimesFromEph,
|
|
257
261
|
niellMapping: () => niellMapping,
|
|
258
262
|
nlWavelength: () => nlWavelength,
|
|
259
263
|
nmeaCoordToDecimal: () => nmeaCoordToDecimal,
|
|
264
|
+
obsEpochToDate: () => obsEpochToDate,
|
|
260
265
|
oem4Frames: () => oem4Frames,
|
|
261
266
|
padL: () => padL,
|
|
262
267
|
padR: () => padR,
|
|
@@ -4068,7 +4073,7 @@ function parseBiasSinex(text) {
|
|
|
4068
4073
|
const endMs = parseEpoch(line.slice(50, 64), Infinity);
|
|
4069
4074
|
const tail = line.slice(65).trim().split(/\s+/);
|
|
4070
4075
|
if (tail.length < 2) continue;
|
|
4071
|
-
const
|
|
4076
|
+
const unit2 = tail[0];
|
|
4072
4077
|
const value = Number(tail[1]);
|
|
4073
4078
|
if (!Number.isFinite(value)) continue;
|
|
4074
4079
|
records.push({
|
|
@@ -4080,7 +4085,7 @@ function parseBiasSinex(text) {
|
|
|
4080
4085
|
startMs,
|
|
4081
4086
|
endMs,
|
|
4082
4087
|
value,
|
|
4083
|
-
unit
|
|
4088
|
+
unit: unit2
|
|
4084
4089
|
});
|
|
4085
4090
|
}
|
|
4086
4091
|
const bySat = /* @__PURE__ */ new Map();
|
|
@@ -4787,9 +4792,6 @@ var BitReader = class {
|
|
|
4787
4792
|
skip(n) {
|
|
4788
4793
|
this.bitPos += n;
|
|
4789
4794
|
}
|
|
4790
|
-
get bitsLeft() {
|
|
4791
|
-
return this.data.length * 8 - this.bitPos;
|
|
4792
|
-
}
|
|
4793
4795
|
};
|
|
4794
4796
|
function crc24q2(data, length) {
|
|
4795
4797
|
let crc = 0;
|
|
@@ -5291,7 +5293,7 @@ function decodeEphemeris(frame) {
|
|
|
5291
5293
|
}
|
|
5292
5294
|
}
|
|
5293
5295
|
|
|
5294
|
-
// src/rtcm3/
|
|
5296
|
+
// src/rtcm3/ssr-common.ts
|
|
5295
5297
|
var UPDATE_INTERVAL_S = [
|
|
5296
5298
|
1,
|
|
5297
5299
|
2,
|
|
@@ -5310,6 +5312,28 @@ var UPDATE_INTERVAL_S = [
|
|
|
5310
5312
|
7200,
|
|
5311
5313
|
10800
|
|
5312
5314
|
];
|
|
5315
|
+
function ssrUraMm(v) {
|
|
5316
|
+
if (v === 0) return null;
|
|
5317
|
+
const cls = v >> 3 & 7;
|
|
5318
|
+
const val = v & 7;
|
|
5319
|
+
return 3 ** cls * (1 + val / 4) - 1;
|
|
5320
|
+
}
|
|
5321
|
+
function readSsrOrbit(r, sat) {
|
|
5322
|
+
sat.iode = r.readU(8);
|
|
5323
|
+
sat.deltaRadial = r.readS(22) * 1e-4;
|
|
5324
|
+
sat.deltaAlongTrack = r.readS(20) * 4e-4;
|
|
5325
|
+
sat.deltaCrossTrack = r.readS(20) * 4e-4;
|
|
5326
|
+
sat.dotRadial = r.readS(21) * 1e-6;
|
|
5327
|
+
sat.dotAlongTrack = r.readS(19) * 4e-6;
|
|
5328
|
+
sat.dotCrossTrack = r.readS(19) * 4e-6;
|
|
5329
|
+
}
|
|
5330
|
+
function readSsrClock(r, sat) {
|
|
5331
|
+
sat.c0 = r.readS(22) * 1e-4;
|
|
5332
|
+
sat.c1 = r.readS(21) * 1e-6;
|
|
5333
|
+
sat.c2 = r.readS(27) * 2e-8;
|
|
5334
|
+
}
|
|
5335
|
+
|
|
5336
|
+
// src/rtcm3/igs-ssr.ts
|
|
5313
5337
|
var SYSTEM_BY_BASE = {
|
|
5314
5338
|
20: "G",
|
|
5315
5339
|
40: "R",
|
|
@@ -5333,12 +5357,6 @@ function prnFor(system, id) {
|
|
|
5333
5357
|
if (system === "S") return `S${two(19 + id)}`;
|
|
5334
5358
|
return `${system}${two(id)}`;
|
|
5335
5359
|
}
|
|
5336
|
-
function ssrUraMm(v) {
|
|
5337
|
-
if (v === 0) return null;
|
|
5338
|
-
const cls = v >> 3 & 7;
|
|
5339
|
-
const val = v & 7;
|
|
5340
|
-
return 3 ** cls * (1 + val / 4) - 1;
|
|
5341
|
-
}
|
|
5342
5360
|
function decodeIgsSsr(frame) {
|
|
5343
5361
|
if (frame.messageType !== 4076) return null;
|
|
5344
5362
|
const r = new BitReader(frame.payload);
|
|
@@ -5365,26 +5383,12 @@ function decodeIgsSsr(frame) {
|
|
|
5365
5383
|
mwConsistency = r.readU(1) === 1;
|
|
5366
5384
|
}
|
|
5367
5385
|
const nsat = r.readU(6);
|
|
5368
|
-
const readOrbit = (s) => {
|
|
5369
|
-
s.iode = r.readU(8);
|
|
5370
|
-
s.deltaRadial = r.readS(22) * 1e-4;
|
|
5371
|
-
s.deltaAlongTrack = r.readS(20) * 4e-4;
|
|
5372
|
-
s.deltaCrossTrack = r.readS(20) * 4e-4;
|
|
5373
|
-
s.dotRadial = r.readS(21) * 1e-6;
|
|
5374
|
-
s.dotAlongTrack = r.readS(19) * 4e-6;
|
|
5375
|
-
s.dotCrossTrack = r.readS(19) * 4e-6;
|
|
5376
|
-
};
|
|
5377
|
-
const readClock2 = (s) => {
|
|
5378
|
-
s.c0 = r.readS(22) * 1e-4;
|
|
5379
|
-
s.c1 = r.readS(21) * 1e-6;
|
|
5380
|
-
s.c2 = r.readS(27) * 2e-8;
|
|
5381
|
-
};
|
|
5382
5386
|
const satellites = [];
|
|
5383
5387
|
for (let i = 0; i < nsat; i++) {
|
|
5384
5388
|
const id = r.readU(6);
|
|
5385
5389
|
const sat = { prn: prnFor(system, id) };
|
|
5386
|
-
if (kind === "orbit" || kind === "combined")
|
|
5387
|
-
if (kind === "clock" || kind === "combined")
|
|
5390
|
+
if (kind === "orbit" || kind === "combined") readSsrOrbit(r, sat);
|
|
5391
|
+
if (kind === "clock" || kind === "combined") readSsrClock(r, sat);
|
|
5388
5392
|
else if (kind === "ura")
|
|
5389
5393
|
sat.uraMm = ssrUraMm(r.readU(6));
|
|
5390
5394
|
else if (kind === "highRateClock")
|
|
@@ -5477,116 +5481,6 @@ function decodeIono(r, version, im) {
|
|
|
5477
5481
|
};
|
|
5478
5482
|
}
|
|
5479
5483
|
|
|
5480
|
-
// src/rtcm3/legacy-obs.ts
|
|
5481
|
-
var PRUNIT_GPS = 299792.458;
|
|
5482
|
-
var PRUNIT_GLO = 599584.916;
|
|
5483
|
-
var LAM_GPS_L1 = C_LIGHT / 157542e4;
|
|
5484
|
-
var LAM_GPS_L2 = C_LIGHT / 12276e5;
|
|
5485
|
-
var PPR_INVALID = -(2 ** 19);
|
|
5486
|
-
var PR21_INVALID = -(2 ** 13);
|
|
5487
|
-
function legacyLockSec(i) {
|
|
5488
|
-
if (i < 24) return i;
|
|
5489
|
-
if (i < 48) return 2 * i - 24;
|
|
5490
|
-
if (i < 72) return 4 * i - 120;
|
|
5491
|
-
if (i < 96) return 8 * i - 408;
|
|
5492
|
-
if (i < 120) return 16 * i - 1176;
|
|
5493
|
-
if (i < 127) return 32 * i - 3096;
|
|
5494
|
-
return 937;
|
|
5495
|
-
}
|
|
5496
|
-
var two2 = (n) => n.toString().padStart(2, "0");
|
|
5497
|
-
function decodeLegacyObs(frame) {
|
|
5498
|
-
const type = frame.messageType;
|
|
5499
|
-
const gps = type >= 1001 && type <= 1004;
|
|
5500
|
-
const glo = type >= 1009 && type <= 1012;
|
|
5501
|
-
if (!gps && !glo) return null;
|
|
5502
|
-
const ext = type === 1002 || type === 1004 || type === 1010 || type === 1012;
|
|
5503
|
-
const dual = type === 1003 || type === 1004 || type === 1011 || type === 1012;
|
|
5504
|
-
const system = gps ? "G" : "R";
|
|
5505
|
-
const r = new BitReader(frame.payload);
|
|
5506
|
-
r.readU(12);
|
|
5507
|
-
r.readU(12);
|
|
5508
|
-
let epochMs;
|
|
5509
|
-
let nsat;
|
|
5510
|
-
if (gps) {
|
|
5511
|
-
epochMs = r.readU(30);
|
|
5512
|
-
r.readU(1);
|
|
5513
|
-
nsat = r.readU(5);
|
|
5514
|
-
r.readU(1);
|
|
5515
|
-
r.readU(3);
|
|
5516
|
-
} else {
|
|
5517
|
-
const tk = r.readU(27);
|
|
5518
|
-
r.readU(1);
|
|
5519
|
-
nsat = r.readU(5);
|
|
5520
|
-
r.readU(1);
|
|
5521
|
-
r.readU(3);
|
|
5522
|
-
const gloDow = new Date(Date.now() + 3 * 36e5).getUTCDay();
|
|
5523
|
-
epochMs = (gloDow << 27 | tk) >>> 0;
|
|
5524
|
-
}
|
|
5525
|
-
const observations = [];
|
|
5526
|
-
for (let s = 0; s < nsat; s++) {
|
|
5527
|
-
const satId = r.readU(6);
|
|
5528
|
-
const code1 = r.readU(1);
|
|
5529
|
-
const freqCh = glo ? r.readU(5) : 0;
|
|
5530
|
-
const pr1raw = r.readU(gps ? 24 : 25);
|
|
5531
|
-
const ppr1 = r.readS(20);
|
|
5532
|
-
const lock1 = r.readU(7);
|
|
5533
|
-
let amb = 0;
|
|
5534
|
-
let cnr1 = 0;
|
|
5535
|
-
if (ext) {
|
|
5536
|
-
amb = r.readU(gps ? 8 : 7);
|
|
5537
|
-
cnr1 = r.readU(8);
|
|
5538
|
-
}
|
|
5539
|
-
let code2 = 0;
|
|
5540
|
-
let pr21 = 0;
|
|
5541
|
-
let ppr2 = 0;
|
|
5542
|
-
let lock2 = 0;
|
|
5543
|
-
let cnr2 = 0;
|
|
5544
|
-
if (dual) {
|
|
5545
|
-
code2 = r.readU(2);
|
|
5546
|
-
pr21 = r.readS(14);
|
|
5547
|
-
ppr2 = r.readS(20);
|
|
5548
|
-
lock2 = r.readU(7);
|
|
5549
|
-
if (ext) cnr2 = r.readU(8);
|
|
5550
|
-
}
|
|
5551
|
-
if (gps && (satId < 1 || satId > 32)) continue;
|
|
5552
|
-
if (glo && (satId < 1 || satId > 24)) continue;
|
|
5553
|
-
const prunit = gps ? PRUNIT_GPS : PRUNIT_GLO;
|
|
5554
|
-
const pr1 = pr1raw * 0.02 + amb * prunit;
|
|
5555
|
-
const k = freqCh - 7;
|
|
5556
|
-
const lamL1 = gps ? LAM_GPS_L1 : C_LIGHT / (GLO_F1_BASE + k * GLO_F1_STEP);
|
|
5557
|
-
const lamL2 = gps ? LAM_GPS_L2 : C_LIGHT / (GLO_F2_BASE + k * GLO_F2_STEP);
|
|
5558
|
-
const signals = [];
|
|
5559
|
-
{
|
|
5560
|
-
const sig = {
|
|
5561
|
-
rinexCode: gps ? code1 ? "1W" : "1C" : code1 ? "1P" : "1C",
|
|
5562
|
-
pseudorange: pr1,
|
|
5563
|
-
wavelength: lamL1,
|
|
5564
|
-
lockTime: legacyLockSec(lock1)
|
|
5565
|
-
};
|
|
5566
|
-
if (ppr1 !== PPR_INVALID) sig.phase = (pr1 + ppr1 * 5e-4) / lamL1;
|
|
5567
|
-
if (ext && cnr1 > 0) sig.cn0 = cnr1 * 0.25;
|
|
5568
|
-
signals.push(sig);
|
|
5569
|
-
}
|
|
5570
|
-
if (dual) {
|
|
5571
|
-
const sig = {
|
|
5572
|
-
rinexCode: gps ? code2 === 0 ? "2X" : "2W" : code2 === 0 ? "2C" : "2P",
|
|
5573
|
-
wavelength: lamL2,
|
|
5574
|
-
lockTime: legacyLockSec(lock2)
|
|
5575
|
-
};
|
|
5576
|
-
if (pr21 !== PR21_INVALID) sig.pseudorange = pr1 + pr21 * 0.02;
|
|
5577
|
-
if (ppr2 !== PPR_INVALID) sig.phase = (pr1 + ppr2 * 5e-4) / lamL2;
|
|
5578
|
-
if (ext && cnr2 > 0) sig.cn0 = cnr2 * 0.25;
|
|
5579
|
-
signals.push(sig);
|
|
5580
|
-
}
|
|
5581
|
-
observations.push({
|
|
5582
|
-
prn: `${system}${two2(satId)}`,
|
|
5583
|
-
system,
|
|
5584
|
-
signals
|
|
5585
|
-
});
|
|
5586
|
-
}
|
|
5587
|
-
return { messageType: type, epochMs, system, observations };
|
|
5588
|
-
}
|
|
5589
|
-
|
|
5590
5484
|
// src/rtcm3/msm.ts
|
|
5591
5485
|
var GPS_L1 = FREQ.G["1"];
|
|
5592
5486
|
var GPS_L2 = FREQ.G["2"];
|
|
@@ -6085,7 +5979,7 @@ function decodeMsmFull(frame) {
|
|
|
6085
5979
|
}
|
|
6086
5980
|
var GPS_EPOCH = START_GPS_TIME.getTime();
|
|
6087
5981
|
var MS_PER_WEEK = MILLISECONDS_IN_WEEK;
|
|
6088
|
-
function
|
|
5982
|
+
function obsEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
|
|
6089
5983
|
const refMs = refTime.getTime();
|
|
6090
5984
|
if (sys === "R") {
|
|
6091
5985
|
const dayOfWeek = epochMs >>> 27 & 7;
|
|
@@ -6121,25 +6015,120 @@ function resetGloFreqCache() {
|
|
|
6121
6015
|
gloFreqNum.fill(-128);
|
|
6122
6016
|
}
|
|
6123
6017
|
|
|
6018
|
+
// src/rtcm3/legacy-obs.ts
|
|
6019
|
+
var PRUNIT_GPS = 299792.458;
|
|
6020
|
+
var PRUNIT_GLO = 599584.916;
|
|
6021
|
+
var LAM_GPS_L1 = C_LIGHT / 157542e4;
|
|
6022
|
+
var LAM_GPS_L2 = C_LIGHT / 12276e5;
|
|
6023
|
+
var PPR_INVALID = -(2 ** 19);
|
|
6024
|
+
var PR21_INVALID = -(2 ** 13);
|
|
6025
|
+
function legacyLockSec(i) {
|
|
6026
|
+
if (i < 24) return i;
|
|
6027
|
+
if (i < 48) return 2 * i - 24;
|
|
6028
|
+
if (i < 72) return 4 * i - 120;
|
|
6029
|
+
if (i < 96) return 8 * i - 408;
|
|
6030
|
+
if (i < 120) return 16 * i - 1176;
|
|
6031
|
+
if (i < 127) return 32 * i - 3096;
|
|
6032
|
+
return 937;
|
|
6033
|
+
}
|
|
6034
|
+
var two2 = (n) => n.toString().padStart(2, "0");
|
|
6035
|
+
function decodeLegacyObs(frame) {
|
|
6036
|
+
const type = frame.messageType;
|
|
6037
|
+
const gps = type >= 1001 && type <= 1004;
|
|
6038
|
+
const glo = type >= 1009 && type <= 1012;
|
|
6039
|
+
if (!gps && !glo) return null;
|
|
6040
|
+
const ext = type === 1002 || type === 1004 || type === 1010 || type === 1012;
|
|
6041
|
+
const dual = type === 1003 || type === 1004 || type === 1011 || type === 1012;
|
|
6042
|
+
const system = gps ? "G" : "R";
|
|
6043
|
+
const r = new BitReader(frame.payload);
|
|
6044
|
+
r.readU(12);
|
|
6045
|
+
r.readU(12);
|
|
6046
|
+
let epochMs;
|
|
6047
|
+
let nsat;
|
|
6048
|
+
if (gps) {
|
|
6049
|
+
epochMs = r.readU(30);
|
|
6050
|
+
r.readU(1);
|
|
6051
|
+
nsat = r.readU(5);
|
|
6052
|
+
r.readU(1);
|
|
6053
|
+
r.readU(3);
|
|
6054
|
+
} else {
|
|
6055
|
+
const tk = r.readU(27);
|
|
6056
|
+
r.readU(1);
|
|
6057
|
+
nsat = r.readU(5);
|
|
6058
|
+
r.readU(1);
|
|
6059
|
+
r.readU(3);
|
|
6060
|
+
const gloDow = new Date(Date.now() + 3 * 36e5).getUTCDay();
|
|
6061
|
+
epochMs = (gloDow << 27 | tk) >>> 0;
|
|
6062
|
+
}
|
|
6063
|
+
const observations = [];
|
|
6064
|
+
for (let s = 0; s < nsat; s++) {
|
|
6065
|
+
const satId = r.readU(6);
|
|
6066
|
+
const code1 = r.readU(1);
|
|
6067
|
+
const freqCh = glo ? r.readU(5) : 0;
|
|
6068
|
+
const pr1raw = r.readU(gps ? 24 : 25);
|
|
6069
|
+
const ppr1 = r.readS(20);
|
|
6070
|
+
const lock1 = r.readU(7);
|
|
6071
|
+
let amb = 0;
|
|
6072
|
+
let cnr1 = 0;
|
|
6073
|
+
if (ext) {
|
|
6074
|
+
amb = r.readU(gps ? 8 : 7);
|
|
6075
|
+
cnr1 = r.readU(8);
|
|
6076
|
+
}
|
|
6077
|
+
let code2 = 0;
|
|
6078
|
+
let pr21 = 0;
|
|
6079
|
+
let ppr2 = 0;
|
|
6080
|
+
let lock2 = 0;
|
|
6081
|
+
let cnr2 = 0;
|
|
6082
|
+
if (dual) {
|
|
6083
|
+
code2 = r.readU(2);
|
|
6084
|
+
pr21 = r.readS(14);
|
|
6085
|
+
ppr2 = r.readS(20);
|
|
6086
|
+
lock2 = r.readU(7);
|
|
6087
|
+
if (ext) cnr2 = r.readU(8);
|
|
6088
|
+
}
|
|
6089
|
+
if (gps && (satId < 1 || satId > 32)) continue;
|
|
6090
|
+
if (glo && (satId < 1 || satId > 24)) continue;
|
|
6091
|
+
const prunit = gps ? PRUNIT_GPS : PRUNIT_GLO;
|
|
6092
|
+
const pr1 = pr1raw * 0.02 + amb * prunit;
|
|
6093
|
+
const k = freqCh - 7;
|
|
6094
|
+
const lamL1 = gps ? LAM_GPS_L1 : C_LIGHT / (GLO_F1_BASE + k * GLO_F1_STEP);
|
|
6095
|
+
const lamL2 = gps ? LAM_GPS_L2 : C_LIGHT / (GLO_F2_BASE + k * GLO_F2_STEP);
|
|
6096
|
+
const signals = [];
|
|
6097
|
+
{
|
|
6098
|
+
const sig = {
|
|
6099
|
+
rinexCode: gps ? code1 ? "1W" : "1C" : code1 ? "1P" : "1C",
|
|
6100
|
+
pseudorange: pr1,
|
|
6101
|
+
wavelength: lamL1,
|
|
6102
|
+
lockTime: legacyLockSec(lock1)
|
|
6103
|
+
};
|
|
6104
|
+
if (ppr1 !== PPR_INVALID) sig.phase = (pr1 + ppr1 * 5e-4) / lamL1;
|
|
6105
|
+
if (ext && cnr1 > 0) sig.cn0 = cnr1 * 0.25;
|
|
6106
|
+
signals.push(sig);
|
|
6107
|
+
}
|
|
6108
|
+
if (dual) {
|
|
6109
|
+
const sig = {
|
|
6110
|
+
rinexCode: gps ? code2 === 0 ? "2X" : "2W" : code2 === 0 ? "2C" : "2P",
|
|
6111
|
+
wavelength: lamL2,
|
|
6112
|
+
lockTime: legacyLockSec(lock2)
|
|
6113
|
+
};
|
|
6114
|
+
if (pr21 !== PR21_INVALID) sig.pseudorange = pr1 + pr21 * 0.02;
|
|
6115
|
+
if (ppr2 !== PPR_INVALID) sig.phase = (pr1 + ppr2 * 5e-4) / lamL2;
|
|
6116
|
+
if (ext && cnr2 > 0) sig.cn0 = cnr2 * 0.25;
|
|
6117
|
+
signals.push(sig);
|
|
6118
|
+
}
|
|
6119
|
+
observations.push({
|
|
6120
|
+
prn: `${system}${two2(satId)}`,
|
|
6121
|
+
system,
|
|
6122
|
+
signals
|
|
6123
|
+
});
|
|
6124
|
+
}
|
|
6125
|
+
return { messageType: type, epochMs, system, observations };
|
|
6126
|
+
}
|
|
6127
|
+
function decodeObs(frame) {
|
|
6128
|
+
return decodeMsmFull(frame) ?? decodeLegacyObs(frame);
|
|
6129
|
+
}
|
|
6130
|
+
|
|
6124
6131
|
// src/rtcm3/ssr.ts
|
|
6125
|
-
var UPDATE_INTERVAL_S2 = [
|
|
6126
|
-
1,
|
|
6127
|
-
2,
|
|
6128
|
-
5,
|
|
6129
|
-
10,
|
|
6130
|
-
15,
|
|
6131
|
-
30,
|
|
6132
|
-
60,
|
|
6133
|
-
120,
|
|
6134
|
-
240,
|
|
6135
|
-
300,
|
|
6136
|
-
600,
|
|
6137
|
-
900,
|
|
6138
|
-
1800,
|
|
6139
|
-
3600,
|
|
6140
|
-
7200,
|
|
6141
|
-
10800
|
|
6142
|
-
];
|
|
6143
6132
|
var GPS_SIGNAL = {
|
|
6144
6133
|
0: "L1 C/A",
|
|
6145
6134
|
1: "L1 P",
|
|
@@ -6174,12 +6163,6 @@ var SSR_KIND = {
|
|
|
6174
6163
|
1067: { system: "R", kind: "ura" },
|
|
6175
6164
|
1068: { system: "R", kind: "highRateClock" }
|
|
6176
6165
|
};
|
|
6177
|
-
function ssrUraMm2(v) {
|
|
6178
|
-
if (v === 0) return null;
|
|
6179
|
-
const cls = v >> 3 & 7;
|
|
6180
|
-
const val = v & 7;
|
|
6181
|
-
return 3 ** cls * (1 + val / 4) - 1;
|
|
6182
|
-
}
|
|
6183
6166
|
var two3 = (n) => n.toString().padStart(2, "0");
|
|
6184
6167
|
function decodeSsr(frame) {
|
|
6185
6168
|
const spec = SSR_KIND[frame.messageType];
|
|
@@ -6189,7 +6172,7 @@ function decodeSsr(frame) {
|
|
|
6189
6172
|
const r = new BitReader(frame.payload);
|
|
6190
6173
|
r.readU(12);
|
|
6191
6174
|
const epochS = r.readU(gps ? 20 : 17);
|
|
6192
|
-
const updateIntervalS =
|
|
6175
|
+
const updateIntervalS = UPDATE_INTERVAL_S[r.readU(4)];
|
|
6193
6176
|
const multipleMessage = r.readU(1) === 1;
|
|
6194
6177
|
const hasDatum = kind === "orbit" || kind === "combined";
|
|
6195
6178
|
const referenceDatum = hasDatum ? r.readU(1) : void 0;
|
|
@@ -6199,30 +6182,14 @@ function decodeSsr(frame) {
|
|
|
6199
6182
|
const nsat = r.readU(6);
|
|
6200
6183
|
const sigName = gps ? GPS_SIGNAL : GLO_SIGNAL;
|
|
6201
6184
|
const satellites = [];
|
|
6202
|
-
const readOrbit = (sat) => {
|
|
6203
|
-
sat.deltaRadial = r.readS(22) * 1e-4;
|
|
6204
|
-
sat.deltaAlongTrack = r.readS(20) * 4e-4;
|
|
6205
|
-
sat.deltaCrossTrack = r.readS(20) * 4e-4;
|
|
6206
|
-
sat.dotRadial = r.readS(21) * 1e-6;
|
|
6207
|
-
sat.dotAlongTrack = r.readS(19) * 4e-6;
|
|
6208
|
-
sat.dotCrossTrack = r.readS(19) * 4e-6;
|
|
6209
|
-
};
|
|
6210
|
-
const readClock2 = (sat) => {
|
|
6211
|
-
sat.c0 = r.readS(22) * 1e-4;
|
|
6212
|
-
sat.c1 = r.readS(21) * 1e-6;
|
|
6213
|
-
sat.c2 = r.readS(27) * 2e-8;
|
|
6214
|
-
};
|
|
6215
6185
|
for (let i = 0; i < nsat; i++) {
|
|
6216
6186
|
const satId = gps ? r.readU(6) : r.readU(5);
|
|
6217
6187
|
const sat = { prn: `${system}${two3(satId)}` };
|
|
6218
|
-
if (kind === "orbit" || kind === "combined")
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
}
|
|
6222
|
-
if (kind === "combined") readClock2(sat);
|
|
6223
|
-
else if (kind === "clock") readClock2(sat);
|
|
6188
|
+
if (kind === "orbit" || kind === "combined") readSsrOrbit(r, sat);
|
|
6189
|
+
if (kind === "combined") readSsrClock(r, sat);
|
|
6190
|
+
else if (kind === "clock") readSsrClock(r, sat);
|
|
6224
6191
|
else if (kind === "ura")
|
|
6225
|
-
sat.uraMm =
|
|
6192
|
+
sat.uraMm = ssrUraMm(r.readU(6));
|
|
6226
6193
|
else if (kind === "highRateClock")
|
|
6227
6194
|
sat.highRateClock = r.readS(22) * 1e-4;
|
|
6228
6195
|
else if (kind === "codeBias") {
|
|
@@ -6590,9 +6557,9 @@ function updateStreamStats(stats, frames, rawBytes) {
|
|
|
6590
6557
|
entry.count++;
|
|
6591
6558
|
entry.lastSeen = now;
|
|
6592
6559
|
entry.totalBytes += frame.length + 6;
|
|
6593
|
-
const
|
|
6594
|
-
if (
|
|
6595
|
-
for (const obs of
|
|
6560
|
+
const obsEpoch = decodeObs(frame);
|
|
6561
|
+
if (obsEpoch) {
|
|
6562
|
+
for (const obs of obsEpoch.observations) {
|
|
6596
6563
|
const signals = [];
|
|
6597
6564
|
let bestCn0 = 0;
|
|
6598
6565
|
for (const sig of obs.signals) {
|
|
@@ -6601,7 +6568,7 @@ function updateStreamStats(stats, frames, rawBytes) {
|
|
|
6601
6568
|
if (sig.cn0 > bestCn0) bestCn0 = sig.cn0;
|
|
6602
6569
|
}
|
|
6603
6570
|
}
|
|
6604
|
-
if (signals.length > 0) {
|
|
6571
|
+
if (obs.signals.length > 0) {
|
|
6605
6572
|
stats.satellites.set(obs.prn, {
|
|
6606
6573
|
prn: obs.prn,
|
|
6607
6574
|
system: obs.system,
|
|
@@ -9152,14 +9119,14 @@ function parseOrbitBlock(c, masks) {
|
|
|
9152
9119
|
const gnssIod = c.u(IOD_BITS[sys.system]);
|
|
9153
9120
|
const rad = c.s(13);
|
|
9154
9121
|
const inT = c.s(12);
|
|
9155
|
-
const
|
|
9122
|
+
const cross3 = c.s(12);
|
|
9156
9123
|
corrections.push({
|
|
9157
9124
|
system: sys.system,
|
|
9158
9125
|
prn,
|
|
9159
9126
|
gnssIod,
|
|
9160
9127
|
deltaRadial: rad === -4096 ? null : rad * 25e-4,
|
|
9161
9128
|
deltaInTrack: inT === -2048 ? null : inT * 8e-3,
|
|
9162
|
-
deltaCrossTrack:
|
|
9129
|
+
deltaCrossTrack: cross3 === -2048 ? null : cross3 * 8e-3
|
|
9163
9130
|
});
|
|
9164
9131
|
}
|
|
9165
9132
|
}
|
|
@@ -14874,6 +14841,55 @@ var SbasProcessor = class {
|
|
|
14874
14841
|
}
|
|
14875
14842
|
};
|
|
14876
14843
|
|
|
14844
|
+
// src/positioning/ssr-apply.ts
|
|
14845
|
+
var cross = (a, b) => [
|
|
14846
|
+
a[1] * b[2] - a[2] * b[1],
|
|
14847
|
+
a[2] * b[0] - a[0] * b[2],
|
|
14848
|
+
a[0] * b[1] - a[1] * b[0]
|
|
14849
|
+
];
|
|
14850
|
+
var norm = (a) => Math.hypot(a[0], a[1], a[2]);
|
|
14851
|
+
var unit = (a) => {
|
|
14852
|
+
const n = norm(a);
|
|
14853
|
+
return n > 0 ? [a[0] / n, a[1] / n, a[2] / n] : [0, 0, 0];
|
|
14854
|
+
};
|
|
14855
|
+
function applyOrbitClock(eph, corr, timeMs) {
|
|
14856
|
+
if (eph.system === "R" || eph.system === "S") return null;
|
|
14857
|
+
if (eph.iode !== corr.iod) return null;
|
|
14858
|
+
const age = (timeMs - corr.refTimeMs) / 1e3;
|
|
14859
|
+
if (corr.validitySeconds != null && (age < -1 || age > corr.validitySeconds))
|
|
14860
|
+
return null;
|
|
14861
|
+
const s = computeSatPosition(eph, timeMs);
|
|
14862
|
+
if (!Number.isFinite(s.x)) return null;
|
|
14863
|
+
const p = [s.x, s.y, s.z];
|
|
14864
|
+
const v = [s.vx, s.vy, s.vz];
|
|
14865
|
+
const er = unit(p);
|
|
14866
|
+
const en = unit(cross(p, v));
|
|
14867
|
+
const ea = cross(en, er);
|
|
14868
|
+
const dr = corr.radial + (corr.dotRadial ?? 0) * age;
|
|
14869
|
+
const da = corr.along + (corr.dotAlong ?? 0) * age;
|
|
14870
|
+
const dc = corr.cross + (corr.dotCross ?? 0) * age;
|
|
14871
|
+
const x = s.x + dr * er[0] + da * ea[0] + dc * en[0];
|
|
14872
|
+
const y = s.y + dr * er[1] + da * ea[1] + dc * en[1];
|
|
14873
|
+
const z = s.z + dr * er[2] + da * ea[2] + dc * en[2];
|
|
14874
|
+
const clockM = corr.clockC0 + (corr.clockC1 ?? 0) * age + (corr.clockC2 ?? 0) * age * age + (corr.highRateClock ?? 0);
|
|
14875
|
+
return { x, y, z, clockOffsetS: clockM / C_LIGHT };
|
|
14876
|
+
}
|
|
14877
|
+
function hasToOrbitClock(orbit, clock, refTimeMs, validitySeconds) {
|
|
14878
|
+
if (orbit.deltaRadial == null || orbit.deltaInTrack == null || orbit.deltaCrossTrack == null)
|
|
14879
|
+
return null;
|
|
14880
|
+
const clockC0 = clock && clock.deltaClock != null && !clock.notUsable ? clock.deltaClock : 0;
|
|
14881
|
+
return {
|
|
14882
|
+
prn: orbit.prn,
|
|
14883
|
+
iod: orbit.gnssIod,
|
|
14884
|
+
refTimeMs,
|
|
14885
|
+
radial: orbit.deltaRadial,
|
|
14886
|
+
along: orbit.deltaInTrack,
|
|
14887
|
+
cross: orbit.deltaCrossTrack,
|
|
14888
|
+
clockC0,
|
|
14889
|
+
validitySeconds
|
|
14890
|
+
};
|
|
14891
|
+
}
|
|
14892
|
+
|
|
14877
14893
|
// src/positioning/ppp-tropo.ts
|
|
14878
14894
|
var HYD_AVG_A = [
|
|
14879
14895
|
0.0012769934,
|
|
@@ -15131,14 +15147,14 @@ function buildPppAntenna(antex) {
|
|
|
15131
15147
|
}
|
|
15132
15148
|
};
|
|
15133
15149
|
}
|
|
15134
|
-
function
|
|
15150
|
+
function cross2(a, b) {
|
|
15135
15151
|
return [
|
|
15136
15152
|
a[1] * b[2] - a[2] * b[1],
|
|
15137
15153
|
a[2] * b[0] - a[0] * b[2],
|
|
15138
15154
|
a[0] * b[1] - a[1] * b[0]
|
|
15139
15155
|
];
|
|
15140
15156
|
}
|
|
15141
|
-
function
|
|
15157
|
+
function norm2(a) {
|
|
15142
15158
|
const n = Math.hypot(a[0], a[1], a[2]) || 1;
|
|
15143
15159
|
return [a[0] / n, a[1] / n, a[2] / n];
|
|
15144
15160
|
}
|
|
@@ -15146,14 +15162,14 @@ function dot(a, b) {
|
|
|
15146
15162
|
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
15147
15163
|
}
|
|
15148
15164
|
function satBodyFrame(satEcef, sunEcef2) {
|
|
15149
|
-
const z =
|
|
15150
|
-
const eSun =
|
|
15165
|
+
const z = norm2([-satEcef[0], -satEcef[1], -satEcef[2]]);
|
|
15166
|
+
const eSun = norm2([
|
|
15151
15167
|
sunEcef2[0] - satEcef[0],
|
|
15152
15168
|
sunEcef2[1] - satEcef[1],
|
|
15153
15169
|
sunEcef2[2] - satEcef[2]
|
|
15154
15170
|
]);
|
|
15155
|
-
const y =
|
|
15156
|
-
const x =
|
|
15171
|
+
const y = norm2(cross2(z, eSun));
|
|
15172
|
+
const x = norm2(cross2(y, z));
|
|
15157
15173
|
return { x, y, z };
|
|
15158
15174
|
}
|
|
15159
15175
|
function satPcoToEcef(pcoBody, frame) {
|
|
@@ -15194,7 +15210,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15194
15210
|
const kx = satFrame.x;
|
|
15195
15211
|
const ky = satFrame.y;
|
|
15196
15212
|
const kdotx = dot(k, kx);
|
|
15197
|
-
const kcrossY =
|
|
15213
|
+
const kcrossY = cross2(k, ky);
|
|
15198
15214
|
const dS = [
|
|
15199
15215
|
kx[0] - k[0] * kdotx - kcrossY[0],
|
|
15200
15216
|
kx[1] - k[1] * kdotx - kcrossY[1],
|
|
@@ -15203,7 +15219,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15203
15219
|
const north = enuToEcef([0, 1, 0], latRad, lonRad);
|
|
15204
15220
|
const east = enuToEcef([1, 0, 0], latRad, lonRad);
|
|
15205
15221
|
const kdotn = dot(k, north);
|
|
15206
|
-
const kcrossE =
|
|
15222
|
+
const kcrossE = cross2(k, east);
|
|
15207
15223
|
const dR = [
|
|
15208
15224
|
north[0] - k[0] * kdotn + kcrossE[0],
|
|
15209
15225
|
north[1] - k[1] * kdotn + kcrossE[1],
|
|
@@ -15213,7 +15229,7 @@ function phaseWindup(prn, losRcvToSat, satFrame, latRad, lonRad, state) {
|
|
|
15213
15229
|
const nR = Math.hypot(dR[0], dR[1], dR[2]) || 1;
|
|
15214
15230
|
let cosPhi = dot(dS, dR) / (nS * nR);
|
|
15215
15231
|
cosPhi = Math.max(-1, Math.min(1, cosPhi));
|
|
15216
|
-
const zeta =
|
|
15232
|
+
const zeta = cross2(dS, dR);
|
|
15217
15233
|
const sign = dot(k, zeta) >= 0 ? 1 : -1;
|
|
15218
15234
|
const dphi = sign * Math.acos(cosPhi) / (2 * Math.PI);
|
|
15219
15235
|
const prev = state.get(prn);
|
|
@@ -15351,13 +15367,35 @@ function ifCoeffs(f1, f2) {
|
|
|
15351
15367
|
const lambdaIf = C_LIGHT / (f1 + f2);
|
|
15352
15368
|
return { g, lambdaIf };
|
|
15353
15369
|
}
|
|
15370
|
+
var Sp3EphemerisSource = class {
|
|
15371
|
+
constructor(sp3, clk) {
|
|
15372
|
+
this.sp3 = sp3;
|
|
15373
|
+
this.clk = clk;
|
|
15374
|
+
}
|
|
15375
|
+
satState(prn, tEmitMs) {
|
|
15376
|
+
const p = sp3Position(this.sp3, prn, tEmitMs);
|
|
15377
|
+
if (!p || p.clk == null) return null;
|
|
15378
|
+
const pPlus = sp3Position(this.sp3, prn, tEmitMs + 500);
|
|
15379
|
+
const pMinus = sp3Position(this.sp3, prn, tEmitMs - 500);
|
|
15380
|
+
let vx = 0;
|
|
15381
|
+
let vy = 0;
|
|
15382
|
+
let vz = 0;
|
|
15383
|
+
if (pPlus && pMinus) {
|
|
15384
|
+
vx = pPlus.x - pMinus.x;
|
|
15385
|
+
vy = pPlus.y - pMinus.y;
|
|
15386
|
+
vz = pPlus.z - pMinus.z;
|
|
15387
|
+
}
|
|
15388
|
+
const clkS = (this.clk ? clkBias(this.clk, prn, tEmitMs) : null) ?? p.clk;
|
|
15389
|
+
return { x: p.x, y: p.y, z: p.z, vx, vy, vz, clkS };
|
|
15390
|
+
}
|
|
15391
|
+
};
|
|
15354
15392
|
function sagnacRotate(x, y, z, travelS) {
|
|
15355
15393
|
const theta = OMEGA_E * travelS;
|
|
15356
15394
|
const c = Math.cos(theta);
|
|
15357
15395
|
const s = Math.sin(theta);
|
|
15358
15396
|
return [x * c + y * s, -x * s + y * c, z];
|
|
15359
15397
|
}
|
|
15360
|
-
function satStateAtEmission(
|
|
15398
|
+
function satStateAtEmission(source, prn, recvTimeMs, rcv) {
|
|
15361
15399
|
let travelS = 0.075;
|
|
15362
15400
|
let sx = 0;
|
|
15363
15401
|
let sy = 0;
|
|
@@ -15366,18 +15404,11 @@ function satStateAtEmission(sp3, prn, recvTimeMs, rcv, clk) {
|
|
|
15366
15404
|
let velDotPos = 0;
|
|
15367
15405
|
for (let iter = 0; iter < 3; iter++) {
|
|
15368
15406
|
const tEmit = recvTimeMs - travelS * 1e3;
|
|
15369
|
-
const
|
|
15370
|
-
if (!
|
|
15371
|
-
|
|
15372
|
-
|
|
15373
|
-
|
|
15374
|
-
const vx = (pPlus.x - pMinus.x) / 1;
|
|
15375
|
-
const vy = (pPlus.y - pMinus.y) / 1;
|
|
15376
|
-
const vz = (pPlus.z - pMinus.z) / 1;
|
|
15377
|
-
velDotPos = p.x * vx + p.y * vy + p.z * vz;
|
|
15378
|
-
}
|
|
15379
|
-
clkS = (clk && clkBias(clk, prn, tEmit)) ?? p.clk;
|
|
15380
|
-
const [rx, ry, rz] = sagnacRotate(p.x, p.y, p.z, travelS);
|
|
15407
|
+
const s = source.satState(prn, tEmit);
|
|
15408
|
+
if (!s) return null;
|
|
15409
|
+
velDotPos = s.x * s.vx + s.y * s.vy + s.z * s.vz;
|
|
15410
|
+
clkS = s.clkS;
|
|
15411
|
+
const [rx, ry, rz] = sagnacRotate(s.x, s.y, s.z, travelS);
|
|
15381
15412
|
sx = rx;
|
|
15382
15413
|
sy = ry;
|
|
15383
15414
|
sz = rz;
|
|
@@ -15399,39 +15430,72 @@ var IDX_ZWD = 3;
|
|
|
15399
15430
|
var NBASE = 4;
|
|
15400
15431
|
var CLK_VAR = 1e10;
|
|
15401
15432
|
var POS_VAR = 60 * 60;
|
|
15402
|
-
|
|
15403
|
-
|
|
15404
|
-
|
|
15405
|
-
|
|
15406
|
-
|
|
15407
|
-
|
|
15408
|
-
|
|
15409
|
-
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15413
|
-
|
|
15414
|
-
|
|
15415
|
-
|
|
15416
|
-
|
|
15417
|
-
|
|
15418
|
-
|
|
15419
|
-
|
|
15420
|
-
|
|
15421
|
-
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
|
|
15433
|
+
var PppEngine = class {
|
|
15434
|
+
source;
|
|
15435
|
+
opts;
|
|
15436
|
+
elevMask;
|
|
15437
|
+
codeSigma;
|
|
15438
|
+
phaseSigma;
|
|
15439
|
+
ztdQ;
|
|
15440
|
+
kinematic;
|
|
15441
|
+
corrections;
|
|
15442
|
+
truth;
|
|
15443
|
+
// Filter state (reset() initialises; mutated in place across epochs).
|
|
15444
|
+
x;
|
|
15445
|
+
P;
|
|
15446
|
+
clkIdx;
|
|
15447
|
+
clockSeeded;
|
|
15448
|
+
ambIdx;
|
|
15449
|
+
lastSeen;
|
|
15450
|
+
arcs;
|
|
15451
|
+
arcSnap;
|
|
15452
|
+
mwState;
|
|
15453
|
+
series;
|
|
15454
|
+
ei = 0;
|
|
15455
|
+
t0 = 0;
|
|
15456
|
+
convergenceSec = null;
|
|
15457
|
+
convergedStreak = 0;
|
|
15458
|
+
constructor(opts, source) {
|
|
15459
|
+
this.opts = opts;
|
|
15460
|
+
this.source = source;
|
|
15461
|
+
this.elevMask = (opts.elevationMaskDeg ?? 10) * Math.PI / 180;
|
|
15462
|
+
this.codeSigma = opts.codeSigma ?? 3;
|
|
15463
|
+
this.phaseSigma = opts.phaseSigma ?? 0.01;
|
|
15464
|
+
this.ztdQ = opts.ztdProcessNoise ?? 1e-8;
|
|
15465
|
+
this.kinematic = opts.mode === "kinematic";
|
|
15466
|
+
this.corrections = opts.corrections;
|
|
15467
|
+
this.truth = opts.groundTruth;
|
|
15468
|
+
this.reset();
|
|
15469
|
+
}
|
|
15470
|
+
/** Reinitialise the filter (fresh session). */
|
|
15471
|
+
reset() {
|
|
15472
|
+
const { opts } = this;
|
|
15473
|
+
this.x = [opts.aprioriPos[0], opts.aprioriPos[1], opts.aprioriPos[2], 0.1];
|
|
15474
|
+
const P = [];
|
|
15475
|
+
for (let i = 0; i < NBASE; i++) P.push(new Array(NBASE).fill(0));
|
|
15476
|
+
P[IDX_X][IDX_X] = 100 * 100;
|
|
15477
|
+
P[IDX_Y][IDX_Y] = 100 * 100;
|
|
15478
|
+
P[IDX_Z][IDX_Z] = 100 * 100;
|
|
15479
|
+
P[IDX_ZWD][IDX_ZWD] = 0.5 * 0.5;
|
|
15480
|
+
this.P = P;
|
|
15481
|
+
this.clkIdx = /* @__PURE__ */ new Map();
|
|
15482
|
+
this.clockSeeded = /* @__PURE__ */ new Set();
|
|
15483
|
+
this.ambIdx = /* @__PURE__ */ new Map();
|
|
15484
|
+
this.lastSeen = /* @__PURE__ */ new Map();
|
|
15485
|
+
this.arcs = [];
|
|
15486
|
+
this.arcSnap = /* @__PURE__ */ new Map();
|
|
15487
|
+
this.mwState = /* @__PURE__ */ new Map();
|
|
15488
|
+
this.series = [];
|
|
15489
|
+
this.ei = 0;
|
|
15490
|
+
this.t0 = 0;
|
|
15491
|
+
this.convergenceSec = null;
|
|
15492
|
+
this.convergedStreak = 0;
|
|
15493
|
+
}
|
|
15494
|
+
flushArc(prn, minEpochs = 10) {
|
|
15495
|
+
const s = this.arcSnap.get(prn);
|
|
15496
|
+
this.arcSnap.delete(prn);
|
|
15433
15497
|
if (!s || s.nEpochs < minEpochs) return;
|
|
15434
|
-
arcs.push({
|
|
15498
|
+
this.arcs.push({
|
|
15435
15499
|
prn,
|
|
15436
15500
|
aIF: s.aIF,
|
|
15437
15501
|
mwCyc: s.mwCyc,
|
|
@@ -15442,64 +15506,88 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15442
15506
|
startMs: s.startMs,
|
|
15443
15507
|
endMs: s.endMs
|
|
15444
15508
|
});
|
|
15445
|
-
}
|
|
15446
|
-
|
|
15447
|
-
|
|
15509
|
+
}
|
|
15510
|
+
/** Detect a cycle slip via the Melbourne–Wübbena wide-lane ambiguity. */
|
|
15511
|
+
detectSlip(o, ei) {
|
|
15448
15512
|
const lamW = C_LIGHT / (o.f1 - o.f2);
|
|
15449
15513
|
const lw = o.l1 - o.l2;
|
|
15450
15514
|
const pn = (o.f1 * o.c1 + o.f2 * o.c2) / (o.f1 + o.f2);
|
|
15451
15515
|
const mw = lw - pn / lamW;
|
|
15452
|
-
const st = mwState.get(o.prn);
|
|
15516
|
+
const st = this.mwState.get(o.prn);
|
|
15453
15517
|
let slip = o.slip;
|
|
15454
15518
|
if (!st || ei - st.lastEi > 2)
|
|
15455
15519
|
slip = true;
|
|
15456
15520
|
else if (Math.abs(mw - st.mean) > 4) slip = true;
|
|
15457
|
-
if (slip) mwState.set(o.prn, { mean: mw, n: 1, lastEi: ei });
|
|
15521
|
+
if (slip) this.mwState.set(o.prn, { mean: mw, n: 1, lastEi: ei });
|
|
15458
15522
|
else {
|
|
15459
15523
|
const n = st.n + 1;
|
|
15460
|
-
mwState.set(o.prn, {
|
|
15524
|
+
this.mwState.set(o.prn, {
|
|
15461
15525
|
mean: st.mean + (mw - st.mean) / Math.min(n, 100),
|
|
15462
15526
|
n,
|
|
15463
15527
|
lastEi: ei
|
|
15464
15528
|
});
|
|
15465
15529
|
}
|
|
15466
15530
|
return slip;
|
|
15467
|
-
}
|
|
15468
|
-
|
|
15469
|
-
const idx = x.length;
|
|
15470
|
-
x.push(initVal);
|
|
15471
|
-
for (const row of P) row.push(0);
|
|
15472
|
-
P.push(new Array(x.length).fill(0));
|
|
15473
|
-
P[idx][idx] = initVar;
|
|
15531
|
+
}
|
|
15532
|
+
growState(initVal, initVar) {
|
|
15533
|
+
const idx = this.x.length;
|
|
15534
|
+
this.x.push(initVal);
|
|
15535
|
+
for (const row of this.P) row.push(0);
|
|
15536
|
+
this.P.push(new Array(this.x.length).fill(0));
|
|
15537
|
+
this.P[idx][idx] = initVar;
|
|
15474
15538
|
return idx;
|
|
15475
|
-
}
|
|
15476
|
-
|
|
15477
|
-
x.splice(idx, 1);
|
|
15478
|
-
P.splice(idx, 1);
|
|
15479
|
-
for (const row of P) row.splice(idx, 1);
|
|
15480
|
-
for (const [prn, i] of ambIdx) {
|
|
15481
|
-
if (i === idx) ambIdx.delete(prn);
|
|
15482
|
-
else if (i > idx) ambIdx.set(prn, i - 1);
|
|
15539
|
+
}
|
|
15540
|
+
dropState(idx) {
|
|
15541
|
+
this.x.splice(idx, 1);
|
|
15542
|
+
this.P.splice(idx, 1);
|
|
15543
|
+
for (const row of this.P) row.splice(idx, 1);
|
|
15544
|
+
for (const [prn, i] of this.ambIdx) {
|
|
15545
|
+
if (i === idx) this.ambIdx.delete(prn);
|
|
15546
|
+
else if (i > idx) this.ambIdx.set(prn, i - 1);
|
|
15483
15547
|
}
|
|
15484
|
-
for (const [sys, i] of clkIdx) {
|
|
15485
|
-
if (i > idx) clkIdx.set(sys, i - 1);
|
|
15548
|
+
for (const [sys, i] of this.clkIdx) {
|
|
15549
|
+
if (i > idx) this.clkIdx.set(sys, i - 1);
|
|
15486
15550
|
}
|
|
15487
|
-
}
|
|
15488
|
-
|
|
15489
|
-
|
|
15551
|
+
}
|
|
15552
|
+
/** State index of a constellation's receiver clock, creating it lazily. */
|
|
15553
|
+
clockOf(sys) {
|
|
15554
|
+
let i = this.clkIdx.get(sys);
|
|
15490
15555
|
if (i === void 0) {
|
|
15491
|
-
i = growState(0, CLK_VAR);
|
|
15492
|
-
clkIdx.set(sys, i);
|
|
15556
|
+
i = this.growState(0, CLK_VAR);
|
|
15557
|
+
this.clkIdx.set(sys, i);
|
|
15493
15558
|
}
|
|
15494
15559
|
return i;
|
|
15495
|
-
}
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
|
|
15560
|
+
}
|
|
15561
|
+
/** Process one epoch, carrying the filter forward; returns its result. */
|
|
15562
|
+
process(epoch) {
|
|
15563
|
+
const {
|
|
15564
|
+
source,
|
|
15565
|
+
opts,
|
|
15566
|
+
elevMask,
|
|
15567
|
+
codeSigma,
|
|
15568
|
+
phaseSigma,
|
|
15569
|
+
ztdQ,
|
|
15570
|
+
kinematic,
|
|
15571
|
+
corrections,
|
|
15572
|
+
truth,
|
|
15573
|
+
x,
|
|
15574
|
+
P,
|
|
15575
|
+
clkIdx,
|
|
15576
|
+
clockSeeded,
|
|
15577
|
+
ambIdx,
|
|
15578
|
+
lastSeen,
|
|
15579
|
+
arcSnap,
|
|
15580
|
+
mwState,
|
|
15581
|
+
series
|
|
15582
|
+
} = this;
|
|
15583
|
+
const flushArc = this.flushArc.bind(this);
|
|
15584
|
+
const detectSlip = this.detectSlip.bind(this);
|
|
15585
|
+
const growState = this.growState.bind(this);
|
|
15586
|
+
const dropState = this.dropState.bind(this);
|
|
15587
|
+
const clockOf = this.clockOf.bind(this);
|
|
15588
|
+
const ei = this.ei;
|
|
15589
|
+
if (ei === 0) this.t0 = epoch.timeMs;
|
|
15590
|
+
const t0 = this.t0;
|
|
15503
15591
|
if (kinematic && ei > 0) {
|
|
15504
15592
|
for (const p of [IDX_X, IDX_Y, IDX_Z]) {
|
|
15505
15593
|
for (let j = 0; j < x.length; j++) {
|
|
@@ -15520,7 +15608,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15520
15608
|
for (const o of epoch.obs) {
|
|
15521
15609
|
if (o.c1 === 0 || o.c2 === 0 || o.l1 === 0 || o.l2 === 0) continue;
|
|
15522
15610
|
const slip = detectSlip(o, ei);
|
|
15523
|
-
const sat = satStateAtEmission(
|
|
15611
|
+
const sat = satStateAtEmission(source, o.prn, epoch.timeMs, rcv);
|
|
15524
15612
|
if (!sat) continue;
|
|
15525
15613
|
const [elRad, azRad] = getAer(
|
|
15526
15614
|
sat.state.x,
|
|
@@ -15540,7 +15628,9 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15540
15628
|
const lam1 = C_LIGHT / o.f1;
|
|
15541
15629
|
const lam2 = C_LIGHT / o.f2;
|
|
15542
15630
|
if (o.c1 === 0 || o.c2 === 0 || o.l1 === 0 || o.l2 === 0) continue;
|
|
15543
|
-
const
|
|
15631
|
+
const b1 = source.codeBias?.(o.prn, o.code1 ?? "", epoch.timeMs) ?? 0;
|
|
15632
|
+
const b2 = source.codeBias?.(o.prn, o.code2 ?? "", epoch.timeMs) ?? 0;
|
|
15633
|
+
const pIf = g * (o.c1 - b1) - (g - 1) * (o.c2 - b2);
|
|
15544
15634
|
const lIf = g * (o.l1 * lam1) - (g - 1) * (o.l2 * lam2);
|
|
15545
15635
|
if (!Number.isFinite(pIf) || !Number.isFinite(lIf)) continue;
|
|
15546
15636
|
const trop = opts.troposphere ?? true ? niellMapping(elRad, latRad, heightM, epoch.timeMs) : { zhd: 0, mh: 0, mw: 0 };
|
|
@@ -15727,16 +15817,16 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15727
15817
|
pos[2] - truth[2]
|
|
15728
15818
|
);
|
|
15729
15819
|
if (error3d < 0.1) {
|
|
15730
|
-
convergedStreak++;
|
|
15731
|
-
if (convergedStreak >= 10 && convergenceSec == null) {
|
|
15732
|
-
convergenceSec = (epoch.timeMs - t0) / 1e3;
|
|
15820
|
+
this.convergedStreak++;
|
|
15821
|
+
if (this.convergedStreak >= 10 && this.convergenceSec == null) {
|
|
15822
|
+
this.convergenceSec = (epoch.timeMs - t0) / 1e3;
|
|
15733
15823
|
}
|
|
15734
15824
|
} else {
|
|
15735
|
-
convergedStreak = 0;
|
|
15736
|
-
convergenceSec = null;
|
|
15825
|
+
this.convergedStreak = 0;
|
|
15826
|
+
this.convergenceSec = null;
|
|
15737
15827
|
}
|
|
15738
15828
|
}
|
|
15739
|
-
|
|
15829
|
+
const result = {
|
|
15740
15830
|
timeMs: epoch.timeMs,
|
|
15741
15831
|
enu,
|
|
15742
15832
|
error3d,
|
|
@@ -15745,50 +15835,68 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
15745
15835
|
ztdWet: x[IDX_ZWD],
|
|
15746
15836
|
ztdHydrostatic: epochZhd,
|
|
15747
15837
|
phaseResRms: nPhaseRes > 0 ? Math.sqrt(sumPhaseResSq / nPhaseRes) : 0
|
|
15748
|
-
}
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
|
|
15761
|
-
|
|
15762
|
-
|
|
15763
|
-
|
|
15764
|
-
|
|
15838
|
+
};
|
|
15839
|
+
series.push(result);
|
|
15840
|
+
this.ei = ei + 1;
|
|
15841
|
+
return result;
|
|
15842
|
+
}
|
|
15843
|
+
/** Finalise the session: capture the AR state, flush open arcs, assemble. */
|
|
15844
|
+
solution() {
|
|
15845
|
+
const { opts, x, P, ambIdx, arcSnap, mwState, arcs, series, truth } = this;
|
|
15846
|
+
const flushArc = this.flushArc.bind(this);
|
|
15847
|
+
let finalState;
|
|
15848
|
+
if (opts.exposeState) {
|
|
15849
|
+
const ambs = [];
|
|
15850
|
+
for (const [prn, index] of ambIdx) {
|
|
15851
|
+
const s = arcSnap.get(prn);
|
|
15852
|
+
if (!s || s.nEpochs < 10) continue;
|
|
15853
|
+
ambs.push({
|
|
15854
|
+
prn,
|
|
15855
|
+
index,
|
|
15856
|
+
aIF: x[index],
|
|
15857
|
+
mwCyc: mwState.get(prn)?.mean ?? s.mwCyc,
|
|
15858
|
+
f1: s.f1,
|
|
15859
|
+
f2: s.f2,
|
|
15860
|
+
elevDeg: s.elevSum / s.nEpochs
|
|
15861
|
+
});
|
|
15862
|
+
}
|
|
15863
|
+
finalState = {
|
|
15864
|
+
position: [x[IDX_X], x[IDX_Y], x[IDX_Z]],
|
|
15865
|
+
covariance: P.map((row) => row.slice()),
|
|
15866
|
+
ambiguities: ambs
|
|
15867
|
+
};
|
|
15765
15868
|
}
|
|
15766
|
-
|
|
15767
|
-
|
|
15768
|
-
|
|
15769
|
-
|
|
15869
|
+
for (const prn of [...arcSnap.keys()]) flushArc(prn);
|
|
15870
|
+
const finalPos = [
|
|
15871
|
+
x[IDX_X],
|
|
15872
|
+
x[IDX_Y],
|
|
15873
|
+
x[IDX_Z]
|
|
15874
|
+
];
|
|
15875
|
+
const llh = ecefToGeodetic(finalPos[0], finalPos[1], finalPos[2]);
|
|
15876
|
+
const finalError3d = truth ? Math.hypot(
|
|
15877
|
+
finalPos[0] - truth[0],
|
|
15878
|
+
finalPos[1] - truth[1],
|
|
15879
|
+
finalPos[2] - truth[2]
|
|
15880
|
+
) : null;
|
|
15881
|
+
return {
|
|
15882
|
+
position: finalPos,
|
|
15883
|
+
llh,
|
|
15884
|
+
series,
|
|
15885
|
+
ztdWet: x[IDX_ZWD],
|
|
15886
|
+
ztdHydrostatic: series.length ? series[series.length - 1].ztdHydrostatic : 0,
|
|
15887
|
+
epochsUsed: series.length,
|
|
15888
|
+
convergenceSec: this.convergenceSec,
|
|
15889
|
+
finalError3d,
|
|
15890
|
+
arcs,
|
|
15891
|
+
finalState
|
|
15770
15892
|
};
|
|
15771
15893
|
}
|
|
15772
|
-
|
|
15773
|
-
|
|
15774
|
-
const
|
|
15775
|
-
const
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
finalPos[2] - truth[2]
|
|
15779
|
-
) : null;
|
|
15780
|
-
return {
|
|
15781
|
-
position: finalPos,
|
|
15782
|
-
llh,
|
|
15783
|
-
series,
|
|
15784
|
-
ztdWet: x[IDX_ZWD],
|
|
15785
|
-
ztdHydrostatic: series.length ? series[series.length - 1].ztdHydrostatic : 0,
|
|
15786
|
-
epochsUsed: epochs.length,
|
|
15787
|
-
convergenceSec,
|
|
15788
|
-
finalError3d,
|
|
15789
|
-
arcs,
|
|
15790
|
-
finalState
|
|
15791
|
-
};
|
|
15894
|
+
};
|
|
15895
|
+
function solvePpp(epochs, sp3OrSource, opts) {
|
|
15896
|
+
const source = "satState" in sp3OrSource ? sp3OrSource : new Sp3EphemerisSource(sp3OrSource, opts.clk);
|
|
15897
|
+
const eng = new PppEngine(opts, source);
|
|
15898
|
+
for (const epoch of epochs) eng.process(epoch);
|
|
15899
|
+
return eng.solution();
|
|
15792
15900
|
}
|
|
15793
15901
|
|
|
15794
15902
|
// src/positioning/ppp-ar.ts
|
|
@@ -18843,6 +18951,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18843
18951
|
MultipathAccumulator,
|
|
18844
18952
|
OEM4_HLEN,
|
|
18845
18953
|
OMEGA_E,
|
|
18954
|
+
PppEngine,
|
|
18846
18955
|
REFERENCE_FRAMES,
|
|
18847
18956
|
RINEX_CODES,
|
|
18848
18957
|
RTCM2_MESSAGE_NAMES,
|
|
@@ -18870,6 +18979,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18870
18979
|
SYS_SHORT,
|
|
18871
18980
|
SbasProcessor,
|
|
18872
18981
|
Scale,
|
|
18982
|
+
Sp3EphemerisSource,
|
|
18873
18983
|
WGS84_ECCENTRICITY_SQUARED,
|
|
18874
18984
|
WGS84_FLATTENING,
|
|
18875
18985
|
WGS84_SEMI_MAJOR_AXIS,
|
|
@@ -18880,6 +18990,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18880
18990
|
analyzeQuality,
|
|
18881
18991
|
applyHelmert,
|
|
18882
18992
|
applyIonoDcb,
|
|
18993
|
+
applyOrbitClock,
|
|
18883
18994
|
biasMetres,
|
|
18884
18995
|
binexCrc16,
|
|
18885
18996
|
binexCrc32,
|
|
@@ -18913,6 +19024,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
18913
19024
|
decodeIgsSsr,
|
|
18914
19025
|
decodeLegacyObs,
|
|
18915
19026
|
decodeMsmFull,
|
|
19027
|
+
decodeObs,
|
|
18916
19028
|
decodeSbfNavigation,
|
|
18917
19029
|
decodeSsr,
|
|
18918
19030
|
decodeSystemParams,
|
|
@@ -19003,6 +19115,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
19003
19115
|
glonassPosition,
|
|
19004
19116
|
gmst,
|
|
19005
19117
|
greatCircleMidpoint,
|
|
19118
|
+
hasToOrbitClock,
|
|
19006
19119
|
hdrLine,
|
|
19007
19120
|
horizonDistance,
|
|
19008
19121
|
ionoFree,
|
|
@@ -19016,11 +19129,11 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
19016
19129
|
looksLikeRtcm2,
|
|
19017
19130
|
maskRadForAzimuth,
|
|
19018
19131
|
moonEcef,
|
|
19019
|
-
msmEpochToDate,
|
|
19020
19132
|
navTimesFromEph,
|
|
19021
19133
|
niellMapping,
|
|
19022
19134
|
nlWavelength,
|
|
19023
19135
|
nmeaCoordToDecimal,
|
|
19136
|
+
obsEpochToDate,
|
|
19024
19137
|
oem4Frames,
|
|
19025
19138
|
padL,
|
|
19026
19139
|
padR,
|