1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.analytical.tle;
18
19 import org.hamcrest.MatcherAssert;
20 import org.hipparchus.geometry.euclidean.threed.Line;
21 import org.hipparchus.geometry.euclidean.threed.Rotation;
22 import org.hipparchus.geometry.euclidean.threed.Vector3D;
23 import org.hipparchus.ode.events.Action;
24 import org.hipparchus.util.FastMath;
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.orekit.OrekitMatchers;
29 import org.orekit.Utils;
30 import org.orekit.attitudes.BodyCenterPointing;
31 import org.orekit.bodies.OneAxisEllipsoid;
32 import org.orekit.frames.Frame;
33 import org.orekit.frames.FramesFactory;
34 import org.orekit.frames.StaticTransform;
35 import org.orekit.orbits.Orbit;
36 import org.orekit.propagation.BoundedPropagator;
37 import org.orekit.propagation.EphemerisGenerator;
38 import org.orekit.propagation.Propagator;
39 import org.orekit.propagation.SpacecraftState;
40 import org.orekit.propagation.events.DateDetector;
41 import org.orekit.propagation.events.handlers.EventHandler;
42 import org.orekit.propagation.sampling.OrekitFixedStepHandler;
43 import org.orekit.time.AbsoluteDate;
44 import org.orekit.utils.Constants;
45 import org.orekit.utils.IERSConventions;
46
47
48 public class TLEPropagatorTest {
49
50 private TLE tle;
51 private double period;
52
53 @Test
54 public void testsecondaryMode() {
55
56 TLEPropagator propagator = TLEPropagator.selectExtrapolator(tle);
57 AbsoluteDate initDate = tle.getDate();
58 SpacecraftState initialState = propagator.getInitialState();
59
60
61
62 SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(period));
63
64
65 final Orbit initialOrbit = initialState.getOrbit();
66 final Orbit finalOrbit = finalState.getOrbit();
67 Assertions.assertEquals(initialOrbit.getA(), finalOrbit.getA(), 1e-1);
68 Assertions.assertEquals(initialOrbit.getEquinoctialEx(), finalOrbit.getEquinoctialEx(), 1e-1);
69 Assertions.assertEquals(initialOrbit.getEquinoctialEy(), finalOrbit.getEquinoctialEy(), 1e-1);
70 Assertions.assertEquals(initialOrbit.getHx(), finalOrbit.getHx(), 1e-3);
71 Assertions.assertEquals(initialOrbit.getHy(), finalOrbit.getHy(), 1e-3);
72 Assertions.assertEquals(initialOrbit.getLM(), finalOrbit.getLM(), 1e-3);
73
74 }
75
76 @Test
77 public void testEphemerisMode() {
78
79 TLEPropagator propagator = TLEPropagator.selectExtrapolator(tle);
80 final EphemerisGenerator generator = propagator.getEphemerisGenerator();
81
82 AbsoluteDate initDate = tle.getDate();
83 SpacecraftState initialState = propagator.getInitialState();
84
85
86
87 AbsoluteDate endDate = initDate.shiftedBy(period);
88 propagator.propagate(endDate);
89
90
91 BoundedPropagator boundedProp = generator.getGeneratedEphemeris();
92
93
94
95 SpacecraftState boundedState = boundedProp.propagate(initDate);
96
97
98 final Orbit initialOrbit = initialState.getOrbit();
99 final Orbit boundedOrbit = boundedState.getOrbit();
100 Assertions.assertEquals(initialOrbit.getA(), boundedOrbit.getA(), 0.);
101 Assertions.assertEquals(initialOrbit.getEquinoctialEx(), boundedOrbit.getEquinoctialEx(), 0.);
102 Assertions.assertEquals(initialOrbit.getEquinoctialEy(), boundedOrbit.getEquinoctialEy(), 0.);
103 Assertions.assertEquals(initialOrbit.getHx(), boundedOrbit.getHx(), 0.);
104 Assertions.assertEquals(initialOrbit.getHy(), boundedOrbit.getHy(), 0.);
105 Assertions.assertEquals(initialOrbit.getLM(), boundedOrbit.getLM(), 1e-14);
106
107 SpacecraftState finalState = boundedProp.propagate(endDate);
108
109
110 final Orbit finalOrbit = finalState.getOrbit();
111 Assertions.assertEquals(initialOrbit.getA(), finalOrbit.getA(), 1e-1);
112 Assertions.assertEquals(initialOrbit.getEquinoctialEx(), finalOrbit.getEquinoctialEx(), 1e-1);
113 Assertions.assertEquals(initialOrbit.getEquinoctialEy(), finalOrbit.getEquinoctialEy(), 1e-1);
114 Assertions.assertEquals(initialOrbit.getHx(), finalOrbit.getHx(), 1e-3);
115 Assertions.assertEquals(initialOrbit.getHy(), finalOrbit.getHy(), 1e-3);
116 Assertions.assertEquals(initialOrbit.getLM(), finalOrbit.getLM(), 1e-3);
117
118 }
119
120
121
122 @Test
123 public void testBodyCenterInPointingDirection() {
124
125 final Frame itrf = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
126 final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
127 Constants.WGS84_EARTH_FLATTENING,
128 itrf);
129 DistanceChecker checker = new DistanceChecker(itrf);
130
131
132 TLEPropagator propagator =
133 TLEPropagator.selectExtrapolator(tle,
134 new BodyCenterPointing(FramesFactory.getTEME(), earth),
135 Propagator.DEFAULT_MASS);
136 propagator.setStepHandler(900.0, checker);
137 propagator.propagate(tle.getDate().shiftedBy(period));
138 Assertions.assertEquals(0.0, checker.getMaxDistance(), 2.0e-7);
139
140
141 propagator = TLEPropagator.selectExtrapolator(tle);
142 propagator.setStepHandler(900.0, checker);
143 propagator.propagate(tle.getDate().shiftedBy(period));
144 MatcherAssert.assertThat(checker.getMinDistance(),
145 OrekitMatchers.greaterThan(1.5218e7));
146 Assertions.assertEquals(2.6572e7, checker.getMaxDistance(), 1000.0);
147
148 }
149
150 private static class DistanceChecker implements OrekitFixedStepHandler {
151
152 private final Frame itrf;
153 private double minDistance;
154 private double maxDistance;
155
156 public DistanceChecker(Frame itrf) {
157 this.itrf = itrf;
158 }
159
160 public double getMinDistance() {
161 return minDistance;
162 }
163
164 public double getMaxDistance() {
165 return maxDistance;
166 }
167
168 public void init(SpacecraftState s0, AbsoluteDate t, double step) {
169 minDistance = Double.POSITIVE_INFINITY;
170 maxDistance = Double.NEGATIVE_INFINITY;
171 }
172
173 public void handleStep(SpacecraftState currentState) {
174
175 Rotation rotSat = currentState.getAttitude().getRotation();
176
177
178 Vector3D zSat = rotSat.applyInverseTo(Vector3D.PLUS_K);
179
180
181 StaticTransform transform = currentState.getFrame().getStaticTransformTo(itrf, currentState.getDate());
182 Vector3D zSatITRF = transform.transformVector(zSat);
183
184
185 Vector3D posSatITRF = transform.transformPosition(currentState.getPosition());
186
187
188 Line pointingLine = new Line(posSatITRF,
189 posSatITRF.add(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
190 zSatITRF),
191 1.0e-10);
192
193 double distance = pointingLine.distance(Vector3D.ZERO);
194 minDistance = FastMath.min(minDistance, distance);
195 maxDistance = FastMath.max(maxDistance, distance);
196 }
197
198 }
199
200 @Test
201 void testResetInitialState() {
202
203 final TLEPropagator tlePropagator = TLEPropagator.selectExtrapolator(tle);
204 final SpacecraftState initialState = tlePropagator.getInitialState();
205 final double unexpectedMass = initialState.getMass();
206 final double expectedMass = 2. * unexpectedMass;
207 final SpacecraftState newState = new SpacecraftState(initialState.getOrbit(), initialState.getAttitude(),
208 expectedMass);
209
210
211 tlePropagator.resetInitialState(newState);
212
213
214 final SpacecraftState actualState = tlePropagator.getInitialState();
215 Assertions.assertEquals(expectedMass, tlePropagator.getMass(actualState.getDate()));
216 Assertions.assertEquals(expectedMass, actualState.getMass());
217 Assertions.assertNotEquals(unexpectedMass, actualState.getMass());
218 }
219
220 @Test
221 void testResetIntermediateStateForward() {
222 testResetIntermediateStateTemplate(true);
223 }
224
225 @Test
226 void testResetIntermediateStateBackward() {
227 testResetIntermediateStateTemplate(false);
228 }
229
230 void testResetIntermediateStateTemplate(final boolean isForward) {
231
232 final TLEPropagator tlePropagator = TLEPropagator.selectExtrapolator(tle);
233 final double expectedMass = 2000.;
234 final SpacecraftState propagatedState = tlePropagator.propagate(tle.getDate().shiftedBy(1));
235 final SpacecraftState modifiedState = new SpacecraftState(propagatedState.getOrbit(), expectedMass);
236
237
238 tlePropagator.resetIntermediateState(modifiedState, isForward);
239
240
241 final double tinyTimeShift = (isForward) ? 1e-3 : -1e-3;
242 final double actualMass = tlePropagator.getMass(modifiedState.getDate().shiftedBy(tinyTimeShift));
243 Assertions.assertEquals(expectedMass, actualMass);
244 }
245
246 @Test
247 void testResetIntermediateStateHighLevelForward() {
248 testResetIntermediateStateHighLevelTemplate(true);
249 }
250
251 @Test
252 void testResetIntermediateStateHighLevelBackward() {
253 testResetIntermediateStateHighLevelTemplate(false);
254 }
255
256 void testResetIntermediateStateHighLevelTemplate(final boolean isForward) {
257
258 final TLEPropagator tlePropagator = TLEPropagator.selectExtrapolator(tle);
259 final AbsoluteDate epoch = tlePropagator.getInitialState().getDate();
260 final double totalShift = 1e4;
261 final double shiftSign = isForward ? 1 : -1;
262 final AbsoluteDate targetDate = epoch.shiftedBy(totalShift * shiftSign);
263 final EventHandler stateResetter = (s, detector, increasing) -> Action.RESET_STATE;
264 final DateDetector detector = new DateDetector(targetDate)
265 .withThreshold(1e-8).withHandler(stateResetter);
266 tlePropagator.addEventDetector(detector);
267
268
269 final SpacecraftState actualState = tlePropagator.propagate(targetDate);
270
271
272 final SpacecraftState expectedState = TLEPropagator.selectExtrapolator(tle).propagate(targetDate);
273 final Vector3D expectedPosition = expectedState.getPosition();
274 final Vector3D actualPosition = actualState.getPosition();
275 final double tolerance = 1e-1;
276 Assertions.assertEquals(expectedPosition.getX(), actualPosition.getX(), tolerance);
277 Assertions.assertEquals(expectedPosition.getY(), actualPosition.getY(), tolerance);
278 Assertions.assertEquals(expectedPosition.getZ(), actualPosition.getZ(), tolerance);
279 }
280
281 @BeforeEach
282 public void setUp() {
283 Utils.setDataRoot("regular-data");
284
285
286 String line1 = "1 37753U 11036A 12090.13205652 -.00000006 00000-0 00000+0 0 2272";
287 String line2 = "2 37753 55.0032 176.5796 0004733 13.2285 346.8266 2.00565440 5153";
288
289 tle = new TLE(line1, line2);
290
291
292 period = 717.97 * 60.0;
293 }
294
295 }
296