Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Significant improvements in noise modeling #129

Conversation

ChristopherRabotin
Copy link
Member

@ChristopherRabotin ChristopherRabotin commented Mar 24, 2023

Effects

Lots of breaking changes in this work.

  • Add Gauss Markov noise models: first order GM (bias only) and coupled bias and drift model (where the bias is a second order GM and the drift is first order). This is a recommended best practice for modeling biases according to D'Souza in "NASA Best Practices for Navigation Filters"
  • Change EstimateFrom trait to support many different sensitivity matrix sizes (this was not possible beforehand)
  • Replace noise model of Ground Stations from Gaussian normal to Gauss Markov
  • Allow initialization of ground stations and their GM noise characteristics from YAML
  • Allow simulation of Gauss Markov models only and from Python (with Parquet export) to verify whether the model seems to match the characteristics of the ground station
  • Allow for Gauss Markov noise on the ground station clock to model
  • Disable noise in OD process when building the expected measurement
  • Change all OD seeds to use the PCG 64 Fast algorithm. This ensures reproducibility of all the runs.
  • Allow generating a dispersed state estimate from its covariance and a truth state
  • Significantly expand the tests: this is greatly enhanced by the new ability to fully reproduce a run since all random number generators are seedable

If this is a new feature or a bug fix ...

  • Yes, the branch I'm proposing to merge is called issue-xyz where xyz is the number of the issue.

If this change adds or modifies a validation case

  • Yes and:
    • I have coded up, or updated, an existing test case; and
    • I have provided a GMAT script which confirms the result(s); and
    • I have updated the VALIDATION.md file with the new error data between nyx and GMAT.
    • I will specify the version of GMAT used for the validation.

This will allow for integration times and light-time corrections.
Signed-off-by: Christopher Rabotin <[email protected]>
The sensitivity is now computed with the EstimateFrom trait.
This implies that the method to compute the sensitivity depends on what is estimated and the measurement is.
This SIGNIFICANTLY unlocks flexibility!

TODO:
1. Most importantly: change the measure() function of Measurement: this currently returns both the measurement and the state of the transmitter at the time of the measurement. Instead, it should return the `Self` of EstimateFrom.
2. Implement the sensitivity computation for the Spacecraft estimator
3. Invert and rename EstimateFrom trait such that there is a `SolveFor` trait instead

Signed-off-by: Christopher Rabotin <[email protected]>
Also cleanup yesterday's work on EstimateFrom

Signed-off-by: Christopher Rabotin <[email protected]>
@ChristopherRabotin ChristopherRabotin added QA:Development T-orbit-determination i-python Relative to the Python interface P-high i-rust Relative to the Rust interface labels Mar 24, 2023
@ChristopherRabotin ChristopherRabotin marked this pull request as draft March 24, 2023 14:43
Signed-off-by: Christopher Rabotin <[email protected]>
I should be using the state transition matrix (eq. 5.81) instead of the
EOMs (eq. 5.78).
This was only obvious after plotting a coupled GM, so I'm glad this
works.
This coupled model is promising but also very complicated, and usually not needed.
I can always add it later.
I would like to integrate these scripts with the package, but I can't seem to make both work yet

Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
@ChristopherRabotin ChristopherRabotin marked this pull request as ready for review April 8, 2023 01:06
@ChristopherRabotin
Copy link
Member Author

ChristopherRabotin commented Apr 21, 2023

Results of the "Robustness" test

Dispersions

  • Inclination dispersed by 2.5e-3 degrees
  • RAAN by 0.022 degrees
  • AoP by 0.02 degrees
// Disperse the initial state based on some orbital elements errors given from ULA Atlas 5 user guide, table 2.3.3-1 <https://www.ulalaunch.com/docs/default-source/rockets/atlasvusersguide2010a.pdf>
    // This assumes that the errors are ONE TENTH of the values given in the table. It assumes that the launch provider has provided an initial state vector, whose error is lower than the injection errors.
    let generator = GaussianGenerator::from_std_devs(
        initial_state,
        &[
            (StateParameter::Inclination, 0.0025),
            (StateParameter::RAAN, 0.022),
            (StateParameter::AoP, 0.02),
        ],
    )
    .unwrap();
