Skip to content

Commit 6f88935

Browse files
authored
Merge pull request #24 from Sceki/deep_propagation
Deep space module
2 parents 9683302 + 964edf1 commit 6f88935

16 files changed

Lines changed: 1414 additions & 124 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ print(states.shape) # (2, 2, 3)
121121
- Time input (`tsince`) is in minutes from the TLE epoch.
122122
- Output units are km (position) and km/s (velocity).
123123
- Supported gravity constants: `wgs-72`, `wgs-84`, `wgs-72old`.
124-
- Deep-space propagation is currently not supported (periods above 225 minutes).
124+
- Deep-space propagation is supported.
125125
- Default torch dtype is set to `float64` when importing `dsgp4`.
126126

127127
## Development
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "7d660414",
6+
"metadata": {},
7+
"source": [
8+
"# Deep Space Propagation\n",
9+
"\n",
10+
"This notebook shows how to propagate TLEs with orbital period above 225 minutes (deep-space regime) and how to keep gradients enabled through propagation.\n",
11+
"\n",
12+
"In dSGP4, deep-space satellites are selected automatically when\\n\n",
13+
"\\n\n",
14+
"$$\\n\n",
15+
"\\frac{2\\pi}{n_0} \\ge 225\\;\\text{minutes}\\n\n",
16+
"$$\\n\n",
17+
"\\n\n",
18+
"where $n_0$ is the mean motion in rad/min."
19+
]
20+
},
21+
{
22+
"cell_type": "code",
23+
"execution_count": null,
24+
"id": "3e2e1e65",
25+
"metadata": {},
26+
"outputs": [],
27+
"source": [
28+
"import dsgp4\n",
29+
"import numpy as np\n",
30+
"import torch"
31+
]
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"id": "5f44d3e7",
36+
"metadata": {},
37+
"source": [
38+
"## 1. Load a deep-space TLE\n",
39+
"\n",
40+
"You can use any TLE with mean motion low enough to satisfy the 225-minute rule (for example geostationary satellites)."
41+
]
42+
},
43+
{
44+
"cell_type": "code",
45+
"execution_count": null,
46+
"id": "45671b5d",
47+
"metadata": {},
48+
"outputs": [],
49+
"source": [
50+
"# Replace these lines with your deep-space TLE lines.\n",
51+
"line1 = \"1 41866U 16071A 24087.50000000 -.00000149 00000+0 00000+0 0 9990\"\n",
52+
"line2 = \"2 41866 0.0171 87.5375 0001375 158.4767 157.4602 1.00270055 26844\"\n",
53+
"\n",
54+
"tle = dsgp4.tle.TLE([line1, line2])\n",
55+
"\n",
56+
"# Initialize (deep-space mode is selected automatically when applicable).\n",
57+
"dsgp4.initialize_tle(tle, gravity_constant_name=\"wgs-84\")\n",
58+
"\n",
59+
"period_minutes = float(2.0 * np.pi / tle._no_unkozai)\n",
60+
"print(\"method:\", tle._method)\n",
61+
"print(\"orbital period [min]:\", period_minutes)"
62+
]
63+
},
64+
{
65+
"cell_type": "markdown",
66+
"id": "d124e84d",
67+
"metadata": {},
68+
"source": [
69+
"## 2. Propagate at one or multiple epochs"
70+
]
71+
},
72+
{
73+
"cell_type": "code",
74+
"execution_count": null,
75+
"id": "f2746b3d",
76+
"metadata": {},
77+
"outputs": [],
78+
"source": [
79+
"tsince = torch.tensor([0.0, 360.0, 720.0, 1440.0]) # minutes since epoch\n",
80+
"state = dsgp4.propagate(tle, tsince, initialized=True)\n",
81+
"\n",
82+
"# state shape: [N, 2, 3]\n",
83+
"# row 0: position [km], row 1: velocity [km/s]\n",
84+
"print(state.shape)\n",
85+
"print(\"r(t0) [km]:\", state[0, 0])\n",
86+
"print(\"v(t0) [km/s]:\", state[0, 1])"
87+
]
88+
},
89+
{
90+
"cell_type": "markdown",
91+
"id": "d0dd15f2",
92+
"metadata": {},
93+
"source": [
94+
"## 3. Enable gradients through deep-space propagation\n",
95+
"\n",
96+
"To differentiate with respect to TLE parameters, initialize with `with_grad=True` and backpropagate from any scalar objective."
97+
]
98+
},
99+
{
100+
"cell_type": "code",
101+
"execution_count": null,
102+
"id": "e16a0407",
103+
"metadata": {},
104+
"outputs": [],
105+
"source": [
106+
"tle = dsgp4.tle.TLE([line1, line2])\n",
107+
"tle_elements = dsgp4.initialize_tle(\n",
108+
" tle,\n",
109+
" gravity_constant_name=\"wgs-84\",\n",
110+
" with_grad=True,\n",
111+
")\n",
112+
"\n",
113+
"tsince = torch.tensor(120.0)\n",
114+
"state = dsgp4.propagate(tle, tsince, initialized=True) # [2, 3]\n",
115+
"\n",
116+
"# Example objective: x-position at tsince=120 min\n",
117+
"loss = state[0, 0]\n",
118+
"loss.backward()\n",
119+
"\n",
120+
"# Gradient order in tle_elements:\n",
121+
"# [bstar, ndot, nddot, ecco, argpo, inclo, mo, no_kozai, nodeo]\n",
122+
"print(tle_elements.grad)"
123+
]
124+
},
125+
{
126+
"cell_type": "markdown",
127+
"id": "5e026f59",
128+
"metadata": {},
129+
"source": [
130+
"## 4. Batch propagation with mixed near-earth and deep-space objects\n",
131+
"\n",
132+
"If a batch contains deep-space members, dSGP4 automatically falls back to a per-satellite propagation path while preserving the same API."
133+
]
134+
},
135+
{
136+
"cell_type": "code",
137+
"execution_count": null,
138+
"id": "33cf0709",
139+
"metadata": {},
140+
"outputs": [],
141+
"source": [
142+
"tles = [\n",
143+
" dsgp4.tle.TLE([line1, line2]), # deep-space example\n",
144+
" dsgp4.tle.TLE([\n",
145+
" \"1 25544U 98067A 24087.49097222 .00016717 00000+0 10270-3 0 9993\",\n",
146+
" \"2 25544 51.6400 82.2420 0006290 58.9900 53.5550 15.50000000000000\",\n",
147+
" ]),\n",
148+
"]\n",
149+
"\n",
150+
"_, initialized = dsgp4.initialize_tle(tles, gravity_constant_name=\"wgs-84\")\n",
151+
"tsinces = torch.tensor([60.0, 60.0])\n",
152+
"batch_state = dsgp4.propagate_batch(initialized, tsinces, initialized=True)\n",
153+
"print(batch_state.shape) # [2, 2, 3]"
154+
]
155+
},
156+
{
157+
"cell_type": "markdown",
158+
"id": "7ff97818",
159+
"metadata": {},
160+
"source": [
161+
"## Notes\n",
162+
"\n",
163+
"- Deep-space support is available in scalar propagation and in mixed batches.\n",
164+
"- Gradients are supported through the deep-space scalar path.\n",
165+
"- For reproducibility against external implementations, use the same gravity constants and operation mode."
166+
]
167+
}
168+
],
169+
"metadata": {
170+
"language_info": {
171+
"name": "python"
172+
}
173+
},
174+
"nbformat": 4,
175+
"nbformat_minor": 5
176+
}

doc/tutorials.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ for more complex tasks.
2424
.. toctree::
2525
:maxdepth: 1
2626

27+
notebooks/deep_space_propagation.ipynb
2728
notebooks/covariance_transformation.ipynb
2829
notebooks/covariance_propagation.ipynb
2930
notebooks/gradient_based_optimization.ipynb

0 commit comments

Comments
 (0)