Python ELFO Propagation and Frame ConversionΒΆ
This example mirrors the C++ tutorial with the Python bindings. It defines an ELFO with classical orbital elements in the Moon orbital plane frame, converts the initial state to Moon-centered inertial coordinates, propagates it with third-body perturbations, and converts the propagated states to the Moon principal-axes frame.
import numpy as np
import pylupnt as pnt
t0_tdb = pnt.convert_time(
pnt.gregorian_to_time(2030, 1, 1, 12, 0, 0),
pnt.UTC,
pnt.TDB,
)
coe_op = np.array(
[
6541.4e3, # semi-major axis [m]
0.60, # eccentricity [-]
65.5 * pnt.RAD, # inclination [rad]
0.0 * pnt.RAD, # right ascension of ascending node [rad]
90.0 * pnt.RAD, # argument of periapsis [rad]
0.0 * pnt.RAD, # true anomaly [rad]
]
)
rv0_op = pnt.classical_to_cart(coe_op, pnt.GM_MOON)
rv0_ci = pnt.convert_frame(t0_tdb, rv0_op, pnt.MOON_OP, pnt.MOON_CI)
dynamics = pnt.NBodyDynamics()
dynamics.set_frame(pnt.MOON_CI)
dynamics.add_body(pnt.Body.Moon(20, 20))
dynamics.add_body(pnt.Body.Earth())
dynamics.add_body(pnt.Body.Sun())
tspan = np.arange(t0_tdb, t0_tdb + 7.0 * pnt.SECS_DAY, pnt.SECS_HOUR)
rv_ci = dynamics.propagate(rv0_ci, tspan)
rv_pa = pnt.convert_frame(tspan, rv_ci, pnt.MOON_CI, pnt.MOON_PA)
print("Initial Moon-CI state [m, m/s]:", rv0_ci)
print("Final Moon-PA state [m, m/s]:", rv_pa[-1])
The dynamics model is configured in Moon-CI because the numerical propagator expects a single integration frame. The frame conversion calls handle the initial geometry and any output products that are more useful in a body-fixed or orbit-related frame.