Skip to content

High-Precision Orbit Propagator

propagate(state, begin, end=None, *, duration=None, duration_secs=None, duration_days=None, output_phi=False, propsettings=None, satproperties=None)

High-precision orbit propagator

Propagate orbits with high-precision force modeling via adaptive Runge-Kutta methods (default is order 9/8).

Parameters:

Name Type Description Default
state NDArray[float64]

6-element numpy array representing satellite GCRF position and velocity in meters and meters/second

required
begin time

Time at which satellite is at input state

required

Other Parameters:

Name Type Description
end time | None

Time at which new position and velocity will be computed

duration duration | None

Duration from begin at which new position & velocity will be computed

duration_secs float | None

Duration in seconds from begin at which new position and velocity will be computed

duration_days float | None

Duration in days from begin at which new position and velocity will be computed

output_phi bool

Output 6x6 state transition matrix between begin and end times. Default is False

propsettings propsettings | None

Settings for the propagation; if omitted, defaults are used

satproperties satproperties | None

Drag and radiation pressure susceptibility of satellite

Returns:

Name Type Description
propresult propresult

Propagation result object holding state outputs, statistics, and dense output if requested

Notes

Propagates satellite ephemeris (position, velocity in GCRF & time) to new time and outputs new position and velocity via Runge-Kutta integration. Inputs and outputs are all in the Geocentric Celestial Reference Frame (GCRF).

Included forces:

  • Earth gravity with higher-order zonal terms
  • Sun, Moon gravity
  • Radiation pressure
  • Atmospheric drag: NRL-MSISE 2000 density model, with option to include space weather effects

End time must be set by keyword argument, either explicitly or by duration. Solid Earth tides are not (yet) included in the model.

For future propagation (beyond available data files):

  • Earth orientation parameters use the last available values (constant extrapolation)
  • Space weather uses the NOAA/SWPC solar cycle forecast for predicted F10.7 values; Ap defaults to 4. If no forecast is available, F10.7 defaults to 150.
Example
import numpy as np

# Define initial state in GCRF (position in meters, velocity in m/s)
state = np.array([6.781e6, 0, 0, 0, 7.5e3, 0])
t0 = satkit.time(2024, 1, 1)

# Propagate forward by 1 day
result = satkit.propagate(state, t0, duration_days=1.0)
print(f"End position: {result.pos} m")
print(f"End velocity: {result.vel} m/s")

# Interpolate at intermediate time
t_mid = t0 + satkit.duration(hours=12)
mid_state = result.interp(t_mid)

propresult

Results of a satellite propagation

This class lets the user access results of the satellite propagation

Notes

If enable_interp is set to True in the propagation settings, the propresult object can be used to interpolate solutions at any time between the begin and end times of the propagation via the interp method.

pos property

GCRF position of satellite, meters

Returns:

Type Description
NDArray[float64]

3-element numpy array representing GCRF position (meters) at end of propagation

vel property

GCRF velocity of satellite, meters/second

Returns:

Type Description
NDArray[float64]

3-element numpy array representing GCRF velocity in meters/second at end of propagation

state property

6-element end state (pos + vel) of satellite in meters & meters/second

Returns:

Type Description
NDArray[float64]

6-element numpy array representing state of satellite in meters & meters/second

state_end property

6-element state (pos + vel) of satellite in meters & meters/second at end of propagation

Notes: - This is the same as the "state" property

Returns:

Type Description
NDArray[float64]

6-element numpy array representing state of satellite in meters & meters/second

state_begin property

6-element state (pos + vel) of satellite in meters & meters/second at begin of propagation Returns: 6-element numpy array representing state of satellite in meters & meters/second at begin of propagation

time property

Time at which state is valid

Returns:

Type Description
time

Time at which state is valid

time_end property

Time at which state is valid

Notes: - This is identical to "time" property

Returns:

Type Description
time

Time at which state is valid

time_begin property

Time at which state_begin is valid

Returns:

Type Description
time

Time at which state_begin is valid

stats property

Statistics of propagation

Returns:

Name Type Description
propstats propstats

Object containing statistics of propagation

can_interp property

Whether this result supports interpolation

Returns:

Type Description
bool

True if dense output is available for interpolation

phi property

State transition matrix

Returns:

Type Description
NDArray[float64] | None

6x6 numpy array representing state transition matrix or None if not computed

interp(time, output_phi=False)

