Skip to content

Satellite State

satstate

Satellite state: position, velocity, optional covariance, and maneuvers

Bundles a GCRF position/velocity with optional 6x6 covariance and a list of impulsive maneuvers into a single propagatable object. Use satstate instead of the free :func:propagate function when you need:

  • Covariance propagation -- attach uncertainty and it propagates automatically via the state transition matrix.
  • Maneuver scheduling -- add impulsive delta-v events at future times; propagation segments around them automatically.
  • Round-trip propagation -- propagate forward then backward, recovering the original state (maneuvers are reversed).

For simple state-vector propagation without covariance or maneuvers, :func:propagate is more direct.

This class supports pickle serialization (all fields including covariance and maneuvers are preserved).

Example
import satkit as sk
import numpy as np

# Create state at 500 km altitude
r = sk.consts.earth_radius + 500e3
v = np.sqrt(sk.consts.mu_earth / r)
sat = sk.satstate(sk.time(2024, 1, 1), np.array([r, 0, 0]), np.array([0, v, 0]))

# Add covariance and maneuver
sat.set_pos_uncertainty(np.array([100.0, 200.0, 50.0]), frame=sk.frame.LVLH)
sat.add_prograde(sat.time + sk.duration.from_hours(1), 10.0)

# Propagate -- covariance and maneuver handled automatically
new_state = sat.propagate(sat.time + sk.duration.from_hours(3))

pos property

Position in meters, GCRF frame (alias for pos_gcrf)

vel property

Velocity in m/s, GCRF frame (alias for vel_gcrf)

pos_gcrf property

Position in meters, GCRF frame

vel_gcrf property

Velocity in m/s, GCRF frame

qgcrf2lvlh property

Quaternion rotating from GCRF to the LVLH frame for the current state

LVLH frame
  • z axis: -r (nadir, pointing toward Earth center)
  • y axis: -h (opposite orbital angular momentum, h = r x v)
  • x axis: completes right-handed system

cov property writable

6x6 state covariance matrix in GCRF, or None if not set

Upper-left 3x3 is position covariance (m^2), lower-right 3x3 is velocity covariance ((m/s)^2), off-diagonal blocks are cross-covariance.

time property

Epoch of this satellite state

num_maneuvers property

Number of impulsive maneuvers scheduled on this state

__init__(time, pos, vel, cov=None)

Create a new satellite state

Parameters:

Name Type Description Default
time time

Epoch of the state

required
pos NDArray[float64]

Position in meters, GCRF frame

required
vel NDArray[float64]

Velocity in m/s, GCRF frame

required
cov NDArray[float64] | None

6x6 covariance matrix in GCRF. Defaults to None.

None
Example
t = satkit.time(2024, 1, 1)
pos = np.array([6.781e6, 0, 0])       # meters, GCRF
vel = np.array([0, 7.5e3, 0])          # m/s, GCRF
state = satkit.satstate(t, pos, vel)

set_pos_uncertainty(sigma, frame)

Set 1-sigma position uncertainty in a satellite-local or inertial frame.

Constructs a diagonal 3x3 covariance from the given 1-sigma values (interpreted along the frame's axes), rotates it into GCRF, and stores it as the position block of the 6x6 state covariance. Any existing velocity covariance is preserved.

Parameters:

Name Type Description Default
sigma NDArray[float64]

3-element numpy array of 1-sigma position components along the frame's axes. Units: meters.

required
frame frame

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

  • frame.GCRF — inertial Cartesian
  • frame.LVLH — Local Vertical / Local Horizontal
  • frame.RTN — Radial / In-track / Cross-track (= RSW = RTN)
  • frame.NTW — Normal-to-velocity / Tangent / Cross-track
required

Raises:

Type Description
RuntimeError

if the frame is not one of the supported frames.

Example
# LVLH: 100 m along-track, 200 m cross-track, 50 m nadir
sat.set_pos_uncertainty(np.array([100.0, 200.0, 50.0]), frame=sk.frame.LVLH)

# RIC: 10 m radial, 200 m in-track, 30 m cross-track
sat.set_pos_uncertainty(np.array([10.0, 200.0, 30.0]), frame=sk.frame.RTN)

set_vel_uncertainty(sigma, frame)

Set 1-sigma velocity uncertainty in a satellite-local or inertial frame.

Analogous to :meth:set_pos_uncertainty, but for the velocity block of the 6x6 state covariance. Any existing position covariance is preserved.

Parameters:

Name Type Description Default
sigma NDArray[float64]

3-element numpy array of 1-sigma velocity components along the frame's axes. Units: m/s.

required
frame frame

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

required

Raises:

Type Description
RuntimeError

if the frame is not one of the supported frames.

add_maneuver(time, delta_v, frame)

Add an impulsive maneuver (instantaneous delta-v)

Parameters:

Name Type Description Default
time time

Time at which to apply the maneuver

required
delta_v array - like

3-element delta-v vector [m/s]

required
frame frame

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

  • frame.GCRF — inertial Cartesian
  • frame.RTN — radial / in-track / cross-track (a.k.a. RSW, RTN). The I axis is perpendicular to R in the orbit plane — for eccentric orbits this is not strictly along velocity.
  • frame.NTW — normal-to-velocity / tangent / cross-track. The T axis is along velocity, so a pure +T burn of magnitude Δv adds exactly Δv to |v|. Preferred for prograde burns on eccentric orbits.
  • frame.LVLH — Local Vertical / Local Horizontal (classical crewed-spaceflight frame with z=nadir, y=-h, x=forward). Geometrically equivalent to RIC with relabeled axes; useful when porting GN&C code written in LVLH conventions.

See the "Theory: Maneuver Coordinate Frames" guide in the satkit documentation for a side-by-side comparison.

required
See Also

:meth:add_prograde, :meth:add_retrograde, :meth:add_radial, :meth:add_normal for scalar-magnitude helpers that pick the frame for you.

Example
# Explicit frame selection
sat.add_maneuver(t_burn, [0, 10, 0], frame=sk.frame.NTW)  # +10 m/s along velocity
sat.add_maneuver(t_burn, [0, 10, 0], frame=sk.frame.RTN)  # +10 m/s in RIC in-track

add_prograde(time, dv_mps)

Add a prograde impulsive burn (NTW +T, along velocity).

A positive dv_mps adds energy (raises semi-major axis). The burn adds exactly dv_mps to |v| regardless of orbit eccentricity.

Parameters:

Name Type Description Default
time time

Time at which to apply the burn

required
dv_mps float

Magnitude along velocity vector [m/s]

required
Example
sat.add_prograde(t_burn, 10.0)  # +10 m/s along velocity

add_retrograde(time, dv_mps)

Add a retrograde impulsive burn (NTW -T, opposite velocity).

Equivalent to add_prograde with a negated magnitude. dv_mps should be positive; a positive value removes energy from the orbit.

Parameters:

Name Type Description Default
time time

Time at which to apply the burn

required
dv_mps float

Magnitude along anti-velocity vector [m/s]

required

add_radial(time, dv_mps)

Add a radial-outward impulsive burn (NTW +N axis).

For circular orbits this is the outward radial direction. For eccentric orbits the N axis leans off the radial by the flight-path angle.

Parameters:

Name Type Description Default
time time

Time at which to apply the burn

required
dv_mps float

Magnitude along in-plane normal-to-velocity [m/s]

required

add_normal(time, dv_mps)

Add a cross-track ("normal") impulsive burn (NTW +W axis).

Positive values push in the +angular-momentum direction. Changes orbit inclination without altering energy (at apsides).

Parameters:

Name Type Description Default
time time

Time at which to apply the burn

required
dv_mps float

Magnitude along angular momentum direction [m/s]

required

propagate(time, *, propsettings=None, satproperties=None)

Propagate this state to a new time

If covariance is set, it is propagated via the state transition matrix. If maneuvers are scheduled between the current and target time, propagation automatically segments at each maneuver epoch and applies the delta-v. Maneuvers are preserved on the returned state.

Parameters:

Name Type Description Default
time time | duration

Target time, or duration from current time

required
propsettings propsettings

Propagation settings

None
satproperties satproperties

Satellite properties (drag, SRP, thrust)

None

Returns:

Name Type Description
satstate satstate

New state at the target time

Example
sat = sk.satstate(time=t0, pos=r, vel=v)
sat.add_maneuver(t_burn, [0, 100, 0], frame=sk.frame.RTN)
new_state = sat.propagate(t_end)