gnss-js 1.16.0 → 1.18.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-R33A2VA7.js → chunk-2IM5VXNI.js} +193 -12
- package/dist/{chunk-YPOVPXNK.js → chunk-CG7SF45F.js} +75 -0
- package/dist/{chunk-6CX6EXRK.js → chunk-FEGLXNWA.js} +97 -23
- package/dist/{chunk-4LVD4DYL.js → chunk-IQ5OIMQD.js} +2 -0
- package/dist/chunk-Y5IWUPJQ.js +206 -0
- package/dist/cnav-CRns0ECn.d.cts +96 -0
- package/dist/cnav-CRns0ECn.d.ts +96 -0
- package/dist/index.cjs +577 -56
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +13 -4
- package/dist/novatel.cjs +192 -11
- package/dist/novatel.d.cts +36 -13
- package/dist/novatel.d.ts +36 -13
- package/dist/novatel.js +2 -2
- package/dist/sbf.cjs +288 -2
- package/dist/sbf.d.cts +82 -1
- package/dist/sbf.d.ts +82 -1
- package/dist/sbf.js +7 -1
- package/dist/ubx.cjs +291 -24
- package/dist/ubx.d.cts +73 -2
- package/dist/ubx.d.ts +73 -2
- package/dist/ubx.js +7 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -222,11 +222,15 @@ __export(src_exports, {
|
|
|
222
222
|
parseNovatelRange: () => parseNovatelRange,
|
|
223
223
|
parseRinexStream: () => parseRinexStream,
|
|
224
224
|
parseSbfAlmanac: () => parseSbfAlmanac,
|
|
225
|
+
parseSbfCnav: () => parseSbfCnav,
|
|
226
|
+
parseSbfIonoUtc: () => parseSbfIonoUtc,
|
|
225
227
|
parseSbfMeas: () => parseSbfMeas,
|
|
226
228
|
parseSbfNav: () => parseSbfNav,
|
|
227
229
|
parseSinexBiasDcb: () => parseSinexBiasDcb,
|
|
228
230
|
parseSourcetable: () => parseSourcetable,
|
|
229
231
|
parseSp3: () => parseSp3,
|
|
232
|
+
parseUbxCnav: () => parseUbxCnav,
|
|
233
|
+
parseUbxIonoUtc: () => parseUbxIonoUtc,
|
|
230
234
|
parseUbxNav: () => parseUbxNav,
|
|
231
235
|
parseUbxRawx: () => parseUbxRawx,
|
|
232
236
|
phiAltBOC: () => phiAltBOC,
|
|
@@ -4777,6 +4781,30 @@ function decodeGpsLnavFrame(subframes, opts = {}) {
|
|
|
4777
4781
|
|
|
4778
4782
|
// src/ubx/nav.ts
|
|
4779
4783
|
var PREAMB_CNAV = 139;
|
|
4784
|
+
function readLnavSubframe(view, f) {
|
|
4785
|
+
const p = f.payload;
|
|
4786
|
+
if (p.length < 8) return null;
|
|
4787
|
+
const gnssId = p[0];
|
|
4788
|
+
const svId = p[1];
|
|
4789
|
+
let prn;
|
|
4790
|
+
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
4791
|
+
prn = `G${String(svId).padStart(2, "0")}`;
|
|
4792
|
+
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
4793
|
+
if (p.length === 44) return null;
|
|
4794
|
+
prn = `J${String(svId).padStart(2, "0")}`;
|
|
4795
|
+
} else {
|
|
4796
|
+
return null;
|
|
4797
|
+
}
|
|
4798
|
+
if (p.length < 8 + 40) return null;
|
|
4799
|
+
const base = f.payloadStart + 8;
|
|
4800
|
+
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) return null;
|
|
4801
|
+
const buff = new Uint8Array(30);
|
|
4802
|
+
for (let k = 0; k < 10; k++) {
|
|
4803
|
+
const dwrd = view.getUint32(base + 4 * k, true);
|
|
4804
|
+
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
4805
|
+
}
|
|
4806
|
+
return { prn, gnssId, svId, buff, id: getBitU(buff, 43, 3) };
|
|
4807
|
+
}
|
|
4780
4808
|
function parseUbxNav(data, opts = {}) {
|
|
4781
4809
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
4782
4810
|
const ephemerides = [];
|
|
@@ -4798,28 +4826,9 @@ function parseUbxNav(data, opts = {}) {
|
|
|
4798
4826
|
const last = /* @__PURE__ */ new Map();
|
|
4799
4827
|
for (const f of ubxFrames(data)) {
|
|
4800
4828
|
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
4801
|
-
const
|
|
4802
|
-
if (
|
|
4803
|
-
const gnssId =
|
|
4804
|
-
const svId = p[1];
|
|
4805
|
-
let prn;
|
|
4806
|
-
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
4807
|
-
prn = `G${String(svId).padStart(2, "0")}`;
|
|
4808
|
-
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
4809
|
-
if (p.length === 44) continue;
|
|
4810
|
-
prn = `J${String(svId).padStart(2, "0")}`;
|
|
4811
|
-
} else {
|
|
4812
|
-
continue;
|
|
4813
|
-
}
|
|
4814
|
-
if (p.length < 8 + 40) continue;
|
|
4815
|
-
const base = f.payloadStart + 8;
|
|
4816
|
-
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) continue;
|
|
4817
|
-
const buff = new Uint8Array(30);
|
|
4818
|
-
for (let k = 0; k < 10; k++) {
|
|
4819
|
-
const dwrd = view.getUint32(base + 4 * k, true);
|
|
4820
|
-
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
4821
|
-
}
|
|
4822
|
-
const id = getBitU(buff, 43, 3);
|
|
4829
|
+
const lnav = readLnavSubframe(view, f);
|
|
4830
|
+
if (!lnav) continue;
|
|
4831
|
+
const { prn, gnssId, svId, buff, id } = lnav;
|
|
4823
4832
|
if (id < 1 || id > 5) {
|
|
4824
4833
|
badParity++;
|
|
4825
4834
|
continue;
|
|
@@ -4849,8 +4858,266 @@ function parseUbxNav(data, opts = {}) {
|
|
|
4849
4858
|
return { ephemerides, badParity };
|
|
4850
4859
|
}
|
|
4851
4860
|
|
|
4852
|
-
// src/ubx/
|
|
4861
|
+
// src/ubx/iono.ts
|
|
4862
|
+
function parseUbxIonoUtc(data) {
|
|
4863
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
4864
|
+
const ionoCorrections = {};
|
|
4865
|
+
let leapSeconds = null;
|
|
4866
|
+
for (const f of ubxFrames(data)) {
|
|
4867
|
+
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
4868
|
+
const sf = readLnavSubframe(view, f);
|
|
4869
|
+
if (!sf || sf.gnssId !== 0 || sf.id !== 4) continue;
|
|
4870
|
+
const b = sf.buff;
|
|
4871
|
+
if (getBitU(b, 48, 2) !== 1 || getBitU(b, 50, 6) !== 56) continue;
|
|
4872
|
+
ionoCorrections["GPSA"] = [
|
|
4873
|
+
getBitS(b, 56, 8) * 2 ** -30,
|
|
4874
|
+
getBitS(b, 64, 8) * 2 ** -27,
|
|
4875
|
+
getBitS(b, 72, 8) * 2 ** -24,
|
|
4876
|
+
getBitS(b, 80, 8) * 2 ** -24
|
|
4877
|
+
];
|
|
4878
|
+
ionoCorrections["GPSB"] = [
|
|
4879
|
+
getBitS(b, 88, 8) * 2 ** 11,
|
|
4880
|
+
getBitS(b, 96, 8) * 2 ** 14,
|
|
4881
|
+
getBitS(b, 104, 8) * 2 ** 16,
|
|
4882
|
+
getBitS(b, 112, 8) * 2 ** 16
|
|
4883
|
+
];
|
|
4884
|
+
leapSeconds = getBitS(b, 192, 8);
|
|
4885
|
+
}
|
|
4886
|
+
return { ionoCorrections, leapSeconds };
|
|
4887
|
+
}
|
|
4888
|
+
|
|
4889
|
+
// src/navbits/cnav.ts
|
|
4853
4890
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
4891
|
+
var SEC_PER_WEEK2 = 7 * 86400;
|
|
4892
|
+
var HALF_WEEK = 302400;
|
|
4893
|
+
var CNAV_PREAMBLE = 139;
|
|
4894
|
+
var CNAV_A_REF = 26559710;
|
|
4895
|
+
var CNAV_OMEGA_DOT_REF = -26e-10;
|
|
4896
|
+
function crc24q2(buff, bitLen) {
|
|
4897
|
+
let crc = 0;
|
|
4898
|
+
for (let i = 0; i < bitLen; i++) {
|
|
4899
|
+
crc ^= (buff[i >> 3] >> 7 - (i & 7) & 1) << 23;
|
|
4900
|
+
const msb = crc & 8388608;
|
|
4901
|
+
crc = crc << 1 & 16777215;
|
|
4902
|
+
if (msb) crc ^= 8801531;
|
|
4903
|
+
}
|
|
4904
|
+
return crc;
|
|
4905
|
+
}
|
|
4906
|
+
function cnavCrcOk(msg) {
|
|
4907
|
+
if (msg.length < 38) return false;
|
|
4908
|
+
return crc24q2(msg, 276) === getBitU(msg, 276, 24);
|
|
4909
|
+
}
|
|
4910
|
+
function getBitU33(b, pos) {
|
|
4911
|
+
return getBitU(b, pos, 1) * 2 ** 32 + getBitU(b, pos + 1, 32);
|
|
4912
|
+
}
|
|
4913
|
+
function getBitS33(b, pos) {
|
|
4914
|
+
const u = getBitU33(b, pos);
|
|
4915
|
+
return u < 2 ** 32 ? u : u - 2 ** 33;
|
|
4916
|
+
}
|
|
4917
|
+
function decodeType10(b, tow) {
|
|
4918
|
+
return {
|
|
4919
|
+
tow,
|
|
4920
|
+
week: getBitU(b, 38, 13),
|
|
4921
|
+
health: getBitU(b, 51, 3),
|
|
4922
|
+
top: getBitU(b, 54, 11) * 300,
|
|
4923
|
+
uraEd: getBitS(b, 65, 5),
|
|
4924
|
+
toe: getBitU(b, 70, 11) * 300,
|
|
4925
|
+
deltaA: getBitS(b, 81, 26) * 2 ** -9,
|
|
4926
|
+
aDot: getBitS(b, 107, 25) * 2 ** -21,
|
|
4927
|
+
deltaN0: getBitS(b, 132, 17) * 2 ** -44 * GPS_PI,
|
|
4928
|
+
deltaN0Dot: getBitS(b, 149, 23) * 2 ** -57 * GPS_PI,
|
|
4929
|
+
m0: getBitS33(b, 172) * 2 ** -32 * GPS_PI,
|
|
4930
|
+
e: getBitU33(b, 205) * 2 ** -34,
|
|
4931
|
+
omega: getBitS33(b, 238) * 2 ** -32 * GPS_PI,
|
|
4932
|
+
integrityFlag: getBitU(b, 271, 1) === 1,
|
|
4933
|
+
l2cPhasing: getBitU(b, 272, 1) === 1
|
|
4934
|
+
};
|
|
4935
|
+
}
|
|
4936
|
+
function decodeType11(b) {
|
|
4937
|
+
return {
|
|
4938
|
+
toe: getBitU(b, 38, 11) * 300,
|
|
4939
|
+
omega0: getBitS33(b, 49) * 2 ** -32 * GPS_PI,
|
|
4940
|
+
i0: getBitS33(b, 82) * 2 ** -32 * GPS_PI,
|
|
4941
|
+
deltaOmegaDot: getBitS(b, 115, 17) * 2 ** -44 * GPS_PI,
|
|
4942
|
+
i0Dot: getBitS(b, 132, 15) * 2 ** -44 * GPS_PI,
|
|
4943
|
+
cis: getBitS(b, 147, 16) * 2 ** -30,
|
|
4944
|
+
cic: getBitS(b, 163, 16) * 2 ** -30,
|
|
4945
|
+
crs: getBitS(b, 179, 24) * 2 ** -8,
|
|
4946
|
+
crc: getBitS(b, 203, 24) * 2 ** -8,
|
|
4947
|
+
cus: getBitS(b, 227, 21) * 2 ** -30,
|
|
4948
|
+
cuc: getBitS(b, 248, 21) * 2 ** -30
|
|
4949
|
+
};
|
|
4950
|
+
}
|
|
4951
|
+
var isc = (b, pos) => {
|
|
4952
|
+
const raw = getBitS(b, pos, 13);
|
|
4953
|
+
return raw === -4096 ? null : raw * 2 ** -35;
|
|
4954
|
+
};
|
|
4955
|
+
function decodeClock(b, msgType) {
|
|
4956
|
+
const clock = {
|
|
4957
|
+
msgType,
|
|
4958
|
+
top: getBitU(b, 38, 11) * 300,
|
|
4959
|
+
uraNed0: getBitS(b, 49, 5),
|
|
4960
|
+
uraNed1: getBitU(b, 54, 3),
|
|
4961
|
+
uraNed2: getBitU(b, 57, 3),
|
|
4962
|
+
toc: getBitU(b, 60, 11) * 300,
|
|
4963
|
+
af0: getBitS(b, 71, 26) * 2 ** -35,
|
|
4964
|
+
af1: getBitS(b, 97, 20) * 2 ** -48,
|
|
4965
|
+
af2: getBitS(b, 117, 10) * 2 ** -60
|
|
4966
|
+
};
|
|
4967
|
+
if (msgType === 30) {
|
|
4968
|
+
clock.tgd = isc(b, 127);
|
|
4969
|
+
clock.iscL1ca = isc(b, 140);
|
|
4970
|
+
clock.iscL2c = isc(b, 153);
|
|
4971
|
+
clock.iscL5i5 = isc(b, 166);
|
|
4972
|
+
clock.iscL5q5 = isc(b, 179);
|
|
4973
|
+
clock.ionoAlpha = [
|
|
4974
|
+
getBitS(b, 192, 8) * 2 ** -30,
|
|
4975
|
+
getBitS(b, 200, 8) * 2 ** -27,
|
|
4976
|
+
getBitS(b, 208, 8) * 2 ** -24,
|
|
4977
|
+
getBitS(b, 216, 8) * 2 ** -24
|
|
4978
|
+
];
|
|
4979
|
+
clock.ionoBeta = [
|
|
4980
|
+
getBitS(b, 224, 8) * 2 ** 11,
|
|
4981
|
+
getBitS(b, 232, 8) * 2 ** 14,
|
|
4982
|
+
getBitS(b, 240, 8) * 2 ** 16,
|
|
4983
|
+
getBitS(b, 248, 8) * 2 ** 16
|
|
4984
|
+
];
|
|
4985
|
+
clock.wnOp = getBitU(b, 256, 8);
|
|
4986
|
+
}
|
|
4987
|
+
return clock;
|
|
4988
|
+
}
|
|
4989
|
+
function resolveWeek(week, towSec, sec) {
|
|
4990
|
+
if (sec < towSec - HALF_WEEK) return week + 1;
|
|
4991
|
+
if (sec > towSec + HALF_WEEK) return week - 1;
|
|
4992
|
+
return week;
|
|
4993
|
+
}
|
|
4994
|
+
function gpsDate(week, sec) {
|
|
4995
|
+
return new Date(GPS_EPOCH_MS2 + (week * SEC_PER_WEEK2 + sec) * 1e3);
|
|
4996
|
+
}
|
|
4997
|
+
var CnavAssembler = class {
|
|
4998
|
+
sats = /* @__PURE__ */ new Map();
|
|
4999
|
+
/**
|
|
5000
|
+
* Push one 300-bit CNAV message (38+ bytes, bit 0 = first bit of
|
|
5001
|
+
* the preamble). Returns the newly completed ephemeris, or null.
|
|
5002
|
+
* Messages that are not MT10/MT11/MT30-37, or whose preamble/PRN
|
|
5003
|
+
* are out of range, are ignored.
|
|
5004
|
+
*/
|
|
5005
|
+
push(msg) {
|
|
5006
|
+
if (msg.length < 38 || getBitU(msg, 0, 8) !== CNAV_PREAMBLE) return null;
|
|
5007
|
+
const prn = getBitU(msg, 8, 6);
|
|
5008
|
+
if (prn < 1 || prn > 32) return null;
|
|
5009
|
+
const type = getBitU(msg, 14, 6);
|
|
5010
|
+
const tow = getBitU(msg, 20, 17) * 6;
|
|
5011
|
+
let sat = this.sats.get(prn);
|
|
5012
|
+
if (!sat) {
|
|
5013
|
+
sat = {};
|
|
5014
|
+
this.sats.set(prn, sat);
|
|
5015
|
+
}
|
|
5016
|
+
if (type === 10) sat.t10 = decodeType10(msg, tow);
|
|
5017
|
+
else if (type === 11) sat.t11 = decodeType11(msg);
|
|
5018
|
+
else if (type >= 30 && type <= 37) {
|
|
5019
|
+
sat.clock = decodeClock(msg, type);
|
|
5020
|
+
if (type === 30) sat.extras = sat.clock;
|
|
5021
|
+
} else return null;
|
|
5022
|
+
return this.tryEmit(prn, sat);
|
|
5023
|
+
}
|
|
5024
|
+
tryEmit(prn, sat) {
|
|
5025
|
+
const { t10, t11, clock, extras } = sat;
|
|
5026
|
+
if (!t10 || !t11 || !clock) return null;
|
|
5027
|
+
if (t10.toe !== t11.toe || clock.toc !== t10.toe) return null;
|
|
5028
|
+
const key = `${t10.week}:${t10.toe}:${clock.af0}:${clock.af1}`;
|
|
5029
|
+
if (key === sat.lastKey) return null;
|
|
5030
|
+
sat.lastKey = key;
|
|
5031
|
+
const weekToe = resolveWeek(t10.week, t10.tow, t10.toe);
|
|
5032
|
+
const a = CNAV_A_REF + t10.deltaA;
|
|
5033
|
+
return {
|
|
5034
|
+
system: "G",
|
|
5035
|
+
prn: `G${String(prn).padStart(2, "0")}`,
|
|
5036
|
+
week: t10.week,
|
|
5037
|
+
health: t10.health,
|
|
5038
|
+
uraEd: t10.uraEd,
|
|
5039
|
+
uraNed0: clock.uraNed0,
|
|
5040
|
+
uraNed1: clock.uraNed1,
|
|
5041
|
+
uraNed2: clock.uraNed2,
|
|
5042
|
+
top: t10.top,
|
|
5043
|
+
toe: t10.toe,
|
|
5044
|
+
toeDate: gpsDate(weekToe, t10.toe),
|
|
5045
|
+
a,
|
|
5046
|
+
deltaA: t10.deltaA,
|
|
5047
|
+
aDot: t10.aDot,
|
|
5048
|
+
deltaN0: t10.deltaN0,
|
|
5049
|
+
deltaN0Dot: t10.deltaN0Dot,
|
|
5050
|
+
m0: t10.m0,
|
|
5051
|
+
e: t10.e,
|
|
5052
|
+
omega: t10.omega,
|
|
5053
|
+
omega0: t11.omega0,
|
|
5054
|
+
i0: t11.i0,
|
|
5055
|
+
omegaDot: CNAV_OMEGA_DOT_REF * GPS_PI + t11.deltaOmegaDot,
|
|
5056
|
+
deltaOmegaDot: t11.deltaOmegaDot,
|
|
5057
|
+
i0Dot: t11.i0Dot,
|
|
5058
|
+
cis: t11.cis,
|
|
5059
|
+
cic: t11.cic,
|
|
5060
|
+
crs: t11.crs,
|
|
5061
|
+
crc: t11.crc,
|
|
5062
|
+
cus: t11.cus,
|
|
5063
|
+
cuc: t11.cuc,
|
|
5064
|
+
toc: clock.toc,
|
|
5065
|
+
tocDate: gpsDate(weekToe, clock.toc),
|
|
5066
|
+
af0: clock.af0,
|
|
5067
|
+
af1: clock.af1,
|
|
5068
|
+
af2: clock.af2,
|
|
5069
|
+
clockMsgType: clock.msgType,
|
|
5070
|
+
tgd: extras?.tgd ?? null,
|
|
5071
|
+
iscL1ca: extras?.iscL1ca ?? null,
|
|
5072
|
+
iscL2c: extras?.iscL2c ?? null,
|
|
5073
|
+
iscL5i5: extras?.iscL5i5 ?? null,
|
|
5074
|
+
iscL5q5: extras?.iscL5q5 ?? null,
|
|
5075
|
+
...extras?.ionoAlpha && { ionoAlpha: extras.ionoAlpha },
|
|
5076
|
+
...extras?.ionoBeta && { ionoBeta: extras.ionoBeta },
|
|
5077
|
+
...extras?.wnOp !== void 0 && { wnOp: extras.wnOp },
|
|
5078
|
+
integrityFlag: t10.integrityFlag,
|
|
5079
|
+
l2cPhasing: t10.l2cPhasing,
|
|
5080
|
+
tow: t10.tow
|
|
5081
|
+
};
|
|
5082
|
+
}
|
|
5083
|
+
};
|
|
5084
|
+
|
|
5085
|
+
// src/ubx/cnav.ts
|
|
5086
|
+
function parseUbxCnav(data) {
|
|
5087
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
5088
|
+
const assembler = new CnavAssembler();
|
|
5089
|
+
const ephemerides = [];
|
|
5090
|
+
let badCrc = 0;
|
|
5091
|
+
let messages = 0;
|
|
5092
|
+
for (const f of ubxFrames(data)) {
|
|
5093
|
+
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
5094
|
+
const p = f.payload;
|
|
5095
|
+
if (p.length < 8 + 40) continue;
|
|
5096
|
+
if (p[0] !== 0 || p[2] !== 3 && p[2] !== 4) continue;
|
|
5097
|
+
const svId = p[1];
|
|
5098
|
+
if (svId < 1 || svId > 32) continue;
|
|
5099
|
+
messages++;
|
|
5100
|
+
const msg = new Uint8Array(40);
|
|
5101
|
+
const base = f.payloadStart + 8;
|
|
5102
|
+
for (let k = 0; k < 10; k++) {
|
|
5103
|
+
const w = view.getUint32(base + 4 * k, true);
|
|
5104
|
+
msg[4 * k] = w >>> 24;
|
|
5105
|
+
msg[4 * k + 1] = w >>> 16 & 255;
|
|
5106
|
+
msg[4 * k + 2] = w >>> 8 & 255;
|
|
5107
|
+
msg[4 * k + 3] = w & 255;
|
|
5108
|
+
}
|
|
5109
|
+
if (!cnavCrcOk(msg)) {
|
|
5110
|
+
badCrc++;
|
|
5111
|
+
continue;
|
|
5112
|
+
}
|
|
5113
|
+
const eph = assembler.push(msg);
|
|
5114
|
+
if (eph) ephemerides.push(eph);
|
|
5115
|
+
}
|
|
5116
|
+
return { ephemerides, badCrc, messages };
|
|
5117
|
+
}
|
|
5118
|
+
|
|
5119
|
+
// src/ubx/index.ts
|
|
5120
|
+
var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
|
|
4854
5121
|
var MS_PER_WEEK2 = 7 * 864e5;
|
|
4855
5122
|
var SIGNALS = {
|
|
4856
5123
|
0: { 0: ["G", "1C"], 3: ["G", "2X"], 4: ["G", "2X"] },
|
|
@@ -4933,7 +5200,7 @@ function parseUbxRawx(data) {
|
|
|
4933
5200
|
if (!codes.includes(sig[1])) codes.push(sig[1]);
|
|
4934
5201
|
}
|
|
4935
5202
|
epochs.push({
|
|
4936
|
-
timeMs:
|
|
5203
|
+
timeMs: GPS_EPOCH_MS3 + week * MS_PER_WEEK2 + Math.round(rcvTow * 1e3),
|
|
4937
5204
|
leapS: leapValid ? leapS : null,
|
|
4938
5205
|
meas
|
|
4939
5206
|
});
|
|
@@ -5004,10 +5271,10 @@ function svidToPrn(svid) {
|
|
|
5004
5271
|
|
|
5005
5272
|
// src/sbf/nav.ts
|
|
5006
5273
|
var PI2 = Math.PI;
|
|
5007
|
-
var
|
|
5274
|
+
var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
|
|
5008
5275
|
var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
|
|
5009
|
-
var
|
|
5010
|
-
var MS_PER_WEEK3 =
|
|
5276
|
+
var SEC_PER_WEEK3 = 7 * 86400;
|
|
5277
|
+
var MS_PER_WEEK3 = SEC_PER_WEEK3 * 1e3;
|
|
5011
5278
|
var F4_DNU = -2e10;
|
|
5012
5279
|
var U4_DNU = 4294967295;
|
|
5013
5280
|
function adjustWeek(refWeek, wn, mod) {
|
|
@@ -5016,8 +5283,8 @@ function adjustWeek(refWeek, wn, mod) {
|
|
|
5016
5283
|
if (offset < -(mod / 2 - 1)) offset += mod;
|
|
5017
5284
|
return refWeek - offset;
|
|
5018
5285
|
}
|
|
5019
|
-
var gpsMs = (week, sec) =>
|
|
5020
|
-
var sowOf = (dateMs) => dateMs / 1e3 %
|
|
5286
|
+
var gpsMs = (week, sec) => GPS_EPOCH_MS4 + week * MS_PER_WEEK3 + sec * 1e3;
|
|
5287
|
+
var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK3;
|
|
5021
5288
|
function decodeGpsQzsNav(view, b, sys) {
|
|
5022
5289
|
const svid = view.getUint8(b + 14);
|
|
5023
5290
|
const prn = sys === "G" ? svid : svid - 180;
|
|
@@ -5166,7 +5433,7 @@ function decodeGloNav(view, b) {
|
|
|
5166
5433
|
const tocDate = new Date(toeGpsMs - leapMs);
|
|
5167
5434
|
const tofGpsMs = gpsMs(wnc, 0) + view.getUint32(b + 8, true);
|
|
5168
5435
|
const tofLeapMs = getGpsLeap(new Date(tofGpsMs)) * 1e3;
|
|
5169
|
-
const messageFrameTime = (tofGpsMs - tofLeapMs -
|
|
5436
|
+
const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS4) / 1e3 % SEC_PER_WEEK3;
|
|
5170
5437
|
return {
|
|
5171
5438
|
system: "R",
|
|
5172
5439
|
prn,
|
|
@@ -5311,9 +5578,78 @@ function parseSbfAlmanac(data) {
|
|
|
5311
5578
|
return { almanacs, badCrc };
|
|
5312
5579
|
}
|
|
5313
5580
|
|
|
5581
|
+
// src/sbf/iono.ts
|
|
5582
|
+
var F4_DNU2 = -2e10;
|
|
5583
|
+
function parseSbfIonoUtc(data) {
|
|
5584
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
5585
|
+
const ionoCorrections = {};
|
|
5586
|
+
let leapSeconds = null;
|
|
5587
|
+
const f4s = (b, n) => {
|
|
5588
|
+
const out = [];
|
|
5589
|
+
for (let k = 0; k < n; k++) {
|
|
5590
|
+
const v = view.getFloat32(b + 4 * k, true);
|
|
5591
|
+
if (v === F4_DNU2) return null;
|
|
5592
|
+
out.push(v);
|
|
5593
|
+
}
|
|
5594
|
+
return out;
|
|
5595
|
+
};
|
|
5596
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
5597
|
+
if ((id === 5893 || id === 4120) && len >= 48) {
|
|
5598
|
+
const alpha = f4s(b + 16, 4);
|
|
5599
|
+
const beta = f4s(b + 32, 4);
|
|
5600
|
+
if (!alpha || !beta) return;
|
|
5601
|
+
const sys = id === 5893 ? "GPS" : "BDS";
|
|
5602
|
+
ionoCorrections[`${sys}A`] = alpha;
|
|
5603
|
+
ionoCorrections[`${sys}B`] = beta;
|
|
5604
|
+
} else if (id === 4030 && len >= 28) {
|
|
5605
|
+
const ai = f4s(b + 16, 3);
|
|
5606
|
+
if (ai) ionoCorrections["GAL"] = ai;
|
|
5607
|
+
} else if (id === 5894 && len >= 37) {
|
|
5608
|
+
leapSeconds = view.getInt8(b + 33);
|
|
5609
|
+
}
|
|
5610
|
+
});
|
|
5611
|
+
return { ionoCorrections, leapSeconds };
|
|
5612
|
+
}
|
|
5613
|
+
|
|
5614
|
+
// src/sbf/rawnav.ts
|
|
5615
|
+
var SIGNAL_OF_BLOCK = {
|
|
5616
|
+
4018: "L2C",
|
|
5617
|
+
4019: "L5"
|
|
5618
|
+
};
|
|
5619
|
+
function parseSbfCnav(data) {
|
|
5620
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
5621
|
+
const ephemerides = [];
|
|
5622
|
+
const assemblers = {
|
|
5623
|
+
L2C: new CnavAssembler(),
|
|
5624
|
+
L5: new CnavAssembler()
|
|
5625
|
+
};
|
|
5626
|
+
let badCrc = 0;
|
|
5627
|
+
let messages = 0;
|
|
5628
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
5629
|
+
const signal = SIGNAL_OF_BLOCK[id];
|
|
5630
|
+
if (!signal || len < 60) return;
|
|
5631
|
+
messages++;
|
|
5632
|
+
const msg = new Uint8Array(40);
|
|
5633
|
+
for (let k = 0; k < 10; k++) {
|
|
5634
|
+
const w = view.getUint32(b + 20 + 4 * k, true);
|
|
5635
|
+
msg[4 * k] = w >>> 24;
|
|
5636
|
+
msg[4 * k + 1] = w >>> 16 & 255;
|
|
5637
|
+
msg[4 * k + 2] = w >>> 8 & 255;
|
|
5638
|
+
msg[4 * k + 3] = w & 255;
|
|
5639
|
+
}
|
|
5640
|
+
if (!cnavCrcOk(msg)) {
|
|
5641
|
+
badCrc++;
|
|
5642
|
+
return;
|
|
5643
|
+
}
|
|
5644
|
+
const eph = assemblers[signal].push(msg);
|
|
5645
|
+
if (eph) ephemerides.push({ ...eph, signal });
|
|
5646
|
+
});
|
|
5647
|
+
return { ephemerides, badCrc, messages };
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5314
5650
|
// src/sbf/index.ts
|
|
5315
5651
|
var CLIGHT = 299792458;
|
|
5316
|
-
var
|
|
5652
|
+
var GPS_EPOCH_MS5 = Date.UTC(1980, 0, 6);
|
|
5317
5653
|
var MS_PER_WEEK4 = 7 * 864e5;
|
|
5318
5654
|
var M3_SYS = ["G", "R", "E", "C", "S", "J", "I"];
|
|
5319
5655
|
var M3_PR_BASE = [19e6, 19e6, 22e6, 2e7, 34e6, 34e6, 34e6];
|
|
@@ -5967,7 +6303,7 @@ function parseSbfMeas(data) {
|
|
|
5967
6303
|
const tow = view.getUint32(i + 8, true);
|
|
5968
6304
|
const wnc = view.getUint16(i + 12, true);
|
|
5969
6305
|
if (tow !== 4294967295 && wnc !== 65535) {
|
|
5970
|
-
ensureEpoch(
|
|
6306
|
+
ensureEpoch(GPS_EPOCH_MS5 + wnc * MS_PER_WEEK4 + tow);
|
|
5971
6307
|
if (id === 4109) decodeMeas3Ranges(i, tow);
|
|
5972
6308
|
else if (id === 4110) decodeMeas3CN0(i, len);
|
|
5973
6309
|
else if (id === 4111) decodeMeas3Doppler(i, len);
|
|
@@ -6024,11 +6360,27 @@ function* oem4Frames(data, view, stats) {
|
|
|
6024
6360
|
}
|
|
6025
6361
|
|
|
6026
6362
|
// src/novatel/nav.ts
|
|
6363
|
+
var ID_IONUTC = 8;
|
|
6027
6364
|
var ID_RAWEPHEM = 41;
|
|
6028
6365
|
var ID_GLOEPHEMERIS = 723;
|
|
6029
|
-
var
|
|
6030
|
-
var
|
|
6366
|
+
var ID_GALEPHEMERIS = 1122;
|
|
6367
|
+
var ID_QZSSEPHEMERIS = 1336;
|
|
6368
|
+
var ID_GPSEPHEM = 7;
|
|
6369
|
+
var ID_BDSEPHEMERIS = 1696;
|
|
6370
|
+
var GPS_EPOCH_MS6 = Date.UTC(1980, 0, 6);
|
|
6371
|
+
var BDT_EPOCH_MS2 = Date.UTC(2006, 0, 1);
|
|
6372
|
+
var SEC_PER_WEEK4 = 7 * 86400;
|
|
6031
6373
|
var SEC_PER_DAY = 86400;
|
|
6374
|
+
var MS_PER_WEEK5 = SEC_PER_WEEK4 * 1e3;
|
|
6375
|
+
var gpsMs2 = (week, sec) => GPS_EPOCH_MS6 + week * MS_PER_WEEK5 + sec * 1e3;
|
|
6376
|
+
var sowOf2 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK4;
|
|
6377
|
+
function nearWeekMs(refMs, sow) {
|
|
6378
|
+
const refWeek = Math.floor((refMs - GPS_EPOCH_MS6) / MS_PER_WEEK5);
|
|
6379
|
+
let ms = gpsMs2(refWeek, sow);
|
|
6380
|
+
if (ms < refMs - MS_PER_WEEK5 / 2) ms += MS_PER_WEEK5;
|
|
6381
|
+
else if (ms > refMs + MS_PER_WEEK5 / 2) ms -= MS_PER_WEEK5;
|
|
6382
|
+
return ms;
|
|
6383
|
+
}
|
|
6032
6384
|
function decodeRawEphem(data, view, p) {
|
|
6033
6385
|
const prn = view.getUint32(p, true);
|
|
6034
6386
|
if (prn < 1 || prn > 32) return null;
|
|
@@ -6050,9 +6402,9 @@ function decodeGloEphemeris(view, p) {
|
|
|
6050
6402
|
tof += Math.floor(tow / SEC_PER_DAY) * SEC_PER_DAY;
|
|
6051
6403
|
if (tof < tow - 43200) tof += SEC_PER_DAY;
|
|
6052
6404
|
else if (tof > tow + 43200) tof -= SEC_PER_DAY;
|
|
6053
|
-
const toeGpsMs =
|
|
6054
|
-
const tofGpsMs =
|
|
6055
|
-
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() -
|
|
6405
|
+
const toeGpsMs = GPS_EPOCH_MS6 + (week * SEC_PER_WEEK4 + tow) * 1e3;
|
|
6406
|
+
const tofGpsMs = GPS_EPOCH_MS6 + (week * SEC_PER_WEEK4 + tof) * 1e3;
|
|
6407
|
+
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS6) / 1e3;
|
|
6056
6408
|
return {
|
|
6057
6409
|
system: "R",
|
|
6058
6410
|
prn: `R${String(slot).padStart(2, "0")}`,
|
|
@@ -6060,7 +6412,7 @@ function decodeGloEphemeris(view, p) {
|
|
|
6060
6412
|
tauN: -view.getFloat64(p + 100, true),
|
|
6061
6413
|
// RINEX stores −τ_n
|
|
6062
6414
|
gammaN: view.getFloat64(p + 116, true),
|
|
6063
|
-
messageFrameTime: (tofUtcSec %
|
|
6415
|
+
messageFrameTime: (tofUtcSec % SEC_PER_WEEK4 + SEC_PER_WEEK4) % SEC_PER_WEEK4,
|
|
6064
6416
|
x: view.getFloat64(p + 28, true) / 1e3,
|
|
6065
6417
|
y: view.getFloat64(p + 36, true) / 1e3,
|
|
6066
6418
|
z: view.getFloat64(p + 44, true) / 1e3,
|
|
@@ -6074,23 +6426,188 @@ function decodeGloEphemeris(view, p) {
|
|
|
6074
6426
|
freqNum
|
|
6075
6427
|
};
|
|
6076
6428
|
}
|
|
6429
|
+
function decodeGalEphemeris(view, p, headerMs) {
|
|
6430
|
+
const prn = view.getUint32(p, true);
|
|
6431
|
+
if (prn < 1 || prn > 36) return null;
|
|
6432
|
+
const fnav = (view.getUint32(p + 4, true) & 1) !== 0;
|
|
6433
|
+
const svhE1b = view.getUint8(p + 12) & 3;
|
|
6434
|
+
const svhE5a = view.getUint8(p + 13) & 3;
|
|
6435
|
+
const svhE5b = view.getUint8(p + 14) & 3;
|
|
6436
|
+
const dvsE1b = view.getUint8(p + 15) & 1;
|
|
6437
|
+
const dvsE5a = view.getUint8(p + 16) & 1;
|
|
6438
|
+
const dvsE5b = view.getUint8(p + 17) & 1;
|
|
6439
|
+
const iodNav = view.getUint32(p + 20, true);
|
|
6440
|
+
const toes = view.getUint32(p + 24, true);
|
|
6441
|
+
const c = fnav ? p + 148 : p + 176;
|
|
6442
|
+
const tocs = view.getUint32(c, true);
|
|
6443
|
+
const toeMs = nearWeekMs(headerMs, toes);
|
|
6444
|
+
const tocDate = new Date(nearWeekMs(headerMs, tocs));
|
|
6445
|
+
return {
|
|
6446
|
+
fnav,
|
|
6447
|
+
eph: {
|
|
6448
|
+
system: "E",
|
|
6449
|
+
prn: `E${String(prn).padStart(2, "0")}`,
|
|
6450
|
+
toc: sowOf2(tocDate.getTime()),
|
|
6451
|
+
tocDate,
|
|
6452
|
+
af0: view.getFloat64(c + 4, true),
|
|
6453
|
+
af1: view.getFloat64(c + 12, true),
|
|
6454
|
+
af2: view.getFloat64(c + 20, true),
|
|
6455
|
+
iode: iodNav,
|
|
6456
|
+
crs: view.getFloat64(p + 92, true),
|
|
6457
|
+
deltaN: view.getFloat64(p + 36, true),
|
|
6458
|
+
m0: view.getFloat64(p + 44, true),
|
|
6459
|
+
cuc: view.getFloat64(p + 68, true),
|
|
6460
|
+
e: view.getFloat64(p + 52, true),
|
|
6461
|
+
cus: view.getFloat64(p + 76, true),
|
|
6462
|
+
sqrtA: view.getFloat64(p + 28, true),
|
|
6463
|
+
toe: toes,
|
|
6464
|
+
cic: view.getFloat64(p + 100, true),
|
|
6465
|
+
omega0: view.getFloat64(p + 132, true),
|
|
6466
|
+
cis: view.getFloat64(p + 108, true),
|
|
6467
|
+
i0: view.getFloat64(p + 116, true),
|
|
6468
|
+
crc: view.getFloat64(p + 84, true),
|
|
6469
|
+
omega: view.getFloat64(p + 60, true),
|
|
6470
|
+
omegaDot: view.getFloat64(p + 140, true),
|
|
6471
|
+
idot: view.getFloat64(p + 124, true),
|
|
6472
|
+
week: Math.floor((toeMs - GPS_EPOCH_MS6) / MS_PER_WEEK5),
|
|
6473
|
+
// RINEX Galileo SVH bit layout (E1B DVS/HS in bits 0-2, E5a in
|
|
6474
|
+
// 3-5, E5b in 6-8) — same packing as RTKLIB.
|
|
6475
|
+
svHealth: svhE5b << 7 | dvsE5b << 6 | svhE5a << 4 | dvsE5a << 3 | svhE1b << 1 | dvsE1b,
|
|
6476
|
+
tgd: view.getFloat64(p + 204, true)
|
|
6477
|
+
// BGD E5a/E1 (RINEX slot)
|
|
6478
|
+
}
|
|
6479
|
+
};
|
|
6480
|
+
}
|
|
6481
|
+
function decodeBdsEphemeris2(view, p) {
|
|
6482
|
+
const prn = view.getUint32(p, true);
|
|
6483
|
+
if (prn < 1 || prn > 63) return null;
|
|
6484
|
+
const week = view.getUint32(p + 4, true);
|
|
6485
|
+
const health = view.getUint32(p + 16, true) & 1;
|
|
6486
|
+
const tgd1 = view.getFloat64(p + 20, true);
|
|
6487
|
+
const tocs = view.getUint32(p + 40, true);
|
|
6488
|
+
const toes = view.getUint32(p + 72, true);
|
|
6489
|
+
const tocDate = new Date(BDT_EPOCH_MS2 + week * MS_PER_WEEK5 + tocs * 1e3);
|
|
6490
|
+
return {
|
|
6491
|
+
system: "C",
|
|
6492
|
+
prn: `C${String(prn).padStart(2, "0")}`,
|
|
6493
|
+
toc: sowOf2(tocDate.getTime()),
|
|
6494
|
+
tocDate,
|
|
6495
|
+
af0: view.getFloat64(p + 44, true),
|
|
6496
|
+
af1: view.getFloat64(p + 52, true),
|
|
6497
|
+
af2: view.getFloat64(p + 60, true),
|
|
6498
|
+
iode: view.getUint32(p + 68, true),
|
|
6499
|
+
// AODE
|
|
6500
|
+
crs: view.getFloat64(p + 172, true),
|
|
6501
|
+
deltaN: view.getFloat64(p + 100, true),
|
|
6502
|
+
m0: view.getFloat64(p + 108, true),
|
|
6503
|
+
cuc: view.getFloat64(p + 148, true),
|
|
6504
|
+
e: view.getFloat64(p + 84, true),
|
|
6505
|
+
cus: view.getFloat64(p + 156, true),
|
|
6506
|
+
sqrtA: view.getFloat64(p + 76, true),
|
|
6507
|
+
toe: toes,
|
|
6508
|
+
cic: view.getFloat64(p + 180, true),
|
|
6509
|
+
omega0: view.getFloat64(p + 116, true),
|
|
6510
|
+
cis: view.getFloat64(p + 188, true),
|
|
6511
|
+
i0: view.getFloat64(p + 132, true),
|
|
6512
|
+
crc: view.getFloat64(p + 164, true),
|
|
6513
|
+
omega: view.getFloat64(p + 92, true),
|
|
6514
|
+
omegaDot: view.getFloat64(p + 124, true),
|
|
6515
|
+
idot: view.getFloat64(p + 140, true),
|
|
6516
|
+
week,
|
|
6517
|
+
// RINEX BDS week field is the BDT week
|
|
6518
|
+
svHealth: health,
|
|
6519
|
+
tgd: tgd1
|
|
6520
|
+
// TGD1 (B1) — RINEX slot
|
|
6521
|
+
};
|
|
6522
|
+
}
|
|
6523
|
+
function decodeGpsQzssEphemeris(view, p, sys) {
|
|
6524
|
+
const prn = view.getUint32(p, true);
|
|
6525
|
+
if (sys === "G" && (prn < 1 || prn > 32)) return null;
|
|
6526
|
+
if (sys === "J" && (prn < 193 || prn > 202)) return null;
|
|
6527
|
+
const health = view.getUint32(p + 12, true) & 63;
|
|
6528
|
+
const iode1 = view.getUint32(p + 16, true);
|
|
6529
|
+
const week = view.getUint32(p + 24, true);
|
|
6530
|
+
const toes = view.getFloat64(p + 32, true);
|
|
6531
|
+
const toeMs = gpsMs2(week, toes);
|
|
6532
|
+
const tocs = view.getFloat64(p + 164, true);
|
|
6533
|
+
const tocDate = new Date(nearWeekMs(toeMs, tocs));
|
|
6534
|
+
return {
|
|
6535
|
+
system: sys,
|
|
6536
|
+
prn: `${sys}${String(sys === "J" ? prn - 192 : prn).padStart(2, "0")}`,
|
|
6537
|
+
toc: sowOf2(tocDate.getTime()),
|
|
6538
|
+
tocDate,
|
|
6539
|
+
af0: view.getFloat64(p + 180, true),
|
|
6540
|
+
af1: view.getFloat64(p + 188, true),
|
|
6541
|
+
af2: view.getFloat64(p + 196, true),
|
|
6542
|
+
iode: iode1,
|
|
6543
|
+
crs: view.getFloat64(p + 104, true),
|
|
6544
|
+
deltaN: view.getFloat64(p + 48, true),
|
|
6545
|
+
m0: view.getFloat64(p + 56, true),
|
|
6546
|
+
cuc: view.getFloat64(p + 80, true),
|
|
6547
|
+
e: view.getFloat64(p + 64, true),
|
|
6548
|
+
cus: view.getFloat64(p + 88, true),
|
|
6549
|
+
sqrtA: Math.sqrt(view.getFloat64(p + 40, true)),
|
|
6550
|
+
toe: toes,
|
|
6551
|
+
cic: view.getFloat64(p + 112, true),
|
|
6552
|
+
omega0: view.getFloat64(p + 144, true),
|
|
6553
|
+
cis: view.getFloat64(p + 120, true),
|
|
6554
|
+
i0: view.getFloat64(p + 128, true),
|
|
6555
|
+
crc: view.getFloat64(p + 96, true),
|
|
6556
|
+
omega: view.getFloat64(p + 72, true),
|
|
6557
|
+
omegaDot: view.getFloat64(p + 152, true),
|
|
6558
|
+
idot: view.getFloat64(p + 136, true),
|
|
6559
|
+
week,
|
|
6560
|
+
svHealth: health,
|
|
6561
|
+
tgd: view.getFloat64(p + 172, true)
|
|
6562
|
+
};
|
|
6563
|
+
}
|
|
6077
6564
|
function parseNovatelNav(data) {
|
|
6078
6565
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
6079
6566
|
const stats = { badCrc: 0 };
|
|
6080
6567
|
const ephemerides = [];
|
|
6081
|
-
const
|
|
6568
|
+
const ionoCorrections = {};
|
|
6569
|
+
let leapSeconds = null;
|
|
6570
|
+
const lastKep = /* @__PURE__ */ new Map();
|
|
6082
6571
|
const lastGlo = /* @__PURE__ */ new Map();
|
|
6572
|
+
const pushKepler = (key, eph) => {
|
|
6573
|
+
const prev = lastKep.get(key);
|
|
6574
|
+
if (prev && prev.iode === eph.iode && prev.toe === eph.toe && prev.tocDate.getTime() === eph.tocDate.getTime()) {
|
|
6575
|
+
return;
|
|
6576
|
+
}
|
|
6577
|
+
lastKep.set(key, eph);
|
|
6578
|
+
ephemerides.push(eph);
|
|
6579
|
+
};
|
|
6083
6580
|
for (const frame of oem4Frames(data, view, stats)) {
|
|
6084
6581
|
if (!frame.binary) continue;
|
|
6085
6582
|
if (frame.id === ID_RAWEPHEM && frame.msgLen >= 102) {
|
|
6086
6583
|
const eph = decodeRawEphem(data, view, frame.payload);
|
|
6087
|
-
if (
|
|
6088
|
-
|
|
6089
|
-
if (
|
|
6090
|
-
|
|
6584
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
6585
|
+
} else if (frame.id === ID_GALEPHEMERIS && frame.msgLen >= 220) {
|
|
6586
|
+
if (frame.week === 0) continue;
|
|
6587
|
+
const headerMs = gpsMs2(frame.week, frame.towMs / 1e3);
|
|
6588
|
+
const dec = decodeGalEphemeris(view, frame.payload, headerMs);
|
|
6589
|
+
if (dec)
|
|
6590
|
+
pushKepler(`${dec.eph.prn}:${dec.fnav ? "fnav" : "inav"}`, dec.eph);
|
|
6591
|
+
} else if (frame.id === ID_BDSEPHEMERIS && frame.msgLen >= 196) {
|
|
6592
|
+
const eph = decodeBdsEphemeris2(view, frame.payload);
|
|
6593
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
6594
|
+
} else if (frame.id === ID_GPSEPHEM && frame.msgLen >= 204) {
|
|
6595
|
+
const eph = decodeGpsQzssEphemeris(view, frame.payload, "G");
|
|
6596
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
6597
|
+
} else if (frame.id === ID_QZSSEPHEMERIS && frame.msgLen >= 204) {
|
|
6598
|
+
const eph = decodeGpsQzssEphemeris(view, frame.payload, "J");
|
|
6599
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
6600
|
+
} else if (frame.id === ID_IONUTC && frame.msgLen >= 108) {
|
|
6601
|
+
const p = frame.payload;
|
|
6602
|
+
const alpha = [];
|
|
6603
|
+
const beta = [];
|
|
6604
|
+
for (let i = 0; i < 4; i++) {
|
|
6605
|
+
alpha.push(view.getFloat64(p + i * 8, true));
|
|
6606
|
+
beta.push(view.getFloat64(p + 32 + i * 8, true));
|
|
6091
6607
|
}
|
|
6092
|
-
|
|
6093
|
-
|
|
6608
|
+
ionoCorrections["GPSA"] = alpha;
|
|
6609
|
+
ionoCorrections["GPSB"] = beta;
|
|
6610
|
+
leapSeconds = view.getInt32(p + 96, true);
|
|
6094
6611
|
} else if (frame.id === ID_GLOEPHEMERIS && frame.msgLen >= 144) {
|
|
6095
6612
|
const eph = decodeGloEphemeris(view, frame.payload);
|
|
6096
6613
|
if (!eph) continue;
|
|
@@ -6102,12 +6619,12 @@ function parseNovatelNav(data) {
|
|
|
6102
6619
|
ephemerides.push(eph);
|
|
6103
6620
|
}
|
|
6104
6621
|
}
|
|
6105
|
-
return { ephemerides, badCrc: stats.badCrc };
|
|
6622
|
+
return { ephemerides, ionoCorrections, leapSeconds, badCrc: stats.badCrc };
|
|
6106
6623
|
}
|
|
6107
6624
|
|
|
6108
6625
|
// src/novatel/index.ts
|
|
6109
|
-
var
|
|
6110
|
-
var
|
|
6626
|
+
var GPS_EPOCH_MS7 = Date.UTC(1980, 0, 6);
|
|
6627
|
+
var MS_PER_WEEK6 = 7 * 864e5;
|
|
6111
6628
|
var HDR = 28;
|
|
6112
6629
|
var ID_RANGE = 43;
|
|
6113
6630
|
var ID_RANGECMP = 140;
|
|
@@ -6276,7 +6793,7 @@ function parseNovatelRange(data) {
|
|
|
6276
6793
|
if (!codes.includes(code)) codes.push(code);
|
|
6277
6794
|
}
|
|
6278
6795
|
epochs.push({
|
|
6279
|
-
timeMs:
|
|
6796
|
+
timeMs: GPS_EPOCH_MS7 + week * MS_PER_WEEK6 + towMs,
|
|
6280
6797
|
meas
|
|
6281
6798
|
});
|
|
6282
6799
|
}
|
|
@@ -6328,7 +6845,7 @@ function parseNovatelRange(data) {
|
|
|
6328
6845
|
if (!codes.includes(code)) codes.push(code);
|
|
6329
6846
|
}
|
|
6330
6847
|
epochs.push({
|
|
6331
|
-
timeMs:
|
|
6848
|
+
timeMs: GPS_EPOCH_MS7 + week * MS_PER_WEEK6 + towMs,
|
|
6332
6849
|
meas
|
|
6333
6850
|
});
|
|
6334
6851
|
}
|
|
@@ -6687,10 +7204,10 @@ function selectBest(ephs, timeMs) {
|
|
|
6687
7204
|
}
|
|
6688
7205
|
return best;
|
|
6689
7206
|
}
|
|
6690
|
-
var
|
|
6691
|
-
var
|
|
7207
|
+
var GPS_EPOCH_MS8 = START_GPS_TIME.getTime();
|
|
7208
|
+
var MS_PER_WEEK7 = 7 * 864e5;
|
|
6692
7209
|
var BDS_EPOCH_MS = START_BDS_TIME.getTime();
|
|
6693
|
-
var GAL_EPOCH_MS =
|
|
7210
|
+
var GAL_EPOCH_MS = GPS_EPOCH_MS8 + 1024 * MS_PER_WEEK7;
|
|
6694
7211
|
function ephInfoToEphemeris(info) {
|
|
6695
7212
|
const sys = info.prn.charAt(0);
|
|
6696
7213
|
if (sys === "R") {
|
|
@@ -6741,11 +7258,11 @@ function ephInfoToEphemeris(info) {
|
|
|
6741
7258
|
} else if (sys === "E") {
|
|
6742
7259
|
epochMs = GAL_EPOCH_MS;
|
|
6743
7260
|
} else {
|
|
6744
|
-
epochMs =
|
|
6745
|
-
const weeksNow = (info.lastReceived -
|
|
7261
|
+
epochMs = GPS_EPOCH_MS8;
|
|
7262
|
+
const weeksNow = (info.lastReceived - GPS_EPOCH_MS8) / MS_PER_WEEK7;
|
|
6746
7263
|
week += 1024 * Math.round((weeksNow - week) / 1024);
|
|
6747
7264
|
}
|
|
6748
|
-
const tocDate = new Date(epochMs + week *
|
|
7265
|
+
const tocDate = new Date(epochMs + week * MS_PER_WEEK7 + tocSec * 1e3);
|
|
6749
7266
|
return {
|
|
6750
7267
|
system: sys,
|
|
6751
7268
|
prn: info.prn,
|
|
@@ -9844,11 +10361,15 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
9844
10361
|
parseNovatelRange,
|
|
9845
10362
|
parseRinexStream,
|
|
9846
10363
|
parseSbfAlmanac,
|
|
10364
|
+
parseSbfCnav,
|
|
10365
|
+
parseSbfIonoUtc,
|
|
9847
10366
|
parseSbfMeas,
|
|
9848
10367
|
parseSbfNav,
|
|
9849
10368
|
parseSinexBiasDcb,
|
|
9850
10369
|
parseSourcetable,
|
|
9851
10370
|
parseSp3,
|
|
10371
|
+
parseUbxCnav,
|
|
10372
|
+
parseUbxIonoUtc,
|
|
9852
10373
|
parseUbxNav,
|
|
9853
10374
|
parseUbxRawx,
|
|
9854
10375
|
phiAltBOC,
|