From 27e10794b5332553fed96b239d570df5ae7f0373 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sun, 25 May 2025 18:27:52 -0700 Subject: [PATCH] trying to track the iss, wildly wrong --- Cargo.lock | 3 + Cargo.toml | 1 + src/main.rs | 184 ++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 169 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34effb3..3f2f3c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1871,7 +1871,9 @@ checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", + "js-sys", "num-traits", + "wasm-bindgen", "windows-link", ] @@ -5819,6 +5821,7 @@ version = "0.1.0" dependencies = [ "anise", "bevy", + "chrono", "hifitime", "log", "nyx-space", diff --git a/Cargo.toml b/Cargo.toml index a2f60e9..3679067 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] anise = "0.5.4" +chrono = "0.4.41" hifitime = "4.0.2" log = { version = "0.4.27", features = ["std"] } nyx-space = "2.1.0" diff --git a/src/main.rs b/src/main.rs index 4ea2579..ad475e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,48 +1,194 @@ +use std::{str::FromStr, sync::Arc, time::UNIX_EPOCH}; + use anise::{ almanac::metaload::MetaFile, constants::{ celestial_objects::{MOON, SUN}, frames::{EARTH_J2000, IAU_EARTH_FRAME}, }, + frames::Frame, + prelude::Almanac, }; -use hifitime::{Epoch, Unit}; -use log::warn; +use chrono::Utc; +use hifitime::Epoch; + use nyx_space::{ cosmic::{Mass, MetaAlmanac, Orbit, SRPData}, dynamics::{Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics}, - io::{gravity::HarmonicsMem, ExportCfg}, + io::gravity::HarmonicsMem, od::GroundStation, propagators::Propagator, - Spacecraft, State, + Spacecraft, }; -use bevy::{ - color::palettes::css::BLUE, - pbr::wireframe::{WireframeColor, WireframeConfig, WireframePlugin}, - platform::collections::HashSet, - prelude::*, -}; +use bevy::{platform::collections::HashSet, prelude::*}; fn main() { let mut app = App::new(); - app.add_plugins((DefaultPlugins, WireframePlugin::default())) + app.add_plugins(DefaultPlugins) .insert_gizmo_config(DefaultGizmoConfigGroup, GizmoConfig::default()) .insert_resource(DebugCamOffset::default()) - .insert_resource(WireframeConfig { - global: false, - ..Default::default() - }) .insert_resource(HomeCartesian::default()) + .insert_resource(SpaceData::default()) + .insert_resource(InterestPoint::default()) .add_systems(Startup, (spawn_earth, spawn_camera)) .add_systems( Update, - (close_on_esc, update_camera_offset, move_camera, draw_arrow), + ( + close_on_esc, + update_camera_offset, + move_camera, + draw_arrow, + find_iss, + ), ) .run(); } -// const RADIUS: f32 = 6378.0; +fn find_iss(mut end: ResMut, mut data: ResMut) { + let Ephemerides { + sma_km, + ecc, + inc_deg, + raan_deg, + aop_deg, + ma_deg, + epoch, + } = data.ephemerides.clone(); + + let now = std::time::SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs_f64(); + let new_epoch = Epoch::from_unix_seconds(now); + let orbit = Orbit::try_keplerian_mean_anomaly( + sma_km, ecc, inc_deg, raan_deg, aop_deg, ma_deg, epoch, data.frame, + ) + .unwrap(); + + let iss = Spacecraft::builder() + .orbit(orbit) + .mass(Mass::from_dry_mass(420_000.0)) + .srp(SRPData { + area_m2: 2190.0, + coeff_reflectivity: 0.8, + }) + .build(); + + let mut orbital_dyn = OrbitalDynamics::point_masses(vec![MOON, SUN]); + let harmonics = Harmonics::from_stor( + data.almanac.frame_from_uid(IAU_EARTH_FRAME).unwrap(), + HarmonicsMem::from_cof(&data.meta_file.uri, 21, 21, true).unwrap(), + ); + + orbital_dyn.accel_models.push(harmonics); + let srp = SolarPressure::default(EARTH_J2000, data.almanac.clone()).unwrap(); + let dynamics = SpacecraftDynamics::from_model(orbital_dyn, srp); + + let (iss, trajectory) = Propagator::default(dynamics) + .with(iss, data.almanac.clone()) + .until_epoch_with_traj(new_epoch) + .unwrap(); + + data.ephemerides.sma_km = iss.orbit.sma_km().unwrap(); + data.ephemerides.ecc = iss.orbit.ecc().unwrap(); + data.ephemerides.inc_deg = iss.orbit.inc_deg().unwrap(); + data.ephemerides.raan_deg = iss.orbit.raan_deg().unwrap(); + data.ephemerides.aop_deg = iss.orbit.aop_deg().unwrap(); + data.ephemerides.ma_deg = iss.orbit.ma_deg().unwrap(); + data.ephemerides.epoch = new_epoch; + + let aer = data + .almanac + .azimuth_elevation_range_sez( + iss.orbit, + data.home + .to_orbit(new_epoch, data.almanac.as_ref()) + .unwrap(), + None, + None, + ) + .unwrap(); + let iss_loc = polar2cart( + aer.elevation_deg as f32, + aer.azimuth_deg as f32, + (aer.range_km / (R_FACTOR * 10.0)) as f32, + ); + dbg!(aer); + end.0 = iss_loc; +} + +#[derive(Debug, Resource, Clone)] +pub struct Ephemerides { + pub sma_km: f64, + pub ecc: f64, + pub inc_deg: f64, + pub raan_deg: f64, + pub aop_deg: f64, + pub ma_deg: f64, + pub epoch: Epoch, +} + +impl Default for Ephemerides { + fn default() -> Self { + Self { + sma_km: 419.0, + ecc: 0.0002408, + inc_deg: 51.6378, + raan_deg: 60.6053, + aop_deg: 142.7188, + ma_deg: 0.8794, + epoch: Epoch::from_gregorian_utc(2025, 5, 25, 6, 31, 36, 00), + } + } +} + +#[derive(Resource)] +pub struct SpaceData { + pub almanac: Arc, + pub meta_file: Arc, + pub frame: Frame, + pub home: GroundStation, + pub radius: f64, + ephemerides: Ephemerides, +} + +impl Default for SpaceData { + fn default() -> Self { + let almanac = Arc::new(MetaAlmanac::latest().map_err(Box::new).unwrap()); + let frame = almanac.frame_from_uid(EARTH_J2000).unwrap(); + let mut mf = MetaFile { + uri: "http://public-data.nyxspace.com/nyx/models/JGM3.cof.gz".to_string(), + crc32: Some(0xF446F027), // Specifying the CRC32 avoids redownloading it if it's cached. + }; + mf.process(true).unwrap(); + + let home = GroundStation::from_point( + "Los Angeles".to_string(), + HOME_LAT as f64, + HOME_LONG as f64, + 0.0, + frame, + ); + + let radius = frame.mean_equatorial_radius_km().unwrap(); + + Self { + almanac, + meta_file: Arc::new(mf), + frame, + home, + radius, + ephemerides: Ephemerides::default(), + } + } +} + +#[derive(Debug, Default, Resource)] +pub struct InterestPoint(pub Vec3); + const RADIUS: f32 = 100.0; +const R_FACTOR: f64 = 63.78; const HOME_LAT: f32 = 34.2; const HOME_LONG: f32 = -118.45; @@ -184,8 +330,8 @@ fn update_camera_offset( } } -fn draw_arrow(home: Res, mut gizmos: Gizmos) { +fn draw_arrow(home: Res, end: Res, mut gizmos: Gizmos) { let start = home.pos; - let end = home.pos * 2.0; + let end = end.0; gizmos.arrow(start, end, Color::linear_rgb(1.0, 1.0, 0.0)); }