gnss-js 2.6.0 → 2.8.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-MIIM4LDY.js → chunk-CVCTRIWU.js} +87 -24
- package/dist/{chunk-JYWYQ7DW.js → chunk-GLMQRZDL.js} +51 -46
- package/dist/{chunk-BWLLHLLS.js → chunk-PHS7OFHN.js} +3 -24
- package/dist/coordinates.cjs +91 -26
- package/dist/coordinates.d.cts +26 -3
- package/dist/coordinates.d.ts +26 -3
- package/dist/coordinates.js +7 -3
- package/dist/index.cjs +141 -94
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -4
- package/dist/orbit.cjs +50 -46
- package/dist/orbit.d.cts +23 -6
- package/dist/orbit.d.ts +23 -6
- package/dist/orbit.js +1 -1
- package/dist/positioning.cjs +48 -69
- package/dist/positioning.js +3 -3
- package/package.json +1 -1
package/dist/orbit.cjs
CHANGED
|
@@ -174,6 +174,30 @@ function getGpsLeap(date) {
|
|
|
174
174
|
return leap_seconds - 19;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
// src/orbit/matrix.ts
|
|
178
|
+
function invertMatrix(A) {
|
|
179
|
+
const n = A.length;
|
|
180
|
+
const M = A.map((row, i) => [
|
|
181
|
+
...row,
|
|
182
|
+
...Array.from({ length: n }, (_, j) => i === j ? 1 : 0)
|
|
183
|
+
]);
|
|
184
|
+
for (let col = 0; col < n; col++) {
|
|
185
|
+
let piv = col;
|
|
186
|
+
for (let r = col + 1; r < n; r++)
|
|
187
|
+
if (Math.abs(M[r][col]) > Math.abs(M[piv][col])) piv = r;
|
|
188
|
+
if (Math.abs(M[piv][col]) < 1e-12) return null;
|
|
189
|
+
[M[col], M[piv]] = [M[piv], M[col]];
|
|
190
|
+
const d = M[col][col];
|
|
191
|
+
for (let j = 0; j < 2 * n; j++) M[col][j] /= d;
|
|
192
|
+
for (let r = 0; r < n; r++) {
|
|
193
|
+
if (r === col) continue;
|
|
194
|
+
const f = M[r][col];
|
|
195
|
+
for (let j = 0; j < 2 * n; j++) M[r][j] -= f * M[col][j];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return M.map((row) => row.slice(n));
|
|
199
|
+
}
|
|
200
|
+
|
|
177
201
|
// src/orbit/almanac.ts
|
|
178
202
|
var GM_GPS = 3986005e8;
|
|
179
203
|
var GM_GAL = 3986004418e5;
|
|
@@ -543,15 +567,20 @@ function ecefToAzEl(rxX, rxY, rxZ, satX, satY, satZ) {
|
|
|
543
567
|
}
|
|
544
568
|
function computeDop(satAzEls) {
|
|
545
569
|
const n = satAzEls.length;
|
|
546
|
-
|
|
570
|
+
const clocks = [...new Set(satAzEls.map((s) => s.prn?.[0] ?? ""))];
|
|
571
|
+
const m = 3 + clocks.length;
|
|
572
|
+
if (n < Math.max(4, m)) return null;
|
|
547
573
|
const H = [];
|
|
548
|
-
for (const { az, el } of satAzEls) {
|
|
574
|
+
for (const { az, el, prn } of satAzEls) {
|
|
549
575
|
const cosEl = Math.cos(el);
|
|
550
|
-
|
|
576
|
+
const row = [cosEl * Math.sin(az), cosEl * Math.cos(az), Math.sin(el)];
|
|
577
|
+
const sys = prn?.[0] ?? "";
|
|
578
|
+
for (const c of clocks) row.push(c === sys ? 1 : 0);
|
|
579
|
+
H.push(row);
|
|
551
580
|
}
|
|
552
|
-
const HtH = Array.from({ length:
|
|
553
|
-
for (let i = 0; i <
|
|
554
|
-
for (let j = 0; j <
|
|
581
|
+
const HtH = Array.from({ length: m }, () => new Array(m).fill(0));
|
|
582
|
+
for (let i = 0; i < m; i++) {
|
|
583
|
+
for (let j = 0; j < m; j++) {
|
|
555
584
|
let sum = 0;
|
|
556
585
|
for (let k = 0; k < n; k++) {
|
|
557
586
|
sum += H[k][i] * H[k][j];
|
|
@@ -559,46 +588,18 @@ function computeDop(satAzEls) {
|
|
|
559
588
|
HtH[i][j] = sum;
|
|
560
589
|
}
|
|
561
590
|
}
|
|
562
|
-
const Q =
|
|
591
|
+
const Q = invertMatrix(HtH);
|
|
563
592
|
if (!Q) return null;
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
inv[4] = -a[4] * a[10] * a[15] + a[4] * a[11] * a[14] + a[8] * a[6] * a[15] - a[8] * a[7] * a[14] - a[12] * a[6] * a[11] + a[12] * a[7] * a[10];
|
|
575
|
-
inv[8] = a[4] * a[9] * a[15] - a[4] * a[11] * a[13] - a[8] * a[5] * a[15] + a[8] * a[7] * a[13] + a[12] * a[5] * a[11] - a[12] * a[7] * a[9];
|
|
576
|
-
inv[12] = -a[4] * a[9] * a[14] + a[4] * a[10] * a[13] + a[8] * a[5] * a[14] - a[8] * a[6] * a[13] - a[12] * a[5] * a[10] + a[12] * a[6] * a[9];
|
|
577
|
-
inv[1] = -a[1] * a[10] * a[15] + a[1] * a[11] * a[14] + a[9] * a[2] * a[15] - a[9] * a[3] * a[14] - a[13] * a[2] * a[11] + a[13] * a[3] * a[10];
|
|
578
|
-
inv[5] = a[0] * a[10] * a[15] - a[0] * a[11] * a[14] - a[8] * a[2] * a[15] + a[8] * a[3] * a[14] + a[12] * a[2] * a[11] - a[12] * a[3] * a[10];
|
|
579
|
-
inv[9] = -a[0] * a[9] * a[15] + a[0] * a[11] * a[13] + a[8] * a[1] * a[15] - a[8] * a[3] * a[13] - a[12] * a[1] * a[11] + a[12] * a[3] * a[9];
|
|
580
|
-
inv[13] = a[0] * a[9] * a[14] - a[0] * a[10] * a[13] - a[8] * a[1] * a[14] + a[8] * a[2] * a[13] + a[12] * a[1] * a[10] - a[12] * a[2] * a[9];
|
|
581
|
-
inv[2] = a[1] * a[6] * a[15] - a[1] * a[7] * a[14] - a[5] * a[2] * a[15] + a[5] * a[3] * a[14] + a[13] * a[2] * a[7] - a[13] * a[3] * a[6];
|
|
582
|
-
inv[6] = -a[0] * a[6] * a[15] + a[0] * a[7] * a[14] + a[4] * a[2] * a[15] - a[4] * a[3] * a[14] - a[12] * a[2] * a[7] + a[12] * a[3] * a[6];
|
|
583
|
-
inv[10] = a[0] * a[5] * a[15] - a[0] * a[7] * a[13] - a[4] * a[1] * a[15] + a[4] * a[3] * a[13] + a[12] * a[1] * a[7] - a[12] * a[3] * a[5];
|
|
584
|
-
inv[14] = -a[0] * a[5] * a[14] + a[0] * a[6] * a[13] + a[4] * a[1] * a[14] - a[4] * a[2] * a[13] - a[12] * a[1] * a[6] + a[12] * a[2] * a[5];
|
|
585
|
-
inv[3] = -a[1] * a[6] * a[11] + a[1] * a[7] * a[10] + a[5] * a[2] * a[11] - a[5] * a[3] * a[10] - a[9] * a[2] * a[7] + a[9] * a[3] * a[6];
|
|
586
|
-
inv[7] = a[0] * a[6] * a[11] - a[0] * a[7] * a[10] - a[4] * a[2] * a[11] + a[4] * a[3] * a[10] + a[8] * a[2] * a[7] - a[8] * a[3] * a[6];
|
|
587
|
-
inv[11] = -a[0] * a[5] * a[11] + a[0] * a[7] * a[9] + a[4] * a[1] * a[11] - a[4] * a[3] * a[9] - a[8] * a[1] * a[7] + a[8] * a[3] * a[5];
|
|
588
|
-
inv[15] = a[0] * a[5] * a[10] - a[0] * a[6] * a[9] - a[4] * a[1] * a[10] + a[4] * a[2] * a[9] + a[8] * a[1] * a[6] - a[8] * a[2] * a[5];
|
|
589
|
-
let det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
|
|
590
|
-
if (Math.abs(det) < 1e-20) return null;
|
|
591
|
-
det = 1 / det;
|
|
592
|
-
const result = Array.from(
|
|
593
|
-
{ length: 4 },
|
|
594
|
-
() => new Array(4).fill(0)
|
|
595
|
-
);
|
|
596
|
-
for (let i = 0; i < 4; i++) {
|
|
597
|
-
for (let j = 0; j < 4; j++) {
|
|
598
|
-
result[i][j] = inv[i * 4 + j] * det;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
return result;
|
|
593
|
+
let clockVar = 0;
|
|
594
|
+
for (let i = 3; i < m; i++) clockVar += Q[i][i];
|
|
595
|
+
const posVar = Q[0][0] + Q[1][1] + Q[2][2];
|
|
596
|
+
return {
|
|
597
|
+
gdop: Math.sqrt(posVar + clockVar),
|
|
598
|
+
pdop: Math.sqrt(posVar),
|
|
599
|
+
hdop: Math.sqrt(Q[0][0] + Q[1][1]),
|
|
600
|
+
vdop: Math.sqrt(Q[2][2]),
|
|
601
|
+
tdop: Math.sqrt(clockVar)
|
|
602
|
+
};
|
|
602
603
|
}
|
|
603
604
|
function selectEphemeris(ephemerides, prn, timeMs) {
|
|
604
605
|
return selectBest(
|
|
@@ -858,6 +859,7 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
858
859
|
const gdop = new Array(times.length).fill(null);
|
|
859
860
|
const hdop = new Array(times.length).fill(null);
|
|
860
861
|
const vdop = new Array(times.length).fill(null);
|
|
862
|
+
const tdop = new Array(times.length).fill(null);
|
|
861
863
|
const visiblePerEpoch = times.map(() => []);
|
|
862
864
|
for (const prn of all.prns) {
|
|
863
865
|
const series = all.positions[prn];
|
|
@@ -871,7 +873,7 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
871
873
|
visibleCount[i]++;
|
|
872
874
|
const sys = prn[0];
|
|
873
875
|
(visibleBySystem[sys] ??= new Array(times.length).fill(0))[i]++;
|
|
874
|
-
visiblePerEpoch[i].push({ az: p.az, el: p.el });
|
|
876
|
+
visiblePerEpoch[i].push({ az: p.az, el: p.el, prn });
|
|
875
877
|
}
|
|
876
878
|
}
|
|
877
879
|
}
|
|
@@ -881,6 +883,7 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
881
883
|
gdop[i] = dop ? dop.gdop : null;
|
|
882
884
|
hdop[i] = dop ? dop.hdop : null;
|
|
883
885
|
vdop[i] = dop ? dop.vdop : null;
|
|
886
|
+
tdop[i] = dop ? dop.tdop : null;
|
|
884
887
|
}
|
|
885
888
|
const passes = [];
|
|
886
889
|
for (const prn of all.prns) {
|
|
@@ -927,6 +930,7 @@ function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
|
927
930
|
gdop,
|
|
928
931
|
hdop,
|
|
929
932
|
vdop,
|
|
933
|
+
tdop,
|
|
930
934
|
passes
|
|
931
935
|
};
|
|
932
936
|
}
|
package/dist/orbit.d.cts
CHANGED
|
@@ -118,6 +118,11 @@ interface DopValues {
|
|
|
118
118
|
pdop: number;
|
|
119
119
|
hdop: number;
|
|
120
120
|
vdop: number;
|
|
121
|
+
/**
|
|
122
|
+
* Time DOP: root of the summed receiver-clock variances (one clock per
|
|
123
|
+
* constellation in view), so GDOP² = PDOP² + TDOP².
|
|
124
|
+
*/
|
|
125
|
+
tdop: number;
|
|
121
126
|
}
|
|
122
127
|
/**
|
|
123
128
|
* Compute satellite ECEF position and velocity from Keplerian ephemeris.
|
|
@@ -154,12 +159,22 @@ declare function ecefToAzEl(rxX: number, rxY: number, rxZ: number, satX: number,
|
|
|
154
159
|
};
|
|
155
160
|
/**
|
|
156
161
|
* Compute DOP values from a set of satellite az/el.
|
|
157
|
-
*
|
|
158
|
-
*
|
|
162
|
+
*
|
|
163
|
+
* Satellites tagged with a `prn` get one receiver-clock unknown per
|
|
164
|
+
* constellation (the PRN's system letter), matching how a multi-GNSS
|
|
165
|
+
* receiver solves and how `solveSpp` does: each system runs on its own
|
|
166
|
+
* time scale, so every extra constellation costs one observation. Untagged
|
|
167
|
+
* satellites share a single clock (the classic single-system model).
|
|
168
|
+
*
|
|
169
|
+
* @param satAzEls Satellite azimuth/elevation pairs (radians), optionally
|
|
170
|
+
* tagged with their PRN.
|
|
171
|
+
* @returns DOP values, or null when there are fewer satellites than
|
|
172
|
+
* unknowns (3 + one clock per constellation) or the geometry is singular.
|
|
159
173
|
*/
|
|
160
174
|
declare function computeDop(satAzEls: {
|
|
161
175
|
az: number;
|
|
162
176
|
el: number;
|
|
177
|
+
prn?: string;
|
|
163
178
|
}[]): DopValues | null;
|
|
164
179
|
/**
|
|
165
180
|
* Find the best ephemeris for a given PRN at a given time.
|
|
@@ -242,14 +257,16 @@ interface VisibilityResult {
|
|
|
242
257
|
visibleCount: number[];
|
|
243
258
|
/** Per-system visible counts per epoch (system letter → counts). */
|
|
244
259
|
visibleBySystem: Record<string, number[]>;
|
|
245
|
-
/** PDOP per epoch (null when
|
|
260
|
+
/** PDOP per epoch (null when fewer satellites than unknowns). */
|
|
246
261
|
pdop: (number | null)[];
|
|
247
|
-
/** GDOP per epoch (null when
|
|
262
|
+
/** GDOP per epoch (null when fewer satellites than unknowns). */
|
|
248
263
|
gdop: (number | null)[];
|
|
249
|
-
/** HDOP per epoch (null when
|
|
264
|
+
/** HDOP per epoch (null when fewer satellites than unknowns). */
|
|
250
265
|
hdop: (number | null)[];
|
|
251
|
-
/** VDOP per epoch (null when
|
|
266
|
+
/** VDOP per epoch (null when fewer satellites than unknowns). */
|
|
252
267
|
vdop: (number | null)[];
|
|
268
|
+
/** TDOP per epoch (all constellation clocks; null like the others). */
|
|
269
|
+
tdop: (number | null)[];
|
|
253
270
|
/** Discrete above-mask passes, sorted by rise time. */
|
|
254
271
|
passes: VisibilityPass[];
|
|
255
272
|
}
|
package/dist/orbit.d.ts
CHANGED
|
@@ -118,6 +118,11 @@ interface DopValues {
|
|
|
118
118
|
pdop: number;
|
|
119
119
|
hdop: number;
|
|
120
120
|
vdop: number;
|
|
121
|
+
/**
|
|
122
|
+
* Time DOP: root of the summed receiver-clock variances (one clock per
|
|
123
|
+
* constellation in view), so GDOP² = PDOP² + TDOP².
|
|
124
|
+
*/
|
|
125
|
+
tdop: number;
|
|
121
126
|
}
|
|
122
127
|
/**
|
|
123
128
|
* Compute satellite ECEF position and velocity from Keplerian ephemeris.
|
|
@@ -154,12 +159,22 @@ declare function ecefToAzEl(rxX: number, rxY: number, rxZ: number, satX: number,
|
|
|
154
159
|
};
|
|
155
160
|
/**
|
|
156
161
|
* Compute DOP values from a set of satellite az/el.
|
|
157
|
-
*
|
|
158
|
-
*
|
|
162
|
+
*
|
|
163
|
+
* Satellites tagged with a `prn` get one receiver-clock unknown per
|
|
164
|
+
* constellation (the PRN's system letter), matching how a multi-GNSS
|
|
165
|
+
* receiver solves and how `solveSpp` does: each system runs on its own
|
|
166
|
+
* time scale, so every extra constellation costs one observation. Untagged
|
|
167
|
+
* satellites share a single clock (the classic single-system model).
|
|
168
|
+
*
|
|
169
|
+
* @param satAzEls Satellite azimuth/elevation pairs (radians), optionally
|
|
170
|
+
* tagged with their PRN.
|
|
171
|
+
* @returns DOP values, or null when there are fewer satellites than
|
|
172
|
+
* unknowns (3 + one clock per constellation) or the geometry is singular.
|
|
159
173
|
*/
|
|
160
174
|
declare function computeDop(satAzEls: {
|
|
161
175
|
az: number;
|
|
162
176
|
el: number;
|
|
177
|
+
prn?: string;
|
|
163
178
|
}[]): DopValues | null;
|
|
164
179
|
/**
|
|
165
180
|
* Find the best ephemeris for a given PRN at a given time.
|
|
@@ -242,14 +257,16 @@ interface VisibilityResult {
|
|
|
242
257
|
visibleCount: number[];
|
|
243
258
|
/** Per-system visible counts per epoch (system letter → counts). */
|
|
244
259
|
visibleBySystem: Record<string, number[]>;
|
|
245
|
-
/** PDOP per epoch (null when
|
|
260
|
+
/** PDOP per epoch (null when fewer satellites than unknowns). */
|
|
246
261
|
pdop: (number | null)[];
|
|
247
|
-
/** GDOP per epoch (null when
|
|
262
|
+
/** GDOP per epoch (null when fewer satellites than unknowns). */
|
|
248
263
|
gdop: (number | null)[];
|
|
249
|
-
/** HDOP per epoch (null when
|
|
264
|
+
/** HDOP per epoch (null when fewer satellites than unknowns). */
|
|
250
265
|
hdop: (number | null)[];
|
|
251
|
-
/** VDOP per epoch (null when
|
|
266
|
+
/** VDOP per epoch (null when fewer satellites than unknowns). */
|
|
252
267
|
vdop: (number | null)[];
|
|
268
|
+
/** TDOP per epoch (all constellation clocks; null like the others). */
|
|
269
|
+
tdop: (number | null)[];
|
|
253
270
|
/** Discrete above-mask passes, sorted by rise time. */
|
|
254
271
|
passes: VisibilityPass[];
|
|
255
272
|
}
|
package/dist/orbit.js
CHANGED
package/dist/positioning.cjs
CHANGED
|
@@ -230,6 +230,30 @@ function getGpsLeap(date) {
|
|
|
230
230
|
return leap_seconds - 19;
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
// src/orbit/matrix.ts
|
|
234
|
+
function invertMatrix(A) {
|
|
235
|
+
const n = A.length;
|
|
236
|
+
const M = A.map((row, i) => [
|
|
237
|
+
...row,
|
|
238
|
+
...Array.from({ length: n }, (_, j) => i === j ? 1 : 0)
|
|
239
|
+
]);
|
|
240
|
+
for (let col = 0; col < n; col++) {
|
|
241
|
+
let piv = col;
|
|
242
|
+
for (let r = col + 1; r < n; r++)
|
|
243
|
+
if (Math.abs(M[r][col]) > Math.abs(M[piv][col])) piv = r;
|
|
244
|
+
if (Math.abs(M[piv][col]) < 1e-12) return null;
|
|
245
|
+
[M[col], M[piv]] = [M[piv], M[col]];
|
|
246
|
+
const d = M[col][col];
|
|
247
|
+
for (let j = 0; j < 2 * n; j++) M[col][j] /= d;
|
|
248
|
+
for (let r = 0; r < n; r++) {
|
|
249
|
+
if (r === col) continue;
|
|
250
|
+
const f = M[r][col];
|
|
251
|
+
for (let j = 0; j < 2 * n; j++) M[r][j] -= f * M[col][j];
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return M.map((row) => row.slice(n));
|
|
255
|
+
}
|
|
256
|
+
|
|
233
257
|
// src/orbit/index.ts
|
|
234
258
|
var GM_GPS = 3986005e8;
|
|
235
259
|
var GM_GAL = 3986004418e5;
|
|
@@ -415,15 +439,20 @@ function ecefToAzEl(rxX, rxY, rxZ, satX, satY, satZ) {
|
|
|
415
439
|
}
|
|
416
440
|
function computeDop(satAzEls) {
|
|
417
441
|
const n = satAzEls.length;
|
|
418
|
-
|
|
442
|
+
const clocks = [...new Set(satAzEls.map((s) => s.prn?.[0] ?? ""))];
|
|
443
|
+
const m = 3 + clocks.length;
|
|
444
|
+
if (n < Math.max(4, m)) return null;
|
|
419
445
|
const H = [];
|
|
420
|
-
for (const { az, el } of satAzEls) {
|
|
446
|
+
for (const { az, el, prn } of satAzEls) {
|
|
421
447
|
const cosEl = Math.cos(el);
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
448
|
+
const row = [cosEl * Math.sin(az), cosEl * Math.cos(az), Math.sin(el)];
|
|
449
|
+
const sys = prn?.[0] ?? "";
|
|
450
|
+
for (const c of clocks) row.push(c === sys ? 1 : 0);
|
|
451
|
+
H.push(row);
|
|
452
|
+
}
|
|
453
|
+
const HtH = Array.from({ length: m }, () => new Array(m).fill(0));
|
|
454
|
+
for (let i = 0; i < m; i++) {
|
|
455
|
+
for (let j = 0; j < m; j++) {
|
|
427
456
|
let sum = 0;
|
|
428
457
|
for (let k = 0; k < n; k++) {
|
|
429
458
|
sum += H[k][i] * H[k][j];
|
|
@@ -431,46 +460,18 @@ function computeDop(satAzEls) {
|
|
|
431
460
|
HtH[i][j] = sum;
|
|
432
461
|
}
|
|
433
462
|
}
|
|
434
|
-
const Q =
|
|
463
|
+
const Q = invertMatrix(HtH);
|
|
435
464
|
if (!Q) return null;
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
inv[4] = -a[4] * a[10] * a[15] + a[4] * a[11] * a[14] + a[8] * a[6] * a[15] - a[8] * a[7] * a[14] - a[12] * a[6] * a[11] + a[12] * a[7] * a[10];
|
|
447
|
-
inv[8] = a[4] * a[9] * a[15] - a[4] * a[11] * a[13] - a[8] * a[5] * a[15] + a[8] * a[7] * a[13] + a[12] * a[5] * a[11] - a[12] * a[7] * a[9];
|
|
448
|
-
inv[12] = -a[4] * a[9] * a[14] + a[4] * a[10] * a[13] + a[8] * a[5] * a[14] - a[8] * a[6] * a[13] - a[12] * a[5] * a[10] + a[12] * a[6] * a[9];
|
|
449
|
-
inv[1] = -a[1] * a[10] * a[15] + a[1] * a[11] * a[14] + a[9] * a[2] * a[15] - a[9] * a[3] * a[14] - a[13] * a[2] * a[11] + a[13] * a[3] * a[10];
|
|
450
|
-
inv[5] = a[0] * a[10] * a[15] - a[0] * a[11] * a[14] - a[8] * a[2] * a[15] + a[8] * a[3] * a[14] + a[12] * a[2] * a[11] - a[12] * a[3] * a[10];
|
|
451
|
-
inv[9] = -a[0] * a[9] * a[15] + a[0] * a[11] * a[13] + a[8] * a[1] * a[15] - a[8] * a[3] * a[13] - a[12] * a[1] * a[11] + a[12] * a[3] * a[9];
|
|
452
|
-
inv[13] = a[0] * a[9] * a[14] - a[0] * a[10] * a[13] - a[8] * a[1] * a[14] + a[8] * a[2] * a[13] + a[12] * a[1] * a[10] - a[12] * a[2] * a[9];
|
|
453
|
-
inv[2] = a[1] * a[6] * a[15] - a[1] * a[7] * a[14] - a[5] * a[2] * a[15] + a[5] * a[3] * a[14] + a[13] * a[2] * a[7] - a[13] * a[3] * a[6];
|
|
454
|
-
inv[6] = -a[0] * a[6] * a[15] + a[0] * a[7] * a[14] + a[4] * a[2] * a[15] - a[4] * a[3] * a[14] - a[12] * a[2] * a[7] + a[12] * a[3] * a[6];
|
|
455
|
-
inv[10] = a[0] * a[5] * a[15] - a[0] * a[7] * a[13] - a[4] * a[1] * a[15] + a[4] * a[3] * a[13] + a[12] * a[1] * a[7] - a[12] * a[3] * a[5];
|
|
456
|
-
inv[14] = -a[0] * a[5] * a[14] + a[0] * a[6] * a[13] + a[4] * a[1] * a[14] - a[4] * a[2] * a[13] - a[12] * a[1] * a[6] + a[12] * a[2] * a[5];
|
|
457
|
-
inv[3] = -a[1] * a[6] * a[11] + a[1] * a[7] * a[10] + a[5] * a[2] * a[11] - a[5] * a[3] * a[10] - a[9] * a[2] * a[7] + a[9] * a[3] * a[6];
|
|
458
|
-
inv[7] = a[0] * a[6] * a[11] - a[0] * a[7] * a[10] - a[4] * a[2] * a[11] + a[4] * a[3] * a[10] + a[8] * a[2] * a[7] - a[8] * a[3] * a[6];
|
|
459
|
-
inv[11] = -a[0] * a[5] * a[11] + a[0] * a[7] * a[9] + a[4] * a[1] * a[11] - a[4] * a[3] * a[9] - a[8] * a[1] * a[7] + a[8] * a[3] * a[5];
|
|
460
|
-
inv[15] = a[0] * a[5] * a[10] - a[0] * a[6] * a[9] - a[4] * a[1] * a[10] + a[4] * a[2] * a[9] + a[8] * a[1] * a[6] - a[8] * a[2] * a[5];
|
|
461
|
-
let det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
|
|
462
|
-
if (Math.abs(det) < 1e-20) return null;
|
|
463
|
-
det = 1 / det;
|
|
464
|
-
const result = Array.from(
|
|
465
|
-
{ length: 4 },
|
|
466
|
-
() => new Array(4).fill(0)
|
|
467
|
-
);
|
|
468
|
-
for (let i = 0; i < 4; i++) {
|
|
469
|
-
for (let j = 0; j < 4; j++) {
|
|
470
|
-
result[i][j] = inv[i * 4 + j] * det;
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
return result;
|
|
465
|
+
let clockVar = 0;
|
|
466
|
+
for (let i = 3; i < m; i++) clockVar += Q[i][i];
|
|
467
|
+
const posVar = Q[0][0] + Q[1][1] + Q[2][2];
|
|
468
|
+
return {
|
|
469
|
+
gdop: Math.sqrt(posVar + clockVar),
|
|
470
|
+
pdop: Math.sqrt(posVar),
|
|
471
|
+
hdop: Math.sqrt(Q[0][0] + Q[1][1]),
|
|
472
|
+
vdop: Math.sqrt(Q[2][2]),
|
|
473
|
+
tdop: Math.sqrt(clockVar)
|
|
474
|
+
};
|
|
474
475
|
}
|
|
475
476
|
function selectEphemeris(ephemerides, prn, timeMs) {
|
|
476
477
|
return selectBest(
|
|
@@ -4307,28 +4308,6 @@ function sbasAirTropoVar(elRad) {
|
|
|
4307
4308
|
const sigTropo = 0.12 * m;
|
|
4308
4309
|
return sigMp * sigMp + NOISE_DIVG_AADA * NOISE_DIVG_AADA + sigTropo * sigTropo;
|
|
4309
4310
|
}
|
|
4310
|
-
function invertMatrix(A) {
|
|
4311
|
-
const n = A.length;
|
|
4312
|
-
const M = A.map((row, i) => [
|
|
4313
|
-
...row,
|
|
4314
|
-
...Array.from({ length: n }, (_, j) => i === j ? 1 : 0)
|
|
4315
|
-
]);
|
|
4316
|
-
for (let col = 0; col < n; col++) {
|
|
4317
|
-
let piv = col;
|
|
4318
|
-
for (let r = col + 1; r < n; r++)
|
|
4319
|
-
if (Math.abs(M[r][col]) > Math.abs(M[piv][col])) piv = r;
|
|
4320
|
-
if (Math.abs(M[piv][col]) < 1e-12) return null;
|
|
4321
|
-
[M[col], M[piv]] = [M[piv], M[col]];
|
|
4322
|
-
const d = M[col][col];
|
|
4323
|
-
for (let j = 0; j < 2 * n; j++) M[col][j] /= d;
|
|
4324
|
-
for (let r = 0; r < n; r++) {
|
|
4325
|
-
if (r === col) continue;
|
|
4326
|
-
const f = M[r][col];
|
|
4327
|
-
for (let j = 0; j < 2 * n; j++) M[r][j] -= f * M[col][j];
|
|
4328
|
-
}
|
|
4329
|
-
}
|
|
4330
|
-
return M.map((row) => row.slice(n));
|
|
4331
|
-
}
|
|
4332
4311
|
function sbasProtectionLevels(sats, opts = {}) {
|
|
4333
4312
|
const kH = opts.kH ?? 6;
|
|
4334
4313
|
const kV = opts.kV ?? 5.33;
|
|
@@ -4555,7 +4534,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
|
|
|
4555
4534
|
const azel = ecefToAzEl(x, y, z, sat.x, sat.y, sat.z);
|
|
4556
4535
|
if (azel.el >= elevationMaskDeg * Math.PI / 180) {
|
|
4557
4536
|
used.push(prn);
|
|
4558
|
-
azels.push(azel);
|
|
4537
|
+
azels.push({ ...azel, prn });
|
|
4559
4538
|
if (sbas) {
|
|
4560
4539
|
const dx = sat.x - x, dy = sat.y - y, dz = sat.z - z;
|
|
4561
4540
|
const dr = Math.hypot(dx, dy, dz) || 1;
|
package/dist/positioning.js
CHANGED
|
@@ -40,11 +40,11 @@ import {
|
|
|
40
40
|
sunEcef,
|
|
41
41
|
toRtkEpoch,
|
|
42
42
|
wlWavelength
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-PHS7OFHN.js";
|
|
44
44
|
import "./chunk-WQX354KD.js";
|
|
45
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-GLMQRZDL.js";
|
|
46
46
|
import "./chunk-HVXYFUCB.js";
|
|
47
|
-
import "./chunk-
|
|
47
|
+
import "./chunk-CVCTRIWU.js";
|
|
48
48
|
import "./chunk-37QNKGTC.js";
|
|
49
49
|
import "./chunk-LEEU5OIO.js";
|
|
50
50
|
import "./chunk-6FAL6P4G.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|