This repository contains the implementation described in:
Acciarini, Baydin, Izzo, Closing the gap between SGP4 and high-precision propagation via differentiable programming, Acta Astronautica (2025), https://doi.org/10.1016/j.actaastro.2024.10.063.
What dSGP4 provides
A PyTorch implementation of SGP4 with autograd support.
Gradients of propagated states with respect to time and TLE-derived parameters.
Parsing, writing and conversion of both TLEs and CCSDS OMMs (JSON/XML/KVN/CSV).
Single-object and batched propagation APIs.
A hybrid model (mldsgp4) for learning corrections around SGP4 dynamics.
Primary use cases include state transition matrix estimation, covariance transformation/propagation, gradient-based orbit estimation, and ML-augmented orbit prediction.
Installation
From PyPI:
pip install dsgp4
From conda-forge:
conda install conda-forge::dsgp4
# or
mamba install dsgp4
From source:
git clone https://github.com/esa/dSGP4.git
cd dSGP4
pip install -e .
Quick start
1. Parse a TLE and propagate
import torch
import dsgp4
tle = dsgp4.TLE([
"1 25544U 98067A 24060.50000000 .00016717 00000-0 30134-3 0 9990",
"2 25544 51.6403 124.7938 0005102 220.2782 248.4427 15.50010353440289",
])
# Initialize once, then reuse for multiple propagations.
dsgp4.initialize_tle(tle, gravity_constant_name="wgs-84")
# tsince is in minutes from TLE epoch.
tsince = torch.tensor([0.0, 10.0, 20.0])
state = dsgp4.propagate(tle, tsince)
# state shape: (N, 2, 3) when tsince has N elements
# state[:, 0, :] -> position [km], state[:, 1, :] -> velocity [km/s]
print(state.shape)
2. Parse an OMM and propagate
Space-Track distributes the same SGP4 mean elements in the CCSDS OMM (Orbit Mean-Elements
Message) format, which dSGP4 reads in all its four serializations (JSON, XML, KVN and CSV):
import torch
import dsgp4
omm = dsgp4.OMM({
"OBJECT_NAME": "ISS (ZARYA)",
"OBJECT_ID": "1998-067A",
"EPOCH": "2024-02-29T12:00:00.000000",
"MEAN_MOTION": "15.50010353",
"ECCENTRICITY": "0.0005102",
"INCLINATION": "51.6403",
"RA_OF_ASC_NODE": "124.7938",
"ARG_OF_PERICENTER": "220.2782",
"MEAN_ANOMALY": "248.4427",
"NORAD_CAT_ID": "25544",
"BSTAR": "0.00030134",
"MEAN_MOTION_DOT": "0.00016717",
"MEAN_MOTION_DDOT": "0",
})
# OMM objects are used exactly like TLE ones:
dsgp4.initialize_tle(omm)
state = dsgp4.propagate(omm, torch.tensor([0.0, 10.0]))
# whole files (one message or many) are read with:
omms = dsgp4.omm.load("gp.json")
# and the two formats convert into each other:
tle = omm.to_tle()
omm = tle.to_omm()
Unlike a TLE, an OMM is not constrained by two fixed-width lines: objects whose catalog number
is above 339999 (i.e. beyond what the Alpha-5 convention can encode) can only be represented
this way, and to_tle() raises a ValueError for them.
3. Differentiate through propagation
import torch
import dsgp4
tle = dsgp4.TLE([
"1 25544U 98067A 24060.50000000 .00016717 00000-0 30134-3 0 9990",
"2 25544 51.6403 124.7938 0005102 220.2782 248.4427 15.50010353440289",
])
time_min = torch.tensor(15.0, requires_grad=True)
state = dsgp4.propagate(tle, time_min, initialized=False)
# Example scalar objective: x-position at time_min.
loss = state[0, 0]
loss.backward()
print(time_min.grad)
@article{acciarini2024closing,
title = {Closing the gap between SGP4 and high-precision propagation via differentiable programming},
journal = {Acta Astronautica},
volume = {226},
pages = {694-701},
year = {2025},
issn = {0094-5765},
doi = {https://doi.org/10.1016/j.actaastro.2024.10.063},
url = {https://www.sciencedirect.com/science/article/pii/S0094576524006374},
author = {Giacomo Acciarini and Atılım Güneş Baydin and Dario Izzo},
keywords = {SGP4, Orbital propagation, Differentiable programming, Machine learning, Spacecraft collision avoidance, Kessler, Kessler syndrome, AI for space, Applied machine learning for space}
}
dSGP4 (∂SGP4)
Differentiable SGP4 in PyTorch.
This repository contains the implementation described in:
Acciarini, Baydin, Izzo, Closing the gap between SGP4 and high-precision propagation via differentiable programming, Acta Astronautica (2025), https://doi.org/10.1016/j.actaastro.2024.10.063.
What dSGP4 provides
mldsgp4) for learning corrections around SGP4 dynamics.Primary use cases include state transition matrix estimation, covariance transformation/propagation, gradient-based orbit estimation, and ML-augmented orbit prediction.
Installation
From PyPI:
From conda-forge:
From source:
Quick start
1. Parse a TLE and propagate
2. Parse an OMM and propagate
Space-Track distributes the same SGP4 mean elements in the CCSDS OMM (Orbit Mean-Elements Message) format, which dSGP4 reads in all its four serializations (JSON, XML, KVN and CSV):
Unlike a TLE, an OMM is not constrained by two fixed-width lines: objects whose catalog number is above 339999 (i.e. beyond what the Alpha-5 convention can encode) can only be represented this way, and
to_tle()raises aValueErrorfor them.3. Differentiate through propagation
4. Batched propagation
Technical notes and limitations
tsince) is in minutes from the TLE epoch.wgs-72,wgs-84,wgs-72old.float64when importingdsgp4.Development
Run tests:
Documentation and notebooks
doc/notebooks/.Citation
If you use
dsgp4, please cite:Authors
The project originated from work at the University of Oxford AI4Science Lab.
Acknowledgements
We thank Dr. T.S. Kelso for support and validation guidance against the official Space-Track SGP4 release: https://www.space-track.org/documentation#/sgp4.
License
dSGP4 is distributed under GNU GPL v3. Contact the authors for alternative licensing options.
Contact