Skip to content

Commit

Permalink
refactor(object): simplify Object struct and delegate fields to Elements
Browse files Browse the repository at this point in the history
- Remove redundant fields from Object struct
- Delegate most fields to sgp4::Elements
- Update ObjectInformation and WorldMap widgets to use new structure
- Add orbital_period and elements methods to Object
  • Loading branch information
ShenMian committed Jan 16, 2025
1 parent c5723a1 commit 9b180d4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 110 deletions.
104 changes: 12 additions & 92 deletions src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,117 +4,37 @@ use chrono::{DateTime, Datelike, Timelike, Utc};

#[derive(Clone, Debug)]
pub struct Object {
/// The name of the object.
name: Option<String>,
/// The COSPAR ID of the object.
cospar_id: Option<String>,
/// The NORAD ID of the object.
norad_id: u64,

epoch: DateTime<Utc>,

/// Radiation pressure coefficient in earth radii⁻¹.
drag_term: f64,
/// Angle between the equator and the orbit plane in deg.
inclination: f64,
/// Angle between vernal equinox and the point where the orbit crosses the equatorial plane in deg.
right_ascension: f64,
/// The shape of the orbit.
eccentricity: f64,
/// Angle between the ascending node and the orbit's point of closest approach to the earth in deg.
argument_of_perigee: f64,
/// Angle of the satellite location measured from perigee in deg.
mean_anomaly: f64,
/// Mean number of orbits per day in day⁻¹ (Kozai convention).
mean_motion: f64,
/// The orbit number at epoch.
revolution_number: u64,

orbital_period: chrono::Duration,
elements: sgp4::Elements,
constants: sgp4::Constants,
}