Truth initial state:
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [-9042.862234, 18536.333069, 6999.957069] km velocity = [-3.288789, -2.226285, 1.646738] km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   sma = 22000.000000 km   ecc = 0.010000  inc = 30.000000 deg     raan = 80.000000 deg    aop = 40.000000 deg     ta = 359.999999 deg
Filter initial state:
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [-9050.309259, 18530.208096, 7006.546242] km velocity = [-3.287950, -2.228182, 1.645847] km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   sma = 22000.000000 km   ecc = 0.010000  inc = 30.002369 deg     raan = 79.986313 deg    aop = 40.041822 deg     ta = 0.000001 deg
Initial state dev:      11.679 km       0.002 km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [7.447026, 6.124973, -6.589172] km   velocity = [-0.000838, 0.001897, 0.000891] km/s

Tracking arc set up

  • Measurements every 60 seconds with Madrid and Canberra.
  • Noise modeled as Gauss markov process, high precision
  • Range and Doppler modeling in sync

Filter setup

  • SNC set to 1e-4 km^2/s^2 in EME2000 frame (all axes), constant, disabled after 2 minutes of gap in measurements
  • Iterate once on the first three hours of tracking data
  • Start the CKF with the rest of the data, which transition into an EKF after 1000 measurements, and disabled if there aren't any measurements for three minutes

Results

RMAG error = 9.95e1 m   VMAG error = 2.180e1 mm/s

State deviation

(Ad hoc plot so the units are km and km/s)
robust_test_pos_err_km
robust_test_vel_err_km_s

Covariance plots

robust-pos-covar-zoom
robust-pos-covar
robust-vel-covar-zoom
robust-vel-covar

@ChristopherRabotin
Copy link
Member Author

The previous EKF trigger was never triggered because there were only 996 measurements in the remaining set.

Filter setup

Trigger EKF after 300 measurements.

Results

RMAG error = 7.44e0 m   VMAG error = 4.731e0 mm/s

There are warnings during the run because the EKF is enabled even when the state deviation is not within the three sigmas. This can probably be fixed by toying with the SNC.

 INFO  nyx_space::od::process           > Navigation propagating for a total of 20 h 22 min with step size 1 min
 INFO  nyx_space::od::process           > Processing 994 measurements with covariance mapping
 INFO  nyx_space::od::process           >   0% done (0 measurements processed)
 INFO  nyx_space::od::process           >  10% done (100 measurements processed)
 INFO  nyx_space::od::process           >  20% done (199 measurements processed)
 WARN  nyx_space::od::process           > EKF enabled @ 2020-01-01T07:42:23 UTC but filter DIVERGING
 INFO  nyx_space::od::process           >  30% done (299 measurements processed)
 INFO  nyx_space::od::process           > EKF disabled @ 2020-01-01T10:06:23 UTC
 INFO  nyx_space::od::process           >  40% done (398 measurements processed)
 INFO  nyx_space::od::process           >  50% done (497 measurements processed)
 INFO  nyx_space::od::process           >  60% done (597 measurements processed)
 WARN  nyx_space::od::process           > EKF enabled @ 2020-01-01T16:46:23 UTC but filter DIVERGING
 INFO  nyx_space::od::process           >  70% done (696 measurements processed)
 INFO  nyx_space::od::process           >  80% done (796 measurements processed)
 INFO  nyx_space::od::process           >  90% done (895 measurements processed)
 INFO  nyx_space::od::process           > 100% done (994 measurements processed)

State deviation

robust-pos-err-km
robust-vel-err-km_s

Residuals

These look extremely good, the noise may be too low.

range-resid

doppler-resid

Covariance plots (EME2000 frame)

robust-pos-covar

robust-vel-covar

Signed-off-by: Christopher Rabotin <[email protected]>
…ovar)

Add generate_orbits and generate_spacecraft to Python's nyx_space.monte_carlo module

Make KfEstimate<T> Copy

Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
…lity-constraints-more-noise-model-design

