use super::thrustctrl::ThrustControl;
use crate::dimensions::Vector3;
use celestia::State;
#[derive(Copy, Clone, Debug)]
pub struct Thruster {
pub thrust: f64,
pub isp: f64,
}
const NORM_ERR: f64 = 1e-12;
const STD_GRAVITY: f64 = 9.80665;
pub struct Propulsion {
pub thrusters: Vec<Thruster>,
pub decrement_mass: bool,
pub ctrl: Box<dyn ThrustControl>,
}
impl Propulsion {
pub fn new(
ctrl: Box<dyn ThrustControl>,
thrusters: Vec<Thruster>,
decrement_mass: bool,
) -> Self {
Self {
thrusters,
decrement_mass,
ctrl,
}
}
pub fn set_state(&mut self, new_orbit: &State) {
(*self.ctrl).next(new_orbit);
}
pub fn eom(&self, osc: &State) -> (Vector3<f64>, f64) {
let thrust_power = self.ctrl.throttle(osc);
if thrust_power > 0.0 {
let thrust_inertial = self.ctrl.direction(osc);
if (thrust_inertial.norm() - 1.0).abs() > NORM_ERR {
panic!(
"thrust orientation is not a unit vector: norm = {}\n{}",
thrust_inertial.norm(),
thrust_inertial
);
}
let mut total_thrust = 0.0;
let mut fuel_usage = 0.0;
for thruster in &self.thrusters {
total_thrust += thrust_power * thruster.thrust;
fuel_usage += thrust_power * thruster.thrust / (thruster.isp * STD_GRAVITY);
}
total_thrust *= 1e-3; (
thrust_inertial * total_thrust,
if self.decrement_mass {
-fuel_usage
} else {
0.0
},
)
} else {
(Vector3::zeros(), 0.0)
}
}
}