nyx_space/od/msr/
range.rsuse crate::cosmic::Orbit;
use crate::linalg::{DimName, Matrix1x6, OVector, Vector1, U1, U6, U7};
use crate::od::Measurement;
use crate::time::Epoch;
use crate::TimeTagged;
use arrow::datatypes::{DataType, Field};
use hyperdual::linalg::norm;
use hyperdual::{hyperspace_from_vector, OHyperdual};
use serde::ser::SerializeSeq;
use serde::{Serialize, Serializer};
use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct RangeMsr {
pub dt: Epoch,
pub obs: Vector1<f64>,
visible: bool,
h_tilde: Matrix1x6<f64>,
}
impl RangeMsr {
pub fn range(&self) -> f64 {
self.obs[(0, 0)]
}
fn compute_sensitivity(
state: &OVector<OHyperdual<f64, U7>, U6>,
) -> (Vector1<f64>, Matrix1x6<f64>) {
let range_vec = state.fixed_rows::<3>(0).into_owned();
let range = norm(&range_vec);
let fx = Vector1::new(range.real());
let mut pmat = Matrix1x6::zeros();
for j in 1..U7::dim() {
pmat[j - 1] = range[j];
}
(fx, pmat)
}
pub fn new(tx: Orbit, rx: Orbit, visible: bool) -> RangeMsr {
assert_eq!(tx.frame, rx.frame, "tx and rx in different frames");
assert_eq!(tx.epoch, rx.epoch, "tx and rx states have different times");
let dt = tx.epoch;
let hyperstate =
hyperspace_from_vector(&(rx.to_cartesian_pos_vel() - tx.to_cartesian_pos_vel()));
let (obs, h_tilde) = Self::compute_sensitivity(&hyperstate);
RangeMsr {
dt,
obs,
visible,
h_tilde,
}
}
}
impl Measurement for RangeMsr {
type MeasurementSize = U1;
fn observation(&self) -> Vector1<f64> {
self.obs
}
fn fields() -> Vec<Field> {
let mut meta = HashMap::new();
meta.insert("unit".to_string(), "km".to_string());
vec![Field::new("Range (km)", DataType::Float64, false).with_metadata(meta)]
}
fn from_observation(epoch: Epoch, obs: OVector<f64, Self::MeasurementSize>) -> Self {
Self {
dt: epoch,
obs,
visible: true,
h_tilde: Matrix1x6::zeros(),
}
}
}
impl TimeTagged for RangeMsr {
fn epoch(&self) -> Epoch {
self.dt
}
fn set_epoch(&mut self, dt: Epoch) {
self.dt = dt
}
}
impl Serialize for RangeMsr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(3))?;
seq.serialize_element(&self.dt.to_mjd_tai_days())?;
let obs = self.observation();
seq.serialize_element(&obs[(0, 0)])?;
seq.end()
}
}