Skip to content

Commit 4e81c8f

Browse files
committed
The TLE handling method was improved according to the description below:
- The meanOE of the TLE are converted to osculationg elements with the SPG4 mentod - Coordinate conversion added to (and from) TEME to J2000/ICRS - When converting the osculationg elements to a TLE, the mean OE are generated using SPG4 - The unit test was updated accordingly
1 parent 8662019 commit 4e81c8f

File tree

2 files changed

+263
-69
lines changed

2 files changed

+263
-69
lines changed

src/tests/test_readTLE.py

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,83 +6,82 @@
66
import Basilisk.utilities.orbitalMotion as om
77
from datetime import datetime, timedelta, timezone
88

9-
A_TOL = 1e-14 #[-]
9+
A_TOL = 1e-9 #[-]
10+
A_TOL_ROUNDTRIP = 1e-4 #[-] Tolerance for eccentricity (roundtrip error)
11+
A_TOL_DEG_ROUNDTRIP = 1.5 # [deg] Tolerance for angles in degrees (roundtrip error)
12+
1013
DATA_DIR = pathlib.Path(__file__).parent / 'data'
1114

1215
###################################################################
1316
# Expected orbital elements for oneWeb (if testing multiple satellites)
1417
EXPECTED_OE_ONE_WEB = {
1518
'a': [
16-
7575817.78380046, # 0
17-
7575897.531671279, # 1
18-
7575896.775957426, # 2
19-
7579911.683283668, # 3
20-
7579911.241546285, # 4
21-
7579912.336286875 # 5
22-
],
19+
np.float64(7578544.80840588),
20+
np.float64(7581725.314320893),
21+
np.float64(7581725.090937277),
22+
np.float64(7585736.508260437),
23+
np.float64(7585735.9677996775),
24+
np.float64(7585737.120163768)
25+
],
2326
'e': [
24-
0.000175, 0.0001764, 0.0002086, 0.0001581, 0.0001714,
25-
0.0002029
26-
],
27+
np.float64(0.0008817590462989669),
28+
np.float64(0.001210093768077448),
29+
np.float64(0.001258633728769965),
30+
np.float64(0.0011981313722308415),
31+
np.float64(0.001206952489243135),
32+
np.float64(0.001239828742668404)
33+
],
2734
'i': [
28-
1.534083325979196, 1.5340868166376997, 1.534083325979196,
29-
1.5341409218445117, 1.5341496484907717, 1.5341409218445117
30-
],
31-
'f': [
32-
2.2017240215026246, 4.489410705143804, 4.744271057621696,
33-
4.549972500184758, 4.511343702990637, 4.567673118903615
34-
],
35+
1.531618126589653,
36+
1.5316291459001932,
37+
1.5316258452568352,
38+
1.5322241554919225,
39+
1.5322307739504486,
40+
1.5322225935006697
41+
],
3542
'Omega': [
36-
4.888890636980372, 4.888930779553168, 4.889318242647111,
37-
5.4216838070781765, 5.420380046126938, 5.4207134040140685
38-
],
43+
4.8831623958720565,
44+
4.883186443196075,
45+
4.883574022425417,
46+
5.415984679757847,
47+
5.414680762509103,
48+
5.415014177551135
49+
],
3950
'omega': [
40-
1.372734617949328, 1.7957483234259417, 1.5408883647327218,
41-
1.7351853983817387, 1.773814770716129, 1.717484269108012
42-
]
51+
1.4377465022195557,
52+
1.2801901375990692,
53+
1.2537640336417852,
54+
1.2645835093359827,
55+
1.2744200510794836,
56+
1.278331704552413
57+
],
58+
'f': [
59+
2.1381866215235528,
60+
5.002606275268809,
61+
5.029031746586543,
62+
5.017006771870916,
63+
5.0071733437393355,
64+
5.003259952527291
65+
],
4366
}
4467

4568
EXPECTED_OE_2LE = {
46-
'a': [
47-
6796012.0083837,
48-
6763487.620700561,
49-
6796034.881033647
50-
],
51-
'e': [
52-
0.0001066,
53-
0.0001842,
54-
0.0001045
55-
],
56-
'i': [
57-
0.9011588713652241,
58-
0.7236833210469288,
59-
0.9011606166944762
60-
],
61-
'f': [
62-
3.019032029543272,
63-
3.4280122815833245,
64-
3.0304383654813503
65-
],
66-
'Omega': [
67-
2.3957855389445846,
68-
1.6320242222841097,
69-
2.4180821201388114
70-
],
71-
'omega': [
72-
3.2658775496243098,
73-
2.8566379826044352,
74-
3.2544735682917785
75-
]
69+
'a': [np.float64(6802505.842859207), np.float64(6770009.6048538275), np.float64(6802528.7123854)],
70+
'e': [np.float64(0.0011264735370325686), np.float64(0.0011530055595853114), np.float64(0.001128835473051786)],
71+
'i': [0.903248948599224, 0.7265482390037918, 0.9032099423215613],
72+
'Omega': [2.3886009471482503, 1.6261518262462817, 2.410867356948434],
73+
'omega': [0.8571434002531804, 0.7478010900864719, 0.8567388460152983],
74+
'f': [5.428341410047342, 5.535537401708238, 5.428797206538743],
7675
}
7776

