Skip to main content

nyx_space/od/position/
sensitivity.rs

1use crate::linalg::DefaultAllocator;
2use crate::linalg::allocator::Allocator;
3use crate::od::ODError;
4use crate::{Spacecraft, State};
5use anise::prelude::Almanac;
6use indexmap::IndexSet;
7use nalgebra::{DimName, OMatrix, U1};
8use std::marker::PhantomData;
9
10use super::PositionDevice;
11use crate::od::msr::MeasurementType;
12use crate::od::msr::measurement::Measurement;
13use crate::od::msr::sensitivity::{ScalarSensitivity, ScalarSensitivityT, TrackerSensitivity};
14
15impl TrackerSensitivity<Spacecraft, Spacecraft> for PositionDevice
16where
17    DefaultAllocator: Allocator<<Spacecraft as State>::Size>
18        + Allocator<<Spacecraft as State>::VecLength>
19        + Allocator<<Spacecraft as State>::Size, <Spacecraft as State>::Size>,
20{
21    fn h_tilde<M: DimName>(
22        &self,
23        msr: &Measurement,
24        msr_types: &IndexSet<MeasurementType>,
25        rx: &Spacecraft,
26        almanac: &Almanac,
27    ) -> Result<OMatrix<f64, M, <Spacecraft as State>::Size>, ODError>
28    where
29        DefaultAllocator: Allocator<M> + Allocator<M, <Spacecraft as State>::Size>,
30    {
31        // Rebuild each row of the scalar sensitivities.
32        let mut mat = OMatrix::<f64, M, <Spacecraft as State>::Size>::zeros();
33        for (ith_row, msr_type) in msr_types.iter().enumerate() {
34            if !msr.data.contains_key(msr_type) {
35                // Skip computation, this row is zero anyway.
36                continue;
37            }
38            let scalar_h =
39                <ScalarSensitivity<Spacecraft, Spacecraft, PositionDevice> as ScalarSensitivityT<
40                    Spacecraft,
41                    Spacecraft,
42                    PositionDevice,
43                >>::new(*msr_type, msr, rx, self, almanac)?;
44
45            mat.set_row(ith_row, &scalar_h.sensitivity_row);
46        }
47        Ok(mat)
48    }
49}
50
51impl ScalarSensitivityT<Spacecraft, Spacecraft, PositionDevice>
52    for ScalarSensitivity<Spacecraft, Spacecraft, PositionDevice>
53{
54    fn new(
55        msr_type: MeasurementType,
56        _msr: &Measurement,
57        _rx: &Spacecraft,
58        _tx: &PositionDevice,
59        _almanac: &Almanac,
60    ) -> Result<Self, ODError> {
61        let idx = match msr_type {
62            MeasurementType::X => 0,
63            MeasurementType::Y => 1,
64            MeasurementType::Z => 2,
65            _ => {
66                return Err(ODError::MeasurementSimError {
67                    details: format!("{msr_type:?} is not supported by XyzDevice"),
68                });
69            }
70        };
71
72        let mut sensitivity_row = OMatrix::<f64, U1, <Spacecraft as State>::Size>::zeros();
73        sensitivity_row[(0, idx)] = 1.0;
74
75        Ok(Self {
76            sensitivity_row,
77            _rx: PhantomData::<_>,
78            _tx: PhantomData::<_>,
79        })
80    }
81}