How-To: Numerical Propagation from a Typed Initial State (Self-Contained)¶
This recipe is designed for package users who installed astrodyn-core
with pip and want a realistic Orekit-backed propagation example without
cloning the repo.
It uses:
OrbitStateRecordfor the initial condition (serializable, state-file-friendly)PropagatorSpec+IntegratorSpec+GravitySpecfor the propagator configAstrodynClient.propagation.build_propagator_from_state(...)for the facade-first workflow
When to use this recipe¶
Use this when you want to:
- run a numerical propagator from a typed state record
- avoid manual Orekit orbit construction in your first script
- build intuition for the facade + spec API pattern
Prerequisites¶
astrodyn-coreinstalled- Orekit data configured
This snippet assumes orekit-data.zip is in the current working directory and
uses setup_orekit_curdir(). If that is not true in your setup, see:
Run (copy-paste)¶
import math
import orekit
orekit.initVM()
from orekit.pyhelpers import setup_orekit_curdir
setup_orekit_curdir()
from org.orekit.frames import FramesFactory
from astrodyn_core import (
AstrodynClient,
GravitySpec,
IntegratorSpec,
OrbitStateRecord,
PropagatorKind,
PropagatorSpec,
)
app = AstrodynClient()
# Serializable initial condition (can later be saved to a state file)
initial_state = OrbitStateRecord(
epoch="2026-02-19T00:00:00Z",
frame="GCRF",
representation="keplerian",
elements={
"a_m": 7578137.0,
"e": 0.001,
"i_deg": 51.6,
"argp_deg": 45.0,
"raan_deg": 120.0,
"anomaly_deg": 30.0,
"anomaly_type": "MEAN",
},
mu_m3_s2="WGS84",
mass_kg=450.0,
)
# Numerical propagator configuration (typed spec)
spec = PropagatorSpec(
kind=PropagatorKind.NUMERICAL,
mass_kg=450.0,
integrator=IntegratorSpec(
kind="dp853",
min_step=1e-6,
max_step=300.0,
position_tolerance=1e-3,
),
force_specs=[
GravitySpec(degree=8, order=8),
],
)
propagator = app.propagation.build_propagator_from_state(initial_state, spec)
start_date = app.state.to_orekit_date(initial_state.epoch)
target_date = start_date.shiftedBy(3600.0) # +1 hour
state = propagator.propagate(target_date)
orbit = state.getOrbit()
pos = state.getPVCoordinates(FramesFactory.getGCRF()).getPosition()
print(f"a = {orbit.getA()/1e3:.2f} km")
print(f"e = {orbit.getE():.6f}")
print(f"i = {math.degrees(orbit.getI()):.3f} deg")
print(f"r = ({pos.getX()/1e3:.1f}, {pos.getY()/1e3:.1f}, {pos.getZ()/1e3:.1f}) km")
What this demonstrates¶
OrbitStateRecordas a user-facing initial condition format- typed numerical propagation config via
PropagatorSpec - facade method
build_propagator_from_state(...) - propagation to a target epoch and basic state inspection
Why this pattern is useful for research workflows¶
This is a good baseline for student/research code because:
- the initial condition is explicit and serializable
- the numerical configuration is explicit and versionable
- the same
OrbitStateRecordcan later be reused in: - state files
- mission scenarios
- uncertainty workflows
Extended repo examples (same ideas)¶
If you cloned the repo, see:
examples/quickstart.py --mode numericalexamples/cookbook/multi_fidelity_comparison.pyexamples/cookbook/force_model_sweep.py