Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
helgee committed Dec 9, 2024
1 parent 1c3b1e3 commit e7df574
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 8,087 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/lox-ephem/src/spk/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Spk {
array: &'a SpkType2Array,
initial_epoch: Epoch,
epoch: Epoch,
) -> Result<(&Vec<SpkType2Coefficients>, f64), DafSpkError> {
) -> Result<(&'a Vec<SpkType2Coefficients>, f64), DafSpkError> {
let seconds_from_record_start = epoch - initial_epoch;

let intlen = array.intlen as f64;
Expand Down Expand Up @@ -81,7 +81,7 @@ impl Spk {
&'a self,
epoch: Epoch,
segment: &'a SpkSegment,
) -> Result<(Vec<f64>, &Vec<SpkType2Coefficients>), DafSpkError> {
) -> Result<(Vec<f64>, &'a Vec<SpkType2Coefficients>), DafSpkError> {
let (coefficients, record) = match &segment.data {
super::parser::SpkArray::Type2(array) => {
let (record, fraction) = self.find_record(array, segment.initial_epoch, epoch)?;
Expand Down
1 change: 1 addition & 0 deletions crates/lox-orbits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ thiserror.workspace = true

[dev-dependencies]
pyo3 = { workspace = true, features = ["auto-initialize"] }
rstest.workspace = true

[features]
python = ["dep:pyo3", "dep:numpy", "lox-bodies/python", "lox-time/python"]
3 changes: 1 addition & 2 deletions crates/lox-orbits/src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::f64::consts::PI;
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*/
use lox_bodies::{RotationalElements, Spheroid};
use lox_bodies::{Origin, RotationalElements, Spheroid};
use lox_math::roots::Brent;
use lox_math::series::{Series, SeriesError};
use lox_math::types::units::Radians;
Expand All @@ -21,7 +21,6 @@ use thiserror::Error;
use crate::events::{find_windows, Window};
use crate::frames::{BodyFixed, FrameTransformationProvider, Icrf, Topocentric, TryToFrame};
use crate::ground::GroundLocation;
use crate::origins::{CoordinateOrigin, Origin};
use crate::trajectories::Trajectory;

#[derive(Debug, Clone, Error, PartialEq)]
Expand Down
7 changes: 0 additions & 7 deletions crates/lox-orbits/src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use lox_time::deltas::TimeDelta;
use lox_time::TimeLike;

use crate::frames::{CoordinateSystem, Icrf};
use crate::origins::CoordinateOrigin;
use crate::states::{State, ToCartesian};

pub trait ToKeplerian<T: TimeLike, O: PointMass> {
Expand Down Expand Up @@ -122,12 +121,6 @@ where
}
}

impl<T: TimeLike, O: PointMass + Clone> CoordinateOrigin<O> for Keplerian<T, O> {
fn origin(&self) -> O {
self.origin.clone()
}
}

impl<T: TimeLike, O: PointMass> CoordinateSystem<Icrf> for Keplerian<T, O> {
fn reference_frame(&self) -> Icrf {
Icrf
Expand Down
2 changes: 1 addition & 1 deletion crates/lox-orbits/src/ensembles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
*/

use crate::frames::ReferenceFrame;
use crate::origins::Origin;
use crate::trajectories::Trajectory;
use lox_bodies::Origin;
use lox_time::TimeLike;
use std::collections::HashMap;

Expand Down
157 changes: 155 additions & 2 deletions crates/lox-orbits/src/frames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*/

use std::convert::Infallible;
use std::f64::consts::FRAC_PI_2;
use std::{convert::Infallible, str::FromStr};

use crate::ground::GroundLocation;
use glam::{DMat3, DVec3};
use lox_bodies::{RotationalElements, Spheroid};
use lox_bodies::{DynOrigin, MaybeRotationalElements, Origin, RotationalElements, Spheroid};
use lox_math::types::units::Seconds;
use lox_time::transformations::OffsetProvider;
use thiserror::Error;

use crate::rotations::Rotation;

pub trait ReferenceFrame {
fn name(&self) -> String;
fn abbreviation(&self) -> String;
fn is_rotating(&self) -> bool;
}

pub trait CoordinateSystem<T: ReferenceFrame> {
Expand Down Expand Up @@ -54,6 +56,61 @@ impl ReferenceFrame for Icrf {
fn abbreviation(&self) -> String {
"ICRF".to_string()
}

fn is_rotating(&self) -> bool {
false
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub struct Cirf;

impl ReferenceFrame for Cirf {
fn name(&self) -> String {
"Celestial Intermediate Reference Frame".to_string()
}

fn abbreviation(&self) -> String {
"CIRF".to_string()
}

fn is_rotating(&self) -> bool {
false
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub struct Tirf;

impl ReferenceFrame for Tirf {
fn name(&self) -> String {
"Terrestrial Intermediate Reference Frame".to_string()
}

fn abbreviation(&self) -> String {
"TIRF".to_string()
}

fn is_rotating(&self) -> bool {
true
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub struct Itrf;

impl ReferenceFrame for Itrf {
fn name(&self) -> String {
"International Terrestrial Reference Frame".to_string()
}

fn abbreviation(&self) -> String {
"ITRF".to_string()
}

fn is_rotating(&self) -> bool {
true
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
Expand Down Expand Up @@ -86,6 +143,10 @@ impl<T: RotationalElements> ReferenceFrame for BodyFixed<T> {
let body = self.0.name().replace([' ', '-'], "_").to_uppercase();
format!("IAU_{}", body)
}

fn is_rotating(&self) -> bool {
true
}
}

#[derive(Clone, Debug)]
Expand All @@ -108,12 +169,94 @@ impl<B: Spheroid> Topocentric<B> {
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DynFrame {
Icrf,
Cirf,
Tirf,
Itrf,
BodyFixed(DynOrigin),
}

impl ReferenceFrame for DynFrame {
fn name(&self) -> String {
match self {
DynFrame::Icrf => Icrf.name(),
DynFrame::Cirf => Cirf.name(),
DynFrame::Tirf => Tirf.name(),
DynFrame::Itrf => Itrf.name(),
DynFrame::BodyFixed(dyn_origin) => {
let body = dyn_origin.name();
match body {
"Sun" | "Moon" => format!("IAU Body-Fixed Reference Frame for the {}", body),
_ => format!("IAU Body-Fixed Reference Frame for {}", body),
}
}
}
}

fn abbreviation(&self) -> String {
match self {
DynFrame::Icrf => Icrf.abbreviation(),
DynFrame::Cirf => Cirf.abbreviation(),
DynFrame::Tirf => Tirf.abbreviation(),
DynFrame::Itrf => Itrf.abbreviation(),
DynFrame::BodyFixed(dyn_origin) => {
let body = dyn_origin.name().replace([' ', '-'], "_").to_uppercase();
format!("IAU_{}", body)
}
}
}

fn is_rotating(&self) -> bool {
match self {
DynFrame::Icrf | DynFrame::Cirf => false,
DynFrame::Tirf | DynFrame::Itrf | DynFrame::BodyFixed(_) => true,
}
}
}

fn parse_iau_frame(s: &str) -> Option<DynFrame> {
let (prefix, origin) = s.split_once("_")?;
if prefix.to_lowercase() != "iau" {
return None;
}
let origin: DynOrigin = origin.parse().ok()?;
let _ = origin.maybe_rotational_elements(0.0)?;
Some(DynFrame::BodyFixed(origin))
}

#[derive(Clone, Debug, Error, PartialEq, Eq)]
#[error("no frame with name '{0}' is known")]
pub struct UnknownFrameError(String);

impl FromStr for DynFrame {
type Err = UnknownFrameError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"icrf" | "ICRF" => Ok(DynFrame::Icrf),
"cirf" | "CIRF" => Ok(DynFrame::Cirf),
"tirf" | "TIRF" => Ok(DynFrame::Tirf),
"itrf" | "ITRF" => Ok(DynFrame::Itrf),
_ => {
if let Some(frame) = parse_iau_frame(s) {
Ok(frame)
} else {
Err(UnknownFrameError(s.to_owned()))
}
}
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use lox_bodies::Earth;
use lox_math::assert_close;
use lox_math::is_close::IsClose;
use rstest::rstest;

#[test]
fn test_topocentric() {
Expand All @@ -134,4 +277,14 @@ mod tests {
assert_close!(r.y_axis, y_axis);
assert_close!(r.z_axis, z_axis);
}

#[rstest]
#[case("IAU_EARTH", Some(DynFrame::BodyFixed(DynOrigin::Earth)))]
#[case("FOO_EARTH", None)]
#[case("IAU_RUPERT", None)]
#[case("IAU_SYCORAX", None)]
fn test_parse_iau_frame(#[case] name: &str, #[case] exp: Option<DynFrame>) {
let act = parse_iau_frame(name);
assert_eq!(act, exp)
}
}
17 changes: 0 additions & 17 deletions crates/lox-orbits/src/ground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use lox_time::transformations::TryToScale;
use lox_time::TimeLike;

use crate::frames::{BodyFixed, CoordinateSystem, FrameTransformationProvider, Icrf, TryToFrame};
use crate::origins::CoordinateOrigin;
use crate::propagators::Propagator;
use crate::states::State;
use crate::trajectories::TrajectoryError;
Expand Down Expand Up @@ -136,12 +135,6 @@ impl<B: Spheroid> GroundLocation<B> {
}
}

impl<O: Spheroid + Clone> CoordinateOrigin<O> for GroundLocation<O> {
fn origin(&self) -> O {
self.body.clone()
}
}

#[derive(Debug, Error)]
pub enum GroundPropagatorError {
#[error("frame transformation error: {0}")]
Expand All @@ -166,16 +159,6 @@ where
}
}

impl<O, P> CoordinateOrigin<O> for GroundPropagator<O, P>
where
O: Spheroid + Clone,
P: FrameTransformationProvider,
{
fn origin(&self) -> O {
self.location.body.clone()
}
}

impl<O, P> CoordinateSystem<Icrf> for GroundPropagator<O, P>
where
O: Spheroid,
Expand Down
1 change: 0 additions & 1 deletion crates/lox-orbits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ pub mod ensembles;
pub mod events;
pub mod frames;
pub mod ground;
pub mod origins;
pub mod propagators;
#[cfg(feature = "python")]
pub mod python;
Expand Down
9 changes: 0 additions & 9 deletions crates/lox-orbits/src/origins.rs

This file was deleted.

3 changes: 2 additions & 1 deletion crates/lox-orbits/src/propagators.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use lox_bodies::Origin;
use lox_time::TimeLike;

use crate::trajectories::TrajectoryError;
use crate::{frames::ReferenceFrame, origins::Origin, states::State, trajectories::Trajectory};
use crate::{frames::ReferenceFrame, states::State, trajectories::Trajectory};

pub mod semi_analytical;
pub mod sgp4;
Expand Down
11 changes: 0 additions & 11 deletions crates/lox-orbits/src/propagators/semi_analytical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use lox_bodies::PointMass;
use lox_time::TimeLike;

use crate::frames::{CoordinateSystem, Icrf};
use crate::origins::CoordinateOrigin;
use crate::propagators::{stumpff, Propagator};
use crate::states::State;
use crate::trajectories::TrajectoryError;
Expand All @@ -31,16 +30,6 @@ pub struct Vallado<T: TimeLike, O: PointMass> {
max_iter: i32,
}

impl<T, O> CoordinateOrigin<O> for Vallado<T, O>
where
T: TimeLike,
O: PointMass + Clone,
{
fn origin(&self) -> O {
self.initial_state.origin()
}
}

impl<T, O> CoordinateSystem<Icrf> for Vallado<T, O>
where
T: TimeLike,
Expand Down
Loading

0 comments on commit e7df574

Please sign in to comment.