use super::hyperdual::Hyperdual;
use super::{AutoDiff, Epoch, ForceModel};
use crate::dimensions::{Matrix3, Vector3, U3, U7};
use celestia::{Cosm, Frame, State};
#[derive(Clone)]
pub struct ConstantDrag<'a> {
pub sc_area: f64,
pub cd: f64,
pub rho: f64,
pub drag_frame_id: i32,
pub cosm: &'a Cosm,
}
impl<'a> ForceModel for ConstantDrag<'a> {
fn eom(&self, osc: &State) -> Vector3<f64> {
let osc = self.cosm.frame_chg_by_id(&osc, self.drag_frame_id);
let velocity = osc.velocity();
-0.5 * self.rho * self.cd * self.sc_area * velocity.norm() * velocity
}
}
impl<'a> AutoDiff for ConstantDrag<'a> {
type HyperStateSize = U7;
type STMSize = U3;
fn dual_eom(
&self,
_: Epoch,
_: Frame,
_: &Vector3<Hyperdual<f64, U7>>,
) -> (Vector3<f64>, Matrix3<f64>) {
unimplemented!("drag models not differentiable yet");
}
}
#[derive(Clone)]
pub struct ExpEarthDrag<'a> {
pub sc_area: f64,
pub cd: f64,
pub cosm: &'a Cosm,
}
impl<'a> ForceModel for ExpEarthDrag<'a> {
fn eom(&self, osc: &State) -> Vector3<f64> {
let eme2k = self.cosm.frame("EME2000");
let rho0 = 3.614e-13; let r0 = 700_000.0 + eme2k.equatorial_radius();
let h = 88_667.0; let rho = rho0 * (-(osc.rmag() - r0) / h).exp();
let osc = self.cosm.frame_chg(&osc, eme2k);
let earth_rot = 7.292_115_855_3e-5;
let velocity = osc.velocity() - Vector3::new(earth_rot * osc.y, -earth_rot * osc.x, 0.0);
-0.5 * rho * self.cd * self.sc_area * velocity.norm() * velocity
}
}
impl<'a> AutoDiff for ExpEarthDrag<'a> {
type HyperStateSize = U7;
type STMSize = U3;
fn dual_eom(
&self,
_: Epoch,
_: Frame,
_: &Vector3<Hyperdual<f64, U7>>,
) -> (Vector3<f64>, Matrix3<f64>) {
unimplemented!("drag models not differentiable yet");
}
}