gnss-js 1.48.0 → 1.49.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-ROVSSEGZ.js → chunk-2IM5JYKP.js} +1 -1
- package/dist/{chunk-EQNC24OB.js → chunk-DEVUKH6A.js} +2 -1
- package/dist/{chunk-KRXX4UGR.js → chunk-DWLVCXA6.js} +505 -11
- package/dist/{chunk-ZIGMN3E5.js → chunk-WQX354KD.js} +1 -0
- package/dist/{chunk-MEDAWNWM.js → chunk-XFPDTGSV.js} +1 -1
- package/dist/index.cjs +511 -22
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -7
- package/dist/novatel.js +2 -2
- package/dist/positioning.cjs +525 -14
- package/dist/positioning.d.cts +66 -1
- package/dist/positioning.d.ts +66 -1
- package/dist/positioning.js +6 -1
- package/dist/rinex.js +2 -2
- package/dist/sbf.js +2 -2
- package/dist/ubx.cjs +1 -0
- package/dist/ubx.d.cts +7 -0
- package/dist/ubx.d.ts +7 -0
- package/dist/ubx.js +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
parseUbxRawNav,
|
|
51
51
|
parseUbxRawx,
|
|
52
52
|
ubxFrames
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-DEVUKH6A.js";
|
|
54
54
|
import {
|
|
55
55
|
crc16,
|
|
56
56
|
decodeSbfNavigation,
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
parseSbfNav,
|
|
69
69
|
parseSbfReceiverSetup,
|
|
70
70
|
scanSbfFrames
|
|
71
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-XFPDTGSV.js";
|
|
72
72
|
import "./chunk-FA2UTLEQ.js";
|
|
73
73
|
import {
|
|
74
74
|
OEM4_HLEN,
|
|
@@ -76,8 +76,7 @@ import {
|
|
|
76
76
|
oem4Frames,
|
|
77
77
|
parseNovatelNav,
|
|
78
78
|
parseNovatelRange
|
|
79
|
-
} from "./chunk-
|
|
80
|
-
import "./chunk-ZIGMN3E5.js";
|
|
79
|
+
} from "./chunk-2IM5JYKP.js";
|
|
81
80
|
import {
|
|
82
81
|
parseTrimble,
|
|
83
82
|
parseTrimbleNav,
|
|
@@ -137,6 +136,7 @@ import {
|
|
|
137
136
|
import {
|
|
138
137
|
IONO_L1_M_PER_TECU,
|
|
139
138
|
RtkFloatEngine,
|
|
139
|
+
SbasProcessor,
|
|
140
140
|
buildPppAntenna,
|
|
141
141
|
createPppCorrections,
|
|
142
142
|
estimateNarrowlaneFcb,
|
|
@@ -164,7 +164,8 @@ import {
|
|
|
164
164
|
sunEcef,
|
|
165
165
|
toRtkEpoch,
|
|
166
166
|
wlWavelength
|
|
167
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-DWLVCXA6.js";
|
|
168
|
+
import "./chunk-WQX354KD.js";
|
|
168
169
|
import {
|
|
169
170
|
almanacEpochMs,
|
|
170
171
|
almanacSatPosition,
|
|
@@ -236,8 +237,6 @@ import {
|
|
|
236
237
|
writeRinexNav4,
|
|
237
238
|
writeRinexObsBlob
|
|
238
239
|
} from "./chunk-6SWJTN6H.js";
|
|
239
|
-
import "./chunk-YUW33VXK.js";
|
|
240
|
-
import "./chunk-V2D5KUKH.js";
|
|
241
240
|
import {
|
|
242
241
|
SYSTEM_ORDER,
|
|
243
242
|
crxDecompress,
|
|
@@ -253,6 +252,8 @@ import {
|
|
|
253
252
|
parseSp3,
|
|
254
253
|
sp3Position
|
|
255
254
|
} from "./chunk-GPEP67TG.js";
|
|
255
|
+
import "./chunk-YUW33VXK.js";
|
|
256
|
+
import "./chunk-V2D5KUKH.js";
|
|
256
257
|
import {
|
|
257
258
|
BitReader,
|
|
258
259
|
RTCM3_MESSAGE_NAMES,
|
|
@@ -435,6 +436,7 @@ export {
|
|
|
435
436
|
SYSTEM_NAMES,
|
|
436
437
|
SYSTEM_ORDER,
|
|
437
438
|
SYS_SHORT,
|
|
439
|
+
SbasProcessor,
|
|
438
440
|
Scale,
|
|
439
441
|
WGS84_ECCENTRICITY_SQUARED,
|
|
440
442
|
WGS84_FLATTENING,
|
package/dist/novatel.js
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
oem4Frames,
|
|
5
5
|
parseNovatelNav,
|
|
6
6
|
parseNovatelRange
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-2IM5JYKP.js";
|
|
8
|
+
import "./chunk-WQX354KD.js";
|
|
9
9
|
import "./chunk-YUW33VXK.js";
|
|
10
10
|
import "./chunk-V2D5KUKH.js";
|
|
11
11
|
import "./chunk-HVXYFUCB.js";
|
package/dist/positioning.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var positioning_exports = {};
|
|
|
22
22
|
__export(positioning_exports, {
|
|
23
23
|
IONO_L1_M_PER_TECU: () => IONO_L1_M_PER_TECU,
|
|
24
24
|
RtkFloatEngine: () => RtkFloatEngine,
|
|
25
|
+
SbasProcessor: () => SbasProcessor,
|
|
25
26
|
buildPppAntenna: () => buildPppAntenna,
|
|
26
27
|
createPppCorrections: () => createPppCorrections,
|
|
27
28
|
estimateNarrowlaneFcb: () => estimateNarrowlaneFcb,
|
|
@@ -450,8 +451,8 @@ function computeSatPosition(eph, timeMs) {
|
|
|
450
451
|
return glonassPosition(eph, (timeMs - leapMs) / 1e3);
|
|
451
452
|
}
|
|
452
453
|
const GPS_EPOCH = START_GPS_TIME.getTime();
|
|
453
|
-
const
|
|
454
|
-
let tow =
|
|
454
|
+
const gpsSeconds2 = (timeMs - GPS_EPOCH) / 1e3;
|
|
455
|
+
let tow = gpsSeconds2 % (7 * 86400);
|
|
455
456
|
if (eph.system === "C") tow = (tow - 14 + 604800) % 604800;
|
|
456
457
|
return keplerPosition(eph, tow);
|
|
457
458
|
}
|
|
@@ -501,8 +502,8 @@ function klobucharDelay(coeffs, latRad, lonRad, azRad, elRad, gpsTowSec) {
|
|
|
501
502
|
const F = 1 + 16 * Math.pow(0.53 - E, 3);
|
|
502
503
|
const x = 2 * Math.PI * (t - 50400) / per;
|
|
503
504
|
if (Math.abs(x) >= 1.57) return F * 5e-9;
|
|
504
|
-
const
|
|
505
|
-
return F * (5e-9 + amp * (1 -
|
|
505
|
+
const x22 = x * x;
|
|
506
|
+
return F * (5e-9 + amp * (1 - x22 / 2 + x22 * x22 / 24));
|
|
506
507
|
}
|
|
507
508
|
|
|
508
509
|
// src/positioning/gim.ts
|
|
@@ -1654,6 +1655,515 @@ function postProcessRtk(base, rover, ephemerides, baseEcef, opts = {}) {
|
|
|
1654
1655
|
return { track, solved, unmatched, fixRate: solved ? fixed / solved : 0 };
|
|
1655
1656
|
}
|
|
1656
1657
|
|
|
1658
|
+
// src/navbits/index.ts
|
|
1659
|
+
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
1660
|
+
var SEC_PER_WEEK = 7 * 86400;
|
|
1661
|
+
function getBitU(buff, pos, len) {
|
|
1662
|
+
let bits = 0;
|
|
1663
|
+
for (let i = pos; i < pos + len; i++) {
|
|
1664
|
+
bits = bits * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
|
|
1665
|
+
}
|
|
1666
|
+
return bits;
|
|
1667
|
+
}
|
|
1668
|
+
function getBitS(buff, pos, len) {
|
|
1669
|
+
const bits = getBitU(buff, pos, len);
|
|
1670
|
+
if (len <= 0 || bits < 2 ** (len - 1)) return bits;
|
|
1671
|
+
return bits - 2 ** len;
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// src/navbits/sbas.ts
|
|
1675
|
+
var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
|
|
1676
|
+
var MS_PER_WEEK2 = 7 * 86400 * 1e3;
|
|
1677
|
+
function sbasMessageType(msg) {
|
|
1678
|
+
return getBitU(msg, 8, 6);
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
// src/positioning/sbas.ts
|
|
1682
|
+
var P2_11 = 2 ** -11;
|
|
1683
|
+
var P2_31 = 2 ** -31;
|
|
1684
|
+
var P2_39 = 2 ** -39;
|
|
1685
|
+
var D2R = Math.PI / 180;
|
|
1686
|
+
var R2D = 180 / Math.PI;
|
|
1687
|
+
var SEC_PER_WEEK2 = 604800;
|
|
1688
|
+
var MAXSBSAGEF = 30;
|
|
1689
|
+
var MAXSBSAGEL = 1800;
|
|
1690
|
+
var MAXBAND = 10;
|
|
1691
|
+
var two = (n) => String(n).padStart(2, "0");
|
|
1692
|
+
var VAR_FCORR = [
|
|
1693
|
+
0.052,
|
|
1694
|
+
0.0924,
|
|
1695
|
+
0.1444,
|
|
1696
|
+
0.283,
|
|
1697
|
+
0.4678,
|
|
1698
|
+
0.8315,
|
|
1699
|
+
1.2992,
|
|
1700
|
+
1.8709,
|
|
1701
|
+
2.5465,
|
|
1702
|
+
3.326,
|
|
1703
|
+
5.1968,
|
|
1704
|
+
20.787,
|
|
1705
|
+
230.9661,
|
|
1706
|
+
2078.695
|
|
1707
|
+
];
|
|
1708
|
+
var varfcorr = (udre) => udre > 0 && udre <= 14 ? VAR_FCORR[udre - 1] : 0;
|
|
1709
|
+
var VAR_ICORR = [
|
|
1710
|
+
84e-4,
|
|
1711
|
+
0.0333,
|
|
1712
|
+
0.0749,
|
|
1713
|
+
0.1331,
|
|
1714
|
+
0.2079,
|
|
1715
|
+
0.2994,
|
|
1716
|
+
0.4075,
|
|
1717
|
+
0.5322,
|
|
1718
|
+
0.6735,
|
|
1719
|
+
0.8315,
|
|
1720
|
+
1.1974,
|
|
1721
|
+
1.8709,
|
|
1722
|
+
3.326,
|
|
1723
|
+
20.787,
|
|
1724
|
+
187.0826
|
|
1725
|
+
];
|
|
1726
|
+
var varicorr = (give) => give > 0 && give <= 15 ? VAR_ICORR[give - 1] : 0;
|
|
1727
|
+
var DEGF = [
|
|
1728
|
+
0,
|
|
1729
|
+
5e-5,
|
|
1730
|
+
9e-5,
|
|
1731
|
+
12e-5,
|
|
1732
|
+
15e-5,
|
|
1733
|
+
2e-4,
|
|
1734
|
+
3e-4,
|
|
1735
|
+
45e-5,
|
|
1736
|
+
6e-4,
|
|
1737
|
+
9e-4,
|
|
1738
|
+
15e-4,
|
|
1739
|
+
21e-4,
|
|
1740
|
+
27e-4,
|
|
1741
|
+
33e-4,
|
|
1742
|
+
46e-4,
|
|
1743
|
+
58e-4
|
|
1744
|
+
];
|
|
1745
|
+
var degfcorr = (ai) => ai > 0 && ai <= 15 ? DEGF[ai] : 58e-4;
|
|
1746
|
+
var x1 = [-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75, 85];
|
|
1747
|
+
var x2 = [-55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];
|
|
1748
|
+
var x3 = [-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75];
|
|
1749
|
+
var x4 = [-85, -75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75];
|
|
1750
|
+
var x5 = [-180, -175, -170, -165, -160, -155, -150, -145, -140, -135, -130, -125, -120, -115, -110, -105, -100, -95, -90, -85, -80, -75, -70, -65, -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175];
|
|
1751
|
+
var x6 = [-180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170];
|
|
1752
|
+
var x7 = [-180, -150, -120, -90, -60, -30, 0, 30, 60, 90, 120, 150];
|
|
1753
|
+
var x8 = [-170, -140, -110, -80, -50, -20, 10, 40, 70, 100, 130, 160];
|
|
1754
|
+
var igpband1 = [
|
|
1755
|
+
[{ coord: -180, arr: x1, bits: 1, bite: 28 }, { coord: -175, arr: x2, bits: 29, bite: 51 }, { coord: -170, arr: x3, bits: 52, bite: 78 }, { coord: -165, arr: x2, bits: 79, bite: 101 }, { coord: -160, arr: x3, bits: 102, bite: 128 }, { coord: -155, arr: x2, bits: 129, bite: 151 }, { coord: -150, arr: x3, bits: 152, bite: 178 }, { coord: -145, arr: x2, bits: 179, bite: 201 }],
|
|
1756
|
+
[{ coord: -140, arr: x4, bits: 1, bite: 28 }, { coord: -135, arr: x2, bits: 29, bite: 51 }, { coord: -130, arr: x3, bits: 52, bite: 78 }, { coord: -125, arr: x2, bits: 79, bite: 101 }, { coord: -120, arr: x3, bits: 102, bite: 128 }, { coord: -115, arr: x2, bits: 129, bite: 151 }, { coord: -110, arr: x3, bits: 152, bite: 178 }, { coord: -105, arr: x2, bits: 179, bite: 201 }],
|
|
1757
|
+
[{ coord: -100, arr: x3, bits: 1, bite: 27 }, { coord: -95, arr: x2, bits: 28, bite: 50 }, { coord: -90, arr: x1, bits: 51, bite: 78 }, { coord: -85, arr: x2, bits: 79, bite: 101 }, { coord: -80, arr: x3, bits: 102, bite: 128 }, { coord: -75, arr: x2, bits: 129, bite: 151 }, { coord: -70, arr: x3, bits: 152, bite: 178 }, { coord: -65, arr: x2, bits: 179, bite: 201 }],
|
|
1758
|
+
[{ coord: -60, arr: x3, bits: 1, bite: 27 }, { coord: -55, arr: x2, bits: 28, bite: 50 }, { coord: -50, arr: x4, bits: 51, bite: 78 }, { coord: -45, arr: x2, bits: 79, bite: 101 }, { coord: -40, arr: x3, bits: 102, bite: 128 }, { coord: -35, arr: x2, bits: 129, bite: 151 }, { coord: -30, arr: x3, bits: 152, bite: 178 }, { coord: -25, arr: x2, bits: 179, bite: 201 }],
|
|
1759
|
+
[{ coord: -20, arr: x3, bits: 1, bite: 27 }, { coord: -15, arr: x2, bits: 28, bite: 50 }, { coord: -10, arr: x3, bits: 51, bite: 77 }, { coord: -5, arr: x2, bits: 78, bite: 100 }, { coord: 0, arr: x1, bits: 101, bite: 128 }, { coord: 5, arr: x2, bits: 129, bite: 151 }, { coord: 10, arr: x3, bits: 152, bite: 178 }, { coord: 15, arr: x2, bits: 179, bite: 201 }],
|
|
1760
|
+
[{ coord: 20, arr: x3, bits: 1, bite: 27 }, { coord: 25, arr: x2, bits: 28, bite: 50 }, { coord: 30, arr: x3, bits: 51, bite: 77 }, { coord: 35, arr: x2, bits: 78, bite: 100 }, { coord: 40, arr: x4, bits: 101, bite: 128 }, { coord: 45, arr: x2, bits: 129, bite: 151 }, { coord: 50, arr: x3, bits: 152, bite: 178 }, { coord: 55, arr: x2, bits: 179, bite: 201 }],
|
|
1761
|
+
[{ coord: 60, arr: x3, bits: 1, bite: 27 }, { coord: 65, arr: x2, bits: 28, bite: 50 }, { coord: 70, arr: x3, bits: 51, bite: 77 }, { coord: 75, arr: x2, bits: 78, bite: 100 }, { coord: 80, arr: x3, bits: 101, bite: 127 }, { coord: 85, arr: x2, bits: 128, bite: 150 }, { coord: 90, arr: x1, bits: 151, bite: 178 }, { coord: 95, arr: x2, bits: 179, bite: 201 }],
|
|
1762
|
+
[{ coord: 100, arr: x3, bits: 1, bite: 27 }, { coord: 105, arr: x2, bits: 28, bite: 50 }, { coord: 110, arr: x3, bits: 51, bite: 77 }, { coord: 115, arr: x2, bits: 78, bite: 100 }, { coord: 120, arr: x3, bits: 101, bite: 127 }, { coord: 125, arr: x2, bits: 128, bite: 150 }, { coord: 130, arr: x4, bits: 151, bite: 178 }, { coord: 135, arr: x2, bits: 179, bite: 201 }],
|
|
1763
|
+
[{ coord: 140, arr: x3, bits: 1, bite: 27 }, { coord: 145, arr: x2, bits: 28, bite: 50 }, { coord: 150, arr: x3, bits: 51, bite: 77 }, { coord: 155, arr: x2, bits: 78, bite: 100 }, { coord: 160, arr: x3, bits: 101, bite: 127 }, { coord: 165, arr: x2, bits: 128, bite: 150 }, { coord: 170, arr: x3, bits: 151, bite: 177 }, { coord: 175, arr: x2, bits: 178, bite: 200 }]
|
|
1764
|
+
];
|
|
1765
|
+
var igpband2 = [
|
|
1766
|
+
[{ coord: 60, arr: x5, bits: 1, bite: 72 }, { coord: 65, arr: x6, bits: 73, bite: 108 }, { coord: 70, arr: x6, bits: 109, bite: 144 }, { coord: 75, arr: x6, bits: 145, bite: 180 }, { coord: 85, arr: x7, bits: 181, bite: 192 }],
|
|
1767
|
+
[{ coord: -60, arr: x5, bits: 1, bite: 72 }, { coord: -65, arr: x6, bits: 73, bite: 108 }, { coord: -70, arr: x6, bits: 109, bite: 144 }, { coord: -75, arr: x6, bits: 145, bite: 180 }, { coord: -85, arr: x8, bits: 181, bite: 192 }]
|
|
1768
|
+
];
|
|
1769
|
+
var gpsSeconds = (week, tow) => week * SEC_PER_WEEK2 + tow;
|
|
1770
|
+
function maskPrn(i) {
|
|
1771
|
+
if (i >= 1 && i <= 37) return `G${two(i)}`;
|
|
1772
|
+
if (i >= 38 && i <= 61) return `R${two(i - 37)}`;
|
|
1773
|
+
if (i >= 120 && i <= 138) return `S${two(i - 100)}`;
|
|
1774
|
+
if (i >= 193 && i <= 202) return `J${two(i - 192)}`;
|
|
1775
|
+
return null;
|
|
1776
|
+
}
|
|
1777
|
+
function ionppp(latRad, lonRad, azRad, elRad, re, hion) {
|
|
1778
|
+
const rp = re / (re + hion) * Math.cos(elRad);
|
|
1779
|
+
const ap = Math.PI / 2 - elRad - Math.asin(rp);
|
|
1780
|
+
const sinap = Math.sin(ap);
|
|
1781
|
+
const tanap = Math.tan(ap);
|
|
1782
|
+
const cosaz = Math.cos(azRad);
|
|
1783
|
+
const latP = Math.asin(
|
|
1784
|
+
Math.sin(latRad) * Math.cos(ap) + Math.cos(latRad) * sinap * cosaz
|
|
1785
|
+
);
|
|
1786
|
+
let lonP;
|
|
1787
|
+
if (latRad > 70 * D2R && tanap * cosaz > Math.tan(Math.PI / 2 - latRad) || latRad < -70 * D2R && -tanap * cosaz > Math.tan(Math.PI / 2 + latRad)) {
|
|
1788
|
+
lonP = lonRad + Math.PI - Math.asin(sinap * Math.sin(azRad) / Math.cos(latP));
|
|
1789
|
+
} else {
|
|
1790
|
+
lonP = lonRad + Math.asin(sinap * Math.sin(azRad) / Math.cos(latP));
|
|
1791
|
+
}
|
|
1792
|
+
return { fp: 1 / Math.sqrt(1 - rp * rp), latP, lonP };
|
|
1793
|
+
}
|
|
1794
|
+
var SbasProcessor = class {
|
|
1795
|
+
sats = [];
|
|
1796
|
+
satIdx = /* @__PURE__ */ new Map();
|
|
1797
|
+
iodp = -1;
|
|
1798
|
+
tlat = 0;
|
|
1799
|
+
ion = [];
|
|
1800
|
+
/** GEO PRN(s) whose messages have been ingested. */
|
|
1801
|
+
geoPrns = /* @__PURE__ */ new Set();
|
|
1802
|
+
/**
|
|
1803
|
+
* Ingest one decoded SBAS L1 message (250-bit, MSB-first) received at the
|
|
1804
|
+
* given GPS week / time-of-week. Returns the message type, or -1 if it was
|
|
1805
|
+
* not a recognised/applicable correction message.
|
|
1806
|
+
*/
|
|
1807
|
+
update(msg, week, tow, geoPrn) {
|
|
1808
|
+
if (week === 0) return -1;
|
|
1809
|
+
const type = sbasMessageType(msg);
|
|
1810
|
+
if (geoPrn != null && geoPrn >= 120 && geoPrn <= 158)
|
|
1811
|
+
this.geoPrns.add(`S${two(geoPrn - 100)}`);
|
|
1812
|
+
switch (type) {
|
|
1813
|
+
case 1:
|
|
1814
|
+
return this.decodeMask(msg) ? type : -1;
|
|
1815
|
+
case 0:
|
|
1816
|
+
case 2:
|
|
1817
|
+
case 3:
|
|
1818
|
+
case 4:
|
|
1819
|
+
case 5:
|
|
1820
|
+
return this.decodeFast(msg, type, week, tow) ? type : -1;
|
|
1821
|
+
case 6:
|
|
1822
|
+
return this.decodeIntegrity(msg) ? type : -1;
|
|
1823
|
+
case 7:
|
|
1824
|
+
return this.decodeDegradation(msg) ? type : -1;
|
|
1825
|
+
case 18:
|
|
1826
|
+
return this.decodeIgpMask(msg) ? type : -1;
|
|
1827
|
+
case 24:
|
|
1828
|
+
return this.decodeMixed(msg, week, tow) ? type : -1;
|
|
1829
|
+
case 25:
|
|
1830
|
+
return this.decodeLongCorrHalf(msg, 14, week, tow) && this.decodeLongCorrHalf(msg, 120, week, tow) ? type : -1;
|
|
1831
|
+
case 26:
|
|
1832
|
+
return this.decodeIgpDelay(msg, week, tow) ? type : -1;
|
|
1833
|
+
case 9:
|
|
1834
|
+
// GEO nav — handled by decodeSbasGeoNav elsewhere
|
|
1835
|
+
case 63:
|
|
1836
|
+
return type;
|
|
1837
|
+
default:
|
|
1838
|
+
return -1;
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
decodeMask(msg) {
|
|
1842
|
+
const sats = [];
|
|
1843
|
+
for (let i = 1; i <= 210; i++) {
|
|
1844
|
+
if (getBitU(msg, 13 + i, 1)) sats.push({ prn: maskPrn(i) });
|
|
1845
|
+
}
|
|
1846
|
+
this.iodp = getBitU(msg, 224, 2);
|
|
1847
|
+
this.sats = sats;
|
|
1848
|
+
this.satIdx.clear();
|
|
1849
|
+
sats.forEach((s, k) => {
|
|
1850
|
+
if (s.prn) this.satIdx.set(s.prn, k);
|
|
1851
|
+
});
|
|
1852
|
+
return true;
|
|
1853
|
+
}
|
|
1854
|
+
decodeFast(msg, type, week, tow) {
|
|
1855
|
+
if (this.iodp !== getBitU(msg, 16, 2)) return false;
|
|
1856
|
+
const iodf = getBitU(msg, 14, 2);
|
|
1857
|
+
const t0s = gpsSeconds(week, tow);
|
|
1858
|
+
for (let i = 0; i < 13; i++) {
|
|
1859
|
+
const j = 13 * ((type === 0 ? 2 : type) - 2) + i;
|
|
1860
|
+
if (j >= this.sats.length) break;
|
|
1861
|
+
const udre = getBitU(msg, 174 + 4 * i, 4);
|
|
1862
|
+
const prc = getBitS(msg, 18 + i * 12, 12) * 0.125;
|
|
1863
|
+
const prev = this.sats[j].fcorr;
|
|
1864
|
+
this.sats[j].fcorr = {
|
|
1865
|
+
prc,
|
|
1866
|
+
udre: udre + 1,
|
|
1867
|
+
ai: prev?.ai ?? 0,
|
|
1868
|
+
iodf,
|
|
1869
|
+
t0s
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
return true;
|
|
1873
|
+
}
|
|
1874
|
+
decodeIntegrity(msg) {
|
|
1875
|
+
const iodf = [0, 1, 2, 3].map((i) => getBitU(msg, 14 + i * 2, 2));
|
|
1876
|
+
for (let i = 0; i < this.sats.length; i++) {
|
|
1877
|
+
const f = this.sats[i].fcorr;
|
|
1878
|
+
if (!f || f.iodf !== iodf[Math.floor(i / 13)]) continue;
|
|
1879
|
+
f.udre = getBitU(msg, 22 + i * 4, 4) + 1;
|
|
1880
|
+
}
|
|
1881
|
+
return true;
|
|
1882
|
+
}
|
|
1883
|
+
decodeDegradation(msg) {
|
|
1884
|
+
if (this.iodp !== getBitU(msg, 18, 2)) return false;
|
|
1885
|
+
this.tlat = getBitU(msg, 14, 4);
|
|
1886
|
+
for (let i = 0; i < this.sats.length; i++) {
|
|
1887
|
+
const ai = getBitU(msg, 22 + i * 4, 4);
|
|
1888
|
+
if (this.sats[i].fcorr) this.sats[i].fcorr.ai = ai;
|
|
1889
|
+
else this.sats[i].fcorr = { prc: 0, udre: 0, ai, iodf: -1, t0s: 0 };
|
|
1890
|
+
}
|
|
1891
|
+
return true;
|
|
1892
|
+
}
|
|
1893
|
+
decodeMixed(msg, week, tow) {
|
|
1894
|
+
if (this.iodp !== getBitU(msg, 110, 2)) return false;
|
|
1895
|
+
const blk = getBitU(msg, 112, 2);
|
|
1896
|
+
const iodf = getBitU(msg, 114, 2);
|
|
1897
|
+
const t0s = gpsSeconds(week, tow);
|
|
1898
|
+
for (let i = 0; i < 6; i++) {
|
|
1899
|
+
const j = 13 * blk + i;
|
|
1900
|
+
if (j >= this.sats.length) break;
|
|
1901
|
+
const udre = getBitU(msg, 86 + 4 * i, 4);
|
|
1902
|
+
const prc = getBitS(msg, 14 + i * 12, 12) * 0.125;
|
|
1903
|
+
const prev = this.sats[j].fcorr;
|
|
1904
|
+
this.sats[j].fcorr = {
|
|
1905
|
+
prc,
|
|
1906
|
+
udre: udre + 1,
|
|
1907
|
+
ai: prev?.ai ?? 0,
|
|
1908
|
+
iodf,
|
|
1909
|
+
t0s
|
|
1910
|
+
};
|
|
1911
|
+
}
|
|
1912
|
+
return this.decodeLongCorrHalf(msg, 120, week, tow);
|
|
1913
|
+
}
|
|
1914
|
+
decodeLongCorrHalf(msg, p, week, tow) {
|
|
1915
|
+
if (getBitU(msg, p, 1) === 0) {
|
|
1916
|
+
if (this.iodp === getBitU(msg, p + 103, 2)) {
|
|
1917
|
+
const a = this.decodeLong0(msg, p + 1, week, tow);
|
|
1918
|
+
const b = this.decodeLong0(msg, p + 52, week, tow);
|
|
1919
|
+
return a || b;
|
|
1920
|
+
}
|
|
1921
|
+
} else if (this.iodp === getBitU(msg, p + 104, 2)) {
|
|
1922
|
+
return this.decodeLong1(msg, p + 1, week, tow);
|
|
1923
|
+
}
|
|
1924
|
+
return false;
|
|
1925
|
+
}
|
|
1926
|
+
decodeLong0(msg, p, week, tow) {
|
|
1927
|
+
const n = getBitU(msg, p, 6);
|
|
1928
|
+
if (n === 0 || n > this.sats.length) return false;
|
|
1929
|
+
this.sats[n - 1].lcorr = {
|
|
1930
|
+
iode: getBitU(msg, p + 6, 8),
|
|
1931
|
+
dpos: [
|
|
1932
|
+
getBitS(msg, p + 14, 9) * 0.125,
|
|
1933
|
+
getBitS(msg, p + 23, 9) * 0.125,
|
|
1934
|
+
getBitS(msg, p + 32, 9) * 0.125
|
|
1935
|
+
],
|
|
1936
|
+
dvel: [0, 0, 0],
|
|
1937
|
+
daf0: getBitS(msg, p + 41, 10) * P2_31,
|
|
1938
|
+
daf1: 0,
|
|
1939
|
+
t0s: gpsSeconds(week, tow)
|
|
1940
|
+
};
|
|
1941
|
+
return true;
|
|
1942
|
+
}
|
|
1943
|
+
decodeLong1(msg, p, week, tow) {
|
|
1944
|
+
const n = getBitU(msg, p, 6);
|
|
1945
|
+
if (n === 0 || n > this.sats.length) return false;
|
|
1946
|
+
let t = getBitU(msg, p + 90, 13) * 16 - tow % 86400;
|
|
1947
|
+
if (t <= -43200) t += 86400;
|
|
1948
|
+
else if (t > 43200) t -= 86400;
|
|
1949
|
+
this.sats[n - 1].lcorr = {
|
|
1950
|
+
iode: getBitU(msg, p + 6, 8),
|
|
1951
|
+
dpos: [
|
|
1952
|
+
getBitS(msg, p + 14, 11) * 0.125,
|
|
1953
|
+
getBitS(msg, p + 25, 11) * 0.125,
|
|
1954
|
+
getBitS(msg, p + 36, 11) * 0.125
|
|
1955
|
+
],
|
|
1956
|
+
dvel: [
|
|
1957
|
+
getBitS(msg, p + 58, 8) * P2_11,
|
|
1958
|
+
getBitS(msg, p + 66, 8) * P2_11,
|
|
1959
|
+
getBitS(msg, p + 74, 8) * P2_11
|
|
1960
|
+
],
|
|
1961
|
+
daf0: getBitS(msg, p + 47, 11) * P2_31,
|
|
1962
|
+
daf1: getBitS(msg, p + 82, 8) * P2_39,
|
|
1963
|
+
t0s: gpsSeconds(week, tow + t)
|
|
1964
|
+
};
|
|
1965
|
+
return true;
|
|
1966
|
+
}
|
|
1967
|
+
decodeIgpMask(msg) {
|
|
1968
|
+
const band = getBitU(msg, 18, 4);
|
|
1969
|
+
let p;
|
|
1970
|
+
let m;
|
|
1971
|
+
if (band <= 8) {
|
|
1972
|
+
p = igpband1[band];
|
|
1973
|
+
m = 8;
|
|
1974
|
+
} else if (band <= 10) {
|
|
1975
|
+
p = igpband2[band - 9];
|
|
1976
|
+
m = 5;
|
|
1977
|
+
} else return false;
|
|
1978
|
+
const igp = [];
|
|
1979
|
+
for (let i = 1; i <= 201; i++) {
|
|
1980
|
+
if (!getBitU(msg, 23 + i, 1)) continue;
|
|
1981
|
+
for (let j = 0; j < m; j++) {
|
|
1982
|
+
const b = p[j];
|
|
1983
|
+
if (i < b.bits || b.bite < i) continue;
|
|
1984
|
+
const varying = b.arr[i - b.bits];
|
|
1985
|
+
igp.push({
|
|
1986
|
+
lat: band <= 8 ? varying : b.coord,
|
|
1987
|
+
lon: band <= 8 ? b.coord : varying,
|
|
1988
|
+
delay: 0,
|
|
1989
|
+
give: 0,
|
|
1990
|
+
t0s: 0
|
|
1991
|
+
});
|
|
1992
|
+
break;
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
this.ion[band] = { iodi: getBitU(msg, 22, 2), igp };
|
|
1996
|
+
return true;
|
|
1997
|
+
}
|
|
1998
|
+
decodeIgpDelay(msg, week, tow) {
|
|
1999
|
+
const band = getBitU(msg, 14, 4);
|
|
2000
|
+
const b = this.ion[band];
|
|
2001
|
+
if (band > MAXBAND || !b || b.iodi !== getBitU(msg, 217, 2)) return false;
|
|
2002
|
+
const block = getBitU(msg, 18, 4);
|
|
2003
|
+
const t0s = gpsSeconds(week, tow);
|
|
2004
|
+
for (let i = 0; i < 15; i++) {
|
|
2005
|
+
const j = block * 15 + i;
|
|
2006
|
+
if (j >= b.igp.length) continue;
|
|
2007
|
+
const give = getBitU(msg, 22 + i * 13 + 9, 4);
|
|
2008
|
+
const delay = getBitU(msg, 22 + i * 13, 9);
|
|
2009
|
+
b.igp[j].delay = delay === 511 ? 0 : delay * 0.125;
|
|
2010
|
+
b.igp[j].give = give + 1 >= 16 ? 0 : give + 1;
|
|
2011
|
+
b.igp[j].t0s = t0s;
|
|
2012
|
+
}
|
|
2013
|
+
return true;
|
|
2014
|
+
}
|
|
2015
|
+
/** PRNs currently in the correction mask (in mask order). */
|
|
2016
|
+
activeSats() {
|
|
2017
|
+
return this.sats.map((s) => s.prn).filter((p) => !!p);
|
|
2018
|
+
}
|
|
2019
|
+
/** Number of ionospheric grid points with a valid delay across all bands. */
|
|
2020
|
+
ionoGridPoints() {
|
|
2021
|
+
let n = 0;
|
|
2022
|
+
for (const b of this.ion) if (b) {
|
|
2023
|
+
for (const g of b.igp) if (g.give > 0) n++;
|
|
2024
|
+
}
|
|
2025
|
+
return n;
|
|
2026
|
+
}
|
|
2027
|
+
/**
|
|
2028
|
+
* Satellite range/clock correction for a PRN at a GPS week/tow, or null if
|
|
2029
|
+
* no valid (unexpired) long-term + fast correction is available. Add `dPos`
|
|
2030
|
+
* to the satellite ECEF position and `dClkS` to its clock bias.
|
|
2031
|
+
*/
|
|
2032
|
+
satCorrection(prn, week, tow) {
|
|
2033
|
+
const idx = this.satIdx.get(prn);
|
|
2034
|
+
if (idx === void 0) return null;
|
|
2035
|
+
const s = this.sats[idx];
|
|
2036
|
+
const now = gpsSeconds(week, tow);
|
|
2037
|
+
const drs = [0, 0, 0];
|
|
2038
|
+
let dclk = 0;
|
|
2039
|
+
let iode = -1;
|
|
2040
|
+
if (s.lcorr && s.lcorr.t0s !== 0) {
|
|
2041
|
+
const t = now - s.lcorr.t0s;
|
|
2042
|
+
if (Math.abs(t) > MAXSBSAGEL) return null;
|
|
2043
|
+
for (let i = 0; i < 3; i++)
|
|
2044
|
+
drs[i] = s.lcorr.dpos[i] + s.lcorr.dvel[i] * t;
|
|
2045
|
+
dclk = s.lcorr.daf0 + s.lcorr.daf1 * t;
|
|
2046
|
+
iode = s.lcorr.iode;
|
|
2047
|
+
} else if (prn[0] !== "S") {
|
|
2048
|
+
return null;
|
|
2049
|
+
}
|
|
2050
|
+
if (!s.fcorr || s.fcorr.t0s === 0) return null;
|
|
2051
|
+
const tf = now - s.fcorr.t0s + this.tlat;
|
|
2052
|
+
if (Math.abs(tf) > MAXSBSAGEF || s.fcorr.udre >= 15) return null;
|
|
2053
|
+
const prc = s.fcorr.prc;
|
|
2054
|
+
const varM2 = varfcorr(s.fcorr.udre) + degfcorr(s.fcorr.ai) * tf * tf / 2;
|
|
2055
|
+
return { dPos: drs, dClkS: dclk + prc / C_LIGHT, prcM: prc, varM2, iode };
|
|
2056
|
+
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Slant L1 ionospheric delay (m) at the pierce point for a receiver geodetic
|
|
2059
|
+
* position (lat/lon rad, height m) and a satellite az/el (rad), interpolated
|
|
2060
|
+
* from the SBAS grid — or null if the pierce point isn't covered. RTKLIB
|
|
2061
|
+
* `sbsioncorr`.
|
|
2062
|
+
*/
|
|
2063
|
+
ionoDelay(week, tow, latRad, lonRad, heightM, azRad, elRad) {
|
|
2064
|
+
if (heightM < -100 || elRad <= 0) return { delayM: 0, varM2: 0 };
|
|
2065
|
+
const { fp, latP, lonP } = ionppp(
|
|
2066
|
+
latRad,
|
|
2067
|
+
lonRad,
|
|
2068
|
+
azRad,
|
|
2069
|
+
elRad,
|
|
2070
|
+
6378.1363,
|
|
2071
|
+
350
|
|
2072
|
+
);
|
|
2073
|
+
const igp = this.searchIgp(latP, lonP);
|
|
2074
|
+
if (!igp) return null;
|
|
2075
|
+
const { pts, x, y } = igp;
|
|
2076
|
+
const w = [0, 0, 0, 0];
|
|
2077
|
+
if (pts[0] && pts[1] && pts[2] && pts[3]) {
|
|
2078
|
+
w[0] = (1 - x) * (1 - y);
|
|
2079
|
+
w[1] = (1 - x) * y;
|
|
2080
|
+
w[2] = x * (1 - y);
|
|
2081
|
+
w[3] = x * y;
|
|
2082
|
+
} else if (pts[0] && pts[1] && pts[2]) {
|
|
2083
|
+
w[1] = y;
|
|
2084
|
+
w[2] = x;
|
|
2085
|
+
w[0] = 1 - w[1] - w[2];
|
|
2086
|
+
if (w[0] < 0) return null;
|
|
2087
|
+
} else if (pts[0] && pts[2] && pts[3]) {
|
|
2088
|
+
w[0] = 1 - x;
|
|
2089
|
+
w[3] = y;
|
|
2090
|
+
w[2] = 1 - w[0] - w[3];
|
|
2091
|
+
if (w[2] < 0) return null;
|
|
2092
|
+
} else if (pts[0] && pts[1] && pts[3]) {
|
|
2093
|
+
w[0] = 1 - y;
|
|
2094
|
+
w[3] = x;
|
|
2095
|
+
w[1] = 1 - w[0] - w[3];
|
|
2096
|
+
if (w[1] < 0) return null;
|
|
2097
|
+
} else if (pts[1] && pts[2] && pts[3]) {
|
|
2098
|
+
w[1] = 1 - x;
|
|
2099
|
+
w[2] = 1 - y;
|
|
2100
|
+
w[3] = 1 - w[1] - w[2];
|
|
2101
|
+
if (w[3] < 0) return null;
|
|
2102
|
+
} else return null;
|
|
2103
|
+
const now = gpsSeconds(week, tow);
|
|
2104
|
+
let delay = 0;
|
|
2105
|
+
let varM2 = 0;
|
|
2106
|
+
for (let i = 0; i < 4; i++) {
|
|
2107
|
+
const g = pts[i];
|
|
2108
|
+
if (!g) continue;
|
|
2109
|
+
delay += w[i] * g.delay;
|
|
2110
|
+
varM2 += w[i] * varicorr(g.give) * 9e-8 * Math.abs(now - g.t0s);
|
|
2111
|
+
}
|
|
2112
|
+
return { delayM: delay * fp, varM2: varM2 * fp * fp };
|
|
2113
|
+
}
|
|
2114
|
+
/** Find the four IGPs bracketing a pierce point (RTKLIB `searchigp`). */
|
|
2115
|
+
searchIgp(latP, lonP) {
|
|
2116
|
+
const lat = latP * R2D;
|
|
2117
|
+
let lon = lonP * R2D;
|
|
2118
|
+
if (lon >= 180) lon -= 360;
|
|
2119
|
+
const latp = [0, 0];
|
|
2120
|
+
const lonp = [0, 0, 0, 0];
|
|
2121
|
+
let x;
|
|
2122
|
+
let y;
|
|
2123
|
+
if (lat >= -55 && lat < 55) {
|
|
2124
|
+
latp[0] = Math.floor(lat / 5) * 5;
|
|
2125
|
+
latp[1] = latp[0] + 5;
|
|
2126
|
+
lonp[0] = lonp[1] = Math.floor(lon / 5) * 5;
|
|
2127
|
+
lonp[2] = lonp[3] = lonp[0] + 5;
|
|
2128
|
+
x = (lon - lonp[0]) / 5;
|
|
2129
|
+
y = (lat - latp[0]) / 5;
|
|
2130
|
+
} else {
|
|
2131
|
+
latp[0] = Math.floor((lat - 5) / 10) * 10 + 5;
|
|
2132
|
+
latp[1] = latp[0] + 10;
|
|
2133
|
+
lonp[0] = lonp[1] = Math.floor(lon / 10) * 10;
|
|
2134
|
+
lonp[2] = lonp[3] = lonp[0] + 10;
|
|
2135
|
+
x = (lon - lonp[0]) / 10;
|
|
2136
|
+
y = (lat - latp[0]) / 10;
|
|
2137
|
+
if (lat >= 75 && lat < 85) {
|
|
2138
|
+
lonp[1] = Math.floor(lon / 90) * 90;
|
|
2139
|
+
lonp[3] = lonp[1] + 90;
|
|
2140
|
+
} else if (lat >= -85 && lat < -75) {
|
|
2141
|
+
lonp[0] = Math.floor((lon - 50) / 90) * 90 + 40;
|
|
2142
|
+
lonp[2] = lonp[0] + 90;
|
|
2143
|
+
} else if (lat >= 85) {
|
|
2144
|
+
for (let i = 0; i < 4; i++) lonp[i] = Math.floor(lon / 90) * 90;
|
|
2145
|
+
} else if (lat < -85) {
|
|
2146
|
+
for (let i = 0; i < 4; i++)
|
|
2147
|
+
lonp[i] = Math.floor((lon - 50) / 90) * 90 + 40;
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
for (let i = 0; i < 4; i++) if (lonp[i] === 180) lonp[i] = -180;
|
|
2151
|
+
const pts = [null, null, null, null];
|
|
2152
|
+
for (const band of this.ion) {
|
|
2153
|
+
if (!band) continue;
|
|
2154
|
+
for (const g of band.igp) {
|
|
2155
|
+
if (g.t0s === 0 || g.give <= 0) continue;
|
|
2156
|
+
if (g.lat === latp[0] && g.lon === lonp[0]) pts[0] = g;
|
|
2157
|
+
else if (g.lat === latp[1] && g.lon === lonp[1]) pts[1] = g;
|
|
2158
|
+
else if (g.lat === latp[0] && g.lon === lonp[2]) pts[2] = g;
|
|
2159
|
+
else if (g.lat === latp[1] && g.lon === lonp[3]) pts[3] = g;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
if (!pts[0] && !pts[1] && !pts[2] && !pts[3]) return null;
|
|
2163
|
+
return { pts, x, y };
|
|
2164
|
+
}
|
|
2165
|
+
};
|
|
2166
|
+
|
|
1657
2167
|
// src/rinex/sp3.ts
|
|
1658
2168
|
function sp3Position(sp3, prn, tMs, order = 9) {
|
|
1659
2169
|
const samples = sp3.satellites[prn];
|
|
@@ -1705,7 +2215,7 @@ function sp3Position(sp3, prn, tMs, order = 9) {
|
|
|
1705
2215
|
}
|
|
1706
2216
|
|
|
1707
2217
|
// src/rinex/clk.ts
|
|
1708
|
-
var
|
|
2218
|
+
var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
|
|
1709
2219
|
function clkBias(clk, prn, tMs) {
|
|
1710
2220
|
const e = clk.sats[prn];
|
|
1711
2221
|
if (!e || e.t.length === 0) return null;
|
|
@@ -3119,7 +3629,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3119
3629
|
const systems = [...new Set(prns.map((p) => p[0]))].sort();
|
|
3120
3630
|
const dim = 3 + systems.length;
|
|
3121
3631
|
const sysIndex = new Map(systems.map((s, i) => [s, 3 + i]));
|
|
3122
|
-
let
|
|
3632
|
+
let x9 = 0;
|
|
3123
3633
|
let y2 = 0;
|
|
3124
3634
|
let z2 = 0;
|
|
3125
3635
|
const clock2 = new Map(systems.map((s) => [s, 0]));
|
|
@@ -3135,8 +3645,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3135
3645
|
const Htv = new Array(dim).fill(0);
|
|
3136
3646
|
let rows = 0;
|
|
3137
3647
|
for (const k of Object.keys(residuals2)) delete residuals2[k];
|
|
3138
|
-
const positionSaneIter =
|
|
3139
|
-
const [rxLat, rxLon, rxHgt] = positionSaneIter ? ecefToGeodetic(
|
|
3648
|
+
const positionSaneIter = x9 * x9 + y2 * y2 + z2 * z2 > 1e12;
|
|
3649
|
+
const [rxLat, rxLon, rxHgt] = positionSaneIter ? ecefToGeodetic(x9, y2, z2) : [0, 0, 0];
|
|
3140
3650
|
for (const prn of prns) {
|
|
3141
3651
|
const psr = pseudoranges.get(prn);
|
|
3142
3652
|
const eph = ephemerides.get(prn);
|
|
@@ -3148,10 +3658,10 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3148
3658
|
if (!Number.isFinite(sat.x)) continue;
|
|
3149
3659
|
const isKepler = eph.system !== "R" && eph.system !== "S";
|
|
3150
3660
|
const dts = dtsClock - (tgd && isKepler ? eph.tgd : 0);
|
|
3151
|
-
const travel = Math.hypot(sat.x -
|
|
3661
|
+
const travel = Math.hypot(sat.x - x9, sat.y - y2, sat.z - z2) / C_LIGHT;
|
|
3152
3662
|
const [sx, sy, sz] = sagnac2(sat, travel);
|
|
3153
|
-
const rho = Math.hypot(sx -
|
|
3154
|
-
const ux = (
|
|
3663
|
+
const rho = Math.hypot(sx - x9, sy - y2, sz - z2);
|
|
3664
|
+
const ux = (x9 - sx) / rho;
|
|
3155
3665
|
const uy = (y2 - sy) / rho;
|
|
3156
3666
|
const uz = (z2 - sz) / rho;
|
|
3157
3667
|
let elev = Math.PI / 2;
|
|
@@ -3159,7 +3669,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3159
3669
|
let weight = 1;
|
|
3160
3670
|
const positionSane = positionSaneIter;
|
|
3161
3671
|
if (positionSane) {
|
|
3162
|
-
const azel = ecefToAzEl(
|
|
3672
|
+
const azel = ecefToAzEl(x9, y2, z2, sx, sy, sz);
|
|
3163
3673
|
elev = azel.el;
|
|
3164
3674
|
azim = azel.az;
|
|
3165
3675
|
if (iter >= 2 && elev < elevationMaskDeg * Math.PI / 180) continue;
|
|
@@ -3197,7 +3707,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3197
3707
|
if (rows < dim) return null;
|
|
3198
3708
|
const dx = solveLinear(HtH, Htv);
|
|
3199
3709
|
if (!dx) return null;
|
|
3200
|
-
|
|
3710
|
+
x9 += dx[0];
|
|
3201
3711
|
y2 += dx[1];
|
|
3202
3712
|
z2 += dx[2];
|
|
3203
3713
|
for (const s of systems)
|
|
@@ -3207,7 +3717,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3207
3717
|
break;
|
|
3208
3718
|
}
|
|
3209
3719
|
}
|
|
3210
|
-
return { x:
|
|
3720
|
+
return { x: x9, y: y2, z: z2, clock: clock2, residuals: residuals2, iterations: iterations2, converged: converged2 };
|
|
3211
3721
|
};
|
|
3212
3722
|
const REJECT_THRESHOLD_M = 50;
|
|
3213
3723
|
let candidates = all;
|
|
@@ -3261,6 +3771,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
3261
3771
|
0 && (module.exports = {
|
|
3262
3772
|
IONO_L1_M_PER_TECU,
|
|
3263
3773
|
RtkFloatEngine,
|
|
3774
|
+
SbasProcessor,
|
|
3264
3775
|
buildPppAntenna,
|
|
3265
3776
|
createPppCorrections,
|
|
3266
3777
|
estimateNarrowlaneFcb,
|