trying to track the iss, wildly wrong
This commit is contained in:
parent
34d2cabf67
commit
27e10794b5
3 changed files with 169 additions and 19 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1871,7 +1871,9 @@ checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"wasm-bindgen",
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -5819,6 +5821,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anise",
|
"anise",
|
||||||
"bevy",
|
"bevy",
|
||||||
|
"chrono",
|
||||||
"hifitime",
|
"hifitime",
|
||||||
"log",
|
"log",
|
||||||
"nyx-space",
|
"nyx-space",
|
||||||
|
|
|
@ -5,6 +5,7 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anise = "0.5.4"
|
anise = "0.5.4"
|
||||||
|
chrono = "0.4.41"
|
||||||
hifitime = "4.0.2"
|
hifitime = "4.0.2"
|
||||||
log = { version = "0.4.27", features = ["std"] }
|
log = { version = "0.4.27", features = ["std"] }
|
||||||
nyx-space = "2.1.0"
|
nyx-space = "2.1.0"
|
||||||
|
|
184
src/main.rs
184
src/main.rs
|
@ -1,48 +1,194 @@
|
||||||
|
use std::{str::FromStr, sync::Arc, time::UNIX_EPOCH};
|
||||||
|
|
||||||
use anise::{
|
use anise::{
|
||||||
almanac::metaload::MetaFile,
|
almanac::metaload::MetaFile,
|
||||||
constants::{
|
constants::{
|
||||||
celestial_objects::{MOON, SUN},
|
celestial_objects::{MOON, SUN},
|
||||||
frames::{EARTH_J2000, IAU_EARTH_FRAME},
|
frames::{EARTH_J2000, IAU_EARTH_FRAME},
|
||||||
},
|
},
|
||||||
|
frames::Frame,
|
||||||
|
prelude::Almanac,
|
||||||
};
|
};
|
||||||
use hifitime::{Epoch, Unit};
|
use chrono::Utc;
|
||||||
use log::warn;
|
use hifitime::Epoch;
|
||||||
|
|
||||||
use nyx_space::{
|
use nyx_space::{
|
||||||
cosmic::{Mass, MetaAlmanac, Orbit, SRPData},
|
cosmic::{Mass, MetaAlmanac, Orbit, SRPData},
|
||||||
dynamics::{Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics},
|
dynamics::{Harmonics, OrbitalDynamics, SolarPressure, SpacecraftDynamics},
|
||||||
io::{gravity::HarmonicsMem, ExportCfg},
|
io::gravity::HarmonicsMem,
|
||||||
od::GroundStation,
|
od::GroundStation,
|
||||||
propagators::Propagator,
|
propagators::Propagator,
|
||||||
Spacecraft, State,
|
Spacecraft,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{
|
use bevy::{platform::collections::HashSet, prelude::*};
|
||||||
color::palettes::css::BLUE,
|
|
||||||
pbr::wireframe::{WireframeColor, WireframeConfig, WireframePlugin},
|
|
||||||
platform::collections::HashSet,
|
|
||||||
prelude::*,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
app.add_plugins((DefaultPlugins, WireframePlugin::default()))
|
app.add_plugins(DefaultPlugins)
|
||||||
.insert_gizmo_config(DefaultGizmoConfigGroup, GizmoConfig::default())
|
.insert_gizmo_config(DefaultGizmoConfigGroup, GizmoConfig::default())
|
||||||
.insert_resource(DebugCamOffset::default())
|
.insert_resource(DebugCamOffset::default())
|
||||||
.insert_resource(WireframeConfig {
|
|
||||||
global: false,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.insert_resource(HomeCartesian::default())
|
.insert_resource(HomeCartesian::default())
|
||||||
|
.insert_resource(SpaceData::default())
|
||||||
|
.insert_resource(InterestPoint::default())
|
||||||
.add_systems(Startup, (spawn_earth, spawn_camera))
|
.add_systems(Startup, (spawn_earth, spawn_camera))
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(close_on_esc, update_camera_offset, move_camera, draw_arrow),
|
(
|
||||||
|
close_on_esc,
|
||||||
|
update_camera_offset,
|
||||||
|
move_camera,
|
||||||
|
draw_arrow,
|
||||||
|
find_iss,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// const RADIUS: f32 = 6378.0;
|
fn find_iss(mut end: ResMut<InterestPoint>, mut data: ResMut<SpaceData>) {
|
||||||
|
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<Almanac>,
|
||||||
|
pub meta_file: Arc<MetaFile>,
|
||||||
|
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 RADIUS: f32 = 100.0;
|
||||||
|
const R_FACTOR: f64 = 63.78;
|
||||||
const HOME_LAT: f32 = 34.2;
|
const HOME_LAT: f32 = 34.2;
|
||||||
const HOME_LONG: f32 = -118.45;
|
const HOME_LONG: f32 = -118.45;
|
||||||
|
|
||||||
|
@ -184,8 +330,8 @@ fn update_camera_offset(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_arrow(home: Res<HomeCartesian>, mut gizmos: Gizmos) {
|
fn draw_arrow(home: Res<HomeCartesian>, end: Res<InterestPoint>, mut gizmos: Gizmos) {
|
||||||
let start = home.pos;
|
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));
|
gizmos.arrow(start, end, Color::linear_rgb(1.0, 1.0, 0.0));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue