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

Fix SV_Elev plotting in coherent OBS/NAV/SP3 rinex scenarios #225

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 53 additions & 6 deletions rinex-cli/src/graph/record/observation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ pub fn plot_observations(ctx: &Context, plot_context: &mut PlotContext, csv_expo

let markers = generate_markers(carriers.len()); // one symbol per carrier
for (index, (observable, vehicles)) in carriers.iter().enumerate() {
for (sv, data) in vehicles {
for (sv_index, (sv, data)) in vehicles.iter().enumerate() {
let data_x: Vec<Epoch> = data.iter().map(|(_cs, e, _y)| *e).collect();
let data_y: Vec<f64> = data.iter().map(|(_cs, _e, y)| *y).collect();

Expand All @@ -150,9 +150,8 @@ pub fn plot_observations(ctx: &Context, plot_context: &mut PlotContext, csv_expo
data_y.clone(),
)
.marker(Marker::new().symbol(markers[index].clone()))
//.web_gl_mode(true)
.visible({
if index < 1 {
if sv_index == 0 {
Visible::True
} else {
Visible::LegendOnly
Expand All @@ -177,29 +176,77 @@ pub fn plot_observations(ctx: &Context, plot_context: &mut PlotContext, csv_expo

if index == 0 && physics == "Signal Strength" {
// Draw SV elevation along SSI plot if that is feasible
if let Some(nav) = ctx.data.brdc_navigation() {
// determine SV state
let rx_ecef = ctx.rx_ecef.unwrap();
let data = data_x
.iter()
.filter_map(|t| {
nav.sv_position_interpolate(*sv, *t, 5)
.map(|(x_km, y_km, z_km)| {
(
*t,
Ephemeris::elevation_azimuth(
(x_km * 1.0E3, y_km * 1.0E3, z_km * 1.0E3),
rx_ecef,
)
.0,
)
})
})
.collect::<Vec<_>>();
// plot
let data_x = data.iter().map(|(x, _)| *x).collect::<Vec<_>>();
let data_y = data.iter().map(|(_, y)| *y).collect::<Vec<_>>();
let trace = build_chart_epoch_axis(
&format!("BRDC_Elev({:X})", sv),
Mode::Markers,
data_x,
data_y,
)
.y_axis("y2")
.marker(Marker::new().symbol(markers[index].clone()))
.visible({
if sv_index == 0 && index == 0 {
Visible::True
} else {
Visible::LegendOnly
}
});
plot_context.add_trace(trace);
}
if let Some(sp3) = ctx.data.sp3() {
// determine SV state
let rx_ecef = ctx.rx_ecef.unwrap();
let data = data_x
.iter()
.filter_map(|t| {
sp3.sv_position_interpolate(*sv, *t, 5)
.map(|pos| (*t, Ephemeris::elevation_azimuth(pos, rx_ecef).0))
.map(|(x_km, y_km, z_km)| {
(
*t,
Ephemeris::elevation_azimuth(
(x_km * 1.0E3, y_km * 1.0E3, z_km * 1.0E3),
rx_ecef,
)
.0,
)
})
})
.collect::<Vec<_>>();
// plot
let data_x = data.iter().map(|(x, _)| *x).collect::<Vec<_>>();
let data_y = data.iter().map(|(_, y)| *y).collect::<Vec<_>>();
let trace = build_chart_epoch_axis(
&format!("Elev({:X})", sv),
&format!("SP3_Elev({:X})", sv),
Mode::Markers,
data_x,
data_y,
)
.y_axis("y2")
.marker(Marker::new().symbol(markers[index].clone()))
.visible({
if index < 1 {
if sv_index == 0 && index == 0 {
Visible::True
} else {
Visible::LegendOnly
Expand Down
5 changes: 3 additions & 2 deletions rinex/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2318,8 +2318,9 @@ impl Rinex {
}))
}
/// Interpolates SV position, expressed in meters ECEF at desired Epoch `t`.
/// An interpolation order of at least 7 is recommended.
/// Operation is not feasible if sampling interval cannot be determined.
/// An interpolation order between 4 and 8 is recommended, depending on the
/// precision you are targetting. Higher orders do not make sense considering the
/// noise on broadcasted (real time) positions.
/// In ideal scenarios, Broadcast Ephemeris are complete and evenly spaced in time:
/// - the first Epoch we an interpolate is ](N +1)/2 * τ; ...]
/// - the last Epoch we an interpolate is [..; T - (N +1)/2 * τ]
Expand Down
Loading