Skip to content

Commit

Permalink
got tle fetching, parseing and horizon plotting working
Browse files Browse the repository at this point in the history
also added plotting lib to frontend & a possible internal api for state update
  • Loading branch information
kiesenverseist committed Sep 1, 2023
1 parent 8e2925a commit cd0adc5
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 38 deletions.
5 changes: 5 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
"@types/react": "^18.0.21",
"@types/react-dom": "^18.0.6",
"fast-json-patch": "^3.1.1",
"plotly.js": "^2.26.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-plotly.js": "^2.6.0",
"react-scripts": "^5.0.1",
"typescript": "^4.8.4",
"web-vitals": "^2.1.4"
Expand Down Expand Up @@ -44,5 +46,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react-plotly.js": "^2.6.0"
}
}
21 changes: 20 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import Plot from 'react-plotly.js';
import './App.css';

import Home from './pages/Home'

Check warning on line 5 in frontend/src/App.tsx

View workflow job for this annotation

GitHub Actions / React Lint

'Home' is defined but never used
Expand All @@ -12,9 +13,27 @@ const App: React.FC = () => {
return (
<div className="App">
{/* <p>hello</p> */}
{state === undefined && <p>yo</p>}
{state === undefined && <p>State not yet initialised</p>}
{state && <p>{`${JSON.stringify(state)}`}</p>}
{/* <Home/> */}
<Plot
data={[
{
x: [0, 90, 180, 270],
y: [45, 30, -15, 30],
type: 'scatter',
mode: 'markers',
// marker: {color: 'red'},
},
// {type:'bar', x:[1, 2, 3], y:[2, 5, 3]},
]}
layout={{
xaxis: {range: [0, 360]},
yaxis: {range: [-90, 90]},
width:720, height: 480,
title: 'A fancy plot',
}}
/>
</div>
);
}
Expand Down
17 changes: 15 additions & 2 deletions orch-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,21 @@ serde_json = "*"
tokio = { version = "1.27", features = ["full"] }
serial = "0.4.0"
serialport = "4.2.1"

nyx-space = "1.1.2"
sgp4 = "1.2.2"
# reqwest = "0.11.20"
# sgp4 = "1.2.2"
parse-tle = "0.1.0"

# reqwest = "0.11.20" # for when we want to move to async requests
ureq = { version = "*", features = ["json"] }

nalgebra = "0.32.3"

# if we wanted to have
plotters = "0.3"
# plotters-cairo = "*"

# because this package is super slow to run if not compiled
# in release mode
[profile.dev.package.nyx-space]
opt-level = 3
92 changes: 67 additions & 25 deletions orch-rs/src/prop_test.rs → orch-rs/examples/prop_test.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
use std::time::Duration;
// use std::time::Duration;

