"""
Modified Equinoctial Elements (MEE) kinematics and conversions.
"""
import numpy as np
[docs]
def kepler2mee(
a: float,
ecc: float,
incl: float,
raan: float,
argp: float,
nu: float,
mu: float = 398600.4415e9
) -> tuple[float, float, float, float, float, float]:
"""
Convert Keplerian elements to Modified Equinoctial Elements (MEE).
MEE are non-singular for circular and equatorial orbits.
State vector: $[p, f, g, h, k, L]^T$.
Parameters
----------
a : float
Semi-major axis (m).
ecc : float
Eccentricity.
incl : float
Inclination (rad).
raan : float
RAAN (rad).
argp : float
Argument of Perigee (rad).
nu : float
True Anomaly (rad).
mu : float, optional
Gravitational parameter ($m^3/s^2$). Default is Earth.
Returns
-------
tuple[float, float, float, float, float, float]
MEE elements (p, f, g, h, k, L).
"""
p_mee = a * (1.0 - ecc**2)
f = ecc * np.cos(raan + argp)
g = ecc * np.sin(raan + argp)
h = np.tan(incl / 2.0) * np.cos(raan)
k = np.tan(incl / 2.0) * np.sin(raan)
l_true = raan + argp + nu
return (
float(p_mee),
float(f),
float(g),
float(h),
float(k),
float(l_true % (2 * np.pi))
)
[docs]
def mee2eci(
p: float,
f: float,
g: float,
h: float,
k: float,
l_true: float,
mu: float = 398600.4415e9
) -> tuple[np.ndarray, np.ndarray]:
"""
Convert Modified Equinoctial Elements to ECI Cartesian state.
Parameters
----------
p, f, g, h, k, l_true : float
Modified Equinoctial Elements.
mu : float, optional
Gravitational parameter ($m^3/s^2$). Default is Earth.
Returns
-------
tuple[np.ndarray, np.ndarray]
(Position vector (m), Velocity vector (m/s)).
"""
sin_l = np.sin(l_true)
cos_l = np.cos(l_true)
w = 1.0 + f * cos_l + g * sin_l
r = p / w
s2 = 1.0 + h**2 + k**2
r_eci = (r / s2) * np.array([
cos_l * (1 + h**2 - k**2) + 2 * h * k * sin_l,
sin_l * (1 - h**2 + k**2) + 2 * h * k * cos_l,
2 * (h * sin_l - k * cos_l),
])
v_coeff = np.sqrt(mu / p) / s2
v_eci = v_coeff * np.array([
-(sin_l * (1 + h**2 - k**2) - 2 * h * k * cos_l + g + g * h**2 - g * k**2 - 2 * f * h * k),
(cos_l * (1 - h**2 + k**2) - 2 * h * k * sin_l + f - f * h**2 + f * k**2 - 2 * g * h * k),
2 * (cos_l + f) * h + 2 * (sin_l + g) * k,
])
return r_eci, v_eci
[docs]
def eci2mee(
r_eci: np.ndarray,
v_eci: np.ndarray,
mu: float = 398600.4415e9
) -> tuple[float, float, float, float, float, float]:
"""
Convert ECI Cartesian state to Modified Equinoctial Elements.
Parameters
----------
r_eci : np.ndarray
Position vector (m).
v_eci : np.ndarray
Velocity vector (m/s).
mu : float, optional
Gravitational parameter ($m^3/s^2$). Default is Earth.
Returns
-------
tuple[float, float, float, float, float, float]
MEE elements (p, f, g, h, k, L).
"""
from .state_to_elements import eci2kepler
rv = np.asarray(r_eci)
vv = np.asarray(v_eci)
a, ecc, incl, raan, argp, nu, _, _, _, _, _, _ = eci2kepler(rv, vv)
return kepler2mee(a, ecc, incl, raan, argp, nu, mu)