Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Time #56

Merged
merged 14 commits into from
Feb 11, 2024
2 changes: 1 addition & 1 deletion crates/lox-space/examples/iss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use lox_space::prelude::*;
fn main() {
let date = Date::new(2016, 5, 30).unwrap();
let utc = UTC::new(12, 0, 0).unwrap();
let time = Time::from_date_and_utc_timestamp(TimeScale::TDB, date, utc);
let time = Time::from_date_and_utc_timestamp(TDB, date, utc);
let position = DVec3::new(6068.27927, -1692.84394, -2516.61918);
let velocity = DVec3::new(-0.660415582, 5.495938726, -5.303093233);
let iss_cartesian = Cartesian::new(time, Earth, Icrf, position, velocity);
Expand Down
52 changes: 8 additions & 44 deletions crates/lox_core/src/coords/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,21 @@ use float_eq::float_eq;
use glam::{DMat3, DVec3};

use crate::math::{mod_two_pi, normalize_two_pi};
use crate::time::continuous::Time;

pub trait TwoBodyState {
fn time(&self) -> Time;
fn to_cartesian_state(&self, grav_param: f64) -> CartesianState;
fn to_keplerian_state(&self, grav_param: f64) -> KeplerianState;
}

#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CartesianState {
time: Time,
position: DVec3,
velocity: DVec3,
}

impl CartesianState {
pub fn new(time: Time, position: DVec3, velocity: DVec3) -> Self {
Self {
time,
position,
velocity,
}
pub fn new(position: DVec3, velocity: DVec3) -> Self {
Self { position, velocity }
}

pub fn position(&self) -> DVec3 {
Expand All @@ -44,10 +37,6 @@ impl CartesianState {
}

impl TwoBodyState for CartesianState {
fn time(&self) -> Time {
self.time
}

fn to_cartesian_state(&self, _grav_param: f64) -> CartesianState {
*self
}
Expand Down Expand Up @@ -107,7 +96,6 @@ impl TwoBodyState for CartesianState {
}

KeplerianState::new(
self.time,
semi_major,
eccentricity,
inclination,
Expand All @@ -118,9 +106,8 @@ impl TwoBodyState for CartesianState {
}
}

#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct KeplerianState {
time: Time,
semi_major: f64,
eccentricity: f64,
inclination: f64,
Expand All @@ -131,7 +118,6 @@ pub struct KeplerianState {

impl KeplerianState {
pub fn new(
time: Time,
semi_major: f64,
eccentricity: f64,
inclination: f64,
Expand All @@ -140,7 +126,6 @@ impl KeplerianState {
true_anomaly: f64,
) -> Self {
Self {
time,
semi_major,
eccentricity,
inclination,
Expand Down Expand Up @@ -196,16 +181,12 @@ impl KeplerianState {
}

impl TwoBodyState for KeplerianState {
fn time(&self) -> Time {
self.time
}

fn to_cartesian_state(&self, grav_param: f64) -> CartesianState {
let (pos, vel) = self.to_perifocal(grav_param);
let rot = DMat3::from_rotation_z(self.ascending_node)
* DMat3::from_rotation_x(self.inclination)
* DMat3::from_rotation_z(self.periapsis_argument);
CartesianState::new(self.time, rot * pos, rot * vel)
CartesianState::new(rot * pos, rot * vel)
}

fn to_keplerian_state(&self, _grav_param: f64) -> KeplerianState {
Expand Down Expand Up @@ -235,13 +216,11 @@ mod tests {
use glam::DVec3;

use crate::bodies::{Earth, PointMass};
use crate::time::continuous::TimeScale;

use super::*;

#[test]
fn test_elliptic() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.9860047e14;
let semi_major = 24464560.0;
let eccentricity = 0.7311;
Expand All @@ -260,11 +239,10 @@ mod tests {
-0.118801577532701e4,
);

let cartesian = CartesianState::new(time, pos, vel);
let cartesian = CartesianState::new(pos, vel);
assert_eq!(cartesian.to_cartesian_state(grav_param), cartesian);

let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand All @@ -277,9 +255,6 @@ mod tests {
let cartesian1 = keplerian.to_cartesian_state(grav_param);
let keplerian1 = cartesian.to_keplerian_state(grav_param);

assert_eq!(cartesian1.time(), time);
assert_eq!(keplerian1.time(), time);

assert_float_eq!(pos.x, cartesian1.position.x, rel <= 1e-8);
assert_float_eq!(pos.y, cartesian1.position.y, rel <= 1e-8);
assert_float_eq!(pos.z, cartesian1.position.z, rel <= 1e-8);
Expand All @@ -297,7 +272,6 @@ mod tests {

#[test]
fn test_circular() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.986004418e14;
let semi_major = 6778136.6;
let eccentricity = 0.0;
Expand All @@ -307,9 +281,8 @@ mod tests {
let true_anomaly = 30f64.to_radians();
let pos = DVec3::new(4396398.60746266, 5083838.45333733, 877155.42119322);
let vel = DVec3::new(-5797.06004014, 4716.60916063, 1718.86034246);
let cartesian = CartesianState::new(time, pos, vel);
let cartesian = CartesianState::new(pos, vel);
let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand Down Expand Up @@ -338,7 +311,6 @@ mod tests {

#[test]
fn test_circular_orekit() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.9860047e14;
let semi_major = 24464560.0;
let eccentricity = 0.0;
Expand All @@ -347,7 +319,6 @@ mod tests {
let periapsis_arg = 0.0;
let true_anomaly = 0.048363;
let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand All @@ -370,7 +341,6 @@ mod tests {

#[test]
fn test_hyperbolic_orekit() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.9860047e14;
let semi_major = -24464560.0;
let eccentricity = 1.7311;
Expand All @@ -379,7 +349,6 @@ mod tests {
let periapsis_arg = 3.10686;
let true_anomaly = 0.12741601769795755;
let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand All @@ -402,7 +371,6 @@ mod tests {

#[test]
fn test_equatorial() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.9860047e14;
let semi_major = 24464560.0;
let eccentricity = 0.7311;
Expand All @@ -411,7 +379,6 @@ mod tests {
let periapsis_arg = 3.10686;
let true_anomaly = 0.44369564302687126;
let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand All @@ -434,7 +401,6 @@ mod tests {

#[test]
fn test_circular_equatorial() {
let time = Time::j2000(TimeScale::TDB);
let grav_param = 3.9860047e14;
let semi_major = 24464560.0;
let eccentricity = 0.0;
Expand All @@ -443,7 +409,6 @@ mod tests {
let periapsis_arg = 0.0;
let true_anomaly = 0.44369564302687126;
let keplerian = KeplerianState::new(
time,
semi_major,
eccentricity,
inclination,
Expand All @@ -466,11 +431,10 @@ mod tests {

#[test]
fn test_iss() {
let time = Time::j2000(TimeScale::TDB);
let position = DVec3::new(6068.27927, -1692.84394, -2516.61918);
let velocity = DVec3::new(-0.660415582, 5.495938726, -5.303093233);
let grav_param = Earth.gravitational_parameter();
let cartesian = CartesianState::new(time, position, velocity);
let cartesian = CartesianState::new(position, velocity);
let cartesian1 = cartesian
.to_keplerian_state(grav_param)
.to_cartesian_state(grav_param);
Expand Down
Loading
Loading