From fb0c4f5bb94172b6b7a8c71cf94996c94a92d217 Mon Sep 17 00:00:00 2001 From: Tobias Edman Date: Sat, 4 Jul 2026 11:22:31 +0200 Subject: [PATCH] Document two-body vs SGP4 propagation fidelity in ActorBuilder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit set_orbit creates an analytical Keplerian two-body orbit, so J2 and drag are unmodelled and propagated positions drift from real satellite trajectories over multi-hour horizons. Measured for a LEO/SSO actor seeded from an SGP4 state: 252 km at +3 h, 5,418 km at +72 h vs the TLE's SGP4 trajectory, while set_TLE matches SGP4 exactly. Add a fidelity note to the set_orbit docstring pointing TLE users to set_TLE, a cross-reference in set_TLE, and a matching N.B. in the README's orbit section. No behaviour change. Verified-by: pytest paseos/tests — 30 passed; 6 pre-existing env failures identical on unmodified tree Co-Authored-By: Claude Fable 5 --- README.md | 2 ++ paseos/actors/actor_builder.py | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c258d719..d8708b4e 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,8 @@ ActorBuilder.set_orbit(actor=sat_actor, epoch=pk.epoch(0), central_body=earth) ``` +N.B. `set_orbit` creates an analytical [two-body](https://en.wikipedia.org/wiki/Two-body_problem) orbit. Perturbations such as Earth oblateness (J2) and atmospheric drag are not modelled, so propagated positions deviate from real satellite trajectories as the propagation horizon grows — for a satellite in low Earth orbit, typically hundreds of kilometers within a few hours and thousands of kilometers within a few days relative to the corresponding SGP4/TLE trajectory. If your orbit data comes from a TLE, prefer `set_TLE` below. + ##### SGP4 / Two-line element (TLE) For using SGP4 / [Two-line element (TLE)](https://en.wikipedia.org/wiki/Two-line_element_set) you need to specify the TLE of the [SpacecraftActor](#spacecraftactor). In this case, we will use the TLE of the [Sentinel-2A](https://en.wikipedia.org/wiki/Sentinel-2) satellite from [celestrak](https://celestrak.com/). diff --git a/paseos/actors/actor_builder.py b/paseos/actors/actor_builder.py index 17d022a3..00bbccbc 100644 --- a/paseos/actors/actor_builder.py +++ b/paseos/actors/actor_builder.py @@ -236,6 +236,10 @@ def set_TLE( TLEs can be obtained from https://www.space-track.org/ or https://celestrak.com/NORAD/elements/ + The actor will be propagated with SGP4, i.e. consistently with the model + that generated the TLE. Prefer this over set_orbit when your orbit data + comes from a TLE (see the note in set_orbit). + Args: actor (SpacecraftActor): Actor to update. line1 (str): First line of the TLE. @@ -262,7 +266,16 @@ def set_orbit( epoch: pk.epoch, central_body: pk.planet, ): - """Define the orbit of the actor + """Define the orbit of the actor as an analytical Keplerian two-body orbit. + + Note that perturbations such as Earth oblateness (J2) and atmospheric drag + are not modelled by this orbit, so propagated positions increasingly deviate + from real satellite trajectories as the propagation horizon grows. For a + satellite in low Earth orbit, the deviation from the corresponding SGP4/TLE + trajectory typically reaches hundreds of kilometers within a few hours and + thousands of kilometers within a few days. If your position / velocity come + from a TLE, use set_TLE instead to propagate with SGP4. For higher-fidelity + propagators, use set_custom_orbit. Args: actor (BaseActor): The actor to define on