Skip to content

Factory

Configurable orbit dynamics factory.

Composes individual force model building blocks into a single dynamics(t, state) -> derivative closure compatible with all astrojax integrators.

The factory captures static configuration at Python trace time — boolean toggles like config.drag become Python if branches that are resolved during jax.jit tracing, producing an optimized computation graph with no runtime branching overhead.

create_orbit_dynamics(eop, epoch_0, config=None, space_weather=None)

Create a configurable orbit dynamics function.

Returns a closure dynamics(t, state) -> derivative that computes the time-derivative of a 6-element ECI state vector, composing the selected force models from config.

The returned function is compatible with all astrojax integrators (rk4_step, rkf45_step, dp54_step, rkn1210_step).

Parameters:

Name Type Description Default
eop EOPData

Earth orientation parameters for ECI-ECEF frame rotations. Use zero_eop() when no Earth orientation corrections are needed.

required
epoch_0 Epoch

Reference epoch. The integrator time t is interpreted as seconds since this epoch.

required
config ForceModelConfig | None

Force model configuration. Defaults to point-mass two-body gravity (ForceModelConfig.two_body()).

None
space_weather SpaceWeatherData | None

Space weather data for NRLMSISE-00 density model. Required when config.density_model is "nrlmsise00". Ignored for Harris-Priester.

None

Returns:

Type Description
Callable[[ArrayLike, ArrayLike], Array]

A callable dynamics(t, state) -> derivative where:

Callable[[ArrayLike, ArrayLike], Array]
  • t: seconds since epoch_0 (scalar).
Callable[[ArrayLike, ArrayLike], Array]
  • state: [x, y, z, vx, vy, vz] in ECI [m, m/s].
Callable[[ArrayLike, ArrayLike], Array]
  • derivative: [vx, vy, vz, ax, ay, az] [m/s, m/s^2].

Raises:

Type Description
ValueError

If gravity_type is "spherical_harmonics" but no gravity_model is provided.

ValueError

If density_model is "nrlmsise00" but no space_weather is provided.

Examples:

import jax.numpy as jnp
from astrojax import Epoch
from astrojax.eop import zero_eop
from astrojax.orbit_dynamics.factory import create_orbit_dynamics
from astrojax.orbit_dynamics.config import ForceModelConfig
from astrojax.integrators import rk4_step
epoch_0 = Epoch(2024, 6, 15, 12, 0, 0)
dynamics = create_orbit_dynamics(zero_eop(), epoch_0)
x0 = jnp.array([6878e3, 0.0, 0.0, 0.0, 7612.0, 0.0])
result = rk4_step(dynamics, 0.0, x0, 60.0)