impl Object {
pub fn from_elements(elements: sgp4::Elements) -> Self {
const SECONDS_PER_DAY: f64 = 24.0 * 60.0 * 60.0;
let orbital_period =
chrono::Duration::seconds((SECONDS_PER_DAY / elements.mean_motion) as i64);

Self {
name: elements.object_name.clone(),
cospar_id: elements.international_designator.clone(),
norad_id: elements.norad_id,
epoch: DateTime::from_naive_utc_and_offset(elements.datetime, Utc),
drag_term: elements.drag_term,
inclination: elements.inclination,
right_ascension: elements.right_ascension,
eccentricity: elements.eccentricity,
argument_of_perigee: elements.argument_of_perigee,
mean_anomaly: elements.mean_anomaly,
mean_motion: elements.mean_motion,
revolution_number: elements.revolution_number,
orbital_period,
constants: sgp4::Constants::from_elements(&elements).unwrap(),
elements,
}
}

/// The name of the object.
pub fn name(&self) -> Option<&String> {
self.name.as_ref()
}

/// The COSPAR ID of the object.
pub fn cospar_id(&self) -> Option<&String> {
self.cospar_id.as_ref()
}

/// The COSPAR ID of the object.
pub fn norad_id(&self) -> u64 {
self.norad_id
}

/// The UTC timestamp of the elements
pub fn epoch(&self) -> DateTime<Utc> {
self.epoch
}

/// Radiation pressure coefficient in earth radii⁻¹
pub fn drag_term(&self) -> f64 {
self.drag_term
}

/// Angle between the equator and the orbit plane in deg
pub fn inclination(&self) -> f64 {
self.inclination
pub fn orbital_period(&self) -> &chrono::Duration {
&self.orbital_period
}

/// Angle between vernal equinox and the point where the orbit crosses the equatorial plane in deg
pub fn right_ascension(&self) -> f64 {
self.right_ascension
}

/// The shape of the orbit
pub fn eccentricity(&self) -> f64 {
self.eccentricity
}

/// Angle between the ascending node and the orbit's point of closest approach to the earth in deg
pub fn argument_of_perigee(&self) -> f64 {
self.argument_of_perigee
}

/// Angle of the satellite location measured from perigee in deg
pub fn mean_anomaly(&self) -> f64 {
self.mean_anomaly
}

/// Mean number of orbits per day in day⁻¹ (Kozai convention)
pub fn mean_motion(&self) -> f64 {
self.mean_motion
}

/// The orbit number at epoch
pub fn revolution_number(&self) -> u64 {
self.revolution_number
}

pub fn orbital_period(&self) -> chrono::Duration {
const SECONDS_PER_DAY: f64 = 24.0 * 60.0 * 60.0;
chrono::Duration::seconds((SECONDS_PER_DAY / self.mean_motion) as i64)
pub fn elements(&self) -> &sgp4::Elements {
&self.elements
}

pub fn predict(&self, time: DateTime<Utc>) -> Result<State, sgp4::Error> {
Expand Down
30 changes: 17 additions & 13 deletions src/widgets/object_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,23 @@ impl ObjectInformation<'_> {
.unwrap()
.name();

let elemenets = object.elements();
state.items = Vec::from([
(
"Name",
object.name().unwrap_or(&UNKNOWN_NAME.to_string()).clone(),
elemenets
.object_name
.clone()
.unwrap_or(UNKNOWN_NAME.to_string()),
),
(
"COSPAR ID",
object
.cospar_id()
.unwrap_or(&UNKNOWN_NAME.to_string())
.clone(),
elemenets
.international_designator
.clone()
.unwrap_or(UNKNOWN_NAME.to_string()),
),
("NORAD ID", object.norad_id().to_string()),
("NORAD ID", elemenets.norad_id.to_string()),
("Longitude", format!("{:9.4}°", object_state.longitude())),
("Latitude", format!("{:9.4}°", object_state.latitude())),
("Altitude", format!("{:.3} km", object_state.altitude())),
Expand All @@ -106,13 +110,13 @@ impl ObjectInformation<'_> {
"Epoch",
object.epoch().format("%Y-%m-%d %H:%M:%S").to_string(),
),
("Drag term", format!("{} 1/ER", object.drag_term())),
("Inc", format!("{}°", object.inclination())),
("Right asc.", format!("{}°", object.right_ascension())),
("Ecc", object.eccentricity().to_string()),
("M. anomaly", format!("{}°", object.mean_anomaly())),
("M. motion", format!("{} 1/day", object.mean_motion())),
("Rev. #", object.revolution_number().to_string()),
("Drag term", format!("{} 1/ER", elemenets.drag_term)),
("Inc", format!("{}°", elemenets.inclination)),
("Right asc.", format!("{}°", elemenets.right_ascension)),
("Ecc", elemenets.eccentricity.to_string()),
("M. anomaly", format!("{}°", elemenets.mean_anomaly)),
("M. motion", format!("{} 1/day", elemenets.mean_motion)),
("Rev. #", elemenets.revolution_number.to_string()),
]);

let (max_key_width, _max_value_width) = state
Expand Down
23 changes: 18 additions & 5 deletions src/widgets/world_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,22 @@ impl WorldMap<'_> {
Self::SATELLIT_SYMBOL.light_red()
+ format!(
" {}",
object.name().unwrap_or(&Self::UNKNOWN_NAME.to_string())
object
.elements()
.object_name
.clone()
.unwrap_or(Self::UNKNOWN_NAME.to_string())
)
.white()
} else {
Self::SATELLIT_SYMBOL.red()
+ format!(
" {}",
object.name().unwrap_or(&Self::UNKNOWN_NAME.to_string())
object
.elements()
.object_name
.clone()
.unwrap_or(Self::UNKNOWN_NAME.to_string())
)
.dark_gray()
};
Expand Down Expand Up @@ -114,7 +122,11 @@ impl WorldMap<'_> {
Self::SATELLIT_SYMBOL.light_green().slow_blink()
+ format!(
" {}",
selected.name().unwrap_or(&Self::UNKNOWN_NAME.to_string())
selected
.elements()
.object_name
.clone()
.unwrap_or(Self::UNKNOWN_NAME.to_string())
)
.white(),
);
Expand All @@ -129,9 +141,10 @@ impl WorldMap<'_> {
Self::SATELLIT_SYMBOL.light_red().reversed()
+ " ".into()
+ hovered
.name()
.unwrap_or(&Self::UNKNOWN_NAME.to_string())
.elements()
.object_name
.clone()
.unwrap_or(Self::UNKNOWN_NAME.to_string())
.white()
.reversed(),
);
Expand Down

0 comments on commit 9b180d4

Please sign in to comment.