pub fn test () {
use std::f64::consts::PI;
use plotters::prelude::*;

pub fn main () {

// let response = ureq::get("https://celestrak.com/NORAD/elements/gp.php")
// .query("GROUP", "galileo")
// .query("FORMAT", "json")
// // .query("FORMAT", "json")
// .call().unwrap();
//
// let elements_vec: Vec<sgp4::Elements> = response.into_json().unwrap();
//
// for elements in &elements_vec {
// println!("{}", elements.object_name.as_ref().unwrap());
// let constants = sgp4::Constants::from_elements(elements).unwrap();
// for hours in &[12, 24] {
// println!(" t = {} min", hours * 60);
// let prediction = constants.propagate((hours * 60) as f64).unwrap();
// println!(" r = {:?} km", prediction.position);
// println!(" ṙ = {:?} km.s⁻¹", prediction.velocity);
// }
// }
// let tle = response.into_string().unwrap().lines()
// .skip(3) // for some reason it doesn't like the first tle?
// .take(3)
// .collect::<Vec<&str>>()
// .join("\n");
let tle = "ISS (ZARYA)
1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927
2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537";
println!("{tle}");
let tle = parse_tle::tle::parse(&tle);

// Set the initial start time of the scenario
let epoch = Epoch::from_gregorian_tai(
tle.epoch_year.try_into().unwrap(), // yay rust
tle.epoch_month.try_into().unwrap(),
tle.epoch_day.try_into().unwrap(),
tle.epoch_hours.try_into().unwrap(),
tle.epoch_min.try_into().unwrap(),
tle.epoch_sec.try_into().unwrap(),
0
);

// from https://space.stackexchange.com/questions/18289/how-to-get-semi-major-axis-from-tle
let mu: f64 = 3.986004418e14; // earth's gravitational parameter
let n = tle.mean_motion;
let sma = mu.powf(1.0/3.0) / (2.0*PI*n/86400.0).powf(2.0/3.0);

use nyx_space::md::ui::*;
use nyx_space::od::ui::*;

let cosm = Cosm::de438();
let eme2k = cosm.frame("EME2000");

// Set the initial start time of the scenario
let epoch = Epoch::from_gregorian_tai_at_noon(2021, 2, 25);
// Nearly circular orbit (ecc of 0.01), inclination of 49 degrees and TA at 30.0
let orbit = Orbit::keplerian(6800.0, 0.01, 0.0, 0.0, 0.0, 30.0, epoch, eme2k);
let orbit = Orbit::keplerian(
sma,
tle.eccentricity,
tle.inc,
tle.raan,
tle.arg_perigee,
tle.mean_anomaly, // should be true anomaly idk
epoch,
eme2k
);

let landmark = GroundStation::from_point(
"Sydney".into(),
Expand All @@ -54,6 +77,8 @@ pub fn test () {
// Printing the state with `:o` will print its Keplerian elements
println!("{}", final_state.to_keplerian_vec());

let mut pts: Vec<(f64, f64)> = Vec::new();

for state in traj.every(2 * Unit::Minute) {
// Compute the elevation
// let (elevation, _, _) = landmark.elevation_of(&state);
Expand All @@ -64,7 +89,6 @@ pub fn test () {
// Then, compute the rotation matrix from the body fixed frame of the ground station to its topocentric frame SEZ
// get the landmark's position at the current time
let land_gs_frame = landmark.to_orbit(*dt);

// Note: we're only looking at the radis so we don't need to apply the transport theorem here.
// get the horizon-frame from the landmark's current position
let dcm_topo2fixed = land_gs_frame.dcm_from_traj_frame(Frame::SEZ).unwrap();
Expand All @@ -81,11 +105,29 @@ pub fn test () {
let elevation = diff_sez.declination();
let azimuth = f64::atan2(-diff_sez.x, diff_sez.y).to_degrees();

println!("{} el:{elevation} az:{azimuth}", state.epoch());
println!("{} {} {}", state.x, state.y, state.z);
println!("{} {} {}", diff_sez.x, diff_sez.y, diff_sez.z);
println!("");
pts.push((azimuth, elevation));

// println!("{} el:{elevation} az:{azimuth}", state.epoch());
// println!("{} {} {}", state.x, state.y, state.z);
// println!("{} {} {}", diff_sez.x, diff_sez.y, diff_sez.z);
// println!("");
println!("el:{elevation}\taz:{azimuth}");
}

std::process::exit(0);
let root_drawing_area = BitMapBackend::new("images/horizon.png", (1024, 768))
.into_drawing_area();

root_drawing_area.fill(&WHITE).unwrap();

let mut chart = ChartBuilder::on(&root_drawing_area)
.set_label_area_size(LabelAreaPosition::Left, 40)
.set_label_area_size(LabelAreaPosition::Bottom, 40)
.build_cartesian_2d(-180.0..180.0, -90.0..90.0)
.unwrap();

chart.configure_mesh().draw().unwrap();

chart.draw_series(pts.iter().map(|pt| Circle::new(*pt, 5, &BLACK)))
.unwrap();

}
Binary file added orch-rs/images/example-iss-horizon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 0 additions & 2 deletions orch-rs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use axum::{
mod groundstation;
mod state;
mod websocket;
mod prop_test;

use groundstation::GroundStation;
use websocket::{handle_socket, WsState};
Expand All @@ -26,7 +25,6 @@ async fn main() {
// ).unwrap()
// );
//
prop_test::test();

println!("Starting server");

Expand Down
13 changes: 5 additions & 8 deletions orch-rs/src/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ impl WsState {
return;
}

println!("New client {tx:?}");

let mut txs = self.txs.lock().await;
txs.push(tx);
}
Expand Down Expand Up @@ -85,10 +87,11 @@ impl WsState {
Ok(())
}

pub async fn update(&self) -> Result<(), Error> {
let state = self.state.lock().await;
pub async fn update(&self, update_fn: &dyn Fn(&mut State)) -> Result<(), Error> {
let mut state = self.state.lock().await;

let old_json = serde_json::to_value(&*state)?;
update_fn(&mut state);
let new_json = serde_json::to_value(&*state)?;

let ops = json_patch::diff(&old_json, &new_json).0;
Expand Down Expand Up @@ -119,12 +122,6 @@ pub async fn handle_socket(socket: WebSocket, state: Arc<WsState>) {
} else {
println!("Recieved invalid message {text}");
}

// println!("{text}");
// // TODO: Action decoding
// state.broadcast_all(text.clone()).await;
// // add the message to the current state
}

}
}

0 comments on commit cd0adc5

Please sign in to comment.