Signed-off-by: Christopher Rabotin <[email protected]>
This is not a recommended API but it could be useful.

Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
@ChristopherRabotin
Copy link
Member Author

ChristopherRabotin commented May 2, 2023

Results from 19ace2b

One way results for a MEO spacecraft

Initial state deviation

Initial estimate:
=== Prediction @ 2019-12-31T23:59:23 UTC -- within 3 sigma: true ===
state [Earth J2000] 2019-12-31T23:59:23 UTC     position = [-9045.344786, 18534.292006, 7002.153779] km velocity = [-3.288510, -2.226917, 1.646441] km/s
sigmas [5.5467591943091556e1,3.7493455598629886e1,4.3429805205314224e1,7.02724001508767e-7,3.5982340051832854e-6,7.935577188194398e-7]

Truth initial state:
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [-9042.862234, 18536.333069, 6999.957069] km velocity = [-3.288789, -2.226285, 1.646738] km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   sma = 22000.000000 km   ecc = 0.010000  inc = 30.000000 deg     raan = 80.000000 deg    aop = 40.000000 deg     ta = 359.999999 deg
Filter initial state:
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [-9045.344786, 18534.292006, 7002.153779] km velocity = [-3.288510, -2.226917, 1.646441] km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   sma = 22000.000000 km   ecc = 0.010000  inc = 30.000790 deg     raan = 79.995438 deg    aop = 40.013941 deg     ta = 360.000000 deg
Initial state dev:      3892.883 km     0.752 km/s
[Earth J2000] 2019-12-31T23:59:23 UTC   position = [2.482552, 2.041063, -2.196710] km   velocity = [-0.000279, 0.000632, 0.000297] km/s

Results

RMAG error = 6.924949 m VMAG error = 0.000999 m/s

Trajectory error and estimated covariance

one-way-traj-err-covar-position

one-way-traj-err-covar-velocity

Zoom on the first six hours

one-way-traj-err-covar-position-zoom

one-way-traj-err-covar-velocity-zoom

Prefit residuals

The residuals drop after the EKF turns on (300 measurements without a gap in time).

one-way-doppler-prefit
one-way-range-prefit

Postfit residuals

one-way-doppler-postfit
one-way-range-postfit

Two way results for a MEO spacecraft

Same initial state deviation and noise levels. SNC is slightly different, but tuning of that may lead to better results.

Results

RMAG error = 7.157629 m VMAG error = 0.001309 m/s

Trajectory error and estimated

two-way-traj-err-covar-position

two-way-traj-err-covar-velocity-zoom

Zoom on first six hours

two-way-traj-err-covar-position-zoom

two-way-traj-err-covar-velocity
covariance

Prefit residuals

two-way-doppler-prefit

two-way-range-prefit

Postfit residuals

two-way-doppler-postfit
two-way-range-postfit

Also update the robustness tests and the github templates.

Signed-off-by: Christopher Rabotin <[email protected]>
Add github links to each TODO

Signed-off-by: Christopher Rabotin <[email protected]>
This does not lead to a better solution or smaller residuals, so I need to debug this again. Maybe it's because SNC not in there? Idk

Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
Signed-off-by: Christopher Rabotin <[email protected]>
@codecov-commenter
Copy link

Codecov Report

❗ No coverage uploaded for pull request base (master@bbd36a1). Click here to learn what that means.
Patch has no changes to coverable lines.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

Additional details and impacted files
@@            Coverage Diff            @@
##             master     #129   +/-   ##
=========================================
  Coverage          ?   29.16%           
=========================================
  Files             ?      126           
  Lines             ?    33301           
  Branches          ?        0           
=========================================
  Hits              ?     9712           
  Misses            ?    23589           
  Partials          ?        0           

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@ChristopherRabotin ChristopherRabotin merged commit c4c3188 into master May 10, 2023
@ChristopherRabotin ChristopherRabotin deleted the 89-add-ground-station-cadence-and-availability-constraints-more-noise-model-design branch May 10, 2023 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i-python Relative to the Python interface i-rust Relative to the Rust interface P-high T-orbit-determination
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Ground Station cadence and availability constraints (more noise model design)
2 participants