gnss-js 1.21.0 → 1.23.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-CUWF56ST.js +966 -0
- package/dist/{chunk-DLXTTHRK.js → chunk-MCAVU3XL.js} +118 -9
- package/dist/{chunk-JNFV5BYB.js → chunk-MHGNKSSH.js} +2 -3
- package/dist/{chunk-K3V3NHWL.js → chunk-PZNVFCKJ.js} +25 -766
- package/dist/chunk-VTX3VCL4.js +769 -0
- package/dist/index.cjs +1906 -1099
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +14 -5
- package/dist/orbit.cjs +2 -3
- package/dist/orbit.js +1 -1
- package/dist/positioning.cjs +734 -9
- package/dist/positioning.d.cts +238 -1
- package/dist/positioning.d.ts +238 -1
- package/dist/positioning.js +10 -4
- package/dist/sbf.js +2 -1
- package/dist/ubx.cjs +809 -10
- package/dist/ubx.d.cts +111 -1
- package/dist/ubx.d.ts +111 -1
- package/dist/ubx.js +6 -1
- package/package.json +1 -1
- package/dist/chunk-B5LU4746.js +0 -262
package/dist/positioning.d.cts
CHANGED
|
@@ -34,6 +34,243 @@ interface KlobucharCoeffs {
|
|
|
34
34
|
*/
|
|
35
35
|
declare function klobucharDelay(coeffs: KlobucharCoeffs, latRad: number, lonRad: number, azRad: number, elRad: number, gpsTowSec: number): number;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* RTK positioning, stage 1: epoch-wise double-differenced (DD)
|
|
39
|
+
* processing of a base/rover receiver pair.
|
|
40
|
+
*
|
|
41
|
+
* Two solvers share the same DD construction:
|
|
42
|
+
*
|
|
43
|
+
* - `solveDgnss` — code-based DGNSS: between-receiver single
|
|
44
|
+
* differences on pseudoranges, double-differenced against a
|
|
45
|
+
* reference satellite (highest elevation per signal group), iterated
|
|
46
|
+
* weighted least squares for the rover position with the full DD
|
|
47
|
+
* covariance (DDs sharing a reference satellite are correlated).
|
|
48
|
+
*
|
|
49
|
+
* - `RtkFloatEngine` — a stateful extended Kalman filter over DD
|
|
50
|
+
* carrier phase + code with one float DD ambiguity state per
|
|
51
|
+
* satellite/signal. An EKF (rather than epoch-wise iterated least
|
|
52
|
+
* squares with appended ambiguity columns) was chosen because the
|
|
53
|
+
* float ambiguities must persist across epochs anyway, and stage 2
|
|
54
|
+
* (LAMBDA) needs the joint float ambiguity covariance — which the
|
|
55
|
+
* EKF maintains natively. This mirrors RTKLIB's float-filter
|
|
56
|
+
* structure (rtkpos.c), which the implementation was validated
|
|
57
|
+
* against; no integer fixing is attempted (`ratio` is reserved).
|
|
58
|
+
*
|
|
59
|
+
* Differencing model: for satellites s and reference r observed by
|
|
60
|
+
* rover R and base B, the DD pseudorange/phase cancels satellite
|
|
61
|
+
* clocks (single difference) and receiver clocks (double difference).
|
|
62
|
+
* On short baselines the ionospheric and most of the tropospheric
|
|
63
|
+
* delay cancel too; the residual troposphere is modelled by the same
|
|
64
|
+
* simple elevation-mapped zenith model `solveSpp` uses, applied
|
|
65
|
+
* differentially. DDs are formed per *signal group* (constellation
|
|
66
|
+
* letter + RINEX code, e.g. `G1C`, `C2I`) so that only like signals
|
|
67
|
+
* are differenced.
|
|
68
|
+
*
|
|
69
|
+
* GLONASS (FDMA): DD phase is formed in metres with per-satellite
|
|
70
|
+
* wavelengths (λ_s·SDφ_s − λ_r·SDφ_r). The common receiver clock
|
|
71
|
+
* term cancels exactly (λ·f = c on every channel); the per-channel
|
|
72
|
+
* receiver phase bias (inter-frequency bias, IFB) does not, but it is
|
|
73
|
+
* constant while lock holds and is absorbed into the float DD
|
|
74
|
+
* ambiguity — the standard reason GLONASS float works while GLONASS
|
|
75
|
+
* integer fixing is hard. DD *code* retains the differential
|
|
76
|
+
* inter-channel code bias between the two receivers, which is small
|
|
77
|
+
* (well below the code noise) for same-model receivers — IFB-safe
|
|
78
|
+
* enough for stage 1, and documented as such.
|
|
79
|
+
*
|
|
80
|
+
* Time convention: `timeMs` is GPS-scale epoch milliseconds, exactly
|
|
81
|
+
* as produced by `parseNovatelRange` / the RINEX and RTCM parsers —
|
|
82
|
+
* the same convention `solveSpp` uses. No system clock is read.
|
|
83
|
+
*
|
|
84
|
+
* Adapting decoder output (see `toRtkEpoch`):
|
|
85
|
+
* - NovAtel: `parseNovatelRange(bytes).epochs[i]` gives
|
|
86
|
+
* `{ timeMs, meas }`; `toRtkEpoch(meas)` picks each satellite's
|
|
87
|
+
* L1-band measurement. When a log carries both RANGE and RANGECMP
|
|
88
|
+
* the same epoch appears twice — keep one epoch per `timeMs`.
|
|
89
|
+
* - RTCM MSM: for each satellite/signal cell build
|
|
90
|
+
* `{ code, pr: pseudorangeM, cp: phaserangeM / lambda, lockTimeMs }`
|
|
91
|
+
* (MSM phaseranges are metres; divide by the carrier wavelength to
|
|
92
|
+
* get cycles) and pass a `prn → measurement` map for the epoch.
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/** One satellite's measurement on one signal, for one epoch. */
|
|
96
|
+
interface RtkMeasurement {
|
|
97
|
+
/** RINEX band+attribute, e.g. "1C", "2I". */
|
|
98
|
+
code: string;
|
|
99
|
+
/** Pseudorange (m). */
|
|
100
|
+
pr: number | null;
|
|
101
|
+
/** Carrier phase (cycles, RINEX sign), optional — DGNSS needs none. */
|
|
102
|
+
cp?: number | null;
|
|
103
|
+
/** Continuous lock time (ms) for cycle-slip detection, optional. */
|
|
104
|
+
lockTimeMs?: number;
|
|
105
|
+
/** GLONASS frequency channel k (−7…+6), for FDMA wavelengths. */
|
|
106
|
+
gloChannel?: number | null;
|
|
107
|
+
}
|
|
108
|
+
/** One epoch of measurements: PRN → measurement (one signal per PRN). */
|
|
109
|
+
type RtkEpochMeasurements = ReadonlyMap<string, RtkMeasurement>;
|
|
110
|
+
/** Decoder-shaped observation (structurally `NovatelMeasurement`). */
|
|
111
|
+
interface RawObservation {
|
|
112
|
+
prn: string;
|
|
113
|
+
code: string;
|
|
114
|
+
pr: number | null;
|
|
115
|
+
cp?: number | null;
|
|
116
|
+
lockTimeS?: number;
|
|
117
|
+
gloChannel?: number | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Adapt one epoch of decoder observations (e.g.
|
|
121
|
+
* `parseNovatelRange(...).epochs[i].meas`) to the RTK input map:
|
|
122
|
+
* keeps each satellite's preferred L1-band code measurement with a
|
|
123
|
+
* valid pseudorange, drops unsupported systems (SBAS, NavIC).
|
|
124
|
+
*/
|
|
125
|
+
declare function toRtkEpoch(meas: readonly RawObservation[]): Map<string, RtkMeasurement>;
|
|
126
|
+
/** Ephemeris source: a per-PRN map, or a list searched per epoch. */
|
|
127
|
+
type EphemerisSource = ReadonlyMap<string, Ephemeris> | readonly Ephemeris[];
|
|
128
|
+
interface DgnssOptions {
|
|
129
|
+
/** Elevation mask at the base, degrees. Default 10. */
|
|
130
|
+
elevationMaskDeg?: number;
|
|
131
|
+
/** Model the differential troposphere. Default true. */
|
|
132
|
+
troposphere?: boolean;
|
|
133
|
+
/** Maximum Gauss-Newton iterations. Default 15. */
|
|
134
|
+
maxIterations?: number;
|
|
135
|
+
/** Convergence threshold on the position update (m). Default 1e-4. */
|
|
136
|
+
convergenceM?: number;
|
|
137
|
+
/** Zenith code sigma per receiver (m). Default 0.3. */
|
|
138
|
+
codeSigmaM?: number;
|
|
139
|
+
/** Worst-first DD residual rejection threshold (m). Default 20. */
|
|
140
|
+
rejectThresholdM?: number;
|
|
141
|
+
/** Initial rover position; defaults to the base position. */
|
|
142
|
+
initialPosition?: [number, number, number];
|
|
143
|
+
}
|
|
144
|
+
interface DgnssSolution {
|
|
145
|
+
/** Rover position, ECEF metres. */
|
|
146
|
+
position: [number, number, number];
|
|
147
|
+
/** Baseline rover − base, ECEF metres. */
|
|
148
|
+
baseline: [number, number, number];
|
|
149
|
+
/** Formal position sigmas from the LSQ covariance, ECEF metres. */
|
|
150
|
+
sigmas: [number, number, number];
|
|
151
|
+
/** Satellites used (including references). */
|
|
152
|
+
usedSatellites: string[];
|
|
153
|
+
/** Reference satellite per signal group. */
|
|
154
|
+
refSatellites: Record<string, string>;
|
|
155
|
+
/** Post-fit DD residual (m) per non-reference PRN. */
|
|
156
|
+
residuals: Record<string, number>;
|
|
157
|
+
/** Satellites rejected by the residual screen. */
|
|
158
|
+
rejectedSatellites: string[];
|
|
159
|
+
nSats: number;
|
|
160
|
+
iterations: number;
|
|
161
|
+
converged: boolean;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Solve the rover position from one epoch of DD pseudoranges.
|
|
165
|
+
*
|
|
166
|
+
* @param rover Rover measurements (PRN → measurement).
|
|
167
|
+
* @param base Base measurements (PRN → measurement, same codes).
|
|
168
|
+
* @param basePos Known base position, ECEF metres.
|
|
169
|
+
* @param ephemerides Broadcast ephemerides (per-PRN map, or a list
|
|
170
|
+
* searched by closest epoch — pass `parseNovatelNav(...).ephemerides`
|
|
171
|
+
* or `parseNavFile(...).ephemerides` directly).
|
|
172
|
+
* @param timeMs Receiver epoch, GPS-scale milliseconds.
|
|
173
|
+
*/
|
|
174
|
+
declare function solveDgnss(rover: RtkEpochMeasurements, base: RtkEpochMeasurements, basePos: readonly [number, number, number], ephemerides: EphemerisSource, timeMs: number, opts?: DgnssOptions): DgnssSolution | null;
|
|
175
|
+
interface RtkFloatOptions {
|
|
176
|
+
/**
|
|
177
|
+
* 'static': the rover position is a constant state (random walk
|
|
178
|
+
* `processNoisePosM`·√s, default 0). 'kinematic': the position is
|
|
179
|
+
* re-initialised each epoch with `kinematicSigmaM` uncertainty
|
|
180
|
+
* (no velocity states at stage 1 — RTKLIB's default kinematic
|
|
181
|
+
* handling without doppler). Default 'kinematic'.
|
|
182
|
+
*/
|
|
183
|
+
mode?: 'static' | 'kinematic';
|
|
184
|
+
/** Elevation mask at the base, degrees. Default 10. */
|
|
185
|
+
elevationMaskDeg?: number;
|
|
186
|
+
/** Model the differential troposphere. Default true. */
|
|
187
|
+
troposphere?: boolean;
|
|
188
|
+
/** Zenith code sigma per receiver (m). Default 0.3. */
|
|
189
|
+
codeSigmaM?: number;
|
|
190
|
+
/** Zenith phase sigma per receiver (m). Default 0.003. */
|
|
191
|
+
phaseSigmaM?: number;
|
|
192
|
+
/** Static-mode position random walk (m/√s). Default 0. */
|
|
193
|
+
processNoisePosM?: number;
|
|
194
|
+
/** Kinematic per-epoch position reset sigma (m). Default 30. */
|
|
195
|
+
kinematicSigmaM?: number;
|
|
196
|
+
/** Ambiguity random walk (cycles/√s). Default 1e-4. */
|
|
197
|
+
ambProcessNoiseCycles?: number;
|
|
198
|
+
/** New float ambiguity sigma (cycles). Default 30. */
|
|
199
|
+
ambInitSigmaCycles?: number;
|
|
200
|
+
/** Drop ambiguity states unseen for this long (ms). Default 10000. */
|
|
201
|
+
maxGapMs?: number;
|
|
202
|
+
/** DD code innovation gate (m): drop the satellite. Default 30. */
|
|
203
|
+
codeGateM?: number;
|
|
204
|
+
/**
|
|
205
|
+
* Phase-minus-code innovation divergence gate (m): treat as an
|
|
206
|
+
* undetected cycle slip and re-initialise the ambiguity. Default 5.
|
|
207
|
+
*/
|
|
208
|
+
slipGateM?: number;
|
|
209
|
+
/** Measurement-update relinearisations (IEKF). Default 2. */
|
|
210
|
+
updateIterations?: number;
|
|
211
|
+
}
|
|
212
|
+
interface RtkFloatSolution {
|
|
213
|
+
/** Epoch, GPS-scale milliseconds. */
|
|
214
|
+
timeMs: number;
|
|
215
|
+
/** Rover position, ECEF metres. */
|
|
216
|
+
position: [number, number, number];
|
|
217
|
+
/** Float baseline rover − base, ECEF metres. */
|
|
218
|
+
floatBaseline: [number, number, number];
|
|
219
|
+
/** Satellites contributing DD rows this epoch (incl. references). */
|
|
220
|
+
nSats: number;
|
|
221
|
+
/** Ambiguity-validation ratio — undefined at stage 1 (no LAMBDA). */
|
|
222
|
+
ratio?: number;
|
|
223
|
+
/** Formal position sigmas (filter covariance), ECEF metres. */
|
|
224
|
+
sigmas: [number, number, number];
|
|
225
|
+
/** Float DD ambiguity (cycles) per non-reference PRN. */
|
|
226
|
+
ambiguities: Record<string, number>;
|
|
227
|
+
/** Reference satellite per signal group. */
|
|
228
|
+
refSatellites: Record<string, string>;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Epoch-by-epoch float RTK filter: EKF states = rover position
|
|
232
|
+
* (static or kinematic) + one float DD ambiguity (cycles) per
|
|
233
|
+
* satellite/signal. Cycle slips are handled via lock-time regressions
|
|
234
|
+
* (LLI-style resets) and a phase/code divergence gate; reference-
|
|
235
|
+
* satellite switches re-map the DD ambiguity states algebraically
|
|
236
|
+
* (N_i' = N_i − N_r', old reference gains −N_r') so no information is
|
|
237
|
+
* lost. Feed epochs in time order via `process`.
|
|
238
|
+
*/
|
|
239
|
+
declare class RtkFloatEngine {
|
|
240
|
+
private readonly basePos;
|
|
241
|
+
private readonly ephemerides;
|
|
242
|
+
private readonly o;
|
|
243
|
+
/** State vector [x, y, z, N₁…] and covariance; null before init. */
|
|
244
|
+
private x;
|
|
245
|
+
private P;
|
|
246
|
+
private amb;
|
|
247
|
+
private refs;
|
|
248
|
+
private track;
|
|
249
|
+
private lastMs;
|
|
250
|
+
constructor(basePos: readonly [number, number, number], ephemerides: EphemerisSource, opts?: RtkFloatOptions);
|
|
251
|
+
/** Clear all filter state (position, ambiguities, lock history). */
|
|
252
|
+
reset(): void;
|
|
253
|
+
private ambIndex;
|
|
254
|
+
/** Remove one ambiguity state (row/col) from x and P. */
|
|
255
|
+
private dropAmb;
|
|
256
|
+
/** Append an ambiguity state with the given value and variance. */
|
|
257
|
+
private addAmb;
|
|
258
|
+
/**
|
|
259
|
+
* Re-map a group's DD ambiguities from the old reference r to the
|
|
260
|
+
* new reference r' (which must hold a state): N_i' = N_i − N_r' and
|
|
261
|
+
* the old reference's slot becomes N_r = −N_r'. Exact linear
|
|
262
|
+
* transform of state and covariance (P' = T P Tᵀ).
|
|
263
|
+
*/
|
|
264
|
+
private retarget;
|
|
265
|
+
/**
|
|
266
|
+
* Process one synchronized epoch (same nominal `timeMs` for both
|
|
267
|
+
* receivers). Returns null until a first position can be
|
|
268
|
+
* initialised (via an internal DGNSS solve) or when the epoch has
|
|
269
|
+
* fewer than 3 usable DD rows.
|
|
270
|
+
*/
|
|
271
|
+
process(rover: RtkEpochMeasurements, base: RtkEpochMeasurements, timeMs: number): RtkFloatSolution | null;
|
|
272
|
+
}
|
|
273
|
+
|
|
37
274
|
/**
|
|
38
275
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
39
276
|
* ephemerides.
|
|
@@ -114,4 +351,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
114
351
|
*/
|
|
115
352
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
116
353
|
|
|
117
|
-
export { type KlobucharCoeffs, type SppOptions, type SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveSpp };
|
|
354
|
+
export { type DgnssOptions, type DgnssSolution, type EphemerisSource, type KlobucharCoeffs, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SppOptions, type SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveDgnss, solveSpp, toRtkEpoch };
|
package/dist/positioning.d.ts
CHANGED
|
@@ -34,6 +34,243 @@ interface KlobucharCoeffs {
|
|
|
34
34
|
*/
|
|
35
35
|
declare function klobucharDelay(coeffs: KlobucharCoeffs, latRad: number, lonRad: number, azRad: number, elRad: number, gpsTowSec: number): number;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* RTK positioning, stage 1: epoch-wise double-differenced (DD)
|
|
39
|
+
* processing of a base/rover receiver pair.
|
|
40
|
+
*
|
|
41
|
+
* Two solvers share the same DD construction:
|
|
42
|
+
*
|
|
43
|
+
* - `solveDgnss` — code-based DGNSS: between-receiver single
|
|
44
|
+
* differences on pseudoranges, double-differenced against a
|
|
45
|
+
* reference satellite (highest elevation per signal group), iterated
|
|
46
|
+
* weighted least squares for the rover position with the full DD
|
|
47
|
+
* covariance (DDs sharing a reference satellite are correlated).
|
|
48
|
+
*
|
|
49
|
+
* - `RtkFloatEngine` — a stateful extended Kalman filter over DD
|
|
50
|
+
* carrier phase + code with one float DD ambiguity state per
|
|
51
|
+
* satellite/signal. An EKF (rather than epoch-wise iterated least
|
|
52
|
+
* squares with appended ambiguity columns) was chosen because the
|
|
53
|
+
* float ambiguities must persist across epochs anyway, and stage 2
|
|
54
|
+
* (LAMBDA) needs the joint float ambiguity covariance — which the
|
|
55
|
+
* EKF maintains natively. This mirrors RTKLIB's float-filter
|
|
56
|
+
* structure (rtkpos.c), which the implementation was validated
|
|
57
|
+
* against; no integer fixing is attempted (`ratio` is reserved).
|
|
58
|
+
*
|
|
59
|
+
* Differencing model: for satellites s and reference r observed by
|
|
60
|
+
* rover R and base B, the DD pseudorange/phase cancels satellite
|
|
61
|
+
* clocks (single difference) and receiver clocks (double difference).
|
|
62
|
+
* On short baselines the ionospheric and most of the tropospheric
|
|
63
|
+
* delay cancel too; the residual troposphere is modelled by the same
|
|
64
|
+
* simple elevation-mapped zenith model `solveSpp` uses, applied
|
|
65
|
+
* differentially. DDs are formed per *signal group* (constellation
|
|
66
|
+
* letter + RINEX code, e.g. `G1C`, `C2I`) so that only like signals
|
|
67
|
+
* are differenced.
|
|
68
|
+
*
|
|
69
|
+
* GLONASS (FDMA): DD phase is formed in metres with per-satellite
|
|
70
|
+
* wavelengths (λ_s·SDφ_s − λ_r·SDφ_r). The common receiver clock
|
|
71
|
+
* term cancels exactly (λ·f = c on every channel); the per-channel
|
|
72
|
+
* receiver phase bias (inter-frequency bias, IFB) does not, but it is
|
|
73
|
+
* constant while lock holds and is absorbed into the float DD
|
|
74
|
+
* ambiguity — the standard reason GLONASS float works while GLONASS
|
|
75
|
+
* integer fixing is hard. DD *code* retains the differential
|
|
76
|
+
* inter-channel code bias between the two receivers, which is small
|
|
77
|
+
* (well below the code noise) for same-model receivers — IFB-safe
|
|
78
|
+
* enough for stage 1, and documented as such.
|
|
79
|
+
*
|
|
80
|
+
* Time convention: `timeMs` is GPS-scale epoch milliseconds, exactly
|
|
81
|
+
* as produced by `parseNovatelRange` / the RINEX and RTCM parsers —
|
|
82
|
+
* the same convention `solveSpp` uses. No system clock is read.
|
|
83
|
+
*
|
|
84
|
+
* Adapting decoder output (see `toRtkEpoch`):
|
|
85
|
+
* - NovAtel: `parseNovatelRange(bytes).epochs[i]` gives
|
|
86
|
+
* `{ timeMs, meas }`; `toRtkEpoch(meas)` picks each satellite's
|
|
87
|
+
* L1-band measurement. When a log carries both RANGE and RANGECMP
|
|
88
|
+
* the same epoch appears twice — keep one epoch per `timeMs`.
|
|
89
|
+
* - RTCM MSM: for each satellite/signal cell build
|
|
90
|
+
* `{ code, pr: pseudorangeM, cp: phaserangeM / lambda, lockTimeMs }`
|
|
91
|
+
* (MSM phaseranges are metres; divide by the carrier wavelength to
|
|
92
|
+
* get cycles) and pass a `prn → measurement` map for the epoch.
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/** One satellite's measurement on one signal, for one epoch. */
|
|
96
|
+
interface RtkMeasurement {
|
|
97
|
+
/** RINEX band+attribute, e.g. "1C", "2I". */
|
|
98
|
+
code: string;
|
|
99
|
+
/** Pseudorange (m). */
|
|
100
|
+
pr: number | null;
|
|
101
|
+
/** Carrier phase (cycles, RINEX sign), optional — DGNSS needs none. */
|
|
102
|
+
cp?: number | null;
|
|
103
|
+
/** Continuous lock time (ms) for cycle-slip detection, optional. */
|
|
104
|
+
lockTimeMs?: number;
|
|
105
|
+
/** GLONASS frequency channel k (−7…+6), for FDMA wavelengths. */
|
|
106
|
+
gloChannel?: number | null;
|
|
107
|
+
}
|
|
108
|
+
/** One epoch of measurements: PRN → measurement (one signal per PRN). */
|
|
109
|
+
type RtkEpochMeasurements = ReadonlyMap<string, RtkMeasurement>;
|
|
110
|
+
/** Decoder-shaped observation (structurally `NovatelMeasurement`). */
|
|
111
|
+
interface RawObservation {
|
|
112
|
+
prn: string;
|
|
113
|
+
code: string;
|
|
114
|
+
pr: number | null;
|
|
115
|
+
cp?: number | null;
|
|
116
|
+
lockTimeS?: number;
|
|
117
|
+
gloChannel?: number | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Adapt one epoch of decoder observations (e.g.
|
|
121
|
+
* `parseNovatelRange(...).epochs[i].meas`) to the RTK input map:
|
|
122
|
+
* keeps each satellite's preferred L1-band code measurement with a
|
|
123
|
+
* valid pseudorange, drops unsupported systems (SBAS, NavIC).
|
|
124
|
+
*/
|
|
125
|
+
declare function toRtkEpoch(meas: readonly RawObservation[]): Map<string, RtkMeasurement>;
|
|
126
|
+
/** Ephemeris source: a per-PRN map, or a list searched per epoch. */
|
|
127
|
+
type EphemerisSource = ReadonlyMap<string, Ephemeris> | readonly Ephemeris[];
|
|
128
|
+
interface DgnssOptions {
|
|
129
|
+
/** Elevation mask at the base, degrees. Default 10. */
|
|
130
|
+
elevationMaskDeg?: number;
|
|
131
|
+
/** Model the differential troposphere. Default true. */
|
|
132
|
+
troposphere?: boolean;
|
|
133
|
+
/** Maximum Gauss-Newton iterations. Default 15. */
|
|
134
|
+
maxIterations?: number;
|
|
135
|
+
/** Convergence threshold on the position update (m). Default 1e-4. */
|
|
136
|
+
convergenceM?: number;
|
|
137
|
+
/** Zenith code sigma per receiver (m). Default 0.3. */
|
|
138
|
+
codeSigmaM?: number;
|
|
139
|
+
/** Worst-first DD residual rejection threshold (m). Default 20. */
|
|
140
|
+
rejectThresholdM?: number;
|
|
141
|
+
/** Initial rover position; defaults to the base position. */
|
|
142
|
+
initialPosition?: [number, number, number];
|
|
143
|
+
}
|
|
144
|
+
interface DgnssSolution {
|
|
145
|
+
/** Rover position, ECEF metres. */
|
|
146
|
+
position: [number, number, number];
|
|
147
|
+
/** Baseline rover − base, ECEF metres. */
|
|
148
|
+
baseline: [number, number, number];
|
|
149
|
+
/** Formal position sigmas from the LSQ covariance, ECEF metres. */
|
|
150
|
+
sigmas: [number, number, number];
|
|
151
|
+
/** Satellites used (including references). */
|
|
152
|
+
usedSatellites: string[];
|
|
153
|
+
/** Reference satellite per signal group. */
|
|
154
|
+
refSatellites: Record<string, string>;
|
|
155
|
+
/** Post-fit DD residual (m) per non-reference PRN. */
|
|
156
|
+
residuals: Record<string, number>;
|
|
157
|
+
/** Satellites rejected by the residual screen. */
|
|
158
|
+
rejectedSatellites: string[];
|
|
159
|
+
nSats: number;
|
|
160
|
+
iterations: number;
|
|
161
|
+
converged: boolean;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Solve the rover position from one epoch of DD pseudoranges.
|
|
165
|
+
*
|
|
166
|
+
* @param rover Rover measurements (PRN → measurement).
|
|
167
|
+
* @param base Base measurements (PRN → measurement, same codes).
|
|
168
|
+
* @param basePos Known base position, ECEF metres.
|
|
169
|
+
* @param ephemerides Broadcast ephemerides (per-PRN map, or a list
|
|
170
|
+
* searched by closest epoch — pass `parseNovatelNav(...).ephemerides`
|
|
171
|
+
* or `parseNavFile(...).ephemerides` directly).
|
|
172
|
+
* @param timeMs Receiver epoch, GPS-scale milliseconds.
|
|
173
|
+
*/
|
|
174
|
+
declare function solveDgnss(rover: RtkEpochMeasurements, base: RtkEpochMeasurements, basePos: readonly [number, number, number], ephemerides: EphemerisSource, timeMs: number, opts?: DgnssOptions): DgnssSolution | null;
|
|
175
|
+
interface RtkFloatOptions {
|
|
176
|
+
/**
|
|
177
|
+
* 'static': the rover position is a constant state (random walk
|
|
178
|
+
* `processNoisePosM`·√s, default 0). 'kinematic': the position is
|
|
179
|
+
* re-initialised each epoch with `kinematicSigmaM` uncertainty
|
|
180
|
+
* (no velocity states at stage 1 — RTKLIB's default kinematic
|
|
181
|
+
* handling without doppler). Default 'kinematic'.
|
|
182
|
+
*/
|
|
183
|
+
mode?: 'static' | 'kinematic';
|
|
184
|
+
/** Elevation mask at the base, degrees. Default 10. */
|
|
185
|
+
elevationMaskDeg?: number;
|
|
186
|
+
/** Model the differential troposphere. Default true. */
|
|
187
|
+
troposphere?: boolean;
|
|
188
|
+
/** Zenith code sigma per receiver (m). Default 0.3. */
|
|
189
|
+
codeSigmaM?: number;
|
|
190
|
+
/** Zenith phase sigma per receiver (m). Default 0.003. */
|
|
191
|
+
phaseSigmaM?: number;
|
|
192
|
+
/** Static-mode position random walk (m/√s). Default 0. */
|
|
193
|
+
processNoisePosM?: number;
|
|
194
|
+
/** Kinematic per-epoch position reset sigma (m). Default 30. */
|
|
195
|
+
kinematicSigmaM?: number;
|
|
196
|
+
/** Ambiguity random walk (cycles/√s). Default 1e-4. */
|
|
197
|
+
ambProcessNoiseCycles?: number;
|
|
198
|
+
/** New float ambiguity sigma (cycles). Default 30. */
|
|
199
|
+
ambInitSigmaCycles?: number;
|
|
200
|
+
/** Drop ambiguity states unseen for this long (ms). Default 10000. */
|
|
201
|
+
maxGapMs?: number;
|
|
202
|
+
/** DD code innovation gate (m): drop the satellite. Default 30. */
|
|
203
|
+
codeGateM?: number;
|
|
204
|
+
/**
|
|
205
|
+
* Phase-minus-code innovation divergence gate (m): treat as an
|
|
206
|
+
* undetected cycle slip and re-initialise the ambiguity. Default 5.
|
|
207
|
+
*/
|
|
208
|
+
slipGateM?: number;
|
|
209
|
+
/** Measurement-update relinearisations (IEKF). Default 2. */
|
|
210
|
+
updateIterations?: number;
|
|
211
|
+
}
|
|
212
|
+
interface RtkFloatSolution {
|
|
213
|
+
/** Epoch, GPS-scale milliseconds. */
|
|
214
|
+
timeMs: number;
|
|
215
|
+
/** Rover position, ECEF metres. */
|
|
216
|
+
position: [number, number, number];
|
|
217
|
+
/** Float baseline rover − base, ECEF metres. */
|
|
218
|
+
floatBaseline: [number, number, number];
|
|
219
|
+
/** Satellites contributing DD rows this epoch (incl. references). */
|
|
220
|
+
nSats: number;
|
|
221
|
+
/** Ambiguity-validation ratio — undefined at stage 1 (no LAMBDA). */
|
|
222
|
+
ratio?: number;
|
|
223
|
+
/** Formal position sigmas (filter covariance), ECEF metres. */
|
|
224
|
+
sigmas: [number, number, number];
|
|
225
|
+
/** Float DD ambiguity (cycles) per non-reference PRN. */
|
|
226
|
+
ambiguities: Record<string, number>;
|
|
227
|
+
/** Reference satellite per signal group. */
|
|
228
|
+
refSatellites: Record<string, string>;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Epoch-by-epoch float RTK filter: EKF states = rover position
|
|
232
|
+
* (static or kinematic) + one float DD ambiguity (cycles) per
|
|
233
|
+
* satellite/signal. Cycle slips are handled via lock-time regressions
|
|
234
|
+
* (LLI-style resets) and a phase/code divergence gate; reference-
|
|
235
|
+
* satellite switches re-map the DD ambiguity states algebraically
|
|
236
|
+
* (N_i' = N_i − N_r', old reference gains −N_r') so no information is
|
|
237
|
+
* lost. Feed epochs in time order via `process`.
|
|
238
|
+
*/
|
|
239
|
+
declare class RtkFloatEngine {
|
|
240
|
+
private readonly basePos;
|
|
241
|
+
private readonly ephemerides;
|
|
242
|
+
private readonly o;
|
|
243
|
+
/** State vector [x, y, z, N₁…] and covariance; null before init. */
|
|
244
|
+
private x;
|
|
245
|
+
private P;
|
|
246
|
+
private amb;
|
|
247
|
+
private refs;
|
|
248
|
+
private track;
|
|
249
|
+
private lastMs;
|
|
250
|
+
constructor(basePos: readonly [number, number, number], ephemerides: EphemerisSource, opts?: RtkFloatOptions);
|
|
251
|
+
/** Clear all filter state (position, ambiguities, lock history). */
|
|
252
|
+
reset(): void;
|
|
253
|
+
private ambIndex;
|
|
254
|
+
/** Remove one ambiguity state (row/col) from x and P. */
|
|
255
|
+
private dropAmb;
|
|
256
|
+
/** Append an ambiguity state with the given value and variance. */
|
|
257
|
+
private addAmb;
|
|
258
|
+
/**
|
|
259
|
+
* Re-map a group's DD ambiguities from the old reference r to the
|
|
260
|
+
* new reference r' (which must hold a state): N_i' = N_i − N_r' and
|
|
261
|
+
* the old reference's slot becomes N_r = −N_r'. Exact linear
|
|
262
|
+
* transform of state and covariance (P' = T P Tᵀ).
|
|
263
|
+
*/
|
|
264
|
+
private retarget;
|
|
265
|
+
/**
|
|
266
|
+
* Process one synchronized epoch (same nominal `timeMs` for both
|
|
267
|
+
* receivers). Returns null until a first position can be
|
|
268
|
+
* initialised (via an internal DGNSS solve) or when the epoch has
|
|
269
|
+
* fewer than 3 usable DD rows.
|
|
270
|
+
*/
|
|
271
|
+
process(rover: RtkEpochMeasurements, base: RtkEpochMeasurements, timeMs: number): RtkFloatSolution | null;
|
|
272
|
+
}
|
|
273
|
+
|
|
37
274
|
/**
|
|
38
275
|
* Single-point positioning (SPP) from pseudoranges and broadcast
|
|
39
276
|
* ephemerides.
|
|
@@ -114,4 +351,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
|
|
|
114
351
|
*/
|
|
115
352
|
declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
|
|
116
353
|
|
|
117
|
-
export { type KlobucharCoeffs, type SppOptions, type SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveSpp };
|
|
354
|
+
export { type DgnssOptions, type DgnssSolution, type EphemerisSource, type KlobucharCoeffs, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SppOptions, type SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveDgnss, solveSpp, toRtkEpoch };
|
package/dist/positioning.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
+
RtkFloatEngine,
|
|
2
3
|
ionoFree,
|
|
3
4
|
klobucharDelay,
|
|
4
5
|
satClockCorrection,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
solveDgnss,
|
|
7
|
+
solveSpp,
|
|
8
|
+
toRtkEpoch
|
|
9
|
+
} from "./chunk-CUWF56ST.js";
|
|
10
|
+
import "./chunk-MHGNKSSH.js";
|
|
8
11
|
import "./chunk-37QNKGTC.js";
|
|
9
12
|
import "./chunk-6FAL6P4G.js";
|
|
10
13
|
import "./chunk-HVXYFUCB.js";
|
|
11
14
|
import "./chunk-LEEU5OIO.js";
|
|
12
15
|
import "./chunk-FIEWO4J4.js";
|
|
13
16
|
export {
|
|
17
|
+
RtkFloatEngine,
|
|
14
18
|
ionoFree,
|
|
15
19
|
klobucharDelay,
|
|
16
20
|
satClockCorrection,
|
|
17
|
-
|
|
21
|
+
solveDgnss,
|
|
22
|
+
solveSpp,
|
|
23
|
+
toRtkEpoch
|
|
18
24
|
};
|
package/dist/sbf.js
CHANGED