Skip to content

Commit

Permalink
Impl sim/proc tracker diff in other tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherRabotin committed Jul 13, 2024
1 parent 3decc0f commit f5f7c11
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 62 deletions.
5 changes: 1 addition & 4 deletions src/od/noise/gauss_markov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,7 @@ impl Stochastics for GaussMarkov {
let steady_noise = 0.5 * self.process_noise * self.tau.to_seconds() * anti_decay;
let ss_sample = rng.sample(Normal::new(0.0, steady_noise).unwrap());

let bias = self.init_sample.unwrap() * decay + ss_sample;

// Return the new bias
bias
self.init_sample.unwrap() * decay + ss_sample
}
}

Expand Down
94 changes: 61 additions & 33 deletions tests/orbit_determination/multi_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,36 @@ fn almanac() -> Arc<Almanac> {
test_almanac_arcd()
}

#[allow(clippy::identity_op)]
#[rstest]
fn od_val_multi_body_ckf_perfect_stations(almanac: Arc<Almanac>) {
let _ = pretty_env_logger::try_init();

#[fixture]
fn sim_devices(almanac: Arc<Almanac>) -> Vec<GroundStation> {
let iau_earth = almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap();
let elevation_mask = 0.0;
let dss65_madrid = GroundStation::dss65_madrid(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);
let dss34_canberra = GroundStation::dss34_canberra(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);
let dss13_goldstone = GroundStation::dss13_goldstone(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);

// Define the ground stations.
vec![dss65_madrid, dss34_canberra, dss13_goldstone]
}

/// Devices for processing the measurement, noise may not be zero.
#[fixture]
fn proc_devices(almanac: Arc<Almanac>) -> Vec<GroundStation> {
let iau_earth = almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap();
let elevation_mask = 0.0;
let dss65_madrid = GroundStation::dss65_madrid(
elevation_mask,
Expand All @@ -53,22 +75,28 @@ fn od_val_multi_body_ckf_perfect_stations(almanac: Arc<Almanac>) {
iau_earth,
);

vec![dss65_madrid, dss34_canberra, dss13_goldstone]
}

#[allow(clippy::identity_op)]
#[rstest]
fn od_val_multi_body_ckf_perfect_stations(
almanac: Arc<Almanac>,
sim_devices: Vec<GroundStation>,
proc_devices: Vec<GroundStation>,
) {
let _ = pretty_env_logger::try_init();

// Define the tracking configurations
let mut configs = BTreeMap::new();
configs.insert(
dss65_madrid.name.clone(),
TrkConfig::from_sample_rate(10.seconds()),
);
configs.insert(
dss34_canberra.name.clone(),
TrkConfig::from_sample_rate(10.seconds()),
);
configs.insert(
dss13_goldstone.name.clone(),
TrkConfig::from_sample_rate(10.seconds()),
);
for device in &sim_devices {
configs.insert(
device.name.clone(),
TrkConfig::from_sample_rate(10.seconds()),
);
}

let all_stations = vec![dss65_madrid, dss34_canberra, dss13_goldstone];
let all_stations = sim_devices;

// Define the propagator information.
let prop_time = 1 * Unit::Day;
Expand All @@ -88,10 +116,11 @@ fn od_val_multi_body_ckf_perfect_stations(almanac: Arc<Almanac>) {
let (final_truth, traj) = prop.for_duration_with_traj(prop_time).unwrap();

// Simulate tracking data
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs, 0).unwrap();
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs.clone(), 0).unwrap();
arc_sim.build_schedule(almanac.clone()).unwrap();

let arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
let mut arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
arc.set_devices(proc_devices, configs).unwrap();

// Now that we have the truth data, let's start an OD with no noise at all and compute the estimates.
// We expect the estimated orbit to be perfect since we're using strictly the same dynamics, no noise on
Expand Down Expand Up @@ -169,19 +198,16 @@ fn od_val_multi_body_ckf_perfect_stations(almanac: Arc<Almanac>) {

#[allow(clippy::identity_op)]
#[rstest]
fn multi_body_ckf_covar_map(almanac: Arc<Almanac>) {
fn multi_body_ckf_covar_map(
almanac: Arc<Almanac>,
sim_devices: Vec<GroundStation>,
proc_devices: Vec<GroundStation>,
) {
// For this test, we're only enabling one station so we can check that the covariance inflates between visibility passes.
let _ = pretty_env_logger::try_init();

let iau_earth = almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap();
// Define the ground stations.
let elevation_mask = 0.0;
let dss13_goldstone = GroundStation::dss13_goldstone(
elevation_mask,
StochasticNoise::MIN,
StochasticNoise::MIN,
iau_earth,
);
let dss13_goldstone = sim_devices[2].clone();

// Define the tracking configurations
let mut configs = BTreeMap::new();
configs.insert(
Expand Down Expand Up @@ -213,10 +239,12 @@ fn multi_body_ckf_covar_map(almanac: Arc<Almanac>) {
let (_, traj) = prop.for_duration_with_traj(prop_time).unwrap();

// Simulate tracking data
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs, 0).unwrap();
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs.clone(), 0).unwrap();
arc_sim.build_schedule(almanac.clone()).unwrap();

let arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
let mut arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
arc.set_devices(vec![proc_devices[2].clone()], configs)
.unwrap();

// Now that we have the truth data, let's start an OD with no noise at all and compute the estimates.
// We expect the estimated orbit to be perfect since we're using strictly the same dynamics, no noise on
Expand Down
86 changes: 61 additions & 25 deletions tests/orbit_determination/spacecraft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,36 @@ fn almanac() -> Arc<Almanac> {
test_almanac_arcd()
}

#[allow(clippy::identity_op)]
#[rstest]
fn od_val_sc_mb_srp_reals_duals_models(almanac: Arc<Almanac>) {
/*
* This tests that the state transition matrix computation is correct when multiple celestial gravities and solar radiation pressure
* are added to the model.
*
* Specifically, the same dynamics are used for both the measurement generation and for the estimation.
* However, only the estimation generation propagates the STM. When STM propagation is enabled, the code will compute
* the dynamics using a hyperdual representation in 9 dimensions: 1 for the reals, 3 for the position partials,
* 3 for the velocity partials, 1 for the Cr partials and 1 for the Cd partials.
*
* Hence, if the filter state estimation is any different from the truth data, then it means that the equations of
* motion computed in hyperdual space differ from the ones computes in the reals.
*
* Thereby, this serves as a validation of the spacecraft dynamics and SRP duals implementation.
**/
let _ = pretty_env_logger::try_init();
#[fixture]
fn sim_devices(almanac: Arc<Almanac>) -> Vec<GroundStation> {
let iau_earth = almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap();
let elevation_mask = 0.0;
let dss65_madrid = GroundStation::dss65_madrid(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);
let dss34_canberra = GroundStation::dss34_canberra(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);
let dss13_goldstone = GroundStation::dss13_goldstone(
elevation_mask,
StochasticNoise::ZERO,
StochasticNoise::ZERO,
iau_earth,
);

vec![dss65_madrid, dss34_canberra, dss13_goldstone]
}

/// Devices for processing the measurement, noise may not be zero.
#[fixture]
fn proc_devices(almanac: Arc<Almanac>) -> Vec<GroundStation> {
let iau_earth = almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap();
// Define the ground stations.
let elevation_mask = 0.0;
let dss65_madrid = GroundStation::dss65_madrid(
elevation_mask,
Expand All @@ -66,6 +75,32 @@ fn od_val_sc_mb_srp_reals_duals_models(almanac: Arc<Almanac>) {
iau_earth,
);

vec![dss65_madrid, dss34_canberra, dss13_goldstone]
}

#[allow(clippy::identity_op)]
#[rstest]
fn od_val_sc_mb_srp_reals_duals_models(
almanac: Arc<Almanac>,
sim_devices: Vec<GroundStation>,
proc_devices: Vec<GroundStation>,
) {
/*
* This tests that the state transition matrix computation is correct when multiple celestial gravities and solar radiation pressure
* are added to the model.
*
* Specifically, the same dynamics are used for both the measurement generation and for the estimation.
* However, only the estimation generation propagates the STM. When STM propagation is enabled, the code will compute
* the dynamics using a hyperdual representation in 9 dimensions: 1 for the reals, 3 for the position partials,
* 3 for the velocity partials, 1 for the Cr partials and 1 for the Cd partials.
*
* Hence, if the filter state estimation is any different from the truth data, then it means that the equations of
* motion computed in hyperdual space differ from the ones computes in the reals.
*
* Thereby, this serves as a validation of the spacecraft dynamics and SRP duals implementation.
**/
let _ = pretty_env_logger::try_init();

let epoch = Epoch::from_gregorian_tai_at_midnight(2020, 1, 1);
let prop_time = 1 * Unit::Day;

Expand All @@ -78,11 +113,11 @@ fn od_val_sc_mb_srp_reals_duals_models(almanac: Arc<Almanac>) {
}])
.build();

configs.insert(dss65_madrid.name.clone(), cfg.clone());
configs.insert(dss34_canberra.name.clone(), cfg.clone());
configs.insert(dss13_goldstone.name.clone(), cfg);
for device in &sim_devices {
configs.insert(device.name.clone(), cfg.clone());
}

let all_stations = vec![dss65_madrid, dss34_canberra, dss13_goldstone];
let all_stations = sim_devices;

// Define the propagator information.
let step_size = 10.0 * Unit::Second;
Expand Down Expand Up @@ -142,10 +177,11 @@ fn od_val_sc_mb_srp_reals_duals_models(almanac: Arc<Almanac>) {
.unwrap();

// Simulate tracking data
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs, 0).unwrap();
let mut arc_sim = TrackingArcSim::with_seed(all_stations, traj, configs.clone(), 0).unwrap();
arc_sim.build_schedule(almanac.clone()).unwrap();

let arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
let mut arc = arc_sim.generate_measurements(almanac.clone()).unwrap();
arc.set_devices(proc_devices, configs).unwrap();

arc.to_parquet_simple(path.with_file_name("sc_msr_arc.parquet"))
.unwrap();
Expand Down

0 comments on commit f5f7c11

Please sign in to comment.