interp(time: time | datetime.datetime, output_phi: typing.Literal[False] = False) -> npt.NDArray[np.float64]
interp(time: time | datetime.datetime, output_phi: typing.Literal[True] = ...) -> tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]
interp(time: list[time | datetime.datetime], output_phi: typing.Literal[False] = False) -> list[npt.NDArray[np.float64]]
interp(time: list[time | datetime.datetime], output_phi: typing.Literal[True] = ...) -> list[tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]]]

Interpolate state at given time(s)

Requires enable_interp=True in propagation settings.

Parameters:

Name Type Description Default
time time | datetime | list

Time or list of times at which to interpolate state. datetime.datetime objects are interpreted as UTC.

required
output_phi bool

If True, also return the 6x6 state transition matrix. Default is False.

False

Returns:

Type Description

For a single time: a 6-element state vector, or a (state, phi) tuple if output_phi=True. For a list of times: a list of state vectors, or a list of (state, phi) tuples.

Example
# After propagation with enable_interp=True
result = satkit.propagate(state, t0, duration_days=1.0)
t_mid = t0 + satkit.duration(hours=12)
mid_state = result.interp(t_mid)
print(f"Position at 12h: {mid_state[0:3]} m")

# Interpolate at multiple times
times = [t0 + satkit.duration(hours=h) for h in range(25)]
states = result.interp(times)

propsettings

This class contains settings used in the high-precision orbit propagator part of the "satkit" python toolbox

Notes
  • Default settings:
    • abs_error: 1e-8
    • rel_error: 1e-8
    • gravity_degree: 4
    • gravity_order: 4
    • gravity_model: gravmodel.egm96
    • use_spaceweather: True
    • use_sun_gravity: True
    • use_moon_gravity: True
    • enable_interp: True
    • integrator: integrator.rkv98
    • gj_step_seconds: 60.0
    • max_steps: 1_000_000
  • enable_interp enables high-precision interpolation of state between begin and end times via the returned function, it is enabled by default. There is a small increase in computational efficiency if set to false

abs_error property writable

Maximum absolute value of error for any element in propagated state following ODE integration

Returns:

Type Description
float

Maximum absolute value of error for any element in propagated state following ODE integration, default is 1e-8

rel_error property writable

Maximum relative error of any element in propagated state following ODE integration

Returns:

Type Description
float

Maximum relative error of any element in propagated state following ODE integration, default is 1e-8

gravity_degree property writable

Maximum degree of spherical harmonic gravity model

Returns:

Type Description
int

Maximum degree of spherical harmonic gravity model, default is 4

gravity_order property writable

Maximum order of spherical harmonic gravity model

Returns:

Type Description
int

Maximum order of spherical harmonic gravity model, default is same as gravity_degree

use_sun_gravity property writable

Include sun third-body gravitational perturbation

Returns:

Type Description
bool

Whether sun gravity is enabled, default is True

use_moon_gravity property writable

Include moon third-body gravitational perturbation

Returns:

Type Description
bool

Whether moon gravity is enabled, default is True

use_spaceweather property writable

Use space weather data when computing atmospheric density for drag forces

Notes:

  • Space weather data can have a large effect on the density of the atmosphere
  • This can be important for accurate drag force calculations
  • Space weather data is updated every 3 hours. Most-recent data can be downloaded with satkit.utils.update_datafiles()
  • Default value is True

Returns:

Type Description
bool

Indicate whether or not space weather data should be used when computing atmospheric density for drag forces

enable_interp property writable

Store intermediate data that allows for fast high-precision interpolation of state between begin and end times If not needed, there is a small computational advantage if set to False

gravity_model property writable

Gravity model used for Earth gravity computation

Returns:

Name Type Description
gravmodel gravmodel

The gravity model, default is gravmodel.egm96

integrator property writable

ODE integrator used for orbit propagation

Returns:

Name Type Description
integrator integrator

The integrator, default is integrator.rkv98

gj_step_seconds property writable

Fixed step size (seconds) used by integrator.gauss_jackson8.

Ignored by adaptive integrators. Typical values: 30-120 s for LEO, 60-300 s for MEO, 300-600 s for GEO.

Returns:

Type Description
float

Fixed step size in seconds, default is 60.0

max_steps property writable

Maximum number of integrator steps before the propagator aborts.

Applies to all integrators (adaptive Runge-Kutta, Rosenbrock, and Gauss-Jackson 8). Increase for very long propagation arcs or tight tolerances.

Returns:

Type Description
int

Maximum steps, default is 1_000_000

