gnss-js 2.9.0 → 2.10.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-6SWJTN6H.js → chunk-56HM5B6T.js} +19 -5
- package/dist/{chunk-NOGA5KD7.js → chunk-K3GLUWZI.js} +61 -0
- package/dist/{chunk-7GNRNKBR.js → chunk-PBENVPFL.js} +28 -10
- package/dist/index.cjs +110 -15
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +7 -3
- package/dist/msm-CcQJV3PC.d.ts +108 -0
- package/dist/msm-DWtoTvx2.d.cts +108 -0
- package/dist/positioning.cjs +62 -0
- package/dist/positioning.d.cts +19 -1
- package/dist/positioning.d.ts +19 -1
- package/dist/positioning.js +3 -1
- package/dist/rinex.cjs +20 -5
- package/dist/rinex.d.cts +10 -1
- package/dist/rinex.d.ts +10 -1
- package/dist/rinex.js +3 -1
- package/dist/rtcm3.cjs +28 -10
- package/dist/rtcm3.d.cts +6 -88
- package/dist/rtcm3.d.ts +6 -88
- package/dist/rtcm3.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { b as Rtcm3Frame } from './ephemeris-BAnBLLB9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Full RTCM3 MSM decoder — extracts pseudorange, carrier phase,
|
|
5
|
+
* Doppler, and C/N0 for every satellite × signal cell.
|
|
6
|
+
*
|
|
7
|
+
* Reference: BNC 2.13.4 RTCM3Decoder.cpp (BKG), RTKLIB rtcm3.c and
|
|
8
|
+
* RTCM 10403.3 §3.5.
|
|
9
|
+
*
|
|
10
|
+
* MSM4–7 carry full observations. MSM1–3 (compact: MSM1 code, MSM2 phase,
|
|
11
|
+
* MSM3 both; no C/N0, no Doppler) carry each satellite's rough range only
|
|
12
|
+
* modulo 1 ms (DF398, no DF397 integer milliseconds): their epochs come back
|
|
13
|
+
* with `rangeModulo1ms` set, ranges complete except for a whole number of
|
|
14
|
+
* light-milliseconds per satellite — see `resolveMsmRanges` (positioning).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Single signal observation for one satellite */
|
|
18
|
+
interface ObsSignal {
|
|
19
|
+
/** RINEX 2-char obs code, e.g. "1C", "5X" */
|
|
20
|
+
rinexCode: string;
|
|
21
|
+
/** Pseudorange in meters (undefined if invalid) */
|
|
22
|
+
pseudorange?: number;
|
|
23
|
+
/** Carrier phase in cycles (undefined if invalid) */
|
|
24
|
+
phase?: number;
|
|
25
|
+
/** Doppler in Hz (undefined if invalid) */
|
|
26
|
+
doppler?: number;
|
|
27
|
+
/** Signal-to-noise ratio in dB-Hz */
|
|
28
|
+
cn0?: number;
|
|
29
|
+
/** Lock time in seconds */
|
|
30
|
+
lockTime?: number;
|
|
31
|
+
/** Half-cycle ambiguity indicator */
|
|
32
|
+
halfCycle?: boolean;
|
|
33
|
+
/** Wavelength used (meters) — needed for RINEX phase */
|
|
34
|
+
wavelength: number;
|
|
35
|
+
}
|
|
36
|
+
/** All observations for one satellite in one epoch */
|
|
37
|
+
interface ObsSatObs {
|
|
38
|
+
/** PRN string, e.g. "G01", "R15", "E04" */
|
|
39
|
+
prn: string;
|
|
40
|
+
/** System letter: G, R, E, C, J, I, S */
|
|
41
|
+
system: string;
|
|
42
|
+
/** Signal observations */
|
|
43
|
+
signals: ObsSignal[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One decoded observation epoch. Originally the MSM4–7 output shape, now the
|
|
47
|
+
* neutral shape every RTCM3 obs source fills: MSM (`decodeMsmFull`), legacy
|
|
48
|
+
* 1001–1012 (`decodeLegacyObs`), via the `decodeObs` dispatcher.
|
|
49
|
+
*/
|
|
50
|
+
interface ObsEpoch {
|
|
51
|
+
/** Message type (1074, 1077, etc.) */
|
|
52
|
+
messageType: number;
|
|
53
|
+
/** Epoch time as GPS milliseconds of week (or GLONASS day-of-week ms, BDS SOW) */
|
|
54
|
+
epochMs: number;
|
|
55
|
+
/** System letter */
|
|
56
|
+
system: string;
|
|
57
|
+
/** Observations per satellite */
|
|
58
|
+
observations: ObsSatObs[];
|
|
59
|
+
/**
|
|
60
|
+
* Set for MSM1–3: every pseudorange and phase is short by an unknown whole
|
|
61
|
+
* number of light-milliseconds (~299.79 km) per satellite. Resolve with
|
|
62
|
+
* `resolveMsmRanges` before using the ranges.
|
|
63
|
+
*/
|
|
64
|
+
rangeModulo1ms?: true;
|
|
65
|
+
}
|
|
66
|
+
/** Options for the RTCM3 observation decoders. */
|
|
67
|
+
interface ObsDecodeOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Also decode compact MSM1–3. Their epochs carry `rangeModulo1ms`: every
|
|
70
|
+
* range is short by whole light-milliseconds until `resolveMsmRanges`
|
|
71
|
+
* completes it, so a consumer must opt in (default false → null, as
|
|
72
|
+
* before).
|
|
73
|
+
*/
|
|
74
|
+
compactMsm?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decode a single RTCM3 MSM frame into observations: MSM4–7, and MSM1–3
|
|
78
|
+
* with `opts.compactMsm` (flagged `rangeModulo1ms`). Null otherwise.
|
|
79
|
+
*/
|
|
80
|
+
declare function decodeMsmFull(frame: Rtcm3Frame, opts?: ObsDecodeOptions): ObsEpoch | null;
|
|
81
|
+
/**
|
|
82
|
+
* Convert an observation epoch timestamp to a Date.
|
|
83
|
+
* For GPS/Galileo/BDS/QZSS: epochMs is ms of GPS week.
|
|
84
|
+
* For GLONASS: epochMs is day-of-week × 86400000 + ms of day (UTC+3).
|
|
85
|
+
*
|
|
86
|
+
* Requires an approximate reference time to resolve the current week.
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* NOTE: returns a GPS-scale Date — the clock-face convention used by
|
|
90
|
+
* the RINEX parser and every consumer of epoch milliseconds in this
|
|
91
|
+
* library (satellite propagation, SPP, RINEX epoch tags). It is NOT
|
|
92
|
+
* UTC: converting to UTC here put every downstream satellite position
|
|
93
|
+
* 18 s (the current leap-second count) off — a ±14 km per-satellite
|
|
94
|
+
* range error that scattered live SPP solutions by kilometres.
|
|
95
|
+
*/
|
|
96
|
+
declare function obsEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
|
|
97
|
+
/**
|
|
98
|
+
* Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
|
|
99
|
+
* e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
|
|
100
|
+
* this the wavelength — and hence carrier phase — stays unknown.
|
|
101
|
+
*/
|
|
102
|
+
declare function setGloFreqNumber(slot: number, k: number): void;
|
|
103
|
+
/**
|
|
104
|
+
* Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
|
|
105
|
+
*/
|
|
106
|
+
declare function resetGloFreqCache(): void;
|
|
107
|
+
|
|
108
|
+
export { type ObsDecodeOptions as O, type ObsEpoch as a, type ObsSatObs as b, type ObsSignal as c, decodeMsmFull as d, obsEpochToDate as o, resetGloFreqCache as r, setGloFreqNumber as s };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { b as Rtcm3Frame } from './ephemeris-BAnBLLB9.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Full RTCM3 MSM decoder — extracts pseudorange, carrier phase,
|
|
5
|
+
* Doppler, and C/N0 for every satellite × signal cell.
|
|
6
|
+
*
|
|
7
|
+
* Reference: BNC 2.13.4 RTCM3Decoder.cpp (BKG), RTKLIB rtcm3.c and
|
|
8
|
+
* RTCM 10403.3 §3.5.
|
|
9
|
+
*
|
|
10
|
+
* MSM4–7 carry full observations. MSM1–3 (compact: MSM1 code, MSM2 phase,
|
|
11
|
+
* MSM3 both; no C/N0, no Doppler) carry each satellite's rough range only
|
|
12
|
+
* modulo 1 ms (DF398, no DF397 integer milliseconds): their epochs come back
|
|
13
|
+
* with `rangeModulo1ms` set, ranges complete except for a whole number of
|
|
14
|
+
* light-milliseconds per satellite — see `resolveMsmRanges` (positioning).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** Single signal observation for one satellite */
|
|
18
|
+
interface ObsSignal {
|
|
19
|
+
/** RINEX 2-char obs code, e.g. "1C", "5X" */
|
|
20
|
+
rinexCode: string;
|
|
21
|
+
/** Pseudorange in meters (undefined if invalid) */
|
|
22
|
+
pseudorange?: number;
|
|
23
|
+
/** Carrier phase in cycles (undefined if invalid) */
|
|
24
|
+
phase?: number;
|
|
25
|
+
/** Doppler in Hz (undefined if invalid) */
|
|
26
|
+
doppler?: number;
|
|
27
|
+
/** Signal-to-noise ratio in dB-Hz */
|
|
28
|
+
cn0?: number;
|
|
29
|
+
/** Lock time in seconds */
|
|
30
|
+
lockTime?: number;
|
|
31
|
+
/** Half-cycle ambiguity indicator */
|
|
32
|
+
halfCycle?: boolean;
|
|
33
|
+
/** Wavelength used (meters) — needed for RINEX phase */
|
|
34
|
+
wavelength: number;
|
|
35
|
+
}
|
|
36
|
+
/** All observations for one satellite in one epoch */
|
|
37
|
+
interface ObsSatObs {
|
|
38
|
+
/** PRN string, e.g. "G01", "R15", "E04" */
|
|
39
|
+
prn: string;
|
|
40
|
+
/** System letter: G, R, E, C, J, I, S */
|
|
41
|
+
system: string;
|
|
42
|
+
/** Signal observations */
|
|
43
|
+
signals: ObsSignal[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* One decoded observation epoch. Originally the MSM4–7 output shape, now the
|
|
47
|
+
* neutral shape every RTCM3 obs source fills: MSM (`decodeMsmFull`), legacy
|
|
48
|
+
* 1001–1012 (`decodeLegacyObs`), via the `decodeObs` dispatcher.
|
|
49
|
+
*/
|
|
50
|
+
interface ObsEpoch {
|
|
51
|
+
/** Message type (1074, 1077, etc.) */
|
|
52
|
+
messageType: number;
|
|
53
|
+
/** Epoch time as GPS milliseconds of week (or GLONASS day-of-week ms, BDS SOW) */
|
|
54
|
+
epochMs: number;
|
|
55
|
+
/** System letter */
|
|
56
|
+
system: string;
|
|
57
|
+
/** Observations per satellite */
|
|
58
|
+
observations: ObsSatObs[];
|
|
59
|
+
/**
|
|
60
|
+
* Set for MSM1–3: every pseudorange and phase is short by an unknown whole
|
|
61
|
+
* number of light-milliseconds (~299.79 km) per satellite. Resolve with
|
|
62
|
+
* `resolveMsmRanges` before using the ranges.
|
|
63
|
+
*/
|
|
64
|
+
rangeModulo1ms?: true;
|
|
65
|
+
}
|
|
66
|
+
/** Options for the RTCM3 observation decoders. */
|
|
67
|
+
interface ObsDecodeOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Also decode compact MSM1–3. Their epochs carry `rangeModulo1ms`: every
|
|
70
|
+
* range is short by whole light-milliseconds until `resolveMsmRanges`
|
|
71
|
+
* completes it, so a consumer must opt in (default false → null, as
|
|
72
|
+
* before).
|
|
73
|
+
*/
|
|
74
|
+
compactMsm?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Decode a single RTCM3 MSM frame into observations: MSM4–7, and MSM1–3
|
|
78
|
+
* with `opts.compactMsm` (flagged `rangeModulo1ms`). Null otherwise.
|
|
79
|
+
*/
|
|
80
|
+
declare function decodeMsmFull(frame: Rtcm3Frame, opts?: ObsDecodeOptions): ObsEpoch | null;
|
|
81
|
+
/**
|
|
82
|
+
* Convert an observation epoch timestamp to a Date.
|
|
83
|
+
* For GPS/Galileo/BDS/QZSS: epochMs is ms of GPS week.
|
|
84
|
+
* For GLONASS: epochMs is day-of-week × 86400000 + ms of day (UTC+3).
|
|
85
|
+
*
|
|
86
|
+
* Requires an approximate reference time to resolve the current week.
|
|
87
|
+
*/
|
|
88
|
+
/**
|
|
89
|
+
* NOTE: returns a GPS-scale Date — the clock-face convention used by
|
|
90
|
+
* the RINEX parser and every consumer of epoch milliseconds in this
|
|
91
|
+
* library (satellite propagation, SPP, RINEX epoch tags). It is NOT
|
|
92
|
+
* UTC: converting to UTC here put every downstream satellite position
|
|
93
|
+
* 18 s (the current leap-second count) off — a ±14 km per-satellite
|
|
94
|
+
* range error that scattered live SPP solutions by kilometres.
|
|
95
|
+
*/
|
|
96
|
+
declare function obsEpochToDate(sys: string, epochMs: number, refTime?: Date): Date;
|
|
97
|
+
/**
|
|
98
|
+
* Set a GLONASS FDMA frequency number (k = -7..+13) for a slot (1-24),
|
|
99
|
+
* e.g. from a decoded 1020 ephemeris. MSM4/6 carry no DF419, so without
|
|
100
|
+
* this the wavelength — and hence carrier phase — stays unknown.
|
|
101
|
+
*/
|
|
102
|
+
declare function setGloFreqNumber(slot: number, k: number): void;
|
|
103
|
+
/**
|
|
104
|
+
* Reset the GLONASS frequency number cache (e.g., when switching mountpoints).
|
|
105
|
+
*/
|
|
106
|
+
declare function resetGloFreqCache(): void;
|
|
107
|
+
|
|
108
|
+
export { type ObsDecodeOptions as O, type ObsEpoch as a, type ObsSatObs as b, type ObsSignal as c, decodeMsmFull as d, obsEpochToDate as o, resetGloFreqCache as r, setGloFreqNumber as s };
|
package/dist/positioning.cjs
CHANGED
|
@@ -49,6 +49,7 @@ __export(positioning_exports, {
|
|
|
49
49
|
nlWavelength: () => nlWavelength,
|
|
50
50
|
postProcessRtk: () => postProcessRtk,
|
|
51
51
|
rcvAntennaRangeM: () => rcvAntennaRangeM,
|
|
52
|
+
resolveMsmRanges: () => resolveMsmRanges,
|
|
52
53
|
resolvePppAmbiguities: () => resolvePppAmbiguities,
|
|
53
54
|
satClockCorrection: () => satClockCorrection,
|
|
54
55
|
sbasIonoDeg: () => sbasIonoDeg,
|
|
@@ -2134,6 +2135,66 @@ var ZeroBaselineEngine = class {
|
|
|
2134
2135
|
}
|
|
2135
2136
|
};
|
|
2136
2137
|
|
|
2138
|
+
// src/positioning/msm-resolve.ts
|
|
2139
|
+
var LIGHT_MS = C_LIGHT / 1e3;
|
|
2140
|
+
var MAX_FRACTION_MISFIT = 0.25;
|
|
2141
|
+
function predictedRange(eph, timeMs, rx) {
|
|
2142
|
+
let tau = 0.075;
|
|
2143
|
+
for (let i = 0; i < 2; i++) {
|
|
2144
|
+
const tEmit = timeMs - tau * 1e3;
|
|
2145
|
+
const p = computeSatPosition(eph, tEmit);
|
|
2146
|
+
if (!Number.isFinite(p.x)) return null;
|
|
2147
|
+
const rho = Math.hypot(p.x - rx[0], p.y - rx[1], p.z - rx[2]);
|
|
2148
|
+
tau = rho / C_LIGHT;
|
|
2149
|
+
if (i === 1) return rho - C_LIGHT * satClockCorrection(eph, tEmit);
|
|
2150
|
+
}
|
|
2151
|
+
return null;
|
|
2152
|
+
}
|
|
2153
|
+
function moduloRange(sat) {
|
|
2154
|
+
for (const s of sat.signals)
|
|
2155
|
+
if (s.pseudorange !== void 0) return s.pseudorange;
|
|
2156
|
+
for (const s of sat.signals)
|
|
2157
|
+
if (s.phase !== void 0 && s.wavelength > 0)
|
|
2158
|
+
return s.phase * s.wavelength;
|
|
2159
|
+
return null;
|
|
2160
|
+
}
|
|
2161
|
+
function resolveMsmRanges(epoch, opts) {
|
|
2162
|
+
if (!epoch.rangeModulo1ms) return epoch;
|
|
2163
|
+
const cand = [];
|
|
2164
|
+
for (const sat of epoch.observations) {
|
|
2165
|
+
const eph = opts.ephFor(sat.prn);
|
|
2166
|
+
const mod = moduloRange(sat);
|
|
2167
|
+
if (!eph || mod === null) continue;
|
|
2168
|
+
const pred = predictedRange(eph, opts.timeMs, opts.rxEcef);
|
|
2169
|
+
if (pred === null) continue;
|
|
2170
|
+
cand.push({ sat, k: (pred - mod) / LIGHT_MS });
|
|
2171
|
+
}
|
|
2172
|
+
const { rangeModulo1ms: _drop, ...rest } = epoch;
|
|
2173
|
+
if (cand.length === 0) return { ...rest, observations: [] };
|
|
2174
|
+
let sx = 0;
|
|
2175
|
+
let sy = 0;
|
|
2176
|
+
for (const c of cand) {
|
|
2177
|
+
sx += Math.cos(2 * Math.PI * c.k);
|
|
2178
|
+
sy += Math.sin(2 * Math.PI * c.k);
|
|
2179
|
+
}
|
|
2180
|
+
const b = Math.atan2(sy, sx) / (2 * Math.PI);
|
|
2181
|
+
const observations = [];
|
|
2182
|
+
for (const { sat, k } of cand) {
|
|
2183
|
+
const n = Math.round(k - b);
|
|
2184
|
+
if (Math.abs(k - b - n) > MAX_FRACTION_MISFIT) continue;
|
|
2185
|
+
const add = n * LIGHT_MS;
|
|
2186
|
+
observations.push({
|
|
2187
|
+
...sat,
|
|
2188
|
+
signals: sat.signals.map((s) => ({
|
|
2189
|
+
...s,
|
|
2190
|
+
...s.pseudorange !== void 0 ? { pseudorange: s.pseudorange + add } : {},
|
|
2191
|
+
...s.phase !== void 0 && s.wavelength > 0 ? { phase: s.phase + add / s.wavelength } : {}
|
|
2192
|
+
}))
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
return { ...rest, observations };
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2137
2198
|
// src/navbits/index.ts
|
|
2138
2199
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
2139
2200
|
var SEC_PER_WEEK = 7 * 86400;
|
|
@@ -4633,6 +4694,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
4633
4694
|
nlWavelength,
|
|
4634
4695
|
postProcessRtk,
|
|
4635
4696
|
rcvAntennaRangeM,
|
|
4697
|
+
resolveMsmRanges,
|
|
4636
4698
|
resolvePppAmbiguities,
|
|
4637
4699
|
satClockCorrection,
|
|
4638
4700
|
sbasIonoDeg,
|
package/dist/positioning.d.cts
CHANGED
|
@@ -2,6 +2,7 @@ import { E as Ephemeris } from './nav-DImXUdbp.cjs';
|
|
|
2
2
|
import { DopValues } from './orbit.cjs';
|
|
3
3
|
import { I as IonexGrid, C as ClkFile, S as Sp3File } from './clk-DGVBGRzA.cjs';
|
|
4
4
|
import { AntexFile } from './antex.cjs';
|
|
5
|
+
import { a as ObsEpoch } from './msm-DWtoTvx2.cjs';
|
|
5
6
|
import { a as HasOrbitCorrection, b as HasClockCorrection } from './has-BaXnQarR.cjs';
|
|
6
7
|
import './ephemeris-BAnBLLB9.cjs';
|
|
7
8
|
import './ecef-CF0uAysr.cjs';
|
|
@@ -613,6 +614,23 @@ declare class ZeroBaselineEngine {
|
|
|
613
614
|
private processReceiver;
|
|
614
615
|
}
|
|
615
616
|
|
|
617
|
+
interface MsmResolveOptions {
|
|
618
|
+
/** Epoch time, GPS-scale ms (as `obsEpochToDate` returns). */
|
|
619
|
+
timeMs: number;
|
|
620
|
+
/** Approximate receiver ECEF (m) — the station's 1005/1006, a sourcetable
|
|
621
|
+
* position, or a previous fix. Tens of km of error are tolerated. */
|
|
622
|
+
rxEcef: readonly [number, number, number];
|
|
623
|
+
/** Broadcast ephemeris for a PRN at this time, or null. */
|
|
624
|
+
ephFor: (prn: string) => Ephemeris | null;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Add the missing whole light-milliseconds to an MSM1–3 epoch's ranges.
|
|
628
|
+
* Returns the epoch with `rangeModulo1ms` cleared, keeping only satellites
|
|
629
|
+
* whose range could be resolved (an ephemeris, and a prediction consistent
|
|
630
|
+
* with the rest of the epoch). Epochs that aren't modulo-1-ms pass through.
|
|
631
|
+
*/
|
|
632
|
+
declare function resolveMsmRanges(epoch: ObsEpoch, opts: MsmResolveOptions): ObsEpoch;
|
|
633
|
+
|
|
616
634
|
/**
|
|
617
635
|
* Integer ambiguity resolution: LAMBDA decorrelation + MLAMBDA
|
|
618
636
|
* integer least-squares search.
|
|
@@ -1714,4 +1732,4 @@ declare function sbasProtectionLevels(sats: readonly {
|
|
|
1714
1732
|
*/
|
|
1715
1733
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
1716
1734
|
|
|
1717
|
-
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
1735
|
+
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type MsmResolveOptions, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolveMsmRanges, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { E as Ephemeris } from './nav-DImXUdbp.js';
|
|
|
2
2
|
import { DopValues } from './orbit.js';
|
|
3
3
|
import { I as IonexGrid, C as ClkFile, S as Sp3File } from './clk-DGVBGRzA.js';
|
|
4
4
|
import { AntexFile } from './antex.js';
|
|
5
|
+
import { a as ObsEpoch } from './msm-CcQJV3PC.js';
|
|
5
6
|
import { a as HasOrbitCorrection, b as HasClockCorrection } from './has-BaXnQarR.js';
|
|
6
7
|
import './ephemeris-BAnBLLB9.js';
|
|
7
8
|
import './ecef-CF0uAysr.js';
|
|
@@ -613,6 +614,23 @@ declare class ZeroBaselineEngine {
|
|
|
613
614
|
private processReceiver;
|
|
614
615
|
}
|
|
615
616
|
|
|
617
|
+
interface MsmResolveOptions {
|
|
618
|
+
/** Epoch time, GPS-scale ms (as `obsEpochToDate` returns). */
|
|
619
|
+
timeMs: number;
|
|
620
|
+
/** Approximate receiver ECEF (m) — the station's 1005/1006, a sourcetable
|
|
621
|
+
* position, or a previous fix. Tens of km of error are tolerated. */
|
|
622
|
+
rxEcef: readonly [number, number, number];
|
|
623
|
+
/** Broadcast ephemeris for a PRN at this time, or null. */
|
|
624
|
+
ephFor: (prn: string) => Ephemeris | null;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Add the missing whole light-milliseconds to an MSM1–3 epoch's ranges.
|
|
628
|
+
* Returns the epoch with `rangeModulo1ms` cleared, keeping only satellites
|
|
629
|
+
* whose range could be resolved (an ephemeris, and a prediction consistent
|
|
630
|
+
* with the rest of the epoch). Epochs that aren't modulo-1-ms pass through.
|
|
631
|
+
*/
|
|
632
|
+
declare function resolveMsmRanges(epoch: ObsEpoch, opts: MsmResolveOptions): ObsEpoch;
|
|
633
|
+
|
|
616
634
|
/**
|
|
617
635
|
* Integer ambiguity resolution: LAMBDA decorrelation + MLAMBDA
|
|
618
636
|
* integer least-squares search.
|
|
@@ -1714,4 +1732,4 @@ declare function sbasProtectionLevels(sats: readonly {
|
|
|
1714
1732
|
*/
|
|
1715
1733
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
1716
1734
|
|
|
1717
|
-
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
|
1735
|
+
export { type AntennaOffset, type AppliedOrbitClock, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type MsmResolveOptions, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type OrbitClockCorrection, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, PppEngine, type PppEphemerisSource, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type ReceiverBias, type ReceiverClockSample, type RtkAntennaConfig, type RtkAntennaModel, type RtkAntennaOffset, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkReceiverAntenna, type RtkTrackPoint, type SatGeom, type SatSample, type SbasCorrectionSource, type SbasIgp, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, Sp3EphemerisSource, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, ZeroBaselineEngine, type ZeroBaselineOptions, antexFreqOfGroup, applyOrbitClock, buildPppAntenna, buildRtkAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, hasToOrbitClock, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, rcvAntennaRangeM, resolveMsmRanges, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
|
package/dist/positioning.js
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
nlWavelength,
|
|
29
29
|
postProcessRtk,
|
|
30
30
|
rcvAntennaRangeM,
|
|
31
|
+
resolveMsmRanges,
|
|
31
32
|
resolvePppAmbiguities,
|
|
32
33
|
satClockCorrection,
|
|
33
34
|
sbasIonoDeg,
|
|
@@ -40,7 +41,7 @@ import {
|
|
|
40
41
|
sunEcef,
|
|
41
42
|
toRtkEpoch,
|
|
42
43
|
wlWavelength
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-K3GLUWZI.js";
|
|
44
45
|
import "./chunk-WQX354KD.js";
|
|
45
46
|
import "./chunk-7T5DLVZL.js";
|
|
46
47
|
import "./chunk-HVXYFUCB.js";
|
|
@@ -82,6 +83,7 @@ export {
|
|
|
82
83
|
nlWavelength,
|
|
83
84
|
postProcessRtk,
|
|
84
85
|
rcvAntennaRangeM,
|
|
86
|
+
resolveMsmRanges,
|
|
85
87
|
resolvePppAmbiguities,
|
|
86
88
|
satClockCorrection,
|
|
87
89
|
sbasIonoDeg,
|
package/dist/rinex.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(rinex_exports, {
|
|
|
32
32
|
fmtD: () => fmtD,
|
|
33
33
|
fmtF: () => fmtF,
|
|
34
34
|
hdrLine: () => hdrLine,
|
|
35
|
+
modalIntervalS: () => modalIntervalS,
|
|
35
36
|
padL: () => padL,
|
|
36
37
|
padR: () => padR,
|
|
37
38
|
parseBiasSinex: () => parseBiasSinex,
|
|
@@ -2600,6 +2601,21 @@ function writeRinexObsBlob(header, epochs, obsTypes) {
|
|
|
2600
2601
|
comment: "Merged from multiple RINEX files"
|
|
2601
2602
|
});
|
|
2602
2603
|
}
|
|
2604
|
+
function modalIntervalS(epochs) {
|
|
2605
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2606
|
+
for (let i = 1; i < epochs.length; i++) {
|
|
2607
|
+
const d = Math.round(epochs[i].time - epochs[i - 1].time);
|
|
2608
|
+
if (d > 0) counts.set(d, (counts.get(d) ?? 0) + 1);
|
|
2609
|
+
}
|
|
2610
|
+
let best = null;
|
|
2611
|
+
let bestN = 0;
|
|
2612
|
+
for (const [d, n] of counts)
|
|
2613
|
+
if (n > bestN || n === bestN && best !== null && d < best) {
|
|
2614
|
+
best = d;
|
|
2615
|
+
bestN = n;
|
|
2616
|
+
}
|
|
2617
|
+
return best === null ? null : best / 1e3;
|
|
2618
|
+
}
|
|
2603
2619
|
async function writeModernObsBlob(header, epochs, obsTypes, opts) {
|
|
2604
2620
|
if (epochs.length === 0) return new Blob([], { type: "application/gzip" });
|
|
2605
2621
|
const sink = createGzipLineSink();
|
|
@@ -2646,11 +2662,9 @@ async function writeModernObsBlob(header, epochs, obsTypes, opts) {
|
|
|
2646
2662
|
"TIME OF LAST OBS"
|
|
2647
2663
|
)
|
|
2648
2664
|
);
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
sink.push(hdrLine(fmtF(interval, 10, 3), "INTERVAL"));
|
|
2653
|
-
}
|
|
2665
|
+
const interval = modalIntervalS(epochs);
|
|
2666
|
+
if (interval !== null && interval < 3600) {
|
|
2667
|
+
sink.push(hdrLine(fmtF(interval, 10, 3), "INTERVAL"));
|
|
2654
2668
|
}
|
|
2655
2669
|
if (header.glonassSlots && Object.keys(header.glonassSlots).length > 0) {
|
|
2656
2670
|
const entries = Object.entries(header.glonassSlots).sort(
|
|
@@ -2916,6 +2930,7 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
|
|
|
2916
2930
|
fmtD,
|
|
2917
2931
|
fmtF,
|
|
2918
2932
|
hdrLine,
|
|
2933
|
+
modalIntervalS,
|
|
2919
2934
|
padL,
|
|
2920
2935
|
padR,
|
|
2921
2936
|
parseBiasSinex,
|
package/dist/rinex.d.cts
CHANGED
|
@@ -258,6 +258,15 @@ interface CompactEpoch {
|
|
|
258
258
|
* the Float64Array index order for each system.
|
|
259
259
|
*/
|
|
260
260
|
declare function writeRinexObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>): Promise<Blob>;
|
|
261
|
+
/**
|
|
262
|
+
* The nominal observation interval (s): the most common spacing between
|
|
263
|
+
* consecutive epochs. The first difference alone mis-states it whenever the
|
|
264
|
+
* file opens with an irregular gap (a late second epoch, a burst). Null with
|
|
265
|
+
* fewer than two epochs.
|
|
266
|
+
*/
|
|
267
|
+
declare function modalIntervalS(epochs: readonly {
|
|
268
|
+
time: number;
|
|
269
|
+
}[]): number | null;
|
|
261
270
|
/** Shared RINEX 3/4 implementation (also used by obs-writer-v4.ts). */
|
|
262
271
|
declare function writeModernObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>, opts: {
|
|
263
272
|
version: string;
|
|
@@ -311,4 +320,4 @@ declare function createGzipLineSink(): {
|
|
|
311
320
|
*/
|
|
312
321
|
declare function stationHeaderLines(header: RinexHeader): string[];
|
|
313
322
|
|
|
314
|
-
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
|
323
|
+
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
package/dist/rinex.d.ts
CHANGED
|
@@ -258,6 +258,15 @@ interface CompactEpoch {
|
|
|
258
258
|
* the Float64Array index order for each system.
|
|
259
259
|
*/
|
|
260
260
|
declare function writeRinexObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>): Promise<Blob>;
|
|
261
|
+
/**
|
|
262
|
+
* The nominal observation interval (s): the most common spacing between
|
|
263
|
+
* consecutive epochs. The first difference alone mis-states it whenever the
|
|
264
|
+
* file opens with an irregular gap (a late second epoch, a burst). Null with
|
|
265
|
+
* fewer than two epochs.
|
|
266
|
+
*/
|
|
267
|
+
declare function modalIntervalS(epochs: readonly {
|
|
268
|
+
time: number;
|
|
269
|
+
}[]): number | null;
|
|
261
270
|
/** Shared RINEX 3/4 implementation (also used by obs-writer-v4.ts). */
|
|
262
271
|
declare function writeModernObsBlob(header: RinexHeader, epochs: CompactEpoch[], obsTypes: Map<string, string[]>, opts: {
|
|
263
272
|
version: string;
|
|
@@ -311,4 +320,4 @@ declare function createGzipLineSink(): {
|
|
|
311
320
|
*/
|
|
312
321
|
declare function stationHeaderLines(header: RinexHeader): string[];
|
|
313
322
|
|
|
314
|
-
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
|
323
|
+
export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
|
package/dist/rinex.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
fmtD,
|
|
8
8
|
fmtF,
|
|
9
9
|
hdrLine,
|
|
10
|
+
modalIntervalS,
|
|
10
11
|
padL,
|
|
11
12
|
padR,
|
|
12
13
|
parseBiasSinex,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
writeRinexNav,
|
|
21
22
|
writeRinexNav4,
|
|
22
23
|
writeRinexObsBlob
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-56HM5B6T.js";
|
|
24
25
|
import {
|
|
25
26
|
SYSTEM_ORDER,
|
|
26
27
|
crxDecompress,
|
|
@@ -52,6 +53,7 @@ export {
|
|
|
52
53
|
fmtD,
|
|
53
54
|
fmtF,
|
|
54
55
|
hdrLine,
|
|
56
|
+
modalIntervalS,
|
|
55
57
|
padL,
|
|
56
58
|
padR,
|
|
57
59
|
parseBiasSinex,
|
package/dist/rtcm3.cjs
CHANGED
|
@@ -1287,12 +1287,14 @@ function satPrn(sys, satIdx1) {
|
|
|
1287
1287
|
const num = sys === "S" ? satIdx1 + 119 : satIdx1;
|
|
1288
1288
|
return `${prefix}${String(num).padStart(2, "0")}`;
|
|
1289
1289
|
}
|
|
1290
|
-
function decodeMsmFull(frame) {
|
|
1290
|
+
function decodeMsmFull(frame, opts = {}) {
|
|
1291
1291
|
const type = frame.messageType;
|
|
1292
1292
|
const sys = msmSystem(type);
|
|
1293
1293
|
if (!sys) return null;
|
|
1294
1294
|
const variant = type % 10;
|
|
1295
|
-
if (variant <
|
|
1295
|
+
if (variant < 1 || variant > 7) return null;
|
|
1296
|
+
const compact = variant <= 3;
|
|
1297
|
+
if (compact && !opts.compactMsm) return null;
|
|
1296
1298
|
const payload = frame.payload;
|
|
1297
1299
|
if (!payload || payload.length < 10) return null;
|
|
1298
1300
|
try {
|
|
@@ -1337,7 +1339,9 @@ function decodeMsmFull(frame) {
|
|
|
1337
1339
|
const rrmod = new Float64Array(numSat);
|
|
1338
1340
|
const extsat = new Int8Array(numSat);
|
|
1339
1341
|
const rdop = new Float64Array(numSat);
|
|
1340
|
-
if (
|
|
1342
|
+
if (compact) {
|
|
1343
|
+
for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
|
|
1344
|
+
} else if (variant === 4 || variant === 6) {
|
|
1341
1345
|
for (let j = 0; j < numSat; j++) rrint[j] = bits.readU(8);
|
|
1342
1346
|
for (let j = 0; j < numSat; j++) rrmod[j] = bits.readU(10) / 1024;
|
|
1343
1347
|
} else {
|
|
@@ -1363,7 +1367,18 @@ function decodeMsmFull(frame) {
|
|
|
1363
1367
|
psr.fill(-1e30);
|
|
1364
1368
|
cp.fill(-1e30);
|
|
1365
1369
|
dop.fill(-1e30);
|
|
1366
|
-
if (variant ===
|
|
1370
|
+
if (variant === 1) {
|
|
1371
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1372
|
+
} else if (variant === 2) {
|
|
1373
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1374
|
+
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
1375
|
+
for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
|
|
1376
|
+
} else if (variant === 3) {
|
|
1377
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1378
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1379
|
+
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
1380
|
+
for (let i = 0; i < activeCells; i++) hc[i] = bits.readU(1);
|
|
1381
|
+
} else if (variant === 4) {
|
|
1367
1382
|
for (let i = 0; i < activeCells; i++) psr[i] = bits.readS(15) / 2 ** 24;
|
|
1368
1383
|
for (let i = 0; i < activeCells; i++) cp[i] = bits.readS(22) / 2 ** 29;
|
|
1369
1384
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.readU(4);
|
|
@@ -1439,8 +1454,10 @@ function decodeMsmFull(frame) {
|
|
|
1439
1454
|
if (cnrVal > 0) {
|
|
1440
1455
|
signal.cn0 = cnrVal;
|
|
1441
1456
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1457
|
+
if (variant !== 1) {
|
|
1458
|
+
signal.lockTime = lockTimeSec(type, ll[cellIdx]);
|
|
1459
|
+
signal.halfCycle = hc[cellIdx] === 1;
|
|
1460
|
+
}
|
|
1444
1461
|
signals.push(signal);
|
|
1445
1462
|
cellIdx++;
|
|
1446
1463
|
}
|
|
@@ -1452,7 +1469,8 @@ function decodeMsmFull(frame) {
|
|
|
1452
1469
|
messageType: type,
|
|
1453
1470
|
epochMs,
|
|
1454
1471
|
system: sys,
|
|
1455
|
-
observations
|
|
1472
|
+
observations,
|
|
1473
|
+
...compact ? { rangeModulo1ms: true } : {}
|
|
1456
1474
|
};
|
|
1457
1475
|
} catch (err) {
|
|
1458
1476
|
reportDecodeError("msm", err);
|
|
@@ -1606,8 +1624,8 @@ function decodeLegacyObs(frame) {
|
|
|
1606
1624
|
}
|
|
1607
1625
|
return { messageType: type, epochMs, system, observations };
|
|
1608
1626
|
}
|
|
1609
|
-
function decodeObs(frame) {
|
|
1610
|
-
return decodeMsmFull(frame) ?? decodeLegacyObs(frame);
|
|
1627
|
+
function decodeObs(frame, opts = {}) {
|
|
1628
|
+
return decodeMsmFull(frame, opts) ?? decodeLegacyObs(frame);
|
|
1611
1629
|
}
|
|
1612
1630
|
|
|
1613
1631
|
// src/rtcm3/ssr.ts
|
|
@@ -2039,7 +2057,7 @@ function updateStreamStats(stats, frames, rawBytes) {
|
|
|
2039
2057
|
entry.count++;
|
|
2040
2058
|
entry.lastSeen = now;
|
|
2041
2059
|
entry.totalBytes += frame.length + 6;
|
|
2042
|
-
const obsEpoch = decodeObs(frame);
|
|
2060
|
+
const obsEpoch = decodeObs(frame, { compactMsm: true });
|
|
2043
2061
|
if (obsEpoch) {
|
|
2044
2062
|
for (const obs of obsEpoch.observations) {
|
|
2045
2063
|
const signals = [];
|