7877
# Values to generate TLE for HYPSO 1
7978
oeHypso1 = om.ClassicElements()
80-
oeHypso1.i = np.deg2rad(97.3197)
81-
oeHypso1.e = 0.0004257 # [-]
82-
oeHypso1.a = (om.RP_EARTH + 445.195971181338)*1e3 # [m]
83-
oeHypso1.Omega = np.deg2rad(349.0390) # [rad]
84-
oeHypso1.omega = np.deg2rad(136.0807) # [rad]
85-
oeHypso1.f = np.deg2rad(224.04427854247686) # [rad]
79+
oeHypso1.i = 1.6979291907417804
80+
oeHypso1.e = 0.0013996087479637449
81+
oeHypso1.a = 6808434.893655814
82+
oeHypso1.Omega = 6.085804103135117
83+
oeHypso1.omega = 1.43544167146666
84+
oeHypso1.f = 4.845270389715793
8685
hypso1noradId = 51053 # [-]
8786
hypso1launch = datetime(2022, 1, 13, 0, 0, 0) # [UTC]
8887
hypso1tleEpoch = datetime(2025, 1, 1, tzinfo=timezone.utc) + timedelta(days=279.47924866 - 1) # [UTC]
@@ -153,7 +152,15 @@ def test_write_tle(satName, orbitalElements, noradID, launchDate, launch_Noyear,
153152
# String compaire (line 1)
154153
eCountTle += int((generatedTle.splitlines()[1] != expectedTLE.splitlines()[1]))
155154
# String compaire (line 2)
156-
eCountTle += int((generatedTle.splitlines()[2][0:63] != expectedTLE.splitlines()[2][0:63])) # Ignore revolutions count and checksum
155+
for i, (field_expected, field_generated) in enumerate(zip(expectedTLE.splitlines()[2].split(), generatedTle.splitlines()[2].split())):
156+
if i in [4]: # 4 = eccentricity (leading decimal point assumed), 5 = argument of perigee, 6 = mean anomaly
157+
# Eccentricity -> leading decimal point assume -> max tolerance is A_TOL_ROUNDTRIP * 1e7 => 1e-4 physical eccentricity tolerance
158+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_ROUNDTRIP * 1e7
159+
elif i in [5,6]: # 5 = argument of perigee, 6 = mean anomaly (degrees)
160+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_DEG_ROUNDTRIP
161+
else:
162+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_ROUNDTRIP
163+
157164
assert eCountTle < 1, f"{eCountTle} functions failed in tleHandling.py script, generateTleDataString() method"
158165

159166
@pytest.mark.parametrize("tlePath", [
@@ -174,7 +181,15 @@ def test_read_write_tle(tlePath):
174181
# String compaire (line 1)
175182
eCountTle += int((generatedTle.splitlines()[1] != tleToBeTested.splitlines()[1]))
176183
# String compaire (line 2)
177-
eCountTle += int((generatedTle.splitlines()[2][0:63] != tleToBeTested.splitlines()[2][0:63])) # Ignore revolutions count and checksum
184+
for i, (field_expected, field_generated) in enumerate(zip(tleToBeTested.splitlines()[2].split(), generatedTle.splitlines()[2].split())):
185+
if i in [4]: # 4 = eccentricity (leading decimal point assumed), 5 = argument of perigee, 6 = mean anomaly
186+
# Eccentricity -> leading decimal point assume -> max tolerance is A_TOL_ROUNDTRIP * 1e7 => 1e-4 physical eccentricity tolerance
187+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_ROUNDTRIP * 1e7
188+
elif i in [5,6]: # 5 = argument of perigee, 6 = mean anomaly (degrees)
189+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_DEG_ROUNDTRIP
190+
else:
191+
eCountTle += abs(float(field_expected) - float(field_generated)) > A_TOL_ROUNDTRIP
192+
178193
assert eCountTle < 1, f"{eCountTle} functions failed in tleHandling.py script, generateTleDataString() method"
179194

180195
if __name__ == "__main__":

0 commit comments

Comments
 (0)