__init__(*, abs_error=1e-08, rel_error=1e-08, gravity_degree=4, gravity_order=4, gravity_model=..., use_spaceweather=True, use_sun_gravity=True, use_moon_gravity=True, enable_interp=True, integrator=..., gj_step_seconds=60.0, max_steps=1000000)

Create propagation settings object used to configure high-precision orbit propagator

Parameters:

Name Type Description Default
abs_error float

Maximum absolute value of error for any element in propagated state following ODE integration. Default is 1e-8

1e-08
rel_error float

Maximum relative error of any element in propagated state following ODE integration. Default is 1e-8

1e-08
gravity_degree int

Maximum degree of spherical harmonic gravity model. Default is 4

4
gravity_order int

Maximum order of spherical harmonic gravity model. Must be <= gravity_degree. Default is same as gravity_degree

4
gravity_model gravmodel

Gravity model to use. Default is gravmodel.egm96

...
use_spaceweather bool

Use space weather data when computing atmospheric density for drag forces. Default is True

True
use_sun_gravity bool

Include sun third-body gravitational perturbation. Default is True

True
use_moon_gravity bool

Include moon third-body gravitational perturbation. Default is True

True
enable_interp bool

Store intermediate data that allows for fast high-precision interpolation of state between begin and end times. Default is True

True
integrator integrator

ODE integrator to use. Default is integrator.rkv98

...
gj_step_seconds float

Fixed step size (seconds) used by integrator.gauss_jackson8. Ignored by adaptive integrators. Typical values: 30-120 s for LEO, 60-300 s for MEO, 300-600 s for GEO. Default is 60.0.

60.0
max_steps int

Maximum number of integrator steps before the propagator aborts with a max-steps error. Applies to all integrators (adaptive Runge-Kutta, Rosenbrock, and Gauss-Jackson 8). Default is 1_000_000, which covers very long propagation arcs with plenty of headroom. Lower for a tighter runaway-propagation safeguard.

1000000

Returns:

Name Type Description
propsettings None

New propsettings object with default settings

Example
settings = satkit.propsettings(
    gravity_degree=16,
    abs_error=1e-10,
    rel_error=1e-10,
    gravity_model=satkit.gravmodel.egm96,
    integrator=satkit.integrator.rkts54,
)

precompute_terms(begin, end, step=None)

Precompute terms for fast interpolation of state between begin and end times

This can be used, for example, to compute sun and moon positions only once if propagating many satellites over the same time period

Parameters:

Name Type Description Default
begin time

Begin time of propagation

required
end time

End time of propagation

required
step duration | float | timedelta

Step size for interpolation. Default = 60 seconds. float is interpreted as seconds.

None

integrator

Choice of ODE integrator for orbit propagation

Available integrators, from highest to lowest order:

  • rkv98 - Verner 9(8) with 9th-order dense output, 26 stages (default)
  • rkv98_nointerp - Verner 9(8) without interpolation, 16 stages
  • rkv87 - Verner 8(7) with 8th-order dense output, 21 stages
  • rkv65 - Verner 6(5), 10 stages
  • rkts54 - Tsitouras 5(4) with FSAL, 7 stages
  • rodas4 - RODAS4 L-stable Rosenbrock 4(3), 6 stages. For stiff problems.
  • gauss_jackson8 - Gauss-Jackson 8, fixed-step multistep predictor-corrector. For high-precision long-duration orbit propagation (days to months).

Higher-order integrators can take larger time steps for the same accuracy, so despite having more stages per step, they often require fewer total function evaluations. For typical orbit propagation, rkv98 (the default) is recommended. For faster but lower-accuracy propagation, rkts54 or rkv65 can be used. For stiff problems (re-entry, very low perigee), rodas4 is recommended. For long-duration high-precision propagation of smooth orbits, gauss_jackson8 typically uses 3-10× fewer force evaluations than rkv98 at comparable accuracy — but it requires a user-chosen fixed step size (gj_step_seconds), does not handle discontinuities such as impulsive maneuvers, and needs ≥9 steps of startup, so it's unsuitable for very short propagations.

rkv98 class-attribute

Verner 9(8) with 9th-order dense output, 26 stages (default)

Highest accuracy integrator. Recommended for precision orbit propagation.

rkv98_nointerp class-attribute

Verner 9(8) without interpolation, 16 stages

Same stepping accuracy as rkv98 but skips interpolation stages. Slightly faster when dense output is not needed (enable_interp=False).

rkv87 class-attribute

Verner 8(7) with 8th-order dense output, 21 stages

rkv65 class-attribute

Verner 6(5), 10 stages

rkts54 class-attribute

Tsitouras 5(4) with FSAL, 7 stages

Fastest integrator. Good for quick propagations where high accuracy is not critical.

rodas4 class-attribute

RODAS4 — L-stable Rosenbrock 4(3), 6 stages

Implicit solver for stiff problems such as re-entry or very low perigee orbits. Uses analytical Jacobian. Does not support dense output interpolation or state transition matrix (output_phi) propagation.

gauss_jackson8 class-attribute

Gauss-Jackson 8 — 8th-order fixed-step multistep predictor-corrector

Specialised for 2nd-order ODEs (r'' = f(t, r, v)). The dominant integrator in high-precision astrodynamics codes (GMAT, STK, ODTK). Typically uses 3-10× fewer force evaluations than rkv98 at comparable accuracy on smooth long-duration orbit propagation.

Uses a fixed step size set via propsettings.gj_step_seconds. Supports dense output interpolation (quintic Hermite, 5th-order). Does not support state transition matrix (output_phi) propagation. Not recommended for highly eccentric orbits or integration across discontinuities (eclipse boundaries, impulsive maneuvers).

propstats

Statistics of a satellite propagation

num_eval property

Number of function evaluations

num_accept property

Number of accepted steps in adaptive RK integrator

num_reject property

Number of rejected steps in adaptive RK integrator

satproperties

Satellite properties relevant for drag, radiation pressure, and thrust

This class lets the satellite radiation pressure, drag, and thrust parameters be set for duration of propagation.

Attributes:

Name Type Description
cdaoverm float

Coefficient of drag times area over mass in m^2/kg

craoverm float

Coefficient of radiation pressure times area over mass in m^2/kg

thrusts list[thrust]

List of continuous thrust arcs

cdaoverm property writable

Coefficient of drag times area over mass. Units are m^2/kg

craoverm property writable

Coefficient of radiation pressure times area over mass. Units are m^2/kg

thrusts property writable

List of continuous thrust arcs

__init__(cdaoverm=0, craoverm=0, *, thrusts=None)

Create a satproperties object

Parameters:

Name Type Description Default
cdaoverm float

Coefficient of drag times area over mass in m^2/kg

0
craoverm float

Coefficient of radiation pressure times area over mass in m^2/kg

0
thrusts list[thrust]

List of continuous thrust arcs

None

Example:

import satkit as sk

t0 = sk.time(2024, 1, 1)
t1 = t0 + sk.duration.from_hours(2)

props = sk.satproperties(
    cdaoverm=0.01,
    thrusts=[sk.thrust.constant([0, 1e-4, 0], t0, t1, frame=sk.frame.RTN)]
)

thrust

Continuous thrust acceleration for orbit maneuvers

Represents a constant thrust acceleration over a time window, specified in GCRF (inertial), RTN (CCSDS-standard orbital frame, also known as RSW or RIC), NTW (velocity-aligned), or LVLH.

RTN components are [R, T, N] where R = radial (outward from Earth centre), T = tangential / in-track, N = normal / cross-track (along angular momentum, h = r × v).

Example:

import satkit as sk

t0 = sk.time(2024, 1, 1)
t1 = t0 + sk.duration.from_hours(2)

# In-track thrust in the RTN (a.k.a. RSW, RIC) frame
t = sk.thrust.constant([0, 1e-4, 0], t0, t1, frame=sk.frame.RTN)

# Fixed direction thrust in GCRF frame
t = sk.thrust.constant([0, 0, 1e-3], t0, t1, frame=sk.frame.GCRF)

accel property

Acceleration vector [m/s^2]

frame property

Coordinate frame

start property

Start time of thrust arc

end property

End time of thrust arc

constant(accel, start, end, frame) staticmethod

Create a constant thrust acceleration

Parameters:

Name Type Description Default
accel array - like

3-element acceleration vector [m/s^2]

required
start time

Start time of thrust arc

required
end time

End time of thrust arc

required
frame frame

Coordinate frame — required, no default (matching the Rust API). Supported values:

  • frame.GCRF — inertial Cartesian
  • frame.RTN — radial / in-track / cross-track
  • frame.NTW — normal-to-velocity / tangent / cross-track (use this for thrust along the velocity vector)
  • frame.LVLH — Local Vertical / Local Horizontal
required

Returns:

Name Type Description
thrust thrust

Thrust object