Deep Space Propagation#
This notebook shows how to propagate TLEs with orbital period above 225 minutes (deep-space regime) and how to keep gradients enabled through propagation.
In dSGP4, deep-space satellites are selected automatically when\n \n $\(\n \frac{2\pi}{n_0} \ge 225\;\text{minutes}\n \)\(\n \n where \)n_0$ is the mean motion in rad/min.
import dsgp4
import numpy as np
import torch
1. Load a deep-space TLE#
You can use any TLE with mean motion low enough to satisfy the 225-minute rule (for example geostationary satellites).
# Replace these lines with your deep-space TLE lines.
line1 = "1 41866U 16071A 24087.50000000 -.00000149 00000+0 00000+0 0 9990"
line2 = "2 41866 0.0171 87.5375 0001375 158.4767 157.4602 1.00270055 26844"
tle = dsgp4.tle.TLE([line1, line2])
# Initialize (deep-space mode is selected automatically when applicable).
dsgp4.initialize_tle(tle, gravity_constant_name="wgs-84")
period_minutes = float(2.0 * np.pi / tle._no_unkozai)
print("method:", tle._method)
print("orbital period [min]:", period_minutes)
method: d
orbital period [min]: 1436.175046066531
2. Propagate at one or multiple epochs#
tsince = torch.tensor([0.0, 360.0, 720.0, 1440.0]) # minutes since epoch
state = dsgp4.propagate(tle, tsince, initialized=True)
# state shape: [N, 2, 3]
# row 0: position [km], row 1: velocity [km/s]
print(state.shape)
print("r(t0) [km]:", state[0, 0])
print("v(t0) [km/s]:", state[0, 1])
torch.Size([4, 2, 3])
r(t0) [km]: tensor([ 3.0597e+04, 2.9019e+04, -4.6631e+00])
v(t0) [km/s]: tensor([-2.1155e+00, 2.2307e+00, -3.2063e-04])
3. Enable gradients through deep-space propagation#
To differentiate with respect to TLE parameters, initialize with with_grad=True and backpropagate from any scalar objective.
tle = dsgp4.tle.TLE([line1, line2])
tle_elements = dsgp4.initialize_tle(
tle,
gravity_constant_name="wgs-84",
with_grad=True,
)
tsince = torch.tensor(120.0)
state = dsgp4.propagate(tle, tsince, initialized=True) # [2, 3]
# Example objective: x-position at tsince=120 min
loss = state[0, 0]
loss.backward()
# Gradient order in tle_elements:
# [bstar, ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo]
print(tle_elements.grad)
tensor([-3.7028e-07, 0.0000e+00, 0.0000e+00, 2.2769e+04, -4.0446e+04,
5.4492e+01, -4.0435e+04, -6.6712e+06, -4.0446e+04])
4. Batch propagation with mixed near-earth and deep-space objects#
If a batch contains deep-space members, dSGP4 automatically falls back to a per-satellite propagation path while preserving the same API.
tles = [
dsgp4.tle.TLE([line1, line2]), # deep-space example
dsgp4.tle.TLE([
"1 25544U 98067A 24087.49097222 .00016717 00000+0 10270-3 0 9993",
"2 25544 51.6400 82.2420 0006290 58.9900 53.5550 15.50000000000000",
]),
]
_, initialized = dsgp4.initialize_tle(tles, gravity_constant_name="wgs-84")
tsinces = torch.tensor([60.0, 60.0])
batch_state = dsgp4.propagate_batch(initialized, tsinces, initialized=True)
print(batch_state.shape) # [2, 2, 3]
torch.Size([2, 2, 3])
Notes#
Deep-space support is available in scalar propagation and in mixed batches.
Gradients are supported through the deep-space scalar path.
For reproducibility against external implementations, use the same gravity constants and operation mode.