Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/orbit_visualiser/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

from .astrodynamics.types import OrbitType
from .astrodynamics.keplerian.classification import orbit_type
from .astrodynamics.keplerian.anomlies import mean_anomaly, eccentric_anomaly
from .astrodynamics.keplerian.anomalies import mean_anomaly, eccentric_anomaly
from .astrodynamics.keplerian.elements import (eccentricity_vector_from_state, eccentricity_from_state,
true_anomaly_from_state, semi_parameter_from_momentum,
semi_parameter_from_eccentricity, semimajor_axis,
semiminor_axis, periapsis, apoapsis,
semiminor_axis, radius_of_periapsis, radius_of_apoapsis,
asymptote_anomaly, turning_angle, aiming_radius,
orbital_period, mean_motion)
from .astrodynamics.keplerian.dynamics import (specific_ang_momentum_from_state, specific_ang_momentum,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ def eccentric_anomaly(e: float, nu: float) -> float:
e : float
Eccentricity
nu : float
True anomaly (rads)
True anomaly (rad)

Returns
-------
float
The eccentric anomaly (rads)
The eccentric anomaly (rad)
"""
type = orbit_type(e)
if type is OrbitType.CIRCULAR:
Expand Down Expand Up @@ -45,15 +45,15 @@ def mean_anomaly(e: float, nu: float, e_anomaly: float) -> float:
e : float
Eccentricity
nu : float
True anomaly (rads)
True anomaly (rad)
e_anomaly : float
The eccentric anomaly (rads)
The eccentric anomaly (rad)


Returns
-------
float
The mean anomaly (rads)
The mean anomaly (rad)
"""
type = orbit_type(e)
if type in (OrbitType.CIRCULAR, OrbitType.ELLIPTICAL):
Expand Down
46 changes: 44 additions & 2 deletions src/orbit_visualiser/core/astrodynamics/keplerian/elements.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def semiminor_axis(e: float, a: float) -> float:

return np.nan

def periapsis(p: float, e: float) -> float:
def radius_of_periapsis(p: float, e: float) -> float:
"""
Calculates the radius of periapsis from the semi-parameter and eccentricity.

Expand All @@ -166,7 +166,26 @@ def periapsis(p: float, e: float) -> float:
"""
return p/(1 + e)

def apoapsis(e: float, a: float) -> float:
def periapsis(p: float, e: NDArray[np.float64]) -> NDArray[np.float64]:
"""
Calculate the periapsis vector from the eccentricity vector and the semi-parameter.

Parameters
----------
p : float
The semi-parameter (km)
e : NDArray[np.float64]
The eccentricity vector

Returns
-------
NDArray[np.float64]
Periapsis vector (km)
"""
e_norm = np.linalg.norm(e)
return p/((e_norm(1 + e_norm)))*e

def radius_of_apoapsis(e: float, a: float) -> float:
"""
Calculates the radius of apoapsis using the eccentricity and semi-major axis.

Expand All @@ -187,6 +206,29 @@ def apoapsis(e: float, a: float) -> float:

return a*(1 + e)

def apoapsis(e: NDArray[np.float64], a: float) -> NDArray[np.float64]:
"""
Calculate the apoapsis vector from the eccentricity vector and the semi-major axis.

Parameters
----------
e : NDArray[np.float64]
Eccentricity vector
a : float
Semi-major axis (km)

Returns
-------
NDArray[np.float64]
Apoapsis vector (km)
"""

e_norm = np.linalg.norm(e)
if orbit_type(e_norm) is OrbitType.PARABOLIC:
return np.empty(e.shape)

return -(a*(1 + e_norm)/e_norm)*e

def asymptote_anomaly(e: float) -> float:
"""
Calculate the asymptote of the true anomaly for open orbits using the eccentricity.
Expand Down
40 changes: 21 additions & 19 deletions src/orbit_visualiser/core/astrodynamics/keplerian/state.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from math import pi
import numpy as np
from numpy.typing import NDArray
from typing import Callable, Literal
from typing import Literal
from orbit_visualiser.core.astrodynamics.types import OrbitType
from orbit_visualiser.core.astrodynamics.keplerian.elements import semi_parameter_from_eccentricity
from orbit_visualiser.core.astrodynamics.keplerian.dynamics import specific_ang_momentum
Expand Down Expand Up @@ -49,7 +49,7 @@ def state_pf_from_e_rp(
elif state == "both":
return [r, v]

def perifocal_position(e: float, p: float, nu: float) -> NDArray[np.float64]:
def perifocal_position(e: float, p: float, nu: float | NDArray[np.float64]) -> NDArray[np.float64]:
"""
Perifocal orbit equation.

Expand All @@ -59,17 +59,18 @@ def perifocal_position(e: float, p: float, nu: float) -> NDArray[np.float64]:
Eccentricity
p : float
Semi-parameter (km)
nu : float
True anomaly (rads)
nu : float | NDArray[np.float64]
True anomaly (rad)

Returns
-------
NDArray[np.float64]
The numpy array of the perifocal orbital position
"""
return p*(1/(1 + e*np.cos(nu)))*np.array([np.cos(nu), np.sin(nu)])
z = 0 if isinstance(nu, float) else np.zeros(nu.shape)
return p*(1/(1 + e*np.cos(nu)))*np.array([np.cos(nu), np.sin(nu), z])

def perifocal_velocity(e: float, mu: float, h: float, nu: float) -> NDArray[np.float64]:
def perifocal_velocity(e: float, mu: float, h: float, nu: float | NDArray[np.float64]) -> NDArray[np.float64]:
"""
The perifocal velocity equation.

Expand All @@ -81,15 +82,16 @@ def perifocal_velocity(e: float, mu: float, h: float, nu: float) -> NDArray[np.f
Gravitational parameter (km^3/s^2)
h : float
Specific angular momentum (km^2/s)
nu : float
True anomaly (rads)
nu : float | NDArray[np.float64]
True anomaly (rad)

Returns
-------
NDArray[np.float64]
The numpy array of the perifocal velocity
"""
return (mu/h)*np.array([-np.sin(nu), e + np.cos(nu)])
z = 0 if isinstance(nu, float) else np.zeros(nu.shape)
return (mu/h)*np.array([-np.sin(nu), e + np.cos(nu), z])


def radial_azimuthal_velocity(
Expand All @@ -106,15 +108,15 @@ def radial_azimuthal_velocity(
Parameters
----------
nu : float
True anomaly (rads)
True anomaly (rad)
mu : float
Gravitational parameter (km^3/s^2)
h : float
Specific angular momentum (km^2/s)
e : float
Eccentricity
asymp_anomaly : float
The asymptote of the free anomaly (rads)
The asymptote of the free anomaly (rad)

Returns
-------
Expand Down Expand Up @@ -166,9 +168,9 @@ def radius_from_orbit_eq(nu: float, asymp_anomaly: float, p: float, e: float) ->
Parameters
----------
nu : float
True anomaly (rads)
True anomaly (rad)
asymp_anomaly : float
The asymptote of the free anomaly (rads)
The asymptote of the free anomaly (rad)
p : float
Semi-parameter (km)
e : float
Expand All @@ -191,9 +193,9 @@ def escape_velocity(nu: float, asymp_anomaly: float, mu: float, r: float) -> flo
Parameters
----------
nu : float
The true anomaly (rads)
The true anomaly (rad)
asymp_anomaly : float
The true anomaly of the asymptot (rads)
The true anomaly of the asymptote (rad)
mu : float
Gravitational parameter (km^3/s^2)
r : float
Expand All @@ -216,16 +218,16 @@ def flight_angle(nu: float, asymp_anomaly: float, e: float) -> float:
Parameters
----------
nu : float
True anomaly (rads)
True anomaly (rad)
asymp_anomaly : float
The true anomaly of the asymptot (rads)
The true anomaly of the asymptot (rad)
e : float
Eccentricity

Returns
-------
float
The satellite flight angle (rads)
The satellite flight angle (rad)
"""
if np.isclose(abs(nu), asymp_anomaly):
return np.sign(nu)*pi/2
Expand All @@ -239,7 +241,7 @@ def time_since_periapsis(m_anomaly: float, period: float, p: float, h: float, e:
Parameters
----------
m_anomaly : float
The mean anomaly (rads)
The mean anomaly (rad)
period : float
The orbital period (s)
p : float
Expand Down
12 changes: 6 additions & 6 deletions src/orbit_visualiser/core/orbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from numpy.typing import NDArray
from orbit_visualiser.core.astrodynamics.keplerian.state import state_pf_from_e_rp
from orbit_visualiser.core.astrodynamics.keplerian.elements import (eccentricity_from_state, semi_parameter_from_momentum,
periapsis, semimajor_axis, semiminor_axis,
apoapsis, asymptote_anomaly, turning_angle,
radius_of_periapsis, semimajor_axis, semiminor_axis,
radius_of_apoapsis, asymptote_anomaly, turning_angle,
aiming_radius, orbital_period, mean_motion)
from orbit_visualiser.core.astrodynamics.keplerian.dynamics import (specific_orbital_energy, characteristic_energy,
excess_velocity, specific_ang_momentum_from_state)
Expand Down Expand Up @@ -58,7 +58,7 @@ class Orbit():
mu : float
The gravitational parameter of the central body (km^3/s^2)
nu : float
The true anomaly of the satellite (rads)
The true anomaly of the satellite (rad)
"""
position : Sequence | NDArray[np.float64]
velocity : Sequence | NDArray[np.float64]
Expand All @@ -78,11 +78,11 @@ def orbit_type(self) -> OrbitType:

@cached_property
def semi_parameter(self) -> float:
return semi_parameter_from_momentum(specific_ang_momentum_from_state(self.position, self.velocity), self.mu)
return semi_parameter_from_momentum(np.linalg.norm(specific_ang_momentum_from_state(self.position, self.velocity)), self.mu)

@cached_property
def radius_of_periapsis(self) -> float:
return periapsis(self.semi_parameter, self.eccentricity)
return radius_of_periapsis(self.semi_parameter, self.eccentricity)

@cached_property
def semimajor_axis(self) -> float:
Expand All @@ -94,7 +94,7 @@ def semiminor_axis(self) -> float:

@cached_property
def radius_of_apoapsis(self) -> float:
return apoapsis(self.eccentricity, self.semimajor_axis)
return radius_of_apoapsis(self.eccentricity, self.semimajor_axis)

@cached_property
def asymptote_anomaly(self) -> float:
Expand Down
14 changes: 6 additions & 8 deletions src/orbit_visualiser/core/propagation.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,23 @@ def two_body_pf_ode(mu: float, t: float, state: NDArray[np.float64], ) -> NDArra
NDArray[np.float64]
The values to be numerically integrated [dx, d^2x]
"""
x, y, v_x, v_y = state
pos = state[:3]
r = np.linalg.norm(pos)

r = np.hypot(x, y)
vel = state[3:]
acc: NDArray[np.float64] = -(mu/r**3)*pos

a_x = -(mu/r**3)*x
a_y = -(mu/r**3)*y

return np.array([v_x, v_y, a_x, a_y])
return np.concatenate((vel, acc))

def get_init_conditions_from_orbit(orbit: Orbit) -> NDArray[np.float64]:
"""
Takes orbital elements and returns the initial conditions (position and velocity) for orbit propagation.
Takes orbit object and returns the initial conditions (position and velocity) for orbit propagation.

Parameters
----------
orbit: NewOrbit
Orbit object to get the initial conditions from


Returns
-------
NDArray[np.float64]
Expand Down
6 changes: 3 additions & 3 deletions src/orbit_visualiser/core/satellite.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Sequence
from orbit_visualiser.core.astrodynamics.keplerian.state import (speed, radial_azimuthal_velocity, escape_velocity,
radius_from_state, flight_angle, time_since_periapsis)
from orbit_visualiser.core.astrodynamics.keplerian.anomlies import mean_anomaly, eccentric_anomaly
from orbit_visualiser.core.astrodynamics.keplerian.anomalies import mean_anomaly, eccentric_anomaly
from orbit_visualiser.core.astrodynamics.keplerian.dynamics import specific_ang_momentum_from_state
from orbit_visualiser.core.astrodynamics.keplerian.elements import true_anomaly_from_state
from orbit_visualiser.core.orbit import CentralBody, Orbit
Expand Down Expand Up @@ -93,7 +93,7 @@ def radial_azimuthal_velocity(self) -> NDArray[np.float64]:
return radial_azimuthal_velocity(
self.true_anomaly,
self.central_body.mu,
self.specific_angular_momentum,
np.linalg.norm(self.specific_angular_momentum),
orbit.eccentricity,
orbit.asymptote_anomaly
)
Expand Down Expand Up @@ -141,6 +141,6 @@ def time_since_periapsis(self) -> float:
self.mean_anomaly,
orbit.orbital_period,
orbit.semi_parameter,
self.specific_angular_momentum,
np.linalg.norm(self.specific_angular_momentum),
orbit.eccentricity
)
2 changes: 1 addition & 1 deletion src/orbit_visualiser/ui/config/config_controller.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from tkinter import Event
from typing import Callable
from orbit_visualiser.core import Orbit, Satellite, CentralBody
from orbit_visualiser.ui.config.config_builder import OrbitConfigBuilder, OrbitConfigBuilder
from orbit_visualiser.ui.config.config_builder import OrbitConfigBuilder
from orbit_visualiser.ui.config.variables_panel.variables_panel_controller import VariablesController
from orbit_visualiser.ui.config.properties_panel.properties_panel_controller import PropertiesController
#from orbit_visualiser.ui.config.display_panel.display_panel_controller import DisplayController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(
"e_anomaly" : PropertySpec("Eccentric anomaly", "°", lambda sat: np.degrees(sat.eccentric_anomaly)),
"m_anomaly" : PropertySpec("Mean anomaly", "°", lambda sat: np.degrees(sat.mean_anomaly)),
"time_periapsis" : PropertySpec("Time since periapsis", "s", lambda sat: sat.time_since_periapsis),
"ang_momentum" : PropertySpec("Angular momentum", "km²/s", lambda sat: sat.specific_angular_momentum),
"ang_momentum" : PropertySpec("Angular momentum", "km²/s", lambda sat: np.linalg.norm(sat.specific_angular_momentum)),
"speed" : PropertySpec("Orbital speed", "km/s", lambda sat: sat.speed),
"azim_velocity" : PropertySpec("Azimuthal velocity", "km/s", lambda sat: sat.radial_azimuthal_velocity[1]),
"radial_velocity" : PropertySpec("Radial velocity", "km/s", lambda sat: sat.radial_azimuthal_velocity[0]),
Expand Down
Loading
Loading