@neilberkman/sidereon 0.8.1 → 0.9.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/README.md +123 -76
- package/package.json +18 -2
- package/pkg/sidereon.d.ts +5060 -1415
- package/pkg/sidereon.js +8715 -850
- package/pkg/sidereon_bg.wasm +0 -0
- package/pkg/sidereon_bg.wasm.d.ts +1012 -521
- package/pkg-node/sidereon.d.ts +3286 -132
- package/pkg-node/sidereon.js +8880 -852
- package/pkg-node/sidereon_bg.wasm +0 -0
- package/pkg-node/sidereon_bg.wasm.d.ts +1012 -521
- package/types/sidereon-extra.d.ts +1417 -7
|
@@ -34,6 +34,25 @@ export interface SppSurfaceMet {
|
|
|
34
34
|
relativeHumidity: number;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/** Opt-in Huber/IRLS robust-reweighting tuning. Including the `robust` key on an
|
|
38
|
+
* SPP request (even as `{}`) enables the engine outer reweighting loop on top of
|
|
39
|
+
* the static elevation weighting; every field is optional and falls back to the
|
|
40
|
+
* engine default. Omitting `robust` runs the static reference solve unchanged. */
|
|
41
|
+
export interface SppRobust {
|
|
42
|
+
/** Huber tuning constant `k`; residuals scaled below this keep full weight.
|
|
43
|
+
* Must be finite and positive. Defaults to the engine constant (~1.345). */
|
|
44
|
+
huberK?: number;
|
|
45
|
+
/** Floor (metres) on the MAD scale, so a near-perfect fit cannot down-weight
|
|
46
|
+
* every satellite. Must be finite and positive. Engine default applies. */
|
|
47
|
+
scaleFloorM?: number;
|
|
48
|
+
/** Maximum total outer solves (the warm start plus reweighted resolves). Must
|
|
49
|
+
* be at least 1. Engine default applies. */
|
|
50
|
+
maxOuter?: number;
|
|
51
|
+
/** Outer-loop position L2 step tolerance (metres). Must be finite and
|
|
52
|
+
* non-negative. Engine default applies. */
|
|
53
|
+
outerTolM?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
37
56
|
/** The object passed to `Sp3.solveSpp`. */
|
|
38
57
|
export interface SppRequest {
|
|
39
58
|
/** Pseudorange observations; at least one is required. */
|
|
@@ -64,6 +83,37 @@ export interface SppRequest {
|
|
|
64
83
|
glonassChannels?: [number, number][];
|
|
65
84
|
/** Populate WGS84 lat/lon/height in the result. Defaults to true. */
|
|
66
85
|
withGeodetic?: boolean;
|
|
86
|
+
/** Opt-in Huber/IRLS robust reweighting. Omit for the static
|
|
87
|
+
* elevation-weighted reference solve; include (even as `{}`) to route through
|
|
88
|
+
* the engine outer reweighting loop. Honored on the SP3, broadcast-only, and
|
|
89
|
+
* fallback paths, since it is a property of the solve inputs. */
|
|
90
|
+
robust?: SppRobust;
|
|
91
|
+
/** Cold-start convergence-basin widening: the number of near-surface
|
|
92
|
+
* golden-spiral seeds the engine tries (plus `initialGuess`), selecting the
|
|
93
|
+
* best redundant converged fix. Must be at least 1. Omit for the single exact
|
|
94
|
+
* solve from `initialGuess`. Honored only by `Sp3.solveSpp` (the policy-bearing
|
|
95
|
+
* path), not the broadcast-only or fallback paths. */
|
|
96
|
+
coarseSearchSeeds?: number;
|
|
97
|
+
/** Optional positive PDOP ceiling: a fix whose geometry is rank-deficient or
|
|
98
|
+
* exceeds this ceiling is refused with an `Error`. Honored only by
|
|
99
|
+
* `Sp3.solveSpp`. */
|
|
100
|
+
maxPdop?: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Shared options for `Sp3.solveSppBatch(epochs, options)`, applied to every
|
|
104
|
+
* epoch of the batch. The batch shares one `withGeodetic` flag and one solve
|
|
105
|
+
* policy across all epochs (each epoch entry is itself an `SppRequest`, but its
|
|
106
|
+
* own `withGeodetic` / `maxPdop` / `coarseSearchSeeds` are ignored in favour of
|
|
107
|
+
* these). Every field is optional. */
|
|
108
|
+
export interface SppBatchOptions {
|
|
109
|
+
/** Populate WGS84 lat/lon/height in each epoch's result. Defaults to true. */
|
|
110
|
+
withGeodetic?: boolean;
|
|
111
|
+
/** Cold-start convergence-basin widening applied to every epoch. Must be at
|
|
112
|
+
* least 1. Omit for the single exact solve from each epoch's `initialGuess`. */
|
|
113
|
+
coarseSearchSeeds?: number;
|
|
114
|
+
/** Positive PDOP ceiling applied to every epoch; a fix that exceeds it (or is
|
|
115
|
+
* rank-deficient) becomes that epoch's error. */
|
|
116
|
+
maxPdop?: number;
|
|
67
117
|
}
|
|
68
118
|
|
|
69
119
|
// --- Observable-domain plain-object inputs ----------------------------------
|
|
@@ -391,6 +441,16 @@ export interface PppMeasurementWeights {
|
|
|
391
441
|
elevationWeighting?: boolean;
|
|
392
442
|
}
|
|
393
443
|
|
|
444
|
+
/** One VMF1 site-wise `a`-coefficient sample (00/06/12/18 UT node). */
|
|
445
|
+
export interface VmfSiteSample {
|
|
446
|
+
/** Modified Julian date of the sample. */
|
|
447
|
+
mjd: number;
|
|
448
|
+
/** Hydrostatic `a` coefficient. */
|
|
449
|
+
ah: number;
|
|
450
|
+
/** Wet `a` coefficient. */
|
|
451
|
+
aw: number;
|
|
452
|
+
}
|
|
453
|
+
|
|
394
454
|
/** PPP troposphere controls. */
|
|
395
455
|
export interface PppTroposphereOptions {
|
|
396
456
|
enabled?: boolean;
|
|
@@ -398,6 +458,12 @@ export interface PppTroposphereOptions {
|
|
|
398
458
|
pressureHpa?: number;
|
|
399
459
|
temperatureK?: number;
|
|
400
460
|
relativeHumidity?: number;
|
|
461
|
+
/**
|
|
462
|
+
* Vienna Mapping Function 1 site-wise `a`-coefficient series. When one or
|
|
463
|
+
* more strictly-ascending samples are supplied the zenith delays are mapped
|
|
464
|
+
* with VMF1; otherwise the climatological Niell (1996) mapping is used.
|
|
465
|
+
*/
|
|
466
|
+
vmf1?: VmfSiteSample[];
|
|
401
467
|
}
|
|
402
468
|
|
|
403
469
|
/** Iteration and convergence controls for PPP. */
|
|
@@ -434,6 +500,133 @@ export interface PppFixedConfig {
|
|
|
434
500
|
options?: PppFloatOptions;
|
|
435
501
|
}
|
|
436
502
|
|
|
503
|
+
// --- Static PPP correction precompute ---------------------------------------
|
|
504
|
+
//
|
|
505
|
+
// `pppCorrections(sp3, epochs, receiverEcefM, options?)` deserializes `epochs`
|
|
506
|
+
// and `options` through serde and returns the correction tables as a plain
|
|
507
|
+
// object (typed `any` by wasm-bindgen). Import:
|
|
508
|
+
//
|
|
509
|
+
// import { pppCorrections } from "@neilberkman/sidereon";
|
|
510
|
+
// import type { PppCorrectionsOptions, PppCorrections } from "@neilberkman/sidereon/types";
|
|
511
|
+
|
|
512
|
+
/** One satellite observation row (carrier frequencies) for the precompute. */
|
|
513
|
+
export interface PppCorrectionObservation {
|
|
514
|
+
satelliteId: string;
|
|
515
|
+
freq1Hz: number;
|
|
516
|
+
freq2Hz: number;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/** One receiver epoch for the correction precompute: civil UTC date/time, the
|
|
520
|
+
* receive time as continuous seconds since J2000, and the visible-satellite rows. */
|
|
521
|
+
export interface PppCorrectionEpoch {
|
|
522
|
+
year: number;
|
|
523
|
+
month: number;
|
|
524
|
+
day: number;
|
|
525
|
+
hour: number;
|
|
526
|
+
minute: number;
|
|
527
|
+
second: number;
|
|
528
|
+
tRxJ2000S: number;
|
|
529
|
+
observations: PppCorrectionObservation[];
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/** Solid-earth pole-tide options: the IERS polar motion of the date (arcsec),
|
|
533
|
+
* sourced from IERS EOP (the engine does not embed polar motion). */
|
|
534
|
+
export interface PoleTideOptions {
|
|
535
|
+
xpArcsec: number;
|
|
536
|
+
ypArcsec: number;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Per-station ocean-loading BLQ coefficients (Bos-Scherneck / HARDISP format).
|
|
540
|
+
*
|
|
541
|
+
* `amplitudeM` (metres) and `phaseDeg` (degrees, positive lag) are each a
|
|
542
|
+
* `3 x 11` nested array indexed `[component][constituent]`: component order is
|
|
543
|
+
* radial/up (0), tangential EW/west (1), tangential NS/south (2); constituent
|
|
544
|
+
* order is the BLQ columns M2 S2 N2 K2 K1 O1 P1 Q1 Mf Mm Ssa. */
|
|
545
|
+
export interface OceanLoadingBlq {
|
|
546
|
+
amplitudeM: number[][];
|
|
547
|
+
phaseDeg: number[][];
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/** Frequency-dependent satellite antenna calibration. */
|
|
551
|
+
export interface PppSatelliteAntennaFrequency {
|
|
552
|
+
label: string;
|
|
553
|
+
/** Body-frame phase-centre offset `[x, y, z]`, metres. */
|
|
554
|
+
pcoM: [number, number, number];
|
|
555
|
+
/** Nadir-angle no-azimuth PCV samples as `[nadirDeg, pcvM]` pairs. */
|
|
556
|
+
noaziPcvM: [number, number][];
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/** One satellite's antenna block, selected by PRN and an optional validity window. */
|
|
560
|
+
export interface PppSatelliteAntenna {
|
|
561
|
+
sat: string;
|
|
562
|
+
validFrom?: PppCivilDateTime;
|
|
563
|
+
validUntil?: PppCivilDateTime;
|
|
564
|
+
frequencies: PppSatelliteAntennaFrequency[];
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/** Satellite-antenna correction options. */
|
|
568
|
+
export interface PppSatelliteAntennaOptions {
|
|
569
|
+
freq1Label: string;
|
|
570
|
+
freq1Hz: number;
|
|
571
|
+
freq2Label: string;
|
|
572
|
+
freq2Hz: number;
|
|
573
|
+
antennas: PppSatelliteAntenna[];
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/** The optional options object passed to `pppCorrections`. Omit a field to leave
|
|
577
|
+
* that correction off. */
|
|
578
|
+
export interface PppCorrectionsOptions {
|
|
579
|
+
/** Compute the per-epoch solid-earth tide displacement. */
|
|
580
|
+
solidEarthTide?: boolean;
|
|
581
|
+
/** Compute the per-satellite carrier-phase wind-up. */
|
|
582
|
+
phaseWindup?: boolean;
|
|
583
|
+
/** Compute the satellite antenna PCO/PCV projection. */
|
|
584
|
+
satelliteAntenna?: PppSatelliteAntennaOptions;
|
|
585
|
+
/** Compute the solid-earth pole tide (needs the date's IERS polar motion). */
|
|
586
|
+
poleTide?: PoleTideOptions;
|
|
587
|
+
/** Compute ocean tide loading from the station's BLQ block. */
|
|
588
|
+
oceanLoading?: OceanLoadingBlq;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** A per-epoch ECEF displacement correction. */
|
|
592
|
+
export interface PppEpochVectorCorrection {
|
|
593
|
+
/** Index into the input `epochs` array. */
|
|
594
|
+
epochIndex: number;
|
|
595
|
+
/** ECEF displacement `[dx, dy, dz]`, metres. */
|
|
596
|
+
vectorM: [number, number, number];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/** A per-satellite, per-epoch scalar correction (metres). */
|
|
600
|
+
export interface PppSatScalarCorrection {
|
|
601
|
+
sat: string;
|
|
602
|
+
epochIndex: number;
|
|
603
|
+
valueM: number;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** A per-satellite, per-epoch ECEF vector correction (metres). */
|
|
607
|
+
export interface PppSatVectorCorrection {
|
|
608
|
+
sat: string;
|
|
609
|
+
epochIndex: number;
|
|
610
|
+
vectorM: [number, number, number];
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/** The correction tables returned by `pppCorrections`. Each list is keyed by the
|
|
614
|
+
* input epoch index; lists for corrections that were not requested are empty. */
|
|
615
|
+
export interface PppCorrections {
|
|
616
|
+
/** Solid-earth tide displacement per epoch. */
|
|
617
|
+
tide: PppEpochVectorCorrection[];
|
|
618
|
+
/** Solid-earth pole-tide displacement per epoch. */
|
|
619
|
+
poleTide: PppEpochVectorCorrection[];
|
|
620
|
+
/** Ocean tide loading displacement per epoch. */
|
|
621
|
+
oceanLoading: PppEpochVectorCorrection[];
|
|
622
|
+
/** Carrier-phase wind-up per satellite per epoch, metres. */
|
|
623
|
+
windupM: PppSatScalarCorrection[];
|
|
624
|
+
/** Satellite antenna PCO projected into ECEF per satellite per epoch, metres. */
|
|
625
|
+
satPcoEcef: PppSatVectorCorrection[];
|
|
626
|
+
/** Satellite antenna nadir PCV per satellite per epoch, metres. */
|
|
627
|
+
satPcvM: PppSatScalarCorrection[];
|
|
628
|
+
}
|
|
629
|
+
|
|
437
630
|
// --- SP3 merge --------------------------------------------------------------
|
|
438
631
|
//
|
|
439
632
|
// `mergeSp3(sources, options?)` deserializes `options` through serde. Import:
|
|
@@ -496,14 +689,34 @@ export interface GnssDopSeriesOptions {
|
|
|
496
689
|
// import { Cdm, CdmObject } from "@neilberkman/sidereon";
|
|
497
690
|
// import type { CdmObjectMeta, CdmMeta } from "@neilberkman/sidereon/types";
|
|
498
691
|
|
|
499
|
-
/** Optional metadata for a `CdmObject
|
|
692
|
+
/** Optional metadata for a `CdmObject`: the full CCSDS 508.0-B-1 object metadata
|
|
693
|
+
* block plus the optional RTN velocity-covariance rows. Every string field is the
|
|
694
|
+
* verbatim textual value; omitted fields are not emitted on encode. */
|
|
500
695
|
export interface CdmObjectMeta {
|
|
501
696
|
objectDesignator?: string;
|
|
502
697
|
catalogName?: string;
|
|
503
698
|
objectName?: string;
|
|
504
699
|
internationalDesignator?: string;
|
|
505
700
|
objectType?: string;
|
|
701
|
+
operatorContactPosition?: string;
|
|
702
|
+
operatorOrganization?: string;
|
|
703
|
+
operatorPhone?: string;
|
|
704
|
+
operatorEmail?: string;
|
|
705
|
+
ephemerisName?: string;
|
|
706
|
+
covarianceMethod?: string;
|
|
707
|
+
maneuverable?: string;
|
|
708
|
+
orbitCenter?: string;
|
|
506
709
|
refFrame?: string;
|
|
710
|
+
gravityModel?: string;
|
|
711
|
+
atmosphericModel?: string;
|
|
712
|
+
nBodyPerturbations?: string;
|
|
713
|
+
solarRadPressure?: string;
|
|
714
|
+
earthTides?: string;
|
|
715
|
+
intrackThrust?: string;
|
|
716
|
+
/** RTN velocity-covariance rows completing the 6x6 matrix, a length-15 array in
|
|
717
|
+
* CCSDS order (`CRDOT_R` .. `CNDOT_NDOT`). Omit when only the position
|
|
718
|
+
* covariance block is carried. */
|
|
719
|
+
velocityCovarianceRtn?: number[];
|
|
507
720
|
}
|
|
508
721
|
|
|
509
722
|
/** Optional message-level fields for a `Cdm`. */
|
|
@@ -634,8 +847,9 @@ export interface FdeRequest {
|
|
|
634
847
|
|
|
635
848
|
// --- Broadcast-vs-precise comparison ----------------------------------------
|
|
636
849
|
//
|
|
637
|
-
// `BroadcastEphemeris.compareToSp3(...)`
|
|
638
|
-
//
|
|
850
|
+
// `BroadcastEphemeris.compareToSp3(...)` and the window-form
|
|
851
|
+
// `BroadcastEphemeris.compareWindowToSp3(...)` both return a plain object typed
|
|
852
|
+
// `any` with the `BroadcastCompareReport` shape below. Import:
|
|
639
853
|
//
|
|
640
854
|
// import { loadRinexNav } from "@neilberkman/sidereon";
|
|
641
855
|
// import type { BroadcastCompareReport } from "@neilberkman/sidereon/types";
|
|
@@ -735,6 +949,9 @@ export interface ConstellationRecord {
|
|
|
735
949
|
noradId: number;
|
|
736
950
|
/** Canonical SP3/RINEX satellite token ("G03"). */
|
|
737
951
|
sp3Id: string;
|
|
952
|
+
/** GLONASS FDMA L1/L2 frequency-channel number (`k`, in -7..=6); absent for
|
|
953
|
+
* the CDMA constellations. */
|
|
954
|
+
fdmaChannel?: number;
|
|
738
955
|
/** Present in the base identity source. */
|
|
739
956
|
active: boolean;
|
|
740
957
|
/** Advisory usability flag. */
|
|
@@ -759,16 +976,23 @@ export interface NavcenStatus {
|
|
|
759
976
|
clock?: string;
|
|
760
977
|
}
|
|
761
978
|
|
|
979
|
+
/** A `(system, prn)` pair. Findings are keyed by system so a legitimate
|
|
980
|
+
* multi-system catalog (GPS PRN 1 and Galileo PRN 1) is not a false collision. */
|
|
981
|
+
export interface ConstellationSystemPrn {
|
|
982
|
+
system: ConstellationSystem;
|
|
983
|
+
prn: number;
|
|
984
|
+
}
|
|
985
|
+
|
|
762
986
|
/** The report returned by `validate` / `validateAgainstSp3Ids`. */
|
|
763
987
|
export interface ConstellationValidation {
|
|
764
988
|
/** Active+usable catalog SP3 ids absent from the compared product. */
|
|
765
989
|
missingSp3Ids: string[];
|
|
766
|
-
/**
|
|
767
|
-
duplicatePrns:
|
|
990
|
+
/** (system, PRN) pairs that appear in more than one record. */
|
|
991
|
+
duplicatePrns: ConstellationSystemPrn[];
|
|
768
992
|
/** NORAD ids that appear in more than one record. */
|
|
769
993
|
duplicateNoradIds: number[];
|
|
770
|
-
/**
|
|
771
|
-
inactiveUnusablePrns:
|
|
994
|
+
/** (system, PRN) pairs that are inactive or unusable. */
|
|
995
|
+
inactiveUnusablePrns: ConstellationSystemPrn[];
|
|
772
996
|
/** SP3 ids in the product absent from the active+usable catalog. */
|
|
773
997
|
extraSp3Ids: string[];
|
|
774
998
|
}
|
|
@@ -790,10 +1014,31 @@ export interface ConstellationDiff {
|
|
|
790
1014
|
noradReassigned: ConstellationFieldChange<number>[];
|
|
791
1015
|
sp3IdChanged: ConstellationFieldChange<string>[];
|
|
792
1016
|
svnChanged: ConstellationFieldChange<number | null>[];
|
|
1017
|
+
/** GLONASS FDMA frequency-channel corrections on a held slot. */
|
|
1018
|
+
fdmaChannelChanged: ConstellationFieldChange<number | null>[];
|
|
793
1019
|
activityChanged: ConstellationFieldChange<boolean>[];
|
|
794
1020
|
usabilityChanged: ConstellationFieldChange<boolean>[];
|
|
795
1021
|
}
|
|
796
1022
|
|
|
1023
|
+
/** An OMM entry `fromCelestrakJsonLenient` could not resolve to a record for the
|
|
1024
|
+
* requested system, carrying its identity so the caller can triage the skip. */
|
|
1025
|
+
export interface SkippedOmm {
|
|
1026
|
+
/** The OMM OBJECT_NAME, when present. */
|
|
1027
|
+
objectName?: string;
|
|
1028
|
+
/** The OMM NORAD_CAT_ID. */
|
|
1029
|
+
noradId: number;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/** The result of `fromCelestrakJsonLenient`: the records that resolved for the
|
|
1033
|
+
* requested system, plus the entries that did not. */
|
|
1034
|
+
export interface ConstellationCatalog {
|
|
1035
|
+
/** Records built from resolvable entries, sorted by `(system, prn)`. */
|
|
1036
|
+
records: ConstellationRecord[];
|
|
1037
|
+
/** Entries whose OBJECT_NAME did not resolve to a PRN for the system, in
|
|
1038
|
+
* input order. */
|
|
1039
|
+
skipped: SkippedOmm[];
|
|
1040
|
+
}
|
|
1041
|
+
|
|
797
1042
|
// --- Product-staleness selection + broadcast fallback -----------------------
|
|
798
1043
|
//
|
|
799
1044
|
// `selectIonex` / `selectSp3` (+ `*OverRange`) and `solveWithFallback` take an
|
|
@@ -894,3 +1139,1168 @@ export interface FixSource {
|
|
|
894
1139
|
staleness: StalenessMetadata | null;
|
|
895
1140
|
broadcastReason: BroadcastReason | null;
|
|
896
1141
|
}
|
|
1142
|
+
|
|
1143
|
+
// --- Integer-ambiguity resolution (LAMBDA / bounded ILS) --------------------
|
|
1144
|
+
//
|
|
1145
|
+
// `lambdaIlsSearch(floatCycles, covariance, ratioThreshold)` and
|
|
1146
|
+
// `boundedIlsSearch(floatCycles, covariance, radius, candidateLimit,
|
|
1147
|
+
// ratioThreshold)` take the covariance as a row-major `number[][]` and return an
|
|
1148
|
+
// `IlsResult` object (typed `any` by wasm-bindgen). Import:
|
|
1149
|
+
//
|
|
1150
|
+
// import { lambdaIlsSearch } from "@neilberkman/sidereon";
|
|
1151
|
+
// import type { IlsResult } from "@neilberkman/sidereon/types";
|
|
1152
|
+
|
|
1153
|
+
/** The outcome of an integer-least-squares search. */
|
|
1154
|
+
export interface IlsResult {
|
|
1155
|
+
/** Best integer vector, parallel to the input `floatCycles`. Cycle counts are
|
|
1156
|
+
* small integers and cross as plain numbers (not BigInt). */
|
|
1157
|
+
fixed: number[];
|
|
1158
|
+
/** Whether the ratio test passes at the requested threshold. */
|
|
1159
|
+
fixedStatus: boolean;
|
|
1160
|
+
/** Runner-up / best score ratio. Saturates to `Number.MAX_VALUE` when the best
|
|
1161
|
+
* score is exactly zero with a positive runner-up; `0` when there is no
|
|
1162
|
+
* runner-up. */
|
|
1163
|
+
ratio: number;
|
|
1164
|
+
/** Best (lowest) quadratic score. */
|
|
1165
|
+
bestScore: number;
|
|
1166
|
+
/** Runner-up score; absent when no second lattice point exists. */
|
|
1167
|
+
secondBestScore?: number;
|
|
1168
|
+
/** Number of lattice points evaluated. */
|
|
1169
|
+
candidatesEvaluated: number;
|
|
1170
|
+
/** Symmetrized covariance actually used, row-major. */
|
|
1171
|
+
covariance: number[][];
|
|
1172
|
+
/** Symmetrized inverse covariance, row-major. */
|
|
1173
|
+
covarianceInverse: number[][];
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// --- SP3-backed visibility geometry -----------------------------------------
|
|
1177
|
+
//
|
|
1178
|
+
// `gnssVisible(sp3, stationEcefM, j2000Seconds, options?)`,
|
|
1179
|
+
// `gnssVisibilitySeries(sp3, stationEcefM, startJ2000S, endJ2000S, stepSeconds,
|
|
1180
|
+
// options?)`, and `gnssPasses(...)` deserialize `options` through serde. The
|
|
1181
|
+
// returned classes (`GnssVisibleSatellite`, `GnssVisibilityCount`, `GnssPass`)
|
|
1182
|
+
// are in the generated types. Import:
|
|
1183
|
+
//
|
|
1184
|
+
// import { gnssVisible } from "@neilberkman/sidereon";
|
|
1185
|
+
// import type { GnssVisibilityOptions } from "@neilberkman/sidereon/types";
|
|
1186
|
+
|
|
1187
|
+
/** Visibility filters shared by `gnssVisible`, `gnssVisibilitySeries`, and
|
|
1188
|
+
* `gnssPasses`. All fields optional. */
|
|
1189
|
+
export interface GnssVisibilityOptions {
|
|
1190
|
+
/** Minimum topocentric elevation, degrees. Defaults to 5. */
|
|
1191
|
+
elevationMaskDeg?: number;
|
|
1192
|
+
/** Constellation filter as RINEX letters/names (e.g. ["G", "E"]); omit to
|
|
1193
|
+
* admit every constellation in the product. */
|
|
1194
|
+
systems?: string[];
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// --- Observable prediction --------------------------------------------------
|
|
1198
|
+
//
|
|
1199
|
+
// `observablesSp3(sp3, satellite, receiverEcefM, tRxJ2000S, options?)` and
|
|
1200
|
+
// `observablesBroadcast(broadcast, satellite, tRxJ2000S, receiverEcefM,
|
|
1201
|
+
// options?)` deserialize `options` through serde and return the generated
|
|
1202
|
+
// `PredictedObservables` class. `solveVelocityBroadcast` reuses
|
|
1203
|
+
// `VelocityObservation` / `VelocitySolveOptions` above. Import:
|
|
1204
|
+
//
|
|
1205
|
+
// import { observablesSp3 } from "@neilberkman/sidereon";
|
|
1206
|
+
// import type { ObservablePredictOptions } from "@neilberkman/sidereon/types";
|
|
1207
|
+
|
|
1208
|
+
/** Options controlling observable prediction. All fields optional. */
|
|
1209
|
+
export interface ObservablePredictOptions {
|
|
1210
|
+
/** Carrier frequency used to scale Doppler, hertz. Defaults to the GPS L1
|
|
1211
|
+
* frequency. */
|
|
1212
|
+
carrierHz?: number;
|
|
1213
|
+
/** Apply fixed-point light-time / transmit-time correction. Defaults to true. */
|
|
1214
|
+
lightTime?: boolean;
|
|
1215
|
+
/** Apply Earth-rotation Sagnac correction. Defaults to true. */
|
|
1216
|
+
sagnac?: boolean;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
// --- Reduced-orbit fit/eval/drift -------------------------------------------
|
|
1220
|
+
//
|
|
1221
|
+
// `fitReducedOrbit(samples, scale, model)` deserializes `samples` through serde
|
|
1222
|
+
// and returns the generated `ReducedOrbit` class, whose `position(query, frame)`
|
|
1223
|
+
// / `positionVelocity(query, frame)` / `drift(truth, thresholdM)` methods take
|
|
1224
|
+
// the same epoch/sample shapes. `scale` is a `TimeScale` enum value; `model` and
|
|
1225
|
+
// `frame` are the string unions below. Import:
|
|
1226
|
+
//
|
|
1227
|
+
// import { fitReducedOrbit } from "@neilberkman/sidereon";
|
|
1228
|
+
// import type { ReducedOrbitSample } from "@neilberkman/sidereon/types";
|
|
1229
|
+
|
|
1230
|
+
/** Reduced-orbit secular model selector. */
|
|
1231
|
+
export type ReducedOrbitModelKind = "circular_secular" | "eccentric_secular";
|
|
1232
|
+
|
|
1233
|
+
/** Frame for reduced-orbit evaluation. */
|
|
1234
|
+
export type ReducedOrbitFrame = "ecef" | "gcrs";
|
|
1235
|
+
|
|
1236
|
+
/** A civil calendar epoch, interpreted in the model's time scale. */
|
|
1237
|
+
export interface ReducedOrbitCalendarEpoch {
|
|
1238
|
+
year: number;
|
|
1239
|
+
month: number;
|
|
1240
|
+
day: number;
|
|
1241
|
+
hour: number;
|
|
1242
|
+
minute: number;
|
|
1243
|
+
/** Second of minute, fractional. */
|
|
1244
|
+
second: number;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/** One ECEF position sample for `fitReducedOrbit` and `ReducedOrbit.drift`. */
|
|
1248
|
+
export interface ReducedOrbitSample {
|
|
1249
|
+
epoch: ReducedOrbitCalendarEpoch;
|
|
1250
|
+
/** ECEF X, metres. */
|
|
1251
|
+
xM: number;
|
|
1252
|
+
/** ECEF Y, metres. */
|
|
1253
|
+
yM: number;
|
|
1254
|
+
/** ECEF Z, metres. */
|
|
1255
|
+
zM: number;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
// --- Source-backed reduced-orbit fit/drift ----------------------------------
|
|
1259
|
+
//
|
|
1260
|
+
// `fitReducedOrbitSp3(sp3, satellite, options)` and
|
|
1261
|
+
// `fitReducedOrbitTle(tle, options)` sample the source over `options` and return
|
|
1262
|
+
// the generated `ReducedOrbitSourceFit` class. The fitted `orbit` exposes
|
|
1263
|
+
// `driftSp3(...)` and `driftTle(...)` methods using the drift options below.
|
|
1264
|
+
|
|
1265
|
+
/** Sampling window for source-backed reduced-orbit calls. */
|
|
1266
|
+
export interface ReducedOrbitSourceSampling {
|
|
1267
|
+
/** Inclusive sampling start in the source time scale. */
|
|
1268
|
+
t0: ReducedOrbitCalendarEpoch;
|
|
1269
|
+
/** Inclusive sampling end in the source time scale. */
|
|
1270
|
+
t1: ReducedOrbitCalendarEpoch;
|
|
1271
|
+
/** Sampling cadence, seconds. */
|
|
1272
|
+
cadenceS: number;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/** Options for `fitReducedOrbitSp3` and `fitReducedOrbitTle`. */
|
|
1276
|
+
export interface ReducedOrbitSourceFitOptions extends ReducedOrbitSourceSampling {
|
|
1277
|
+
model: ReducedOrbitModelKind;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
/** Options for `ReducedOrbit.driftSp3` and `ReducedOrbit.driftTle`. */
|
|
1281
|
+
export interface ReducedOrbitSourceDriftOptions extends ReducedOrbitSourceSampling {
|
|
1282
|
+
/** First crossing threshold, metres. */
|
|
1283
|
+
thresholdM: number;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
// --- Piecewise reduced-orbit fit/eval/drift ---------------------------------
|
|
1287
|
+
//
|
|
1288
|
+
// `fitPiecewiseReducedOrbit(samples, scale, model, t0, t1, segmentSeconds)` tiles
|
|
1289
|
+
// the `[t0, t1]` window (both `ReducedOrbitCalendarEpoch`) into
|
|
1290
|
+
// `segmentSeconds`-long segments, fits each independently, and returns the
|
|
1291
|
+
// generated `PiecewiseOrbit` class. Its `position(query, frame)` /
|
|
1292
|
+
// `positionVelocity(query, frame)` / `drift(truth, thresholdM)` /
|
|
1293
|
+
// `segmentIndexAt(query)` methods take the same `ReducedOrbitCalendarEpoch` /
|
|
1294
|
+
// `ReducedOrbitSample` / `ReducedOrbitFrame` shapes as the single-segment model.
|
|
1295
|
+
// `samples` is `ReducedOrbitSample[]`; `scale` is a `TimeScale` enum value;
|
|
1296
|
+
// `model` is `ReducedOrbitModelKind`.
|
|
1297
|
+
|
|
1298
|
+
// `fitPiecewiseReducedOrbitSp3(sp3, satellite, options)` and
|
|
1299
|
+
// `fitPiecewiseReducedOrbitTle(tle, options)` sample the source over `options`
|
|
1300
|
+
// and return the generated `PiecewiseOrbitSourceFit` class. The fitted `orbit`
|
|
1301
|
+
// exposes `driftSp3(...)` and `driftTle(...)` methods using
|
|
1302
|
+
// `ReducedOrbitSourceDriftOptions`.
|
|
1303
|
+
|
|
1304
|
+
/** Options for source-backed piecewise reduced-orbit fitting. */
|
|
1305
|
+
export interface PiecewiseReducedOrbitSourceFitOptions extends ReducedOrbitSourceFitOptions {
|
|
1306
|
+
/** Segment length, seconds. */
|
|
1307
|
+
segmentSeconds: number;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
// --- GPS LNAV navigation-message codec --------------------------------------
|
|
1311
|
+
//
|
|
1312
|
+
// `lnavEncode(params, options)` deserializes both objects through serde and
|
|
1313
|
+
// returns the generated `LnavSubframes` class. Import:
|
|
1314
|
+
//
|
|
1315
|
+
// import { lnavEncode } from "@neilberkman/sidereon";
|
|
1316
|
+
// import type { LnavParams } from "@neilberkman/sidereon/types";
|
|
1317
|
+
|
|
1318
|
+
/** LNAV clock/ephemeris parameters in engineering units, the per-field input to
|
|
1319
|
+
* `lnavEncode`. Integer fields (week number, codes, health, IODC/IODE,
|
|
1320
|
+
* fit-interval flag, AODO) take whole numbers; the scaled fields take floats in
|
|
1321
|
+
* the documented physical units. */
|
|
1322
|
+
export interface LnavParams {
|
|
1323
|
+
/** GPS week number. */
|
|
1324
|
+
weekNumber: number;
|
|
1325
|
+
/** L2 code indicator. */
|
|
1326
|
+
l2Code: number;
|
|
1327
|
+
/** L2 P data flag (encode-only; not recovered by `lnavDecode`). */
|
|
1328
|
+
l2PDataFlag: number;
|
|
1329
|
+
/** User range accuracy index. */
|
|
1330
|
+
uraIndex: number;
|
|
1331
|
+
/** SV health bits. */
|
|
1332
|
+
svHealth: number;
|
|
1333
|
+
/** Issue of data, clock. */
|
|
1334
|
+
iodc: number;
|
|
1335
|
+
/** Group delay differential, seconds. */
|
|
1336
|
+
tgd: number;
|
|
1337
|
+
/** Clock reference time, seconds. */
|
|
1338
|
+
toc: number;
|
|
1339
|
+
/** Clock bias coefficient, seconds. */
|
|
1340
|
+
af0: number;
|
|
1341
|
+
/** Clock drift coefficient, seconds per second. */
|
|
1342
|
+
af1: number;
|
|
1343
|
+
/** Clock drift-rate coefficient, seconds per second squared. */
|
|
1344
|
+
af2: number;
|
|
1345
|
+
/** Issue of data, ephemeris. */
|
|
1346
|
+
iode: number;
|
|
1347
|
+
/** Sine harmonic correction to orbit radius, metres. */
|
|
1348
|
+
crs: number;
|
|
1349
|
+
/** Mean motion difference, radians per second. */
|
|
1350
|
+
deltaN: number;
|
|
1351
|
+
/** Mean anomaly at reference time, radians. */
|
|
1352
|
+
m0: number;
|
|
1353
|
+
/** Cosine harmonic correction to argument of latitude, radians. */
|
|
1354
|
+
cuc: number;
|
|
1355
|
+
/** Eccentricity. */
|
|
1356
|
+
eccentricity: number;
|
|
1357
|
+
/** Sine harmonic correction to argument of latitude, radians. */
|
|
1358
|
+
cus: number;
|
|
1359
|
+
/** Square root of the semi-major axis, sqrt(metres). */
|
|
1360
|
+
sqrtA: number;
|
|
1361
|
+
/** Ephemeris reference time, seconds. */
|
|
1362
|
+
toe: number;
|
|
1363
|
+
/** Fit-interval flag. */
|
|
1364
|
+
fitIntervalFlag: number;
|
|
1365
|
+
/** Age of data offset. */
|
|
1366
|
+
aodo: number;
|
|
1367
|
+
/** Cosine harmonic correction to inclination, radians. */
|
|
1368
|
+
cic: number;
|
|
1369
|
+
/** Longitude of ascending node at weekly epoch, radians. */
|
|
1370
|
+
omega0: number;
|
|
1371
|
+
/** Sine harmonic correction to inclination, radians. */
|
|
1372
|
+
cis: number;
|
|
1373
|
+
/** Inclination at reference time, radians. */
|
|
1374
|
+
i0: number;
|
|
1375
|
+
/** Cosine harmonic correction to orbit radius, metres. */
|
|
1376
|
+
crc: number;
|
|
1377
|
+
/** Argument of perigee, radians. */
|
|
1378
|
+
omega: number;
|
|
1379
|
+
/** Rate of right ascension, radians per second. */
|
|
1380
|
+
omegaDot: number;
|
|
1381
|
+
/** Rate of inclination, radians per second. */
|
|
1382
|
+
idot: number;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
/** Optional TLM/HOW options for `lnavEncode`. Every field is an integer and
|
|
1386
|
+
* defaults to 0 when omitted. */
|
|
1387
|
+
export interface LnavOptions {
|
|
1388
|
+
/** Time-of-week count (17-bit). */
|
|
1389
|
+
tow?: number;
|
|
1390
|
+
/** Alert flag (1-bit). */
|
|
1391
|
+
alert?: number;
|
|
1392
|
+
/** Anti-spoof flag (1-bit). */
|
|
1393
|
+
antiSpoof?: number;
|
|
1394
|
+
/** Integrity status flag (1-bit). */
|
|
1395
|
+
integrity?: number;
|
|
1396
|
+
/** TLM message (14-bit). */
|
|
1397
|
+
tlmMessage?: number;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// ---------------------------------------------------------------------------
|
|
1401
|
+
// Classical orbital elements (rv2coe / coe2rv)
|
|
1402
|
+
// ---------------------------------------------------------------------------
|
|
1403
|
+
|
|
1404
|
+
/** Geometric classification of a two-body orbit. */
|
|
1405
|
+
export type OrbitType =
|
|
1406
|
+
| "ellipticalInclined"
|
|
1407
|
+
| "ellipticalEquatorial"
|
|
1408
|
+
| "circularInclined"
|
|
1409
|
+
| "circularEquatorial";
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* Classical (Keplerian) orbital elements in the Vallado convention. Returned by
|
|
1413
|
+
* `rv2coe` and accepted by `coe2rv`. Angles are radians; `p` and `a` are km.
|
|
1414
|
+
* Undefined primary angles and inapplicable auxiliary angles are `NaN`. For
|
|
1415
|
+
* `coe2rv` only `p`, `ecc`, `incl`, `raan`, `argp`, and `nu` are required (an
|
|
1416
|
+
* ordinary elliptical-inclined orbit); `orbitType` and the auxiliary angles
|
|
1417
|
+
* default.
|
|
1418
|
+
*/
|
|
1419
|
+
export interface ClassicalElements {
|
|
1420
|
+
/** Semi-latus rectum p = h^2 / mu, km. */
|
|
1421
|
+
p: number;
|
|
1422
|
+
/** Semi-major axis a, km (Infinity for a parabolic orbit). Output only. */
|
|
1423
|
+
a?: number;
|
|
1424
|
+
ecc: number;
|
|
1425
|
+
incl: number;
|
|
1426
|
+
raan: number;
|
|
1427
|
+
argp: number;
|
|
1428
|
+
nu: number;
|
|
1429
|
+
/** Argument of latitude u = argp + nu, rad (circular inclined orbits). */
|
|
1430
|
+
arglat?: number;
|
|
1431
|
+
/** True longitude, rad (circular equatorial orbits). */
|
|
1432
|
+
truelon?: number;
|
|
1433
|
+
/** Longitude of perigee, rad (elliptical equatorial orbits). */
|
|
1434
|
+
lonper?: number;
|
|
1435
|
+
orbitType?: OrbitType;
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
/** An inertial Cartesian state, returned by `coe2rv`. */
|
|
1439
|
+
export interface CartesianState {
|
|
1440
|
+
positionKm: [number, number, number];
|
|
1441
|
+
velocityKmS: [number, number, number];
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
// ---------------------------------------------------------------------------
|
|
1445
|
+
// Observational-astronomy geometry
|
|
1446
|
+
// ---------------------------------------------------------------------------
|
|
1447
|
+
|
|
1448
|
+
/** A point on a body surface, geocentric/planetocentric latitude and longitude. */
|
|
1449
|
+
export interface SurfacePoint {
|
|
1450
|
+
/** Degrees on [-90, 90]. */
|
|
1451
|
+
latitudeDeg: number;
|
|
1452
|
+
/** Degrees on (-180, 180]. */
|
|
1453
|
+
longitudeDeg: number;
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// ---------------------------------------------------------------------------
|
|
1457
|
+
// RTCM 3.x decode
|
|
1458
|
+
// ---------------------------------------------------------------------------
|
|
1459
|
+
|
|
1460
|
+
/** A 1005 / 1006 station antenna reference point. */
|
|
1461
|
+
export interface RtcmStationCoordinates {
|
|
1462
|
+
type: "stationCoordinates";
|
|
1463
|
+
messageNumber: number;
|
|
1464
|
+
referenceStationId: number;
|
|
1465
|
+
itrfRealizationYear: number;
|
|
1466
|
+
gpsIndicator: boolean;
|
|
1467
|
+
glonassIndicator: boolean;
|
|
1468
|
+
galileoIndicator: boolean;
|
|
1469
|
+
referenceStationIndicator: boolean;
|
|
1470
|
+
ecefX: bigint;
|
|
1471
|
+
singleReceiverOscillator: boolean;
|
|
1472
|
+
reserved: boolean;
|
|
1473
|
+
ecefY: bigint;
|
|
1474
|
+
quarterCycleIndicator: number;
|
|
1475
|
+
ecefZ: bigint;
|
|
1476
|
+
/** Antenna height, raw 0.1 mm units (1006 only). */
|
|
1477
|
+
antennaHeight?: number;
|
|
1478
|
+
/** ECEF coordinates in metres. */
|
|
1479
|
+
xM: number;
|
|
1480
|
+
yM: number;
|
|
1481
|
+
zM: number;
|
|
1482
|
+
/** Antenna height in metres (1006 only). */
|
|
1483
|
+
antennaHeightM?: number;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
/** A 1007 / 1008 / 1033 antenna or receiver descriptor. */
|
|
1487
|
+
export interface RtcmAntennaDescriptor {
|
|
1488
|
+
type: "antennaDescriptor";
|
|
1489
|
+
messageNumber: number;
|
|
1490
|
+
referenceStationId: number;
|
|
1491
|
+
antennaDescriptor: string;
|
|
1492
|
+
antennaSetupId: number;
|
|
1493
|
+
antennaSerialNumber?: string;
|
|
1494
|
+
receiverType?: string;
|
|
1495
|
+
receiverFirmwareVersion?: string;
|
|
1496
|
+
receiverSerialNumber?: string;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
/** MSM common header. */
|
|
1500
|
+
export interface RtcmMsmHeader {
|
|
1501
|
+
referenceStationId: number;
|
|
1502
|
+
epochTime: number;
|
|
1503
|
+
multipleMessage: boolean;
|
|
1504
|
+
iods: number;
|
|
1505
|
+
reserved: number;
|
|
1506
|
+
clockSteering: number;
|
|
1507
|
+
externalClock: number;
|
|
1508
|
+
divergenceFreeSmoothing: boolean;
|
|
1509
|
+
smoothingInterval: number;
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
/** One MSM satellite record (raw transmitted integers). */
|
|
1513
|
+
export interface RtcmMsmSatellite {
|
|
1514
|
+
id: number;
|
|
1515
|
+
roughRangeMs: number;
|
|
1516
|
+
roughRangeMod1: number;
|
|
1517
|
+
extendedInfo?: number;
|
|
1518
|
+
roughPhaseRangeRateMS?: number;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
/** One MSM signal record (raw transmitted integers). */
|
|
1522
|
+
export interface RtcmMsmSignal {
|
|
1523
|
+
satelliteId: number;
|
|
1524
|
+
signalId: number;
|
|
1525
|
+
finePseudorange: number;
|
|
1526
|
+
finePhaseRange: number;
|
|
1527
|
+
lockTimeIndicator: number;
|
|
1528
|
+
halfCycleAmbiguity: boolean;
|
|
1529
|
+
cnr: number;
|
|
1530
|
+
finePhaseRangeRate?: number;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
/** An MSM4 / MSM7 multi-signal observation message. */
|
|
1534
|
+
export interface RtcmMsm {
|
|
1535
|
+
type: "msm";
|
|
1536
|
+
messageNumber: number;
|
|
1537
|
+
/** GNSS constellation label, e.g. "gps", "glonass". */
|
|
1538
|
+
system: string;
|
|
1539
|
+
/** "msm4" or "msm7". */
|
|
1540
|
+
kind: string;
|
|
1541
|
+
header: RtcmMsmHeader;
|
|
1542
|
+
satellites: RtcmMsmSatellite[];
|
|
1543
|
+
signals: RtcmMsmSignal[];
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/** A 1019 GPS broadcast ephemeris (raw transmitted integers). */
|
|
1547
|
+
export interface RtcmGpsEphemeris {
|
|
1548
|
+
type: "gpsEphemeris";
|
|
1549
|
+
messageNumber: number;
|
|
1550
|
+
satelliteId: number;
|
|
1551
|
+
weekNumber: number;
|
|
1552
|
+
svAccuracy: number;
|
|
1553
|
+
codeOnL2: number;
|
|
1554
|
+
idot: number;
|
|
1555
|
+
iode: number;
|
|
1556
|
+
tOc: number;
|
|
1557
|
+
aF2: number;
|
|
1558
|
+
aF1: number;
|
|
1559
|
+
aF0: number;
|
|
1560
|
+
iodc: number;
|
|
1561
|
+
cRs: number;
|
|
1562
|
+
deltaN: number;
|
|
1563
|
+
m0: bigint;
|
|
1564
|
+
cUc: number;
|
|
1565
|
+
eccentricity: bigint;
|
|
1566
|
+
cUs: number;
|
|
1567
|
+
sqrtA: bigint;
|
|
1568
|
+
tOe: number;
|
|
1569
|
+
cIc: number;
|
|
1570
|
+
omega0: bigint;
|
|
1571
|
+
cIs: number;
|
|
1572
|
+
i0: bigint;
|
|
1573
|
+
cRc: number;
|
|
1574
|
+
omega: bigint;
|
|
1575
|
+
omegaDot: number;
|
|
1576
|
+
tGd: number;
|
|
1577
|
+
svHealth: number;
|
|
1578
|
+
l2PDataFlag: boolean;
|
|
1579
|
+
fitInterval: boolean;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
/** A 1020 GLONASS broadcast ephemeris (raw transmitted integers). */
|
|
1583
|
+
export interface RtcmGlonassEphemeris {
|
|
1584
|
+
type: "glonassEphemeris";
|
|
1585
|
+
messageNumber: number;
|
|
1586
|
+
satelliteId: number;
|
|
1587
|
+
frequencyChannel: number;
|
|
1588
|
+
almanacHealth: boolean;
|
|
1589
|
+
almanacHealthAvailability: boolean;
|
|
1590
|
+
p1: number;
|
|
1591
|
+
tK: number;
|
|
1592
|
+
bNMsb: boolean;
|
|
1593
|
+
p2: boolean;
|
|
1594
|
+
tB: number;
|
|
1595
|
+
xnDot: number;
|
|
1596
|
+
xn: number;
|
|
1597
|
+
xnDotDot: number;
|
|
1598
|
+
ynDot: number;
|
|
1599
|
+
yn: number;
|
|
1600
|
+
ynDotDot: number;
|
|
1601
|
+
znDot: number;
|
|
1602
|
+
zn: number;
|
|
1603
|
+
znDotDot: number;
|
|
1604
|
+
p3: boolean;
|
|
1605
|
+
gammaN: number;
|
|
1606
|
+
mP: number;
|
|
1607
|
+
mLNThird: boolean;
|
|
1608
|
+
tauN: number;
|
|
1609
|
+
deltaTauN: number;
|
|
1610
|
+
eN: number;
|
|
1611
|
+
mP4: boolean;
|
|
1612
|
+
mFT: number;
|
|
1613
|
+
mNT: number;
|
|
1614
|
+
mM: number;
|
|
1615
|
+
additionalDataAvailable: boolean;
|
|
1616
|
+
nA: number;
|
|
1617
|
+
tauC: bigint;
|
|
1618
|
+
mN4: number;
|
|
1619
|
+
mTauGps: number;
|
|
1620
|
+
mLNFifth: boolean;
|
|
1621
|
+
reserved: number;
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
/** A recognized-but-undecoded message, preserved verbatim. */
|
|
1625
|
+
export interface RtcmUnsupported {
|
|
1626
|
+
type: "unsupported";
|
|
1627
|
+
messageNumber: number;
|
|
1628
|
+
/** Undecoded body bytes. */
|
|
1629
|
+
body: number[];
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
/** The decoded RTCM 3 message IR, tagged by `type`. Returned by `decodeRtcm`. */
|
|
1633
|
+
export type RtcmMessage =
|
|
1634
|
+
| RtcmMsm
|
|
1635
|
+
| RtcmStationCoordinates
|
|
1636
|
+
| RtcmAntennaDescriptor
|
|
1637
|
+
| RtcmGpsEphemeris
|
|
1638
|
+
| RtcmGlonassEphemeris
|
|
1639
|
+
| RtcmUnsupported;
|
|
1640
|
+
|
|
1641
|
+
/** A single decoded frame, returned by `decodeRtcmFrame`. */
|
|
1642
|
+
export interface RtcmDecodedFrame {
|
|
1643
|
+
message: RtcmMessage;
|
|
1644
|
+
/** Total frame length in bytes (preamble, length, body, CRC). */
|
|
1645
|
+
frameLen: number;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
/** One yielded frame from a `FrameScanner`. */
|
|
1649
|
+
export interface RtcmScannedFrame {
|
|
1650
|
+
/** Message body (bytes between the length word and the CRC). */
|
|
1651
|
+
body: Uint8Array;
|
|
1652
|
+
frameLen: number;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
// ---------------------------------------------------------------------------
|
|
1656
|
+
// Moving-baseline RTK
|
|
1657
|
+
// ---------------------------------------------------------------------------
|
|
1658
|
+
|
|
1659
|
+
/** One moving-baseline epoch: a per-epoch base ECEF position plus an RTK epoch. */
|
|
1660
|
+
export interface MovingBaselineEpoch extends RtkEpoch {
|
|
1661
|
+
/** Base receiver ECEF position [x, y, z] this epoch, metres. */
|
|
1662
|
+
basePositionM: [number, number, number];
|
|
1663
|
+
}
|
|
1664
|
+
|
|
1665
|
+
/** The object passed to `solveMovingBaseline`. The ambiguity set is shared. */
|
|
1666
|
+
export interface MovingBaselineConfig {
|
|
1667
|
+
epochs: MovingBaselineEpoch[];
|
|
1668
|
+
ambiguityIds: string[];
|
|
1669
|
+
ambiguitySatellites: Record<string, string>;
|
|
1670
|
+
wavelengthsM: Record<string, number>;
|
|
1671
|
+
offsetsM: Record<string, number>;
|
|
1672
|
+
floatOnlySystems?: string[];
|
|
1673
|
+
model: RtkMeasurementModel;
|
|
1674
|
+
floatOptions?: RtkFloatOptions;
|
|
1675
|
+
fixedOptions?: RtkFixedOptions;
|
|
1676
|
+
initialBaselineM?: [number, number, number];
|
|
1677
|
+
/** Carry each solved baseline into the next epoch. Defaults to true. */
|
|
1678
|
+
warmStart?: boolean;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
// ---------------------------------------------------------------------------
|
|
1682
|
+
// Time of closest approach (TCA)
|
|
1683
|
+
// ---------------------------------------------------------------------------
|
|
1684
|
+
|
|
1685
|
+
/** Finder sampling controls (defaults: 60 s coarse step, 1e-3 s tolerance). */
|
|
1686
|
+
export interface TcaFinderOptions {
|
|
1687
|
+
coarseStepSeconds?: number;
|
|
1688
|
+
timeToleranceSeconds?: number;
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
/** Collision-probability options for the TCA conjunction finders. */
|
|
1692
|
+
export interface TcaPcOptions {
|
|
1693
|
+
hardBodyRadiusKm: number;
|
|
1694
|
+
/** Pc method; defaults to "foster_equal_area". */
|
|
1695
|
+
method?: "foster_equal_area" | "foster_numerical" | "alfano_2005";
|
|
1696
|
+
/** Primary-object 3x3 position covariance (flat row-major, km^2). */
|
|
1697
|
+
primaryCovarianceKm2?: number[];
|
|
1698
|
+
/** Secondary-object 3x3 position covariance (flat row-major, km^2). */
|
|
1699
|
+
secondaryCovarianceKm2?: number[];
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
/** A borrowed TLE line pair for the screening catalogs. */
|
|
1703
|
+
export interface Tle {
|
|
1704
|
+
line1: string;
|
|
1705
|
+
line2: string;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
/** One local time-of-closest-approach candidate. */
|
|
1709
|
+
export interface TcaCandidate {
|
|
1710
|
+
/** Refined TCA split Julian date (whole boundary). */
|
|
1711
|
+
tcaJdWhole: number;
|
|
1712
|
+
tcaJdFraction: number;
|
|
1713
|
+
/** Recombined TCA Julian date. */
|
|
1714
|
+
tcaJd: number;
|
|
1715
|
+
tcaSecondsSinceWindowStart: number;
|
|
1716
|
+
missDistanceKm: number;
|
|
1717
|
+
/** Primary minus secondary TEME position [x, y, z], km. */
|
|
1718
|
+
relativePositionKm: [number, number, number];
|
|
1719
|
+
/** Primary minus secondary TEME velocity [vx, vy, vz], km/s. */
|
|
1720
|
+
relativeVelocityKmS: [number, number, number];
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
/** A TCA candidate with the collision probability evaluated at that TCA. */
|
|
1724
|
+
export interface TcaConjunction {
|
|
1725
|
+
candidate: TcaCandidate;
|
|
1726
|
+
pc: number;
|
|
1727
|
+
missKm: number;
|
|
1728
|
+
relativeSpeedKmS: number;
|
|
1729
|
+
sigmaXKm: number;
|
|
1730
|
+
sigmaZKm: number;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
/** One threshold-screening hit. */
|
|
1734
|
+
export interface TcaScreeningHit {
|
|
1735
|
+
/** Index of the secondary in the supplied catalog. */
|
|
1736
|
+
secondaryIndex: number;
|
|
1737
|
+
candidate: TcaCandidate;
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
/** A threshold-screening hit with Pc evaluated at the returned TCA. */
|
|
1741
|
+
export interface TcaScreeningConjunctionHit {
|
|
1742
|
+
secondaryIndex: number;
|
|
1743
|
+
conjunction: TcaConjunction;
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
// ---------------------------------------------------------------------------
|
|
1747
|
+
// NeQuick-G full three-dimensional slant ionosphere
|
|
1748
|
+
// ---------------------------------------------------------------------------
|
|
1749
|
+
//
|
|
1750
|
+
// `nequickGStecTecu(eval)` / `nequickGDelayM(eval, frequencyHz)` take a serde-
|
|
1751
|
+
// `any` object. Import:
|
|
1752
|
+
//
|
|
1753
|
+
// import { nequickGStecTecu } from "@neilberkman/sidereon";
|
|
1754
|
+
// import type { NequickGEval } from "@neilberkman/sidereon/types";
|
|
1755
|
+
|
|
1756
|
+
/** One receiver-to-satellite ray (geometry, epoch, and the Galileo broadcast
|
|
1757
|
+
* effective-ionisation coefficients) for the full NeQuick-G slant model. */
|
|
1758
|
+
export interface NequickGEval {
|
|
1759
|
+
/** Galileo broadcast effective-ionisation coefficient a_i0. */
|
|
1760
|
+
ai0: number;
|
|
1761
|
+
ai1: number;
|
|
1762
|
+
ai2: number;
|
|
1763
|
+
/** Month of the year, 1..=12. */
|
|
1764
|
+
month: number;
|
|
1765
|
+
/** UTC time of day in hours, [0, 24]. */
|
|
1766
|
+
utcHours: number;
|
|
1767
|
+
/** Receiver geodetic longitude, degrees. */
|
|
1768
|
+
stationLonDeg: number;
|
|
1769
|
+
/** Receiver geodetic latitude, degrees. */
|
|
1770
|
+
stationLatDeg: number;
|
|
1771
|
+
/** Receiver height above the reference sphere, metres. */
|
|
1772
|
+
stationHeightM: number;
|
|
1773
|
+
/** Satellite geodetic longitude, degrees. */
|
|
1774
|
+
satelliteLonDeg: number;
|
|
1775
|
+
/** Satellite geodetic latitude, degrees. */
|
|
1776
|
+
satelliteLatDeg: number;
|
|
1777
|
+
/** Satellite height above the reference sphere, metres. */
|
|
1778
|
+
satelliteHeightM: number;
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
// ---------------------------------------------------------------------------
|
|
1782
|
+
// Range RAIM / fault detection and exclusion (design-matrix form)
|
|
1783
|
+
// ---------------------------------------------------------------------------
|
|
1784
|
+
//
|
|
1785
|
+
// `raimFdeDesign(rows, options?)` takes a serde-`any` array and object and
|
|
1786
|
+
// returns the result as a plain object (typed `any` by wasm-bindgen). Import:
|
|
1787
|
+
//
|
|
1788
|
+
// import { raimFdeDesign } from "@neilberkman/sidereon";
|
|
1789
|
+
// import type { RaimFdeRow, RaimFdeResult } from "@neilberkman/sidereon/types";
|
|
1790
|
+
|
|
1791
|
+
/** One linearized range measurement. */
|
|
1792
|
+
export interface RaimFdeRow {
|
|
1793
|
+
/** Stable measurement identifier, e.g. a satellite token "G01". */
|
|
1794
|
+
id: string;
|
|
1795
|
+
/** Observed-minus-computed range residual, metres. */
|
|
1796
|
+
residualM: number;
|
|
1797
|
+
/** Design-matrix row (partials of predicted range w.r.t. each state
|
|
1798
|
+
* parameter). Length equals the estimated state dimension. */
|
|
1799
|
+
designRow: number[];
|
|
1800
|
+
/** Inverse-variance weight 1 / sigma^2; finite and strictly positive. */
|
|
1801
|
+
weight: number;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
/** Options for `raimFdeDesign`. Every field is optional. */
|
|
1805
|
+
export interface RaimFdeOptions {
|
|
1806
|
+
/** False-alarm probability for the global chi-square test. Default 1.0e-3. */
|
|
1807
|
+
pFa?: number;
|
|
1808
|
+
/** Maximum measurements the exclusion loop may remove. Default unbounded. */
|
|
1809
|
+
maxExclusions?: number;
|
|
1810
|
+
/** Minimum redundancy an exclusion must leave behind. Default 1. */
|
|
1811
|
+
minRedundancy?: number;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
/** Global chi-square consistency test over the protected set. */
|
|
1815
|
+
export interface RaimChiSquareTest {
|
|
1816
|
+
weightedSumSquares: number;
|
|
1817
|
+
/** Redundancy: nUsed - nState. */
|
|
1818
|
+
dof: number;
|
|
1819
|
+
/** Chi-square threshold, absent when dof <= 0. */
|
|
1820
|
+
threshold?: number;
|
|
1821
|
+
testable: boolean;
|
|
1822
|
+
faultDetected: boolean;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
/** Per-measurement diagnostic, in input order. */
|
|
1826
|
+
export interface RaimMeasurementDiagnostic {
|
|
1827
|
+
id: string;
|
|
1828
|
+
excluded: boolean;
|
|
1829
|
+
postFitResidualM: number;
|
|
1830
|
+
normalizedResidual: number;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
/** Result of `raimFdeDesign`. */
|
|
1834
|
+
export interface RaimFdeResult {
|
|
1835
|
+
/** Protected weighted-least-squares state correction, length nState. */
|
|
1836
|
+
stateCorrection: number[];
|
|
1837
|
+
/** Protected state covariance (H^T W H)^-1, nState-by-nState. */
|
|
1838
|
+
stateCovariance: number[][];
|
|
1839
|
+
globalTest: RaimChiSquareTest;
|
|
1840
|
+
/** Excluded measurement ids, in exclusion order. */
|
|
1841
|
+
excluded: string[];
|
|
1842
|
+
diagnostics: RaimMeasurementDiagnostic[];
|
|
1843
|
+
iterations: number;
|
|
1844
|
+
}
|
|
1845
|
+
|
|
1846
|
+
// ---------------------------------------------------------------------------
|
|
1847
|
+
// PPP auto-init (SPP-seeded) drivers
|
|
1848
|
+
// ---------------------------------------------------------------------------
|
|
1849
|
+
//
|
|
1850
|
+
// `solvePppAutoInitFloat(sp3, epochs, options?, config)` and
|
|
1851
|
+
// `solvePppAutoInitFixed(sp3, epochs, options?, floatConfig, fixedConfig)` seed
|
|
1852
|
+
// the float state from the SPP solver, so no initial state is supplied. Import:
|
|
1853
|
+
//
|
|
1854
|
+
// import { solvePppAutoInitFloat } from "@neilberkman/sidereon";
|
|
1855
|
+
// import type { PppAutoInitOptions } from "@neilberkman/sidereon/types";
|
|
1856
|
+
|
|
1857
|
+
/** Explicit static-position/clock seed that bypasses the SPP auto-init stages. */
|
|
1858
|
+
export interface PppInitialGuess {
|
|
1859
|
+
positionM: [number, number, number];
|
|
1860
|
+
/** Receiver clock seed, metres (duplicated across every epoch). */
|
|
1861
|
+
clockM: number;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
/** SPP surface meteorology for the auto-init seed troposphere. */
|
|
1865
|
+
export interface PppSppSurfaceMet {
|
|
1866
|
+
pressureHpa: number;
|
|
1867
|
+
temperatureK: number;
|
|
1868
|
+
relativeHumidity: number;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
/** Auto-initialization policy for the raw-epochs PPP drivers. Every field is
|
|
1872
|
+
* optional; omitting `initialGuess` runs the per-epoch SPP seed. */
|
|
1873
|
+
export interface PppAutoInitOptions {
|
|
1874
|
+
/** Explicit seed; present skips the SPP/mean stages entirely. */
|
|
1875
|
+
initialGuess?: PppInitialGuess;
|
|
1876
|
+
/** SPP cold-start guess [x, y, z, b] for each per-epoch seed. Default zeros. */
|
|
1877
|
+
sppInitialGuess?: [number, number, number, number];
|
|
1878
|
+
/** Apply the troposphere correction in the SPP seed. Default false. */
|
|
1879
|
+
sppTroposphere?: boolean;
|
|
1880
|
+
/** Surface meteorology used by the SPP seed troposphere. */
|
|
1881
|
+
sppMet?: PppSppSurfaceMet;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
// ---------------------------------------------------------------------------
|
|
1885
|
+
// Sequential RTK baseline arc driver
|
|
1886
|
+
// ---------------------------------------------------------------------------
|
|
1887
|
+
//
|
|
1888
|
+
// `solveRtkArc(epochs, config)` takes serde-`any` arrays/objects and returns
|
|
1889
|
+
// the solution as a plain object (typed `any` by wasm-bindgen). Import:
|
|
1890
|
+
//
|
|
1891
|
+
// import { solveRtkArc } from "@neilberkman/sidereon";
|
|
1892
|
+
// import type { RtkArcEpoch, RtkArcConfig, RtkArcSolution } from "@neilberkman/sidereon/types";
|
|
1893
|
+
|
|
1894
|
+
/** One raw single-frequency code/carrier observation at a receiver. */
|
|
1895
|
+
export interface RtkArcObservation {
|
|
1896
|
+
satelliteId: string;
|
|
1897
|
+
/** Ambiguity-arc id (the satellite id for a clean arc; a distinct id splits
|
|
1898
|
+
* a cycle-slip arc so the single-difference key resets). */
|
|
1899
|
+
ambiguityId: string;
|
|
1900
|
+
codeM: number;
|
|
1901
|
+
phaseM: number;
|
|
1902
|
+
/** Loss-of-lock indicator. Bit 0 set marks a cycle-slip event when enabled. */
|
|
1903
|
+
lli?: number;
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
/** One raw RTK arc epoch: paired base/rover observations and satellite positions. */
|
|
1907
|
+
export interface RtkArcEpoch {
|
|
1908
|
+
base: RtkArcObservation[];
|
|
1909
|
+
rover: RtkArcObservation[];
|
|
1910
|
+
/** Shared receive-time satellite ECEF positions (metres), satellite -> xyz. */
|
|
1911
|
+
satellitePositionsM: Record<string, [number, number, number]>;
|
|
1912
|
+
/** Transmit-time positions for the base; defaults to the shared map. */
|
|
1913
|
+
baseSatellitePositionsM?: Record<string, [number, number, number]>;
|
|
1914
|
+
/** Transmit-time positions for the rover; defaults to the shared map. */
|
|
1915
|
+
roverSatellitePositionsM?: Record<string, [number, number, number]>;
|
|
1916
|
+
velocityMps?: [number, number, number];
|
|
1917
|
+
/** Epoch time coordinate (seconds) for the prediction-delta computation. */
|
|
1918
|
+
predictionTimeS?: number;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
/** Reference-satellite selection policy for the arc. */
|
|
1922
|
+
export interface RtkArcReferenceSelection {
|
|
1923
|
+
/** "auto" (default), "satellite", or "perSystem". */
|
|
1924
|
+
mode?: "auto" | "satellite" | "perSystem";
|
|
1925
|
+
/** Fixed reference satellite token (mode "satellite", single-system only). */
|
|
1926
|
+
satellite?: string;
|
|
1927
|
+
/** Constellation letter -> reference satellite (mode "perSystem"). */
|
|
1928
|
+
references?: Record<string, string>;
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
/** Optional predicted-residual screen for one epoch update. */
|
|
1932
|
+
export interface RtkArcInnovationScreen {
|
|
1933
|
+
thresholdSigma: number;
|
|
1934
|
+
minRows: number;
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
/** Per-epoch sequential-update controls. Every field is optional. */
|
|
1938
|
+
export interface RtkArcUpdateOptions {
|
|
1939
|
+
holdSigmaM?: number;
|
|
1940
|
+
positionTolM?: number;
|
|
1941
|
+
ambiguityTolM?: number;
|
|
1942
|
+
maxIterations?: number;
|
|
1943
|
+
/** Kinematic baseline process-noise sigma (metres); 0 is the static filter. */
|
|
1944
|
+
processNoiseBaselineSigmaM?: number;
|
|
1945
|
+
/** Prediction dynamics. Default "constantPosition". */
|
|
1946
|
+
dynamicsModel?: "constantPosition" | "velocityPropagated";
|
|
1947
|
+
/** Constellation letters kept float-only (never integer-fixed), e.g. ["R"]. */
|
|
1948
|
+
floatOnlySystems?: string[];
|
|
1949
|
+
innovationScreen?: RtkArcInnovationScreen;
|
|
1950
|
+
/** Emit per-epoch residual diagnostics. Default false. */
|
|
1951
|
+
reportResiduals?: boolean;
|
|
1952
|
+
/** AR commitment arming gate (metres); omit to keep always-armed. */
|
|
1953
|
+
arArmingSigmaM?: number;
|
|
1954
|
+
/** LAMBDA acceptance ratio threshold. Default 3.0. */
|
|
1955
|
+
ratioThreshold?: number;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
/** Cycle-slip handling policy for arc preprocessing. */
|
|
1959
|
+
export type RtkArcCycleSlipPolicy = "error" | "dropSatellite" | "splitArc";
|
|
1960
|
+
|
|
1961
|
+
/** Optional preprocessing chained ahead of the RTK arc solve. */
|
|
1962
|
+
export interface RtkArcPreprocessing {
|
|
1963
|
+
/** Reads `RtkArcObservation.lli`; omit to skip cycle-slip preprocessing. */
|
|
1964
|
+
cycleSlip?: RtkArcCycleSlipPolicy;
|
|
1965
|
+
/** Hatch code-smoothing window cap; omit to skip smoothing. */
|
|
1966
|
+
hatchWindowCap?: number;
|
|
1967
|
+
/** Base-receiver elevation mask in degrees; omit to skip masking. */
|
|
1968
|
+
elevationMaskDeg?: number;
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
/** The config object passed to `solveRtkArc`. */
|
|
1972
|
+
export interface RtkArcConfig {
|
|
1973
|
+
/** Base-station ECEF position [x, y, z], metres. */
|
|
1974
|
+
baseM: [number, number, number];
|
|
1975
|
+
reference?: RtkArcReferenceSelection;
|
|
1976
|
+
model: RtkMeasurementModel;
|
|
1977
|
+
/** Baseline prior sigma (metres) for the initial information matrix. */
|
|
1978
|
+
baselinePriorSigmaM: number;
|
|
1979
|
+
/** Ambiguity prior sigma (metres) for each new single-difference column. */
|
|
1980
|
+
ambiguityPriorSigmaM: number;
|
|
1981
|
+
initialBaselineM?: [number, number, number];
|
|
1982
|
+
/** Per-ambiguity carrier wavelengths (metres) for the integer search. */
|
|
1983
|
+
wavelengthsM?: Record<string, number>;
|
|
1984
|
+
/** Per-ambiguity code-to-phase metre offsets for the integer search. */
|
|
1985
|
+
offsetsM?: Record<string, number>;
|
|
1986
|
+
updateOpts?: RtkArcUpdateOptions;
|
|
1987
|
+
preprocessing?: RtkArcPreprocessing;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
/** Option groups used by the validated fixed solve inside `solveStaticRtkArc`. */
|
|
1991
|
+
export interface RtkValidatedFixedOptions {
|
|
1992
|
+
float?: RtkFloatOptions;
|
|
1993
|
+
fixed?: RtkFixedOptions;
|
|
1994
|
+
residual?: RtkResidualValidationOptions;
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
/** The config object passed to `solveStaticRtkArc`. */
|
|
1998
|
+
export interface RtkStaticArcConfig {
|
|
1999
|
+
arc: RtkArcConfig;
|
|
2000
|
+
opts?: RtkValidatedFixedOptions;
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
/** Scalar summary of one epoch's LAMBDA integer search. */
|
|
2004
|
+
export interface RtkArcSearchSummary {
|
|
2005
|
+
integerStatus: "Fixed" | "NotFixed";
|
|
2006
|
+
integerMethod: string;
|
|
2007
|
+
integerRatio?: number;
|
|
2008
|
+
integerBestScore?: number;
|
|
2009
|
+
integerSecondBestScore?: number;
|
|
2010
|
+
integerCandidates: number;
|
|
2011
|
+
partialEnabled: boolean;
|
|
2012
|
+
partialFixed: boolean;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
/** One public residual row at a reported epoch solution. */
|
|
2016
|
+
export interface RtkArcResidual {
|
|
2017
|
+
epochIndex: number;
|
|
2018
|
+
satelliteId: string;
|
|
2019
|
+
referenceSatelliteId: string;
|
|
2020
|
+
ambiguityId: string;
|
|
2021
|
+
codeM: number;
|
|
2022
|
+
phaseM: number;
|
|
2023
|
+
codeSigmaM: number;
|
|
2024
|
+
phaseSigmaM: number;
|
|
2025
|
+
codeNormalized: number;
|
|
2026
|
+
phaseNormalized: number;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
/** Static float RTK solution returned inside `RtkStaticArcSolution`. */
|
|
2030
|
+
export interface RtkStaticArcFloatSolution {
|
|
2031
|
+
baselineM: [number, number, number];
|
|
2032
|
+
ambiguitiesM: Record<string, number>;
|
|
2033
|
+
ambiguityCovarianceM: number[];
|
|
2034
|
+
ambiguityCovarianceInverseM: number[];
|
|
2035
|
+
residuals: RtkArcResidual[];
|
|
2036
|
+
iterations: number;
|
|
2037
|
+
converged: boolean;
|
|
2038
|
+
status: "StateTolerance" | "MaxIterations";
|
|
2039
|
+
codeRmsM: number;
|
|
2040
|
+
phaseRmsM: number;
|
|
2041
|
+
weightedRmsM: number;
|
|
2042
|
+
nObservations: number;
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
/** Static fixed RTK solution returned inside `RtkStaticArcSolution`. */
|
|
2046
|
+
export interface RtkStaticArcFixedSolution {
|
|
2047
|
+
baselineM: [number, number, number];
|
|
2048
|
+
freeAmbiguitiesM: Record<string, number>;
|
|
2049
|
+
fixedAmbiguitiesCycles: Record<string, number>;
|
|
2050
|
+
fixedAmbiguitiesM: Record<string, number>;
|
|
2051
|
+
residuals: RtkArcResidual[];
|
|
2052
|
+
search: RtkArcSearchSummary;
|
|
2053
|
+
iterations: number;
|
|
2054
|
+
converged: boolean;
|
|
2055
|
+
status: "StateTolerance" | "MaxIterations";
|
|
2056
|
+
codeRmsM: number;
|
|
2057
|
+
phaseRmsM: number;
|
|
2058
|
+
weightedRmsM: number;
|
|
2059
|
+
nObservations: number;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
/** One residual-validation outlier selected by fixed RTK validation. */
|
|
2063
|
+
export interface RtkResidualValidationOutlier {
|
|
2064
|
+
epochIndex: number;
|
|
2065
|
+
satelliteId: string;
|
|
2066
|
+
referenceSatelliteId: string;
|
|
2067
|
+
ambiguityId: string;
|
|
2068
|
+
kind: "code" | "phase";
|
|
2069
|
+
residualM: number;
|
|
2070
|
+
sigmaM: number;
|
|
2071
|
+
normalizedResidual: number;
|
|
2072
|
+
thresholdSigma: number;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
/** Residual-validation metadata for the accepted fixed RTK solution. */
|
|
2076
|
+
export interface RtkResidualValidationResult {
|
|
2077
|
+
thresholdSigma: number;
|
|
2078
|
+
maxExclusions: number;
|
|
2079
|
+
excludedSats: string[];
|
|
2080
|
+
exclusions: RtkResidualValidationOutlier[];
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
/** Validated fixed RTK solution returned inside `RtkStaticArcSolution`. */
|
|
2084
|
+
export interface RtkValidatedFixedSolution {
|
|
2085
|
+
floatSolution: RtkStaticArcFloatSolution;
|
|
2086
|
+
fixedSolution: RtkStaticArcFixedSolution;
|
|
2087
|
+
residualValidation?: RtkResidualValidationResult;
|
|
2088
|
+
ambiguityIds: string[];
|
|
2089
|
+
ambiguitySatellites: Record<string, string>;
|
|
2090
|
+
}
|
|
2091
|
+
|
|
2092
|
+
/** The full static RTK arc solution returned by `solveStaticRtkArc`. */
|
|
2093
|
+
export interface RtkStaticArcSolution {
|
|
2094
|
+
references: Record<string, string>;
|
|
2095
|
+
ambiguityIds: string[];
|
|
2096
|
+
ambiguitySatellites: Record<string, string>;
|
|
2097
|
+
floatSolution: RtkStaticArcFloatSolution;
|
|
2098
|
+
fixedSolution: RtkValidatedFixedSolution;
|
|
2099
|
+
droppedSats: string[];
|
|
2100
|
+
splitCycleSlipArcs: RtkArcCycleSlipSplitArc[];
|
|
2101
|
+
elevationMaskedSats: string[];
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
/** One epoch's predicted-residual (innovation) screen outcome, present only when
|
|
2105
|
+
* the screen was enabled via `updateOpts.innovationScreen`. */
|
|
2106
|
+
export interface RtkArcInnovationScreenResult {
|
|
2107
|
+
thresholdSigma: number;
|
|
2108
|
+
minRows: number;
|
|
2109
|
+
inputRows: number;
|
|
2110
|
+
acceptedRows: number;
|
|
2111
|
+
rejectedRows: number;
|
|
2112
|
+
rejectedCodeRows: number;
|
|
2113
|
+
rejectedPhaseRows: number;
|
|
2114
|
+
maxAbsNormalizedInnovation?: number;
|
|
2115
|
+
maxRejectedAbsNormalizedInnovation?: number;
|
|
2116
|
+
/** Whether the epoch was coasted (too few rows survived the screen). */
|
|
2117
|
+
coasted: boolean;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
/** One epoch's reported baseline/ambiguity solution. */
|
|
2121
|
+
export interface RtkArcEpochSolution {
|
|
2122
|
+
reportedBaselineM: [number, number, number];
|
|
2123
|
+
floatBaselineM: [number, number, number];
|
|
2124
|
+
integerFixed: boolean;
|
|
2125
|
+
integerRatio: number;
|
|
2126
|
+
newlyFixed: string[];
|
|
2127
|
+
fixedIds: string[];
|
|
2128
|
+
/** Reported single-difference ambiguities (id -> metres). */
|
|
2129
|
+
sdAmbiguitiesM: Record<string, number>;
|
|
2130
|
+
fixedDoubleDifferenceIds: string[];
|
|
2131
|
+
usedSatelliteIds: string[];
|
|
2132
|
+
search?: RtkArcSearchSummary;
|
|
2133
|
+
residuals: RtkArcResidual[];
|
|
2134
|
+
/** Per-epoch innovation-screen result, present only when the screen is enabled
|
|
2135
|
+
* for the arc via `updateOpts.innovationScreen`. */
|
|
2136
|
+
innovationScreen?: RtkArcInnovationScreenResult;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
/** The final carried filter state (the serializable streaming ABI). */
|
|
2140
|
+
export interface RtkArcFilterState {
|
|
2141
|
+
version: number;
|
|
2142
|
+
references: Record<string, string>;
|
|
2143
|
+
sdAmbiguityIds: string[];
|
|
2144
|
+
baselineM: [number, number, number];
|
|
2145
|
+
sdAmbiguitiesM: number[];
|
|
2146
|
+
/** Row-major n-by-n information matrix, n = 3 + sdAmbiguityIds.length. */
|
|
2147
|
+
information: number[];
|
|
2148
|
+
ambiguityPriorSigmaM: number;
|
|
2149
|
+
epochCount: number;
|
|
2150
|
+
fixedCycles: Record<string, number>;
|
|
2151
|
+
fixedM: Record<string, number>;
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2154
|
+
/** Cycle-slip split-arc metadata emitted by preprocessing. */
|
|
2155
|
+
export interface RtkArcCycleSlipSplitArc {
|
|
2156
|
+
receiver: "base" | "rover";
|
|
2157
|
+
satelliteId: string;
|
|
2158
|
+
ambiguityId: string;
|
|
2159
|
+
startEpochIndex: number;
|
|
2160
|
+
endEpochIndex: number;
|
|
2161
|
+
nEpochs: number;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
/** The full sequential RTK arc solution returned by `solveRtkArc`. */
|
|
2165
|
+
export interface RtkArcSolution {
|
|
2166
|
+
/** Per-constellation reference single-difference ambiguity ids. */
|
|
2167
|
+
references: Record<string, string>;
|
|
2168
|
+
epochs: RtkArcEpochSolution[];
|
|
2169
|
+
finalState: RtkArcFilterState;
|
|
2170
|
+
droppedSats: string[];
|
|
2171
|
+
splitCycleSlipArcs: RtkArcCycleSlipSplitArc[];
|
|
2172
|
+
elevationMaskedSats: string[];
|
|
2173
|
+
/** Row-major posterior covariance, n-by-n with n = finalState information size. */
|
|
2174
|
+
measurementCovariance: number[];
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
/** One receiver's dual-frequency code/carrier observation. */
|
|
2178
|
+
export interface RtkDualFrequencyObservation {
|
|
2179
|
+
ambiguityId: string;
|
|
2180
|
+
p1M: number;
|
|
2181
|
+
p2M: number;
|
|
2182
|
+
phi1Cycles: number;
|
|
2183
|
+
phi2Cycles: number;
|
|
2184
|
+
f1Hz: number;
|
|
2185
|
+
f2Hz: number;
|
|
2186
|
+
lli1?: number;
|
|
2187
|
+
lli2?: number;
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
/** Paired base/rover dual-frequency observation for one satellite. */
|
|
2191
|
+
export interface RtkDualFrequencySatelliteObservation {
|
|
2192
|
+
satelliteId: string;
|
|
2193
|
+
base: RtkDualFrequencyObservation;
|
|
2194
|
+
rover: RtkDualFrequencyObservation;
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
/** One dual-frequency RTK arc epoch. */
|
|
2198
|
+
export interface RtkDualFrequencyArcEpoch {
|
|
2199
|
+
jdWhole: number;
|
|
2200
|
+
jdFraction: number;
|
|
2201
|
+
epochSortKey?: string;
|
|
2202
|
+
gapTimeS?: number;
|
|
2203
|
+
observations: RtkDualFrequencySatelliteObservation[];
|
|
2204
|
+
satellitePositionsM: Record<string, [number, number, number]>;
|
|
2205
|
+
baseSatellitePositionsM?: Record<string, [number, number, number]>;
|
|
2206
|
+
roverSatellitePositionsM?: Record<string, [number, number, number]>;
|
|
2207
|
+
velocityMps?: [number, number, number];
|
|
2208
|
+
predictionTimeS?: number;
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
/** Dual-frequency cycle-slip classifier thresholds. */
|
|
2212
|
+
export interface RtkDualCycleSlipOptions {
|
|
2213
|
+
gfThresholdM?: number;
|
|
2214
|
+
mwThresholdCycles?: number;
|
|
2215
|
+
minArcGapS?: number;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
/** Optional dual-frequency cycle-slip preprocessing for wide-lane fixing. */
|
|
2219
|
+
export interface RtkDualCycleSlipConfig {
|
|
2220
|
+
policy: RtkArcCycleSlipPolicy;
|
|
2221
|
+
options?: RtkDualCycleSlipOptions;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
/** Wide-lane integer estimation controls. */
|
|
2225
|
+
export interface RtkWideLaneOptions {
|
|
2226
|
+
minEpochs: number;
|
|
2227
|
+
toleranceCycles: number;
|
|
2228
|
+
skipShortFragments: boolean;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
/** The config object passed to `fixWideLaneRtkArc`. */
|
|
2232
|
+
export interface RtkWideLaneArcConfig {
|
|
2233
|
+
baseM: [number, number, number];
|
|
2234
|
+
reference?: RtkArcReferenceSelection;
|
|
2235
|
+
options: RtkWideLaneOptions;
|
|
2236
|
+
cycleSlip?: RtkDualCycleSlipConfig;
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
/** The wide-lane RTK arc solution returned by `fixWideLaneRtkArc`. */
|
|
2240
|
+
export interface RtkWideLaneArcSolution {
|
|
2241
|
+
references: Record<string, string>;
|
|
2242
|
+
wideLaneCycles: Record<string, number>;
|
|
2243
|
+
epochs: RtkDualFrequencyArcEpoch[];
|
|
2244
|
+
droppedSats: string[];
|
|
2245
|
+
splitCycleSlipArcs: RtkArcCycleSlipSplitArc[];
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
/** The config object passed to `prepareIonosphereFreeRtkArc`. */
|
|
2249
|
+
export interface RtkIonosphereFreeArcConfig {
|
|
2250
|
+
baseM: [number, number, number];
|
|
2251
|
+
initialBaselineM?: [number, number, number];
|
|
2252
|
+
reference?: RtkArcReferenceSelection;
|
|
2253
|
+
applyTroposphere?: boolean;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/** The ionosphere-free RTK arc setup returned by `prepareIonosphereFreeRtkArc`. */
|
|
2257
|
+
export interface RtkIonosphereFreeArcSolution {
|
|
2258
|
+
references: Record<string, string>;
|
|
2259
|
+
epochs: RtkArcEpoch[];
|
|
2260
|
+
wavelengthsM: Record<string, number>;
|
|
2261
|
+
offsetsM: Record<string, number>;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// ---------------------------------------------------------------------------
|
|
2265
|
+
// RTCM construction + encode (the inverse of decodeRtcm)
|
|
2266
|
+
// ---------------------------------------------------------------------------
|
|
2267
|
+
//
|
|
2268
|
+
// `encodeRtcm(message)` / `encodeRtcmFrame(message)` take a `type`-tagged plain
|
|
2269
|
+
// object carrying the raw transmitted field integers and return the encoded body
|
|
2270
|
+
// / framed bytes. The accepted shapes mirror the `decodeRtcm` output minus the
|
|
2271
|
+
// derived convenience fields. Import:
|
|
2272
|
+
//
|
|
2273
|
+
// import { encodeRtcmFrame } from "@neilberkman/sidereon";
|
|
2274
|
+
// import type { RtcmMessageInput } from "@neilberkman/sidereon/types";
|
|
2275
|
+
|
|
2276
|
+
/** A 1005 / 1006 station antenna reference point for encoding. */
|
|
2277
|
+
export type RtcmStationCoordinatesInput = Omit<
|
|
2278
|
+
RtcmStationCoordinates,
|
|
2279
|
+
"xM" | "yM" | "zM" | "antennaHeightM"
|
|
2280
|
+
>;
|
|
2281
|
+
|
|
2282
|
+
/** A 1007 / 1008 / 1033 antenna or receiver descriptor for encoding. */
|
|
2283
|
+
export type RtcmAntennaDescriptorInput = RtcmAntennaDescriptor;
|
|
2284
|
+
|
|
2285
|
+
/** An MSM4 / MSM7 observation message for encoding. */
|
|
2286
|
+
export type RtcmMsmInput = RtcmMsm;
|
|
2287
|
+
|
|
2288
|
+
/** A 1019 GPS broadcast ephemeris for encoding (`messageNumber` is implied). */
|
|
2289
|
+
export type RtcmGpsEphemerisInput = Omit<RtcmGpsEphemeris, "messageNumber">;
|
|
2290
|
+
|
|
2291
|
+
/** A 1020 GLONASS broadcast ephemeris for encoding (`messageNumber` is implied). */
|
|
2292
|
+
export type RtcmGlonassEphemerisInput = Omit<RtcmGlonassEphemeris, "messageNumber">;
|
|
2293
|
+
|
|
2294
|
+
/** A recognized-but-undecoded message for encoding (body preserved verbatim). */
|
|
2295
|
+
export type RtcmUnsupportedInput = RtcmUnsupported;
|
|
2296
|
+
|
|
2297
|
+
/** The message IR accepted by `encodeRtcm` / `encodeRtcmFrame`, tagged by `type`.
|
|
2298
|
+
* A `decodeRtcm` output object is also accepted (its extra derived fields are
|
|
2299
|
+
* ignored). */
|
|
2300
|
+
export type RtcmMessageInput =
|
|
2301
|
+
| RtcmMsmInput
|
|
2302
|
+
| RtcmStationCoordinatesInput
|
|
2303
|
+
| RtcmAntennaDescriptorInput
|
|
2304
|
+
| RtcmGpsEphemerisInput
|
|
2305
|
+
| RtcmGlonassEphemerisInput
|
|
2306
|
+
| RtcmUnsupportedInput;
|