pub(crate) mod spline;
mod traj;
mod traj_it;
pub(crate) use traj::interpolate;
pub use traj::Traj;
use super::StateParameter;
use crate::linalg::allocator::Allocator;
use crate::linalg::DefaultAllocator;
use crate::time::{Duration, Epoch};
use crate::{NyxError, Orbit, Spacecraft, State};
use std::error::Error;
use std::fmt;
#[derive(Clone, PartialEq, Debug)]
pub enum TrajError {
EventNotFound {
start: Epoch,
end: Epoch,
event: String,
},
NoInterpolationData(Epoch),
CreationError(String),
OutOfSpline {
req_epoch: Epoch,
req_dur: Duration,
spline_dur: Duration,
},
}
impl fmt::Display for TrajError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::EventNotFound { start, end, event } => {
write!(f, "Event {} not found between {} and {}", event, start, end)
}
Self::CreationError(reason) => write!(f, "Failed to create trajectory: {}", reason),
Self::NoInterpolationData(e) => write!(f, "No interpolation data at {}", e),
Self::OutOfSpline {
req_epoch,
req_dur,
spline_dur,
} => {
write!(f, "Probable bug: Requested epoch {}, corresponding to an offset of {} in a spline of duration {}", req_epoch, req_dur, spline_dur)
}
}
}
}
impl Error for TrajError {}
pub trait InterpState: State
where
Self: Sized,
DefaultAllocator: Allocator<f64, Self::Size>
+ Allocator<f64, Self::Size, Self::Size>
+ Allocator<f64, Self::VecLength>,
{
fn params() -> Vec<StateParameter>;
fn value_and_deriv(&self, param: &StateParameter) -> Result<(f64, f64), NyxError> {
Ok((self.value(param)?, self.deriv(param)?))
}
fn deriv(&self, param: &StateParameter) -> Result<f64, NyxError> {
Ok(self.value_and_deriv(param)?.1)
}
fn set_value_and_deriv(
&mut self,
param: &StateParameter,
value: f64,
value_dt: f64,
) -> Result<(), NyxError>;
}
impl InterpState for Orbit {
fn params() -> Vec<StateParameter> {
vec![
StateParameter::X,
StateParameter::Y,
StateParameter::Z,
StateParameter::VX,
StateParameter::VY,
StateParameter::VZ,
]
}
fn value_and_deriv(&self, param: &StateParameter) -> Result<(f64, f64), NyxError> {
match *param {
StateParameter::X => Ok((self.x, self.vx)),
StateParameter::Y => Ok((self.y, self.vy)),
StateParameter::Z => Ok((self.z, self.vz)),
StateParameter::VX => Ok((self.vx, 0.0)),
StateParameter::VY => Ok((self.vy, 0.0)),
StateParameter::VZ => Ok((self.vz, 0.0)),
_ => Err(NyxError::StateParameterUnavailable),
}
}
fn set_value_and_deriv(
&mut self,
param: &StateParameter,
value: f64,
_: f64,
) -> Result<(), NyxError> {
match *param {
StateParameter::X => {
self.x = value;
}
StateParameter::Y => {
self.y = value;
}
StateParameter::Z => {
self.z = value;
}
StateParameter::VX => {
self.vx = value;
}
StateParameter::VY => {
self.vy = value;
}
StateParameter::VZ => {
self.vz = value;
}
_ => return Err(NyxError::StateParameterUnavailable),
}
Ok(())
}
}
impl InterpState for Spacecraft {
fn params() -> Vec<StateParameter> {
vec![
StateParameter::X,
StateParameter::Y,
StateParameter::Z,
StateParameter::VX,
StateParameter::VY,
StateParameter::VZ,
StateParameter::FuelMass,
]
}
fn value_and_deriv(&self, param: &StateParameter) -> Result<(f64, f64), NyxError> {
match *param {
StateParameter::X => Ok((self.orbit.x, self.orbit.vx)),
StateParameter::Y => Ok((self.orbit.y, self.orbit.vy)),
StateParameter::Z => Ok((self.orbit.z, self.orbit.vz)),
StateParameter::VX => Ok((self.orbit.vx, 0.0)),
StateParameter::VY => Ok((self.orbit.vy, 0.0)),
StateParameter::VZ => Ok((self.orbit.vz, 0.0)),
StateParameter::FuelMass => Ok((self.fuel_mass_kg, 0.0)),
_ => Err(NyxError::StateParameterUnavailable),
}
}
fn set_value_and_deriv(
&mut self,
param: &StateParameter,
value: f64,
_: f64,
) -> Result<(), NyxError> {
match *param {
StateParameter::X => {
self.orbit.x = value;
}
StateParameter::Y => {
self.orbit.y = value;
}
StateParameter::Z => {
self.orbit.z = value;
}
StateParameter::VX => {
self.orbit.vx = value;
}
StateParameter::VY => {
self.orbit.vy = value;
}
StateParameter::VZ => {
self.orbit.vz = value;
}
StateParameter::Cr => self.cr = value,
StateParameter::Cd => self.cd = value,
StateParameter::FuelMass => self.fuel_mass_kg = value,
_ => return Err(NyxError::StateParameterUnavailable),
}
Ok(())
}
}