Skip to content

Commit

Permalink
Ground station stochastics now indexmap instead of explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristopherRabotin committed Nov 23, 2024
1 parent bbf019f commit 62b7e78
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 96 deletions.
42 changes: 22 additions & 20 deletions data/tests/config/many_ground_stations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@
mu_km3_s2: 398600.435436096
shape: null
elevation_mask_deg: 5.0
range_noise_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_noise_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
stochastic_noises:
range_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
light_time_correction: false
latitude_deg: 2.3522
longitude_deg: 48.8566
height_km: 0.4
measurement_types:
- Range
- Doppler
- range_km
- doppler_km_s

- name: Canberra
frame:
Expand All @@ -31,15 +32,16 @@
longitude_deg: 148.981944
height_km: 0.691750
elevation_mask_deg: 5.0
range_noise_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_noise_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
stochastic_noises:
range_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
light_time_correction: false
measurement_types:
- Range
- Doppler
- range_km
- doppler_km_s
21 changes: 11 additions & 10 deletions data/tests/config/one_ground_station.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ elevation_mask_deg: 5.0
latitude_deg: 2.3522
longitude_deg: 48.8566
height_km: 0.4
range_noise_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_noise_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
stochastic_noises:
range_km:
bias:
tau: 24 h
process_noise: 5.0e-3 # 5 m
doppler_km_s:
bias:
tau: 24 h
process_noise: 50.0e-6 # 5 cm/s
light_time_correction: false
measurement_types:
- Range
- Doppler
- range_km
- doppler_km_s
integration_time: 1 min
24 changes: 18 additions & 6 deletions src/od/ground_station/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ impl GroundStation {
let mut measurement_types = IndexSet::new();
measurement_types.insert(MeasurementType::Range);
measurement_types.insert(MeasurementType::Doppler);

let mut stochastics = IndexMap::new();
stochastics.insert(MeasurementType::Range, range_noise_km);
stochastics.insert(MeasurementType::Doppler, doppler_noise_km_s);

Self {
name: "Madrid".to_string(),
elevation_mask_deg: elevation_mask,
Expand All @@ -39,8 +44,7 @@ impl GroundStation {
integration_time: None,
light_time_correction: false,
timestamp_noise_s: None,
range_noise_km: Some(range_noise_km),
doppler_noise_km_s: Some(doppler_noise_km_s),
stochastic_noises: Some(stochastics),
}
}

Expand All @@ -53,6 +57,11 @@ impl GroundStation {
let mut measurement_types = IndexSet::new();
measurement_types.insert(MeasurementType::Range);
measurement_types.insert(MeasurementType::Doppler);

let mut stochastics = IndexMap::new();
stochastics.insert(MeasurementType::Range, range_noise_km);
stochastics.insert(MeasurementType::Doppler, doppler_noise_km_s);

Self {
name: "Canberra".to_string(),
elevation_mask_deg: elevation_mask,
Expand All @@ -64,8 +73,7 @@ impl GroundStation {
integration_time: None,
light_time_correction: false,
timestamp_noise_s: None,
range_noise_km: Some(range_noise_km),
doppler_noise_km_s: Some(doppler_noise_km_s),
stochastic_noises: Some(stochastics),
}
}

Expand All @@ -78,6 +86,11 @@ impl GroundStation {
let mut measurement_types = IndexSet::new();
measurement_types.insert(MeasurementType::Range);
measurement_types.insert(MeasurementType::Doppler);

let mut stochastics = IndexMap::new();
stochastics.insert(MeasurementType::Range, range_noise_km);
stochastics.insert(MeasurementType::Doppler, doppler_noise_km_s);

Self {
name: "Goldstone".to_string(),
elevation_mask_deg: elevation_mask,
Expand All @@ -89,8 +102,7 @@ impl GroundStation {
integration_time: None,
light_time_correction: false,
timestamp_noise_s: None,
range_noise_km: Some(range_noise_km),
doppler_noise_km_s: Some(doppler_noise_km_s),
stochastic_noises: Some(stochastics),
}
}
}
103 changes: 58 additions & 45 deletions src/od/ground_station/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ use anise::astro::{Aberration, AzElRange, PhysicsResult};
use anise::constants::frames::EARTH_J2000;
use anise::errors::AlmanacResult;
use anise::prelude::{Almanac, Frame, Orbit};
use indexmap::IndexSet;
use indexmap::{IndexMap, IndexSet};
use snafu::ensure;

use super::msr::MeasurementType;
use super::noise::StochasticNoise;
use super::{ODAlmanacSnafu, ODError, ODTrajSnafu, TrackingDevice};
use crate::io::ConfigRepr;
use crate::od::NoiseNotConfiguredSnafu;
use crate::time::Epoch;
use hifitime::Duration;
use rand_pcg::Pcg64Mcg;
Expand Down Expand Up @@ -61,10 +63,7 @@ pub struct GroundStation {
pub light_time_correction: bool,
/// Noise on the timestamp of the measurement
pub timestamp_noise_s: Option<StochasticNoise>,
/// Noise on the range data of the measurement
pub range_noise_km: Option<StochasticNoise>,
/// Noise on the Doppler data of the measurement
pub doppler_noise_km_s: Option<StochasticNoise>,
pub stochastic_noises: Option<IndexMap<MeasurementType, StochasticNoise>>,
}

impl GroundStation {
Expand All @@ -88,8 +87,7 @@ impl GroundStation {
integration_time: None,
light_time_correction: false,
timestamp_noise_s: None,
range_noise_km: None,
doppler_noise_km_s: None,
stochastic_noises: None,
}
}

Expand Down Expand Up @@ -132,24 +130,27 @@ impl GroundStation {
let mut noises = vec![0.0; self.measurement_types.len() + 1];

if let Some(rng) = rng {
ensure!(
self.stochastic_noises.is_some(),
NoiseNotConfiguredSnafu {
kind: "ground station stochastics".to_string(),
}
);
// Add the timestamp noise first

if let Some(mut timestamp_noise) = self.timestamp_noise_s {
noises[0] = timestamp_noise.sample(epoch, rng);
}

let stochastics = self.stochastic_noises.as_mut().unwrap();

for (ii, msr_type) in self.measurement_types.iter().enumerate() {
noises[ii + 1] = match msr_type {
MeasurementType::Range => self
.range_noise_km
.ok_or(ODError::NoiseNotConfigured { kind: "Range" })?
.sample(epoch, rng),
MeasurementType::Doppler => self
.doppler_noise_km_s
.ok_or(ODError::NoiseNotConfigured { kind: "Doppler" })?
.sample(epoch, rng),
_ => todo!("az/el"),
};
noises[ii + 1] = stochastics
.get_mut(msr_type)
.ok_or(ODError::NoiseNotConfigured {
kind: format!("{msr_type:?}"),
})?
.sample(epoch, rng);
}
}

Expand All @@ -173,8 +174,7 @@ impl Default for GroundStation {
integration_time: None,
light_time_correction: false,
timestamp_noise_s: None,
range_noise_km: None,
doppler_noise_km_s: None,
stochastic_noises: None,
}
}
}
Expand All @@ -200,7 +200,7 @@ impl fmt::Display for GroundStation {
mod gs_ut {

use anise::constants::frames::IAU_EARTH_FRAME;
use indexmap::IndexSet;
use indexmap::{IndexMap, IndexSet};

use crate::io::ConfigRepr;
use crate::od::prelude::*;
Expand Down Expand Up @@ -232,19 +232,28 @@ mod gs_ut {
measurement_types.insert(MeasurementType::Range);
measurement_types.insert(MeasurementType::Doppler);

let mut stochastics = IndexMap::new();
stochastics.insert(
MeasurementType::Range,
StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-3).unwrap()),
..Default::default()
},
);
stochastics.insert(
MeasurementType::Doppler,
StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-5).unwrap()),
..Default::default()
},
);

let expected_gs = GroundStation {
name: "Demo ground station".to_string(),
frame: IAU_EARTH_FRAME,
measurement_types,
elevation_mask_deg: 5.0,
range_noise_km: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-3).unwrap()),
..Default::default()
}),
doppler_noise_km_s: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-5).unwrap()),
..Default::default()
}),
stochastic_noises: Some(stochastics),
latitude_deg: 2.3522,
longitude_deg: 48.8566,
height_km: 0.4,
Expand All @@ -253,6 +262,8 @@ mod gs_ut {
integration_time: Some(60 * Unit::Second),
};

println!("{}", serde_yml::to_string(&expected_gs).unwrap());

assert_eq!(expected_gs, gs);
}

Expand Down Expand Up @@ -280,20 +291,29 @@ mod gs_ut {
measurement_types.insert(MeasurementType::Range);
measurement_types.insert(MeasurementType::Doppler);

let mut stochastics = IndexMap::new();
stochastics.insert(
MeasurementType::Range,
StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-3).unwrap()),
..Default::default()
},
);
stochastics.insert(
MeasurementType::Doppler,
StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-5).unwrap()),
..Default::default()
},
);

let expected = vec![
GroundStation {
name: "Demo ground station".to_string(),
frame: IAU_EARTH_FRAME.with_mu_km3_s2(398600.435436096),
measurement_types: measurement_types.clone(),
elevation_mask_deg: 5.0,
range_noise_km: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-3).unwrap()),
..Default::default()
}),
doppler_noise_km_s: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-5).unwrap()),
..Default::default()
}),
stochastic_noises: Some(stochastics.clone()),
latitude_deg: 2.3522,
longitude_deg: 48.8566,
height_km: 0.4,
Expand All @@ -306,14 +326,7 @@ mod gs_ut {
frame: IAU_EARTH_FRAME.with_mu_km3_s2(398600.435436096),
measurement_types,
elevation_mask_deg: 5.0,
range_noise_km: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-3).unwrap()),
..Default::default()
}),
doppler_noise_km_s: Some(StochasticNoise {
bias: Some(GaussMarkov::new(1.days(), 5e-5).unwrap()),
..Default::default()
}),
stochastic_noises: Some(stochastics),
latitude_deg: -35.398333,
longitude_deg: 148.981944,
height_km: 0.691750,
Expand Down
19 changes: 8 additions & 11 deletions src/od/ground_station/trk_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,13 @@ impl TrackingDevice<Spacecraft> for GroundStation {
/// a diagonal matrix. The first item in the diagonal is the range noise (in km), set to the square of the steady state sigma. The
/// second item is the Doppler noise (in km/s), set to the square of the steady state sigma of that Gauss Markov process.
fn measurement_covar(&self, msr_type: MeasurementType, epoch: Epoch) -> Result<f64, ODError> {
Ok(match msr_type {
MeasurementType::Range => self
.range_noise_km
.ok_or(ODError::NoiseNotConfigured { kind: "Range" })?
.covariance(epoch),
MeasurementType::Doppler => self
.doppler_noise_km_s
.ok_or(ODError::NoiseNotConfigured { kind: "Doppler" })?
.covariance(epoch),
_ => todo!("az/el"),
})
let stochastics = self.stochastic_noises.as_ref().unwrap();

Ok(stochastics
.get(&msr_type)
.ok_or(ODError::NoiseNotConfigured {
kind: format!("{msr_type:?}"),
})?
.covariance(epoch))
}
}
2 changes: 1 addition & 1 deletion src/od/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ pub enum ODError {
#[snafu(display("Noise matrix is singular"))]
SingularNoiseRk,
#[snafu(display("{kind} noise not configured"))]
NoiseNotConfigured { kind: &'static str },
NoiseNotConfigured { kind: String },
#[snafu(display("measurement sim error: {details}"))]
MeasurementSimError { details: String },
#[snafu(display("during an OD encountered {source}"))]
Expand Down
Loading

0 comments on commit 62b7e78

Please sign in to comment.