1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.events;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.ode.events.Action;
21 import org.junit.jupiter.api.AfterEach;
22 import org.junit.jupiter.api.Assertions;
23 import org.junit.jupiter.api.BeforeEach;
24 import org.junit.jupiter.api.Test;
25 import org.junit.jupiter.params.ParameterizedTest;
26 import org.junit.jupiter.params.provider.EnumSource;
27 import org.mockito.Mockito;
28 import org.orekit.Utils;
29 import org.orekit.bodies.CelestialBodyFactory;
30 import org.orekit.bodies.OneAxisEllipsoid;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.frames.FramesFactory;
33 import org.orekit.orbits.EquinoctialOrbit;
34 import org.orekit.orbits.Orbit;
35 import org.orekit.propagation.Propagator;
36 import org.orekit.propagation.SpacecraftState;
37 import org.orekit.propagation.analytical.KeplerianPropagator;
38 import org.orekit.propagation.events.handlers.EventHandler;
39 import org.orekit.time.AbsoluteDate;
40 import org.orekit.time.TimeScalesFactory;
41 import org.orekit.utils.Constants;
42 import org.orekit.utils.IERSConventions;
43 import org.orekit.utils.PVCoordinates;
44
45 class EventSlopeFilterTest {
46
47 private AbsoluteDate iniDate;
48 private Propagator propagator;
49 private OneAxisEllipsoid earth;
50
51 private double sunRadius = 696000000.;
52 private double earthRadius = 6400000.;
53
54 @ParameterizedTest
55 @EnumSource(FilterType.class)
56 void testWithDetectionSettings(final FilterType filterType) {
57
58 final DateDetector detector = new DateDetector();
59 final EventSlopeFilter<DateDetector> template = new EventSlopeFilter<>(detector, filterType);
60 final EventDetectionSettings detectionSettings = Mockito.mock();
61
62 final EventSlopeFilter<DateDetector> eventSlopeFilter = template.withDetectionSettings(detectionSettings);
63
64 Assertions.assertEquals(detector, eventSlopeFilter.getDetector());
65 Assertions.assertEquals(detectionSettings, eventSlopeFilter.getDetectionSettings());
66 }
67
68 @Test
69 void testInit() {
70
71 final TestHandler handler = new TestHandler();
72 final EventSlopeFilter<DateDetector> slopeFilter = new EventSlopeFilter<>(new DateDetector().withHandler(handler),
73 FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
74 final SpacecraftState mockedState = Mockito.mock();
75 Mockito.when(mockedState.getDate()).thenReturn(AbsoluteDate.ARBITRARY_EPOCH);
76
77 slopeFilter.init(mockedState, AbsoluteDate.ARBITRARY_EPOCH);
78
79 Assertions.assertTrue(handler.initialized);
80 }
81
82 @Test
83 void testFinish() {
84
85 final TestHandler handler = new TestHandler();
86 final EventSlopeFilter<DateDetector> slopeFilter = new EventSlopeFilter<>(new DateDetector().withHandler(handler),
87 FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
88 final SpacecraftState mockedState = Mockito.mock();
89
90 slopeFilter.finish(mockedState);
91
92 Assertions.assertTrue(handler.finished);
93 }
94
95 private static class TestHandler implements EventHandler {
96 boolean initialized = false;
97 boolean finished = false;
98
99 @Override
100 public void init(SpacecraftState initialState, AbsoluteDate target, EventDetector detector) {
101 EventHandler.super.init(initialState, target, detector);
102 initialized = true;
103 }
104
105 @Override
106 public void finish(SpacecraftState finalState, EventDetector detector) {
107 EventHandler.super.finish(finalState, detector);
108 finished = true;
109 }
110
111 @Override
112 public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
113 return null;
114 }
115 }
116
117 @Test
118 void testEnums() {
119
120
121 Assertions.assertEquals(5, Transformer.values().length);
122 Assertions.assertSame(Transformer.UNINITIALIZED, Transformer.valueOf("UNINITIALIZED"));
123 Assertions.assertSame(Transformer.PLUS, Transformer.valueOf("PLUS"));
124 Assertions.assertSame(Transformer.MINUS, Transformer.valueOf("MINUS"));
125 Assertions.assertSame(Transformer.MIN, Transformer.valueOf("MIN"));
126 Assertions.assertSame(Transformer.MAX, Transformer.valueOf("MAX"));
127
128 Assertions.assertEquals(2, FilterType.values().length);
129 Assertions.assertSame(FilterType.TRIGGER_ONLY_DECREASING_EVENTS,
130 FilterType.valueOf("TRIGGER_ONLY_DECREASING_EVENTS"));
131 Assertions.assertSame(FilterType.TRIGGER_ONLY_INCREASING_EVENTS,
132 FilterType.valueOf("TRIGGER_ONLY_INCREASING_EVENTS"));
133
134 }
135
136 @Test
137 void testReplayForward() {
138 EclipseDetector detector =
139 new EclipseDetector(CelestialBodyFactory.getSun(), sunRadius,
140 new OneAxisEllipsoid(earthRadius,
141 0.0,
142 FramesFactory.getITRF(IERSConventions.IERS_2010, true))).
143 withMaxCheck(60.0).
144 withThreshold(1.0e-3).
145 withPenumbra().withHandler(new Counter());
146 final EventDetectionSettings settings = EventDetectionSettings.getDefaultEventDetectionSettings().withMaxIter(200);
147 final EventSlopeFilter<EclipseDetector> filter =
148 new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_INCREASING_EVENTS).
149 withDetectionSettings(settings);
150 Assertions.assertSame(detector, filter.getDetector());
151 Assertions.assertEquals(200, filter.getMaxIterationCount());
152
153 propagator.clearEventsDetectors();
154 propagator.addEventDetector(filter);
155 propagator.propagate(iniDate, iniDate.shiftedBy(7 * Constants.JULIAN_DAY));
156 Assertions.assertEquals(102, ((Counter) detector.getHandler()).getIncreasingCounter());
157 Assertions.assertEquals( 0, ((Counter) detector.getHandler()).getDecreasingCounter());
158 ((Counter) detector.getHandler()).reset();
159
160 propagator.clearEventsDetectors();
161 propagator.setStepHandler(10.0, currentState -> {
162
163
164
165
166 Assertions.assertTrue(filter.g(currentState) > 0);
167 });
168 propagator.propagate(iniDate.shiftedBy(-3600), iniDate.shiftedBy(Constants.JULIAN_DAY + 3600));
169 }
170
171 @Test
172 void testReplayBackward() {
173 EclipseDetector detector =
174 new EclipseDetector(CelestialBodyFactory.getSun(), sunRadius,
175 new OneAxisEllipsoid(earthRadius,
176 0.0,
177 FramesFactory.getITRF(IERSConventions.IERS_2010, true))).
178 withMaxCheck(60.0).
179 withThreshold(1.0e-3).
180 withPenumbra().
181 withHandler(new Counter());
182 final EventDetectionSettings settings = EventDetectionSettings.getDefaultEventDetectionSettings().withMaxIter(200);
183 final EventSlopeFilter<EclipseDetector> filter =
184 new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_DECREASING_EVENTS).
185 withDetectionSettings(settings);
186 Assertions.assertEquals(200, filter.getMaxIterationCount());
187
188 propagator.clearEventsDetectors();
189 propagator.addEventDetector(filter);
190 propagator.propagate(iniDate.shiftedBy(7 * Constants.JULIAN_DAY), iniDate);
191 Assertions.assertEquals( 0, ((Counter) detector.getHandler()).getIncreasingCounter());
192 Assertions.assertEquals(102, ((Counter) detector.getHandler()).getDecreasingCounter());
193 ((Counter) detector.getHandler()).reset();
194
195 propagator.clearEventsDetectors();
196 propagator.setStepHandler(10.0, currentState -> {
197
198
199
200
201 Assertions.assertTrue(filter.g(currentState) < 0);
202 });
203 propagator.propagate(iniDate.shiftedBy(7 * Constants.JULIAN_DAY + 3600),
204 iniDate.shiftedBy(6 * Constants.JULIAN_DAY + 3600));
205 }
206
207 @Test
208 void testUmbra() {
209 EclipseDetector detector =
210 new EclipseDetector(CelestialBodyFactory.getSun(), sunRadius,
211 new OneAxisEllipsoid(earthRadius,
212 0.0,
213 FramesFactory.getITRF(IERSConventions.IERS_2010, true))).
214 withMaxCheck(60.0).
215 withThreshold(1.0e-3).
216 withPenumbra().
217 withHandler(new Counter());
218
219 propagator.clearEventsDetectors();
220 propagator.addEventDetector(detector);
221 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
222 Assertions.assertEquals(14, ((Counter) detector.getHandler()).getIncreasingCounter());
223 Assertions.assertEquals(15, ((Counter) detector.getHandler()).getDecreasingCounter());
224 ((Counter) detector.getHandler()).reset();
225
226 propagator.clearEventsDetectors();
227 propagator.addEventDetector(new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_INCREASING_EVENTS));
228 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
229 Assertions.assertEquals(14, ((Counter) detector.getHandler()).getIncreasingCounter());
230 Assertions.assertEquals( 0, ((Counter) detector.getHandler()).getDecreasingCounter());
231 ((Counter) detector.getHandler()).reset();
232
233 propagator.clearEventsDetectors();
234 propagator.addEventDetector(new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_DECREASING_EVENTS));
235 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
236 Assertions.assertEquals( 0, ((Counter) detector.getHandler()).getIncreasingCounter());
237 Assertions.assertEquals(15, ((Counter) detector.getHandler()).getDecreasingCounter());
238
239 }
240
241 @Test
242 void testPenumbra() {
243 EclipseDetector detector =
244 new EclipseDetector(CelestialBodyFactory.getSun(), sunRadius,
245 new OneAxisEllipsoid(earthRadius,
246 0.0,
247 FramesFactory.getITRF(IERSConventions.IERS_2010, true))).
248 withMaxCheck(60.0).
249 withThreshold(1.0e-3).
250 withPenumbra().
251 withHandler(new Counter());
252
253 propagator.clearEventsDetectors();
254 propagator.addEventDetector(detector);
255 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
256 Assertions.assertEquals(14, ((Counter) detector.getHandler()).getIncreasingCounter());
257 Assertions.assertEquals(15, ((Counter) detector.getHandler()).getDecreasingCounter());
258 ((Counter) detector.getHandler()).reset();
259
260 propagator.clearEventsDetectors();
261 final EventSlopeFilter<EclipseDetector> outOfEclipseDetector =
262 new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
263 propagator.addEventDetector(outOfEclipseDetector);
264 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
265 Assertions.assertEquals(14, ((Counter) detector.getHandler()).getIncreasingCounter());
266 Assertions.assertEquals(0, ((Counter) detector.getHandler()).getDecreasingCounter());
267 Assertions.assertEquals(FilterType.TRIGGER_ONLY_INCREASING_EVENTS, outOfEclipseDetector.getFilterType());
268 ((Counter) detector.getHandler()).reset();
269
270 propagator.clearEventsDetectors();
271 final EventSlopeFilter<EclipseDetector> enteringEclipseDetector =
272 new EventSlopeFilter<>(detector, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
273 propagator.addEventDetector(enteringEclipseDetector);
274 propagator.propagate(iniDate, iniDate.shiftedBy(Constants.JULIAN_DAY));
275 Assertions.assertEquals(0, ((Counter) detector.getHandler()).getIncreasingCounter());
276 Assertions.assertEquals(15, ((Counter) detector.getHandler()).getDecreasingCounter());
277 Assertions.assertEquals(FilterType.TRIGGER_ONLY_DECREASING_EVENTS, enteringEclipseDetector.getFilterType());
278
279 }
280
281 @Test
282 void testForwardIncreasingStartPos() {
283
284 SpacecraftState s = propagator.getInitialState();
285 double startLatitude = earth.transform(s.getPosition(),
286 s.getFrame(), s.getDate()).getLatitude();
287
288
289 doTestLatitude(75500.0, startLatitude - 0.1, 12, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
290
291 }
292
293 @Test
294 void testForwardIncreasingStartZero() {
295
296 SpacecraftState s = propagator.getInitialState();
297 double startLatitude = earth.transform(s.getPosition(),
298 s.getFrame(), s.getDate()).getLatitude();
299
300
301 doTestLatitude(75500.0, startLatitude, 12, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
302
303 }
304
305 @Test
306 void testForwardIncreasingStartNeg() {
307
308 SpacecraftState s = propagator.getInitialState();
309 double startLatitude = earth.transform(s.getPosition(),
310 s.getFrame(), s.getDate()).getLatitude();
311
312
313 doTestLatitude(75500.0, startLatitude + 0.1, 13, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
314
315 }
316
317 @Test
318 void testForwardDecreasingStartPos() {
319
320 SpacecraftState s = propagator.getInitialState();
321 double startLatitude = earth.transform(s.getPosition(),
322 s.getFrame(), s.getDate()).getLatitude();
323
324
325 doTestLatitude(75500.0, startLatitude - 0.1, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
326 }
327
328 @Test
329 void testForwardDecreasingStartZero() {
330
331 SpacecraftState s = propagator.getInitialState();
332 double startLatitude = earth.transform(s.getPosition(),
333 s.getFrame(), s.getDate()).getLatitude();
334
335
336 doTestLatitude(75500.0, startLatitude, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
337 }
338
339 @Test
340 void testForwardDecreasingStartNeg() {
341
342 SpacecraftState s = propagator.getInitialState();
343 double startLatitude = earth.transform(s.getPosition(),
344 s.getFrame(), s.getDate()).getLatitude();
345
346
347 doTestLatitude(75500.0, startLatitude + 0.1, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
348 }
349
350 @Test
351 void testBackwardIncreasingStartPos() {
352
353 SpacecraftState s = propagator.getInitialState();
354 double startLatitude = earth.transform(s.getPosition(),
355 s.getFrame(), s.getDate()).getLatitude();
356
357
358 doTestLatitude(-75500.0, startLatitude - 0.1, 13, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
359
360 }
361
362 @Test
363 void testBackwardIncreasingStartZero() {
364
365 SpacecraftState s = propagator.getInitialState();
366 double startLatitude = earth.transform(s.getPosition(),
367 s.getFrame(), s.getDate()).getLatitude();
368
369
370 doTestLatitude(-75500.0, startLatitude, 12, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
371
372 }
373
374 @Test
375 void testBackwardIncreasingStartNeg() {
376
377 SpacecraftState s = propagator.getInitialState();
378 double startLatitude = earth.transform(s.getPosition(),
379 s.getFrame(), s.getDate()).getLatitude();
380
381
382 doTestLatitude(-75500.0, startLatitude + 0.1, 12, FilterType.TRIGGER_ONLY_INCREASING_EVENTS);
383
384 }
385
386 @Test
387 void testBackwardDecreasingStartPos() {
388
389 SpacecraftState s = propagator.getInitialState();
390 double startLatitude = earth.transform(s.getPosition(),
391 s.getFrame(), s.getDate()).getLatitude();
392
393
394 doTestLatitude(-75500.0, startLatitude - 0.1, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
395 }
396
397 @Test
398 void testBackwardDecreasingStartZero() {
399
400 SpacecraftState s = propagator.getInitialState();
401 double startLatitude = earth.transform(s.getPosition(),
402 s.getFrame(), s.getDate()).getLatitude();
403
404
405 doTestLatitude(-75500.0, startLatitude, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
406 }
407
408 @Test
409 void testBackwardDecreasingStartNeg() {
410
411 SpacecraftState s = propagator.getInitialState();
412 double startLatitude = earth.transform(s.getPosition(),
413 s.getFrame(), s.getDate()).getLatitude();
414
415
416 doTestLatitude(-75500.0, startLatitude + 0.1, 13, FilterType.TRIGGER_ONLY_DECREASING_EVENTS);
417 }
418
419 private void doTestLatitude(final double dt, final double latitude, final int expected, final FilterType filter)
420 {
421 final int[] count = new int[2];
422 LatitudeCrossingDetector detector =
423 new LatitudeCrossingDetector(earth, latitude).
424 withMaxCheck(300.0).
425 withMaxIter(100).
426 withThreshold(1.0e-3).
427 withHandler(new EventHandler() {
428
429 @Override
430 public Action eventOccurred(SpacecraftState s, EventDetector detector, boolean increasing) {
431 Assertions.assertEquals(filter.getTriggeredIncreasing(), increasing);
432 count[0]++;
433 return Action.RESET_STATE;
434 }
435
436 @Override
437 public SpacecraftState resetState(EventDetector detector, SpacecraftState oldState) {
438 count[1]++;
439 return oldState;
440 }
441
442 });
443 Assertions.assertSame(earth, detector.getBody());
444 propagator.addEventDetector(new EventSlopeFilter<EventDetector>(detector, filter));
445 AbsoluteDate target = propagator.getInitialState().getDate().shiftedBy(dt);
446 SpacecraftState finalState = propagator.propagate(target);
447 Assertions.assertEquals(0.0, finalState.getDate().durationFrom(target), 1.0e-10);
448 Assertions.assertEquals(expected, count[0]);
449 Assertions.assertEquals(expected, count[1]);
450 }
451
452 private static class Counter implements EventHandler {
453
454 private int increasingCounter;
455 private int decreasingCounter;
456
457 public Counter() {
458 reset();
459 }
460
461 public void reset() {
462 increasingCounter = 0;
463 decreasingCounter = 0;
464 }
465
466 @Override
467 public Action eventOccurred(SpacecraftState s, EventDetector ed, boolean increasing) {
468 if (increasing) {
469 increasingCounter++;
470 } else {
471 decreasingCounter++;
472 }
473 return Action.CONTINUE;
474 }
475
476 public int getIncreasingCounter() {
477 return increasingCounter;
478 }
479
480 public int getDecreasingCounter() {
481 return decreasingCounter;
482 }
483
484 }
485
486 @BeforeEach
487 public void setUp() {
488 try {
489 Utils.setDataRoot("regular-data");
490 double mu = 3.9860047e14;
491 final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
492 final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231);
493 iniDate = new AbsoluteDate(1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
494 final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position, velocity),
495 FramesFactory.getGCRF(), iniDate, mu);
496 propagator = new KeplerianPropagator(orbit, Utils.defaultLaw(), mu);
497 earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
498 Constants.WGS84_EARTH_FLATTENING,
499 FramesFactory.getITRF(IERSConventions.IERS_2010, true));
500
501 } catch (OrekitException oe) {
502 Assertions.fail(oe.getLocalizedMessage());
503 }
504 }
505
506 @AfterEach
507 public void tearDown() {
508 iniDate = null;
509 propagator = null;
510 earth = null;
511 }
512
513 }
514