gnss-js 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-4KOXMHUW.js +223 -0
- package/dist/{chunk-ZCNXERQ2.js → chunk-CC2R4JGS.js} +8 -6
- package/dist/chunk-USHP4IND.js +206 -0
- package/dist/frames.js +6 -216
- package/dist/index.cjs +435 -9
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +21 -1
- package/dist/orbit.cjs +9 -6
- package/dist/orbit.d.cts +3 -1
- package/dist/orbit.d.ts +3 -1
- package/dist/orbit.js +3 -1
- package/dist/positioning.cjs +6 -3
- package/dist/positioning.d.cts +11 -3
- package/dist/positioning.d.ts +11 -3
- package/dist/positioning.js +6 -196
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -75,6 +75,7 @@ __export(src_exports, {
|
|
|
75
75
|
MILLISECONDS_IN_WEEK: () => MILLISECONDS_IN_WEEK,
|
|
76
76
|
MILLISECONDS_TT_TAI: () => MILLISECONDS_TT_TAI,
|
|
77
77
|
MultipathAccumulator: () => MultipathAccumulator,
|
|
78
|
+
REFERENCE_FRAMES: () => REFERENCE_FRAMES,
|
|
78
79
|
RINEX_CODES: () => RINEX_CODES,
|
|
79
80
|
RTCM3_MESSAGE_NAMES: () => RTCM3_MESSAGE_NAMES,
|
|
80
81
|
Rtcm3Decoder: () => Rtcm3Decoder,
|
|
@@ -101,6 +102,7 @@ __export(src_exports, {
|
|
|
101
102
|
WGS84_SEMI_MINOR_AXIS: () => WGS84_SEMI_MINOR_AXIS,
|
|
102
103
|
WarningAccumulator: () => WarningAccumulator,
|
|
103
104
|
analyzeQuality: () => analyzeQuality,
|
|
105
|
+
applyHelmert: () => applyHelmert,
|
|
104
106
|
buildGloChannelMap: () => buildGloChannelMap,
|
|
105
107
|
buildObsIndices: () => buildObsIndices,
|
|
106
108
|
clampUnit: () => clampUnit,
|
|
@@ -116,12 +118,14 @@ __export(src_exports, {
|
|
|
116
118
|
createStreamStats: () => createStreamStats,
|
|
117
119
|
crxDecompress: () => crxDecompress,
|
|
118
120
|
crxRepair: () => crxRepair,
|
|
121
|
+
dateToEpoch: () => dateToEpoch,
|
|
119
122
|
decodeEphemeris: () => decodeEphemeris,
|
|
120
123
|
decodeMsmFull: () => decodeMsmFull,
|
|
121
124
|
deg2dms: () => deg2dms,
|
|
122
125
|
deg2rad: () => deg2rad,
|
|
123
126
|
ecefToAzEl: () => ecefToAzEl,
|
|
124
127
|
ecefToGeodetic: () => ecefToGeodetic,
|
|
128
|
+
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
125
129
|
euclidean3D: () => euclidean3D,
|
|
126
130
|
fetchSourcetable: () => fetchSourcetable,
|
|
127
131
|
fmtF: () => fmtF,
|
|
@@ -189,6 +193,7 @@ __export(src_exports, {
|
|
|
189
193
|
greatCircleMidpoint: () => greatCircleMidpoint,
|
|
190
194
|
hdrLine: () => hdrLine,
|
|
191
195
|
horizonDistance: () => horizonDistance,
|
|
196
|
+
ionoFree: () => ionoFree,
|
|
192
197
|
keplerPosition: () => keplerPosition,
|
|
193
198
|
msmEpochToDate: () => msmEpochToDate,
|
|
194
199
|
navTimesFromEph: () => navTimesFromEph,
|
|
@@ -211,11 +216,14 @@ __export(src_exports, {
|
|
|
211
216
|
resetGloFreqCache: () => resetGloFreqCache,
|
|
212
217
|
rhumbLine: () => rhumbLine,
|
|
213
218
|
rtcm3Constellation: () => rtcm3Constellation,
|
|
219
|
+
satClockCorrection: () => satClockCorrection,
|
|
214
220
|
selectEphemeris: () => selectEphemeris,
|
|
215
221
|
setGloFreqNumber: () => setGloFreqNumber,
|
|
216
222
|
setRtcm3DebugHandler: () => setRtcm3DebugHandler,
|
|
223
|
+
solveSpp: () => solveSpp,
|
|
217
224
|
systemCmp: () => systemCmp,
|
|
218
225
|
systemName: () => systemName,
|
|
226
|
+
transformFrame: () => transformFrame,
|
|
219
227
|
updateStationMeta: () => updateStationMeta,
|
|
220
228
|
updateStreamStats: () => updateStreamStats,
|
|
221
229
|
verifyChecksum: () => verifyChecksum,
|
|
@@ -4129,17 +4137,17 @@ function ecefToAzEl(rxX, rxY, rxZ, satX, satY, satZ) {
|
|
|
4129
4137
|
function computeDop(satAzEls) {
|
|
4130
4138
|
const n = satAzEls.length;
|
|
4131
4139
|
if (n < 4) return null;
|
|
4132
|
-
const
|
|
4140
|
+
const H2 = [];
|
|
4133
4141
|
for (const { az, el } of satAzEls) {
|
|
4134
4142
|
const cosEl = Math.cos(el);
|
|
4135
|
-
|
|
4143
|
+
H2.push([cosEl * Math.sin(az), cosEl * Math.cos(az), Math.sin(el), 1]);
|
|
4136
4144
|
}
|
|
4137
4145
|
const HtH = Array.from({ length: 4 }, () => new Array(4).fill(0));
|
|
4138
4146
|
for (let i = 0; i < 4; i++) {
|
|
4139
4147
|
for (let j = 0; j < 4; j++) {
|
|
4140
4148
|
let sum = 0;
|
|
4141
4149
|
for (let k = 0; k < n; k++) {
|
|
4142
|
-
sum +=
|
|
4150
|
+
sum += H2[k][i] * H2[k][j];
|
|
4143
4151
|
}
|
|
4144
4152
|
HtH[i][j] = sum;
|
|
4145
4153
|
}
|
|
@@ -4192,7 +4200,8 @@ function selectEphemeris(ephemerides, prn, timeMs) {
|
|
|
4192
4200
|
if (eph.prn !== prn) continue;
|
|
4193
4201
|
const ephTime = eph.tocDate.getTime();
|
|
4194
4202
|
const dt = Math.abs(timeMs - ephTime);
|
|
4195
|
-
|
|
4203
|
+
const maxAge = eph.system === "R" || eph.system === "S" ? 18e5 : 4 * 36e5;
|
|
4204
|
+
if (dt > maxAge) continue;
|
|
4196
4205
|
if (dt < bestDt) {
|
|
4197
4206
|
bestDt = dt;
|
|
4198
4207
|
best = eph;
|
|
@@ -4300,13 +4309,13 @@ function ephInfoToEphemeris(info) {
|
|
|
4300
4309
|
return null;
|
|
4301
4310
|
if (info.vx === void 0 || info.vy === void 0 || info.vz === void 0)
|
|
4302
4311
|
return null;
|
|
4303
|
-
const
|
|
4312
|
+
const moscow = new Date(info.lastReceived + 3 * 3600 * 1e3);
|
|
4304
4313
|
const utcMidnight = Date.UTC(
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4314
|
+
moscow.getUTCFullYear(),
|
|
4315
|
+
moscow.getUTCMonth(),
|
|
4316
|
+
moscow.getUTCDate()
|
|
4308
4317
|
);
|
|
4309
|
-
const tbSec = (info.tb ?? 0) *
|
|
4318
|
+
const tbSec = (info.tb ?? 0) * 60;
|
|
4310
4319
|
const moscowOffset = 3 * 3600;
|
|
4311
4320
|
const tocMs = utcMidnight + (tbSec - moscowOffset) * 1e3;
|
|
4312
4321
|
return {
|
|
@@ -4469,6 +4478,415 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
4469
4478
|
return { times, elevation, visibleCount, pdop, passes };
|
|
4470
4479
|
}
|
|
4471
4480
|
|
|
4481
|
+
// src/frames/index.ts
|
|
4482
|
+
var H = (t, d, r, tDot, dDot, rDot, epoch) => ({ t, d, r, tDot, dDot, rDot, epoch });
|
|
4483
|
+
var Z = [0, 0, 0];
|
|
4484
|
+
var FROM_ITRF2020 = {
|
|
4485
|
+
ITRF2014: H([-1.4, -0.9, 1.4], -0.42, Z, [0, -0.1, 0.2], 0, Z, 2015),
|
|
4486
|
+
ITRF2008: H([0.2, 1, 3.3], -0.29, Z, [0, -0.1, 0.1], 0.03, Z, 2015),
|
|
4487
|
+
ITRF2005: H([2.7, 0.1, -1.4], 0.65, Z, [0.3, -0.1, 0.1], 0.03, Z, 2015),
|
|
4488
|
+
ITRF2000: H([-0.2, 0.8, -34.2], 2.25, Z, [0.1, 0, -1.7], 0.11, Z, 2015),
|
|
4489
|
+
ITRF97: H(
|
|
4490
|
+
[6.5, -3.9, -77.9],
|
|
4491
|
+
3.98,
|
|
4492
|
+
[0, 0, 0.36],
|
|
4493
|
+
[0.1, -0.6, -3.1],
|
|
4494
|
+
0.12,
|
|
4495
|
+
[0, 0, 0.02],
|
|
4496
|
+
2015
|
|
4497
|
+
),
|
|
4498
|
+
ITRF96: H(
|
|
4499
|
+
[6.5, -3.9, -77.9],
|
|
4500
|
+
3.98,
|
|
4501
|
+
[0, 0, 0.36],
|
|
4502
|
+
[0.1, -0.6, -3.1],
|
|
4503
|
+
0.12,
|
|
4504
|
+
[0, 0, 0.02],
|
|
4505
|
+
2015
|
|
4506
|
+
),
|
|
4507
|
+
ITRF94: H(
|
|
4508
|
+
[6.5, -3.9, -77.9],
|
|
4509
|
+
3.98,
|
|
4510
|
+
[0, 0, 0.36],
|
|
4511
|
+
[0.1, -0.6, -3.1],
|
|
4512
|
+
0.12,
|
|
4513
|
+
[0, 0, 0.02],
|
|
4514
|
+
2015
|
|
4515
|
+
),
|
|
4516
|
+
ITRF93: H(
|
|
4517
|
+
[-65.8, 1.9, -71.3],
|
|
4518
|
+
4.47,
|
|
4519
|
+
[-3.36, -4.33, 0.75],
|
|
4520
|
+
[-2.8, -0.2, -2.3],
|
|
4521
|
+
0.12,
|
|
4522
|
+
[-0.11, -0.19, 0.07],
|
|
4523
|
+
2015
|
|
4524
|
+
),
|
|
4525
|
+
ITRF92: H(
|
|
4526
|
+
[14.5, -1.9, -85.9],
|
|
4527
|
+
3.27,
|
|
4528
|
+
[0, 0, 0.36],
|
|
4529
|
+
[0.1, -0.6, -3.1],
|
|
4530
|
+
0.12,
|
|
4531
|
+
[0, 0, 0.02],
|
|
4532
|
+
2015
|
|
4533
|
+
),
|
|
4534
|
+
ITRF91: H(
|
|
4535
|
+
[26.5, 12.1, -91.9],
|
|
4536
|
+
4.67,
|
|
4537
|
+
[0, 0, 0.36],
|
|
4538
|
+
[0.1, -0.6, -3.1],
|
|
4539
|
+
0.12,
|
|
4540
|
+
[0, 0, 0.02],
|
|
4541
|
+
2015
|
|
4542
|
+
),
|
|
4543
|
+
ITRF90: H(
|
|
4544
|
+
[24.5, 8.1, -107.9],
|
|
4545
|
+
4.97,
|
|
4546
|
+
[0, 0, 0.36],
|
|
4547
|
+
[0.1, -0.6, -3.1],
|
|
4548
|
+
0.12,
|
|
4549
|
+
[0, 0, 0.02],
|
|
4550
|
+
2015
|
|
4551
|
+
),
|
|
4552
|
+
ITRF89: H(
|
|
4553
|
+
[29.5, 32.1, -145.9],
|
|
4554
|
+
8.37,
|
|
4555
|
+
[0, 0, 0.36],
|
|
4556
|
+
[0.1, -0.6, -3.1],
|
|
4557
|
+
0.12,
|
|
4558
|
+
[0, 0, 0.02],
|
|
4559
|
+
2015
|
|
4560
|
+
),
|
|
4561
|
+
ITRF88: H(
|
|
4562
|
+
[24.5, -3.9, -169.9],
|
|
4563
|
+
11.47,
|
|
4564
|
+
[0.1, 0, 0.36],
|
|
4565
|
+
[0.1, -0.6, -3.1],
|
|
4566
|
+
0.12,
|
|
4567
|
+
[0, 0, 0.02],
|
|
4568
|
+
2015
|
|
4569
|
+
),
|
|
4570
|
+
/** ITRF2020 → ETRF2020, EPSG:10572 (epoch-1989 variant) */
|
|
4571
|
+
ETRF2020: H(Z, 0, Z, Z, 0, [0.086, 0.519, -0.753], 1989)
|
|
4572
|
+
};
|
|
4573
|
+
var ITRF2014_TO_ETRF2014 = H(Z, 0, Z, Z, 0, [0.085, 0.531, -0.77], 1989);
|
|
4574
|
+
var ITRF2014_TO_ETRF2000 = H(
|
|
4575
|
+
[54.7, 52.2, -74.1],
|
|
4576
|
+
2.12,
|
|
4577
|
+
[1.701, 10.29, -16.632],
|
|
4578
|
+
[0.1, 0.1, -1.9],
|
|
4579
|
+
0.11,
|
|
4580
|
+
[0.081, 0.49, -0.792],
|
|
4581
|
+
2010
|
|
4582
|
+
);
|
|
4583
|
+
var ITRF2014_TO_NAD83_2011 = H(
|
|
4584
|
+
[1005.3, -1909.21, -541.57],
|
|
4585
|
+
0.36891,
|
|
4586
|
+
[-26.78138, 0.42027, -10.93206],
|
|
4587
|
+
[0.79, -0.6, -1.44],
|
|
4588
|
+
-0.07201,
|
|
4589
|
+
[-0.06667, 0.75744, 0.05133],
|
|
4590
|
+
2010
|
|
4591
|
+
);
|
|
4592
|
+
var MAS_TO_RAD = Math.PI / (180 * 3600 * 1e3);
|
|
4593
|
+
function applyHelmert(xyz, p, epoch, inverse = false) {
|
|
4594
|
+
const dt = epoch - p.epoch;
|
|
4595
|
+
const sign = inverse ? -1 : 1;
|
|
4596
|
+
const tx = sign * (p.t[0] + p.tDot[0] * dt) / 1e3;
|
|
4597
|
+
const ty = sign * (p.t[1] + p.tDot[1] * dt) / 1e3;
|
|
4598
|
+
const tz = sign * (p.t[2] + p.tDot[2] * dt) / 1e3;
|
|
4599
|
+
const d = sign * (p.d + p.dDot * dt) * 1e-9;
|
|
4600
|
+
const rx = sign * (p.r[0] + p.rDot[0] * dt) * MAS_TO_RAD;
|
|
4601
|
+
const ry = sign * (p.r[1] + p.rDot[1] * dt) * MAS_TO_RAD;
|
|
4602
|
+
const rz = sign * (p.r[2] + p.rDot[2] * dt) * MAS_TO_RAD;
|
|
4603
|
+
const [x, y, z] = xyz;
|
|
4604
|
+
return [
|
|
4605
|
+
x + tx + d * x - rz * y + ry * z,
|
|
4606
|
+
y + ty + rz * x + d * y - rx * z,
|
|
4607
|
+
z + tz - ry * x + rx * y + d * z
|
|
4608
|
+
];
|
|
4609
|
+
}
|
|
4610
|
+
var EDGES = [
|
|
4611
|
+
...Object.entries(FROM_ITRF2020).map(([to, p]) => ({
|
|
4612
|
+
from: "ITRF2020",
|
|
4613
|
+
to,
|
|
4614
|
+
p
|
|
4615
|
+
})),
|
|
4616
|
+
{ from: "ITRF2014", to: "ETRF2014", p: ITRF2014_TO_ETRF2014 },
|
|
4617
|
+
{ from: "ITRF2014", to: "ETRF2000", p: ITRF2014_TO_ETRF2000 },
|
|
4618
|
+
{ from: "ITRF2014", to: "NAD83(2011)", p: ITRF2014_TO_NAD83_2011 }
|
|
4619
|
+
];
|
|
4620
|
+
var REFERENCE_FRAMES = [
|
|
4621
|
+
"WGS84",
|
|
4622
|
+
"ITRF2020",
|
|
4623
|
+
"ITRF2014",
|
|
4624
|
+
"ITRF2008",
|
|
4625
|
+
"ITRF2005",
|
|
4626
|
+
"ITRF2000",
|
|
4627
|
+
"ITRF97",
|
|
4628
|
+
"ITRF96",
|
|
4629
|
+
"ITRF94",
|
|
4630
|
+
"ITRF93",
|
|
4631
|
+
"ITRF92",
|
|
4632
|
+
"ITRF91",
|
|
4633
|
+
"ITRF90",
|
|
4634
|
+
"ITRF89",
|
|
4635
|
+
"ITRF88",
|
|
4636
|
+
"ETRF2020",
|
|
4637
|
+
"ETRF2014",
|
|
4638
|
+
"ETRF2000",
|
|
4639
|
+
"NAD83(2011)"
|
|
4640
|
+
];
|
|
4641
|
+
function resolveAlias(f) {
|
|
4642
|
+
return f === "WGS84" ? "ITRF2020" : f;
|
|
4643
|
+
}
|
|
4644
|
+
function findPath(from, to) {
|
|
4645
|
+
if (from === to) return [];
|
|
4646
|
+
const queue = [from];
|
|
4647
|
+
const cameFrom = /* @__PURE__ */ new Map();
|
|
4648
|
+
const seen = /* @__PURE__ */ new Set([from]);
|
|
4649
|
+
while (queue.length > 0) {
|
|
4650
|
+
const cur = queue.shift();
|
|
4651
|
+
for (const edge of EDGES) {
|
|
4652
|
+
let next = null;
|
|
4653
|
+
let inverse = false;
|
|
4654
|
+
if (edge.from === cur) {
|
|
4655
|
+
next = edge.to;
|
|
4656
|
+
} else if (edge.to === cur) {
|
|
4657
|
+
next = edge.from;
|
|
4658
|
+
inverse = true;
|
|
4659
|
+
}
|
|
4660
|
+
if (next === null || seen.has(next)) continue;
|
|
4661
|
+
seen.add(next);
|
|
4662
|
+
cameFrom.set(next, { prev: cur, edge, inverse });
|
|
4663
|
+
if (next === to) {
|
|
4664
|
+
const path = [];
|
|
4665
|
+
let node = to;
|
|
4666
|
+
while (node !== from) {
|
|
4667
|
+
const step = cameFrom.get(node);
|
|
4668
|
+
path.unshift({ edge: step.edge, inverse: step.inverse });
|
|
4669
|
+
node = step.prev;
|
|
4670
|
+
}
|
|
4671
|
+
return path;
|
|
4672
|
+
}
|
|
4673
|
+
queue.push(next);
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
return null;
|
|
4677
|
+
}
|
|
4678
|
+
function transformFrame(xyz, from, to, epoch) {
|
|
4679
|
+
const src = resolveAlias(from);
|
|
4680
|
+
const dst = resolveAlias(to);
|
|
4681
|
+
const path = findPath(src, dst);
|
|
4682
|
+
if (!path) {
|
|
4683
|
+
throw new Error(`No transformation path from ${from} to ${to}`);
|
|
4684
|
+
}
|
|
4685
|
+
let out = [xyz[0], xyz[1], xyz[2]];
|
|
4686
|
+
for (const { edge, inverse } of path) {
|
|
4687
|
+
out = applyHelmert(out, edge.p, epoch, inverse);
|
|
4688
|
+
}
|
|
4689
|
+
return out;
|
|
4690
|
+
}
|
|
4691
|
+
function dateToEpoch(date) {
|
|
4692
|
+
const year = date.getUTCFullYear();
|
|
4693
|
+
const start = Date.UTC(year, 0, 1);
|
|
4694
|
+
const end = Date.UTC(year + 1, 0, 1);
|
|
4695
|
+
return year + (date.getTime() - start) / (end - start);
|
|
4696
|
+
}
|
|
4697
|
+
|
|
4698
|
+
// src/positioning/index.ts
|
|
4699
|
+
var GM_GPS2 = 3986005e8;
|
|
4700
|
+
var F_REL = -4442807633e-19;
|
|
4701
|
+
function satClockCorrection(eph, tMs) {
|
|
4702
|
+
if (eph.system === "R" || eph.system === "S") {
|
|
4703
|
+
const dt2 = (tMs - eph.tocDate.getTime()) / 1e3;
|
|
4704
|
+
return eph.tauN + eph.gammaN * dt2;
|
|
4705
|
+
}
|
|
4706
|
+
const k = eph;
|
|
4707
|
+
const dt = (tMs - k.tocDate.getTime()) / 1e3;
|
|
4708
|
+
const poly = k.af0 + k.af1 * dt + k.af2 * dt * dt;
|
|
4709
|
+
const a = k.sqrtA * k.sqrtA;
|
|
4710
|
+
const n = Math.sqrt(GM_GPS2 / (a * a * a)) + k.deltaN;
|
|
4711
|
+
const tk = dt;
|
|
4712
|
+
const Mk = k.m0 + n * tk;
|
|
4713
|
+
let Ek = Mk;
|
|
4714
|
+
for (let i = 0; i < 8; i++) {
|
|
4715
|
+
Ek = Mk + k.e * Math.sin(Ek);
|
|
4716
|
+
}
|
|
4717
|
+
const rel = F_REL * k.e * k.sqrtA * Math.sin(Ek);
|
|
4718
|
+
return poly + rel;
|
|
4719
|
+
}
|
|
4720
|
+
function ionoFree(p1, p2, f1, f2) {
|
|
4721
|
+
const g = f1 * f1 / (f1 * f1 - f2 * f2);
|
|
4722
|
+
return g * p1 - (g - 1) * p2;
|
|
4723
|
+
}
|
|
4724
|
+
function tropoDelay(elevationRad) {
|
|
4725
|
+
const sinEl = Math.sin(elevationRad);
|
|
4726
|
+
return 2.47 / (sinEl + 0.0121);
|
|
4727
|
+
}
|
|
4728
|
+
function sagnac(pos, travelTimeS) {
|
|
4729
|
+
const OMEGA_E2 = 72921151467e-15;
|
|
4730
|
+
const theta = OMEGA_E2 * travelTimeS;
|
|
4731
|
+
const c = Math.cos(theta);
|
|
4732
|
+
const s = Math.sin(theta);
|
|
4733
|
+
return [pos.x * c + pos.y * s, -pos.x * s + pos.y * c, pos.z];
|
|
4734
|
+
}
|
|
4735
|
+
function solveLinear(A, b) {
|
|
4736
|
+
const n = b.length;
|
|
4737
|
+
const M = A.map((row, i) => [...row, b[i]]);
|
|
4738
|
+
for (let col = 0; col < n; col++) {
|
|
4739
|
+
let pivot = col;
|
|
4740
|
+
for (let r = col + 1; r < n; r++) {
|
|
4741
|
+
if (Math.abs(M[r][col]) > Math.abs(M[pivot][col])) pivot = r;
|
|
4742
|
+
}
|
|
4743
|
+
if (Math.abs(M[pivot][col]) < 1e-12) return null;
|
|
4744
|
+
[M[col], M[pivot]] = [M[pivot], M[col]];
|
|
4745
|
+
for (let r = 0; r < n; r++) {
|
|
4746
|
+
if (r === col) continue;
|
|
4747
|
+
const f = M[r][col] / M[col][col];
|
|
4748
|
+
for (let c = col; c <= n; c++) M[r][c] -= f * M[col][c];
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
return M.map((row, i) => row[n] / M[i][i]);
|
|
4752
|
+
}
|
|
4753
|
+
function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
4754
|
+
const {
|
|
4755
|
+
elevationMaskDeg = 10,
|
|
4756
|
+
troposphere = true,
|
|
4757
|
+
maxIterations = 15,
|
|
4758
|
+
convergenceM = 1e-4,
|
|
4759
|
+
tgd = true
|
|
4760
|
+
} = opts;
|
|
4761
|
+
const all = [...pseudoranges.keys()].filter((p) => ephemerides.has(p));
|
|
4762
|
+
const minSats = (list) => 3 + new Set(list.map((p) => p[0])).size;
|
|
4763
|
+
if (all.length < minSats(all)) return null;
|
|
4764
|
+
const gaussNewton = (prns) => {
|
|
4765
|
+
const systems = [...new Set(prns.map((p) => p[0]))].sort();
|
|
4766
|
+
const dim = 3 + systems.length;
|
|
4767
|
+
const sysIndex = new Map(systems.map((s, i) => [s, 3 + i]));
|
|
4768
|
+
let x2 = 0;
|
|
4769
|
+
let y2 = 0;
|
|
4770
|
+
let z2 = 0;
|
|
4771
|
+
const clock2 = new Map(systems.map((s) => [s, 0]));
|
|
4772
|
+
const residuals2 = {};
|
|
4773
|
+
let iterations2 = 0;
|
|
4774
|
+
let converged2 = false;
|
|
4775
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
4776
|
+
iterations2 = iter + 1;
|
|
4777
|
+
const HtH = Array.from(
|
|
4778
|
+
{ length: dim },
|
|
4779
|
+
() => new Array(dim).fill(0)
|
|
4780
|
+
);
|
|
4781
|
+
const Htv = new Array(dim).fill(0);
|
|
4782
|
+
let rows = 0;
|
|
4783
|
+
for (const k of Object.keys(residuals2)) delete residuals2[k];
|
|
4784
|
+
for (const prn of prns) {
|
|
4785
|
+
const psr = pseudoranges.get(prn);
|
|
4786
|
+
const eph = ephemerides.get(prn);
|
|
4787
|
+
const sys = prn[0];
|
|
4788
|
+
const clk = clock2.get(sys);
|
|
4789
|
+
const tTx = timeMs - psr / C_LIGHT * 1e3;
|
|
4790
|
+
const dtsClock = satClockCorrection(eph, tTx);
|
|
4791
|
+
const sat = computeSatPosition(eph, tTx - dtsClock * 1e3);
|
|
4792
|
+
if (!Number.isFinite(sat.x)) continue;
|
|
4793
|
+
const isKepler2 = eph.system !== "R" && eph.system !== "S";
|
|
4794
|
+
const dts = dtsClock - (tgd && isKepler2 ? eph.tgd : 0);
|
|
4795
|
+
const travel = Math.hypot(sat.x - x2, sat.y - y2, sat.z - z2) / C_LIGHT;
|
|
4796
|
+
const [sx, sy, sz] = sagnac(sat, travel);
|
|
4797
|
+
const rho = Math.hypot(sx - x2, sy - y2, sz - z2);
|
|
4798
|
+
const ux = (x2 - sx) / rho;
|
|
4799
|
+
const uy = (y2 - sy) / rho;
|
|
4800
|
+
const uz = (z2 - sz) / rho;
|
|
4801
|
+
let elev = Math.PI / 2;
|
|
4802
|
+
let weight = 1;
|
|
4803
|
+
const positionSane = x2 * x2 + y2 * y2 + z2 * z2 > 1e12;
|
|
4804
|
+
if (positionSane) {
|
|
4805
|
+
const azel = ecefToAzEl(x2, y2, z2, sx, sy, sz);
|
|
4806
|
+
elev = azel.el;
|
|
4807
|
+
if (iter >= 2 && elev < elevationMaskDeg * Math.PI / 180) continue;
|
|
4808
|
+
const sinEl = Math.max(Math.sin(elev), 0.1);
|
|
4809
|
+
weight = sinEl * sinEl;
|
|
4810
|
+
}
|
|
4811
|
+
const tropo = troposphere && positionSane ? tropoDelay(elev) : 0;
|
|
4812
|
+
const predicted = rho + clk - C_LIGHT * dts + tropo;
|
|
4813
|
+
const v = psr - predicted;
|
|
4814
|
+
const h = new Array(dim).fill(0);
|
|
4815
|
+
h[0] = ux;
|
|
4816
|
+
h[1] = uy;
|
|
4817
|
+
h[2] = uz;
|
|
4818
|
+
h[sysIndex.get(sys)] = 1;
|
|
4819
|
+
for (let i = 0; i < dim; i++) {
|
|
4820
|
+
for (let j = 0; j < dim; j++) HtH[i][j] += weight * h[i] * h[j];
|
|
4821
|
+
Htv[i] += weight * h[i] * v;
|
|
4822
|
+
}
|
|
4823
|
+
residuals2[prn] = v;
|
|
4824
|
+
rows++;
|
|
4825
|
+
}
|
|
4826
|
+
if (rows < dim) return null;
|
|
4827
|
+
const dx = solveLinear(HtH, Htv);
|
|
4828
|
+
if (!dx) return null;
|
|
4829
|
+
x2 += dx[0];
|
|
4830
|
+
y2 += dx[1];
|
|
4831
|
+
z2 += dx[2];
|
|
4832
|
+
for (const s of systems)
|
|
4833
|
+
clock2.set(s, clock2.get(s) + dx[sysIndex.get(s)]);
|
|
4834
|
+
if (Math.hypot(dx[0], dx[1], dx[2]) < convergenceM) {
|
|
4835
|
+
converged2 = true;
|
|
4836
|
+
break;
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
return { x: x2, y: y2, z: z2, clock: clock2, residuals: residuals2, iterations: iterations2, converged: converged2 };
|
|
4840
|
+
};
|
|
4841
|
+
const REJECT_THRESHOLD_M = 50;
|
|
4842
|
+
let candidates = all;
|
|
4843
|
+
const rejected = [];
|
|
4844
|
+
let inner = null;
|
|
4845
|
+
for (let round = 0; round <= all.length; round++) {
|
|
4846
|
+
inner = gaussNewton(candidates);
|
|
4847
|
+
if (!inner) return null;
|
|
4848
|
+
const vals = Object.entries(inner.residuals);
|
|
4849
|
+
let worst = null;
|
|
4850
|
+
let worstAbs = REJECT_THRESHOLD_M;
|
|
4851
|
+
for (const [prn, v] of vals) {
|
|
4852
|
+
if (Math.abs(v) > worstAbs) {
|
|
4853
|
+
worstAbs = Math.abs(v);
|
|
4854
|
+
worst = prn;
|
|
4855
|
+
}
|
|
4856
|
+
}
|
|
4857
|
+
if (!worst) break;
|
|
4858
|
+
const remaining = candidates.filter((p) => p !== worst);
|
|
4859
|
+
if (remaining.length < minSats(remaining)) break;
|
|
4860
|
+
rejected.push(worst);
|
|
4861
|
+
candidates = remaining;
|
|
4862
|
+
}
|
|
4863
|
+
if (!inner) return null;
|
|
4864
|
+
const { x, y, z, clock, residuals, iterations, converged } = inner;
|
|
4865
|
+
const used = [];
|
|
4866
|
+
const azels = [];
|
|
4867
|
+
for (const prn of candidates) {
|
|
4868
|
+
if (!(prn in residuals)) continue;
|
|
4869
|
+
const eph = ephemerides.get(prn);
|
|
4870
|
+
const sat = computeSatPosition(eph, timeMs);
|
|
4871
|
+
if (!Number.isFinite(sat.x)) continue;
|
|
4872
|
+
const azel = ecefToAzEl(x, y, z, sat.x, sat.y, sat.z);
|
|
4873
|
+
if (azel.el >= elevationMaskDeg * Math.PI / 180) {
|
|
4874
|
+
used.push(prn);
|
|
4875
|
+
azels.push(azel);
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
return {
|
|
4879
|
+
position: [x, y, z],
|
|
4880
|
+
clockBias: Object.fromEntries(clock),
|
|
4881
|
+
usedSatellites: used,
|
|
4882
|
+
rejectedSatellites: rejected,
|
|
4883
|
+
residuals,
|
|
4884
|
+
dop: computeDop(azels),
|
|
4885
|
+
iterations,
|
|
4886
|
+
converged
|
|
4887
|
+
};
|
|
4888
|
+
}
|
|
4889
|
+
|
|
4472
4890
|
// src/ntrip/index.ts
|
|
4473
4891
|
function parseStreamEntry(fields) {
|
|
4474
4892
|
if (fields.length < 19) return null;
|
|
@@ -6345,6 +6763,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
6345
6763
|
MILLISECONDS_IN_WEEK,
|
|
6346
6764
|
MILLISECONDS_TT_TAI,
|
|
6347
6765
|
MultipathAccumulator,
|
|
6766
|
+
REFERENCE_FRAMES,
|
|
6348
6767
|
RINEX_CODES,
|
|
6349
6768
|
RTCM3_MESSAGE_NAMES,
|
|
6350
6769
|
Rtcm3Decoder,
|
|
@@ -6371,6 +6790,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
6371
6790
|
WGS84_SEMI_MINOR_AXIS,
|
|
6372
6791
|
WarningAccumulator,
|
|
6373
6792
|
analyzeQuality,
|
|
6793
|
+
applyHelmert,
|
|
6374
6794
|
buildGloChannelMap,
|
|
6375
6795
|
buildObsIndices,
|
|
6376
6796
|
clampUnit,
|
|
@@ -6386,12 +6806,14 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
6386
6806
|
createStreamStats,
|
|
6387
6807
|
crxDecompress,
|
|
6388
6808
|
crxRepair,
|
|
6809
|
+
dateToEpoch,
|
|
6389
6810
|
decodeEphemeris,
|
|
6390
6811
|
decodeMsmFull,
|
|
6391
6812
|
deg2dms,
|
|
6392
6813
|
deg2rad,
|
|
6393
6814
|
ecefToAzEl,
|
|
6394
6815
|
ecefToGeodetic,
|
|
6816
|
+
ephInfoToEphemeris,
|
|
6395
6817
|
euclidean3D,
|
|
6396
6818
|
fetchSourcetable,
|
|
6397
6819
|
fmtF,
|
|
@@ -6459,6 +6881,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
6459
6881
|
greatCircleMidpoint,
|
|
6460
6882
|
hdrLine,
|
|
6461
6883
|
horizonDistance,
|
|
6884
|
+
ionoFree,
|
|
6462
6885
|
keplerPosition,
|
|
6463
6886
|
msmEpochToDate,
|
|
6464
6887
|
navTimesFromEph,
|
|
@@ -6481,11 +6904,14 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
6481
6904
|
resetGloFreqCache,
|
|
6482
6905
|
rhumbLine,
|
|
6483
6906
|
rtcm3Constellation,
|
|
6907
|
+
satClockCorrection,
|
|
6484
6908
|
selectEphemeris,
|
|
6485
6909
|
setGloFreqNumber,
|
|
6486
6910
|
setRtcm3DebugHandler,
|
|
6911
|
+
solveSpp,
|
|
6487
6912
|
systemCmp,
|
|
6488
6913
|
systemName,
|
|
6914
|
+
transformFrame,
|
|
6489
6915
|
updateStationMeta,
|
|
6490
6916
|
updateStreamStats,
|
|
6491
6917
|
verifyChecksum,
|
package/dist/index.d.cts
CHANGED
|
@@ -9,7 +9,9 @@ export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResul
|
|
|
9
9
|
export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.cjs';
|
|
10
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.cjs';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.cjs';
|
|
13
|
+
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
|
|
14
|
+
export { SppOptions, SppSolution, ionoFree, satClockCorrection, solveSpp } from './positioning.cjs';
|
|
13
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
|
|
14
16
|
export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, analyzeQuality } from './analysis.cjs';
|
|
15
17
|
export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResul
|
|
|
9
9
|
export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.js';
|
|
10
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.js';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.js';
|
|
13
|
+
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
|
|
14
|
+
export { SppOptions, SppSolution, ionoFree, satClockCorrection, solveSpp } from './positioning.js';
|
|
13
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
|
|
14
16
|
export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, analyzeQuality } from './analysis.js';
|
|
15
17
|
export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.js';
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,17 @@ import {
|
|
|
87
87
|
rhumbLine,
|
|
88
88
|
vincenty
|
|
89
89
|
} from "./chunk-MIIM4LDY.js";
|
|
90
|
+
import {
|
|
91
|
+
REFERENCE_FRAMES,
|
|
92
|
+
applyHelmert,
|
|
93
|
+
dateToEpoch,
|
|
94
|
+
transformFrame
|
|
95
|
+
} from "./chunk-4KOXMHUW.js";
|
|
96
|
+
import {
|
|
97
|
+
ionoFree,
|
|
98
|
+
satClockCorrection,
|
|
99
|
+
solveSpp
|
|
100
|
+
} from "./chunk-USHP4IND.js";
|
|
90
101
|
import {
|
|
91
102
|
computeAllPositions,
|
|
92
103
|
computeDop,
|
|
@@ -94,11 +105,12 @@ import {
|
|
|
94
105
|
computeSatPosition,
|
|
95
106
|
computeVisibility,
|
|
96
107
|
ecefToAzEl,
|
|
108
|
+
ephInfoToEphemeris,
|
|
97
109
|
glonassPosition,
|
|
98
110
|
keplerPosition,
|
|
99
111
|
navTimesFromEph,
|
|
100
112
|
selectEphemeris
|
|
101
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-CC2R4JGS.js";
|
|
102
114
|
import {
|
|
103
115
|
getBdsTime,
|
|
104
116
|
getDateFromBdsTime,
|
|
@@ -288,6 +300,7 @@ export {
|
|
|
288
300
|
MILLISECONDS_IN_WEEK,
|
|
289
301
|
MILLISECONDS_TT_TAI,
|
|
290
302
|
MultipathAccumulator,
|
|
303
|
+
REFERENCE_FRAMES,
|
|
291
304
|
RINEX_CODES,
|
|
292
305
|
RTCM3_MESSAGE_NAMES,
|
|
293
306
|
Rtcm3Decoder,
|
|
@@ -314,6 +327,7 @@ export {
|
|
|
314
327
|
WGS84_SEMI_MINOR_AXIS,
|
|
315
328
|
WarningAccumulator,
|
|
316
329
|
analyzeQuality,
|
|
330
|
+
applyHelmert,
|
|
317
331
|
buildGloChannelMap,
|
|
318
332
|
buildObsIndices,
|
|
319
333
|
clampUnit,
|
|
@@ -329,12 +343,14 @@ export {
|
|
|
329
343
|
createStreamStats,
|
|
330
344
|
crxDecompress,
|
|
331
345
|
crxRepair,
|
|
346
|
+
dateToEpoch,
|
|
332
347
|
decodeEphemeris,
|
|
333
348
|
decodeMsmFull,
|
|
334
349
|
deg2dms,
|
|
335
350
|
deg2rad,
|
|
336
351
|
ecefToAzEl,
|
|
337
352
|
ecefToGeodetic,
|
|
353
|
+
ephInfoToEphemeris,
|
|
338
354
|
euclidean3D,
|
|
339
355
|
fetchSourcetable,
|
|
340
356
|
fmtF,
|
|
@@ -402,6 +418,7 @@ export {
|
|
|
402
418
|
greatCircleMidpoint,
|
|
403
419
|
hdrLine,
|
|
404
420
|
horizonDistance,
|
|
421
|
+
ionoFree,
|
|
405
422
|
keplerPosition,
|
|
406
423
|
msmEpochToDate,
|
|
407
424
|
navTimesFromEph,
|
|
@@ -424,11 +441,14 @@ export {
|
|
|
424
441
|
resetGloFreqCache,
|
|
425
442
|
rhumbLine,
|
|
426
443
|
rtcm3Constellation,
|
|
444
|
+
satClockCorrection,
|
|
427
445
|
selectEphemeris,
|
|
428
446
|
setGloFreqNumber,
|
|
429
447
|
setRtcm3DebugHandler,
|
|
448
|
+
solveSpp,
|
|
430
449
|
systemCmp,
|
|
431
450
|
systemName,
|
|
451
|
+
transformFrame,
|
|
432
452
|
updateStationMeta,
|
|
433
453
|
updateStreamStats,
|
|
434
454
|
verifyChecksum,
|