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.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.ode.events.Action;
22 import org.hipparchus.util.FastMath;
23 import org.junit.jupiter.api.Assertions;
24 import org.junit.jupiter.api.BeforeAll;
25 import org.junit.jupiter.api.Test;
26 import org.orekit.Utils;
27 import org.orekit.bodies.OneAxisEllipsoid;
28 import org.orekit.frames.Frame;
29 import org.orekit.frames.FramesFactory;
30 import org.orekit.orbits.FieldKeplerianOrbit;
31 import org.orekit.orbits.PositionAngleType;
32 import org.orekit.propagation.FieldPropagator;
33 import org.orekit.propagation.FieldSpacecraftState;
34 import org.orekit.propagation.SpacecraftState;
35 import org.orekit.propagation.events.handlers.EventHandler;
36 import org.orekit.propagation.events.handlers.FieldContinueOnEvent;
37 import org.orekit.propagation.events.handlers.FieldEventHandler;
38 import org.orekit.propagation.events.handlers.FieldRecordAndContinue;
39 import org.orekit.propagation.events.handlers.FieldRecordAndContinue.Event;
40 import org.orekit.propagation.events.handlers.FieldStopOnEvent;
41 import org.orekit.propagation.events.intervals.FieldAdaptableInterval;
42 import org.orekit.propagation.sampling.FieldOrekitStepHandler;
43 import org.orekit.propagation.sampling.FieldOrekitStepInterpolator;
44 import org.orekit.time.AbsoluteDate;
45 import org.orekit.time.FieldAbsoluteDate;
46 import org.orekit.utils.Constants;
47
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.List;
51
52
53
54
55
56
57 public abstract class FieldCloseEventsAbstractTest<T extends CalculusFieldElement<T>>{
58
59 public static final double mu = Constants.EIGEN5C_EARTH_MU;
60 public static final Frame eci = FramesFactory.getGCRF();
61 public static final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, Constants.WGS84_EARTH_FLATTENING, eci);
62
63 public final Field<T> field;
64 public final FieldAbsoluteDate<T> epoch;
65 public final FieldKeplerianOrbit<T> initialOrbit;
66
67 @BeforeAll
68 public static void setUpBefore() {
69 Utils.setDataRoot("regular-data");
70 }
71
72 public FieldCloseEventsAbstractTest(final Field<T> field) {
73 this.field = field;
74 this.epoch = new FieldAbsoluteDate<>(field, AbsoluteDate.J2000_EPOCH);
75 this.initialOrbit = new FieldKeplerianOrbit<>(
76 v(6378137 + 500e3), v(0), v(0), v(0), v(0), v(0), PositionAngleType.TRUE,
77 eci, epoch, v(mu));
78 }
79
80
81
82
83
84
85
86 public abstract FieldPropagator<T> getPropagator(double stepSize);
87
88 @Test
89 public void testCloseEventsFirstOneIsReset() {
90
91
92
93
94
95
96
97
98
99
100 FieldPropagator<T> propagator = getPropagator(10.0);
101
102 double t1 = 49, t2 = t1 + 1e-15, t3 = t1 + 4.9;
103 List<Event<T>> events = new ArrayList<>();
104 TimeDetector detector1 = new TimeDetector(t1)
105 .withHandler(new Handler<>(events, Action.RESET_DERIVATIVES))
106 .withMaxCheck(10)
107 .withThreshold(v(1e-9));
108 propagator.addEventDetector(detector1);
109 TimeDetector detector2 = new TimeDetector(t2, t3)
110 .withHandler(new FieldRecordAndContinue<>(events))
111 .withMaxCheck(11)
112 .withThreshold(v(1e-9));
113 propagator.addEventDetector(detector2);
114
115
116 propagator.propagate(epoch.shiftedBy(60));
117
118
119 Assertions.assertEquals(1, events.size());
120 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
121 Assertions.assertEquals(detector1, events.get(0).getDetector());
122 }
123
124 @Test
125 public void testCloseEvents() {
126
127 double tolerance = 1;
128 FieldPropagator<T> propagator = getPropagator(10);
129
130 FieldRecordAndContinue<T> handler = new FieldRecordAndContinue<>();
131 TimeDetector detector1 = new TimeDetector(5)
132 .withHandler(handler)
133 .withMaxCheck(10)
134 .withThreshold(v(tolerance));
135 propagator.addEventDetector(detector1);
136 TimeDetector detector2 = new TimeDetector(5.5)
137 .withHandler(handler)
138 .withMaxCheck(10)
139 .withThreshold(v(tolerance));
140 propagator.addEventDetector(detector2);
141
142
143 propagator.propagate(epoch.shiftedBy(20));
144
145
146 List<Event<T>> events = handler.getEvents();
147 Assertions.assertEquals(2, events.size());
148 Assertions.assertEquals(5, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
149 Assertions.assertEquals(detector1, events.get(0).getDetector());
150 Assertions.assertEquals(5.5, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
151 Assertions.assertEquals(detector2, events.get(1).getDetector());
152 }
153
154 @Test
155 public void testSimultaneousEvents() {
156
157 FieldPropagator<T> propagator = getPropagator(10);
158
159 FieldRecordAndContinue<T> handler1 = new FieldRecordAndContinue<>();
160 TimeDetector detector1 = new TimeDetector(5)
161 .withHandler(handler1)
162 .withMaxCheck(10)
163 .withThreshold(v(1));
164 propagator.addEventDetector(detector1);
165 FieldRecordAndContinue<T> handler2 = new FieldRecordAndContinue<>();
166 TimeDetector detector2 = new TimeDetector(5)
167 .withHandler(handler2)
168 .withMaxCheck(10)
169 .withThreshold(v(1));
170 propagator.addEventDetector(detector2);
171
172
173 propagator.propagate(epoch.shiftedBy(20));
174
175
176 List<Event<T>> events1 = handler1.getEvents();
177 Assertions.assertEquals(1, events1.size());
178 Assertions.assertEquals(5, events1.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
179 List<Event<T>> events2 = handler2.getEvents();
180 Assertions.assertEquals(1, events2.size());
181 Assertions.assertEquals(5, events2.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
182 }
183
184
185
186
187
188
189 @Test
190 public void testSimultaneousEventsReset() {
191
192 double tol = 1e-10;
193 FieldPropagator<T> propagator = getPropagator(10);
194 boolean[] firstEventOccurred = {false};
195 List<FieldRecordAndContinue.Event<T>> events = new ArrayList<>();
196
197 TimeDetector detector1 = new TimeDetector(5)
198 .withMaxCheck(10)
199 .withThreshold(v(tol))
200 .withHandler(new Handler<FieldEventDetector<T>>(events, Action.RESET_STATE) {
201 @Override
202 public Action eventOccurred(FieldSpacecraftState<T> s, FieldEventDetector<T> detector, boolean increasing) {
203 firstEventOccurred[0] = true;
204 return super.eventOccurred(s, detector, increasing);
205 }
206
207 @Override
208 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> oldState) {
209 return oldState;
210 }
211 });
212 propagator.addEventDetector(detector1);
213
214 FieldFunctionalDetector<T> detector2 = new FieldFunctionalDetector<>(field)
215 .withMaxCheck(1)
216 .withThreshold(v(tol))
217 .withHandler(new FieldRecordAndContinue<>(events))
218 .withFunction(state -> {
219 if (firstEventOccurred[0]) {
220 return new TimeDetector(1, 3, 5).g(state);
221 }
222 return new TimeDetector(5).g(state);
223 }
224 );
225 propagator.addEventDetector(detector2);
226
227
228 propagator.propagate(epoch.shiftedBy(20));
229
230
231
232 Assertions.assertEquals(5, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
233 Assertions.assertTrue(events.get(0).isIncreasing());
234 Assertions.assertEquals(detector1, events.get(0).getDetector());
235 Assertions.assertEquals(5, events.get(1).getState().getDate().durationFrom(epoch).getReal(), 0.0);
236 Assertions.assertTrue(events.get(1).isIncreasing());
237 Assertions.assertEquals(detector2, events.get(1).getDetector());
238 Assertions.assertEquals(2, events.size());
239 }
240
241
242
243
244
245
246
247 @Test
248 public void testSimultaneousDiscontinuousEventsAfterReset() {
249
250 double t = FastMath.PI;
251 double tol = 1e-10;
252 FieldPropagator<T> propagator = getPropagator(10);
253 List<FieldRecordAndContinue.Event<T>> events = new ArrayList<>();
254 FieldSpacecraftState<T> newState = new FieldSpacecraftState<>(new FieldKeplerianOrbit<>(
255 v(42e6), v(0), v(0), v(0), v(0), v(0), PositionAngleType.TRUE, eci, epoch.shiftedBy(t), v(mu)));
256
257 TimeDetector resetDetector = new TimeDetector(t)
258 .withHandler(new ResetHandler<>(events, newState))
259 .withMaxCheck(10)
260 .withThreshold(v(tol));
261 propagator.addEventDetector(resetDetector);
262 List<FieldEventDetector<T>> detectors = new ArrayList<>();
263 for (int i = 0; i < 2; i++) {
264 FieldFunctionalDetector<T> detector1 = new FieldFunctionalDetector<>(field)
265 .withFunction(s -> s.getOrbit().getA().subtract(10e6))
266 .withThreshold(v(tol))
267 .withMaxCheck(10)
268 .withHandler(new FieldRecordAndContinue<>(events));
269 propagator.addEventDetector(detector1);
270 detectors.add(detector1);
271 }
272
273
274 propagator.propagate(epoch.shiftedBy(10));
275
276
277 Assertions.assertEquals(t, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tol);
278 Assertions.assertTrue(events.get(0).isIncreasing());
279 Assertions.assertEquals(resetDetector, events.get(0).getDetector());
280
281 Assertions.assertEquals(t, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tol);
282 Assertions.assertTrue(events.get(1).isIncreasing());
283 Assertions.assertEquals(detectors.get(0), events.get(1).getDetector());
284 Assertions.assertEquals(t, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tol);
285 Assertions.assertTrue(events.get(2).isIncreasing());
286 Assertions.assertEquals(detectors.get(1), events.get(2).getDetector());
287 Assertions.assertEquals(events.size(), 3);
288 }
289
290
291
292
293
294
295 @Test
296 public void testFastSwitching() {
297
298
299 FieldPropagator<T> propagator = getPropagator(10);
300
301 FieldRecordAndContinue<T> handler = new FieldRecordAndContinue<>();
302 TimeDetector detector1 = new TimeDetector(9.9, 10.1, 12)
303 .withHandler(handler)
304 .withMaxCheck(10)
305 .withThreshold(v(0.2));
306 propagator.addEventDetector(detector1);
307
308
309 propagator.propagate(epoch.shiftedBy(20));
310
311
312
313 List<Event<T>> events1 = handler.getEvents();
314 Assertions.assertEquals(1, events1.size());
315 Assertions.assertEquals(9.9, events1.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.1);
316 Assertions.assertEquals(true, events1.get(0).isIncreasing());
317 }
318
319
320 @Test
321 public void testTrickyCaseLower() {
322
323 double maxCheck = 10;
324 double tolerance = 1e-6;
325 double t1 = 1.0, t2 = 15, t3 = 16, t4 = 17, t5 = 18;
326
327 List<Event<T>> events = new ArrayList<>();
328 TimeDetector detectorA = new TimeDetector(t3)
329 .withHandler(new FieldRecordAndContinue<>(events))
330 .withMaxCheck(maxCheck)
331 .withThreshold(v(tolerance));
332 TimeDetector detectorB = new TimeDetector(-10, t1, t2, t5)
333 .withHandler(new FieldRecordAndContinue<>(events))
334 .withMaxCheck(maxCheck)
335 .withThreshold(v(tolerance));
336 TimeDetector detectorC = new TimeDetector(t4)
337 .withHandler(new Handler<>(events, Action.RESET_DERIVATIVES))
338 .withMaxCheck(maxCheck)
339 .withThreshold(v(tolerance));
340
341 FieldPropagator<T> propagator = getPropagator(10);
342 propagator.addEventDetector(detectorA);
343 propagator.addEventDetector(detectorB);
344 propagator.addEventDetector(detectorC);
345
346
347 propagator.propagate(epoch.shiftedBy(30));
348
349
350
351
352 Assertions.assertEquals(5, events.size());
353 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
354 Assertions.assertEquals(false, events.get(0).isIncreasing());
355 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
356 Assertions.assertEquals(true, events.get(1).isIncreasing());
357 Assertions.assertEquals(t3, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
358 Assertions.assertEquals(true, events.get(2).isIncreasing());
359 Assertions.assertEquals(t4, events.get(3).getState().getDate().durationFrom(epoch).getReal(), tolerance);
360 Assertions.assertEquals(true, events.get(3).isIncreasing());
361 Assertions.assertEquals(t5, events.get(4).getState().getDate().durationFrom(epoch).getReal(), tolerance);
362 Assertions.assertEquals(false, events.get(4).isIncreasing());
363 }
364
365
366
367
368
369
370 @Test
371 public void testRootFindingTolerance() {
372
373 double maxCheck = 10;
374 double t2 = 11, t3 = t2 + 1e-5;
375 List<Event<T>> events = new ArrayList<>();
376 TimeDetector detectorA = new TimeDetector(t2)
377 .withHandler(new FieldRecordAndContinue<>(events))
378 .withMaxCheck(maxCheck)
379 .withThreshold(v(1e-6));
380 FlatDetector detectorB = new FlatDetector(t3)
381 .withHandler(new FieldRecordAndContinue<>(events))
382 .withMaxCheck(maxCheck)
383 .withThreshold(v(0.5));
384 FieldPropagator<T> propagator = getPropagator(10);
385 propagator.addEventDetector(detectorA);
386 propagator.addEventDetector(detectorB);
387
388
389 propagator.propagate(epoch.shiftedBy(30));
390
391
392
393
394 Assertions.assertSame(detectorB, events.get(0).getDetector());
395 Assertions.assertSame(detectorA, events.get(1).getDetector());
396 Assertions.assertTrue(events.get(0).getState().getDate().compareTo(
397 events.get(1).getState().getDate()) < 0);
398
399
400 Assertions.assertEquals(2, events.size());
401 Assertions.assertEquals(t3, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.5);
402 Assertions.assertEquals(true, events.get(0).isIncreasing());
403 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), 1e-6);
404 Assertions.assertEquals(true, events.get(1).isIncreasing());
405 }
406
407
408 @Test
409 public void testRootPlusToleranceHasWrongSign() {
410
411 double maxCheck = 10;
412 double tolerance = 1e-6;
413 final double toleranceB = 0.3;
414 double t1 = 11, t2 = 11.1, t3 = 11.2;
415
416 List<Event<T>> events = new ArrayList<>();
417 TimeDetector detectorA = new TimeDetector(t2)
418 .withHandler(new FieldRecordAndContinue<>(events))
419 .withMaxCheck(maxCheck)
420 .withThreshold(v(1e-6));
421 TimeDetector detectorB = new TimeDetector(t1, t3)
422 .withHandler(new FieldRecordAndContinue<>(events))
423 .withMaxCheck(maxCheck)
424 .withThreshold(v(toleranceB));
425 FieldPropagator<T> propagator = getPropagator(10);
426 propagator.addEventDetector(detectorA);
427 propagator.addEventDetector(detectorB);
428
429
430 propagator.propagate(epoch.shiftedBy(30));
431
432
433
434 Assertions.assertEquals(3, events.size());
435 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), toleranceB);
436 Assertions.assertEquals(true, events.get(0).isIncreasing());
437 Assertions.assertSame(detectorB, events.get(0).getDetector());
438
439 try {
440 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
441 Assertions.assertEquals(true, events.get(1).isIncreasing());
442 Assertions.assertSame(detectorA, events.get(1).getDetector());
443 Assertions.assertEquals(t3, events.get(2).getState().getDate().durationFrom(epoch).getReal(), toleranceB);
444 Assertions.assertEquals(false, events.get(2).isIncreasing());
445 Assertions.assertSame(detectorB, events.get(2).getDetector());
446 } catch (AssertionError e) {
447 Assertions.assertEquals(t3, events.get(1).getState().getDate().durationFrom(epoch).getReal(), toleranceB);
448 Assertions.assertEquals(false, events.get(1).isIncreasing());
449 Assertions.assertSame(detectorB, events.get(1).getDetector());
450 Assertions.assertEquals(t2, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
451 Assertions.assertEquals(true, events.get(2).isIncreasing());
452 Assertions.assertSame(detectorA, events.get(2).getDetector());
453 }
454
455 for (int i = 1; i < events.size(); i++) {
456 Assertions.assertTrue(events.get(i).getState().getDate().compareTo(
457 events.get(i - 1).getState().getDate()) >= 0);
458 }
459 }
460
461
462 @Test
463 public void testRootPlusToleranceHasWrongSignAndLessThanTb() {
464
465
466 double maxCheck = 10;
467 double tolerance = 0.5;
468 double t1 = 11, t2 = 11.4, t3 = 12.0;
469
470 List<Event<T>> events = new ArrayList<>();
471 FlatDetector detectorB = new FlatDetector(t1, t2, t3)
472 .withHandler(new FieldRecordAndContinue<>(events))
473 .withMaxCheck(maxCheck)
474 .withThreshold(v(tolerance));
475 FieldPropagator<T> propagator = getPropagator(10);
476 propagator.addEventDetector(detectorB);
477
478
479 propagator.propagate(epoch.shiftedBy(30));
480
481
482
483 Assertions.assertEquals(1, events.size());
484 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
485 Assertions.assertEquals(true, events.get(0).isIncreasing());
486 Assertions.assertSame(detectorB, events.get(0).getDetector());
487 }
488
489
490
491
492
493 @Test
494 public void testDoubleRoot() {
495
496 double maxCheck = 10;
497 double tolerance = 1e-6;
498 double t1 = 11;
499
500 List<Event<T>> events = new ArrayList<>();
501 TimeDetector detectorA = new TimeDetector(t1)
502 .withHandler(new FieldRecordAndContinue<>(events))
503 .withMaxCheck(maxCheck)
504 .withThreshold(v(tolerance));
505 TimeDetector detectorB = new TimeDetector(t1, t1)
506 .withHandler(new FieldRecordAndContinue<>(events))
507 .withMaxCheck(maxCheck)
508 .withThreshold(v(tolerance));
509 FieldPropagator<T> propagator = getPropagator(10);
510 propagator.addEventDetector(detectorA);
511 propagator.addEventDetector(detectorB);
512
513
514 propagator.propagate(epoch.shiftedBy(30));
515
516
517 Assertions.assertEquals(1, events.size());
518 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
519 Assertions.assertEquals(true, events.get(0).isIncreasing());
520 Assertions.assertSame(detectorA, events.get(0).getDetector());
521
522 Assertions.assertTrue(detectorB.g(state(t1)).getReal() == 0.0);
523 Assertions.assertTrue(detectorB.g(state(t1 - 1e-6)).getReal() < 0);
524 Assertions.assertTrue(detectorB.g(state(t1 + 1e-6)).getReal() < 0);
525 }
526
527
528
529
530
531 @Test
532 public void testDoubleRootOppositeSign() {
533
534 double maxCheck = 10;
535 double tolerance = 1e-6;
536 double t1 = 11;
537
538 List<Event<T>> events = new ArrayList<>();
539 TimeDetector detectorA = new TimeDetector(t1)
540 .withHandler(new FieldRecordAndContinue<>(events))
541 .withMaxCheck(maxCheck)
542 .withThreshold(v(tolerance));
543 ContinuousDetector detectorB = new ContinuousDetector(-20, t1, t1)
544 .withHandler(new FieldRecordAndContinue<>(events))
545 .withMaxCheck(maxCheck)
546 .withThreshold(v(tolerance));
547 FieldPropagator<T> propagator = getPropagator(10);
548 propagator.addEventDetector(detectorA);
549 propagator.addEventDetector(detectorB);
550
551
552 propagator.propagate(epoch.shiftedBy(30));
553
554
555 Assertions.assertEquals(1, events.size());
556 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
557 Assertions.assertEquals(true, events.get(0).isIncreasing());
558 Assertions.assertSame(detectorA, events.get(0).getDetector());
559
560 Assertions.assertEquals(0.0, detectorB.g(state(t1)).getReal(), 0.0);
561 Assertions.assertTrue(detectorB.g(state(t1 - 1e-6)).getReal() > 0);
562 Assertions.assertTrue(detectorB.g(state(t1 + 1e-6)).getReal() > 0);
563 }
564
565
566 @Test
567 public void testZeroAtBeginningAndEndOfInterval() {
568
569 double maxCheck = 10;
570 double tolerance = 1e-6;
571 double t1 = 10, t2 = 20;
572
573 List<Event<T>> events = new ArrayList<>();
574 ContinuousDetector detectorA = new ContinuousDetector(t1, t2)
575 .withHandler(new FieldRecordAndContinue<>(events))
576 .withMaxCheck(maxCheck)
577 .withThreshold(v(tolerance));
578 FieldPropagator<T> propagator = getPropagator(10);
579 propagator.addEventDetector(detectorA);
580
581 propagator.propagate(epoch.shiftedBy(30));
582
583
584 Assertions.assertEquals(2, events.size());
585 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
586 Assertions.assertEquals(true, events.get(0).isIncreasing());
587 Assertions.assertSame(detectorA, events.get(0).getDetector());
588 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
589 Assertions.assertEquals(false, events.get(1).isIncreasing());
590 Assertions.assertSame(detectorA, events.get(1).getDetector());
591 }
592
593
594 @Test
595 public void testZeroAtBeginningAndEndOfIntervalOppositeSign() {
596
597 double maxCheck = 10;
598 double tolerance = 1e-6;
599 double t1 = 10, t2 = 20;
600
601 List<Event<T>> events = new ArrayList<>();
602 ContinuousDetector detectorA = new ContinuousDetector(-10, t1, t2)
603 .withHandler(new FieldRecordAndContinue<>(events))
604 .withMaxCheck(maxCheck)
605 .withThreshold(v(tolerance));
606 FieldPropagator<T> propagator = getPropagator(10);
607 propagator.addEventDetector(detectorA);
608
609
610 propagator.propagate(epoch.shiftedBy(30));
611
612
613 Assertions.assertEquals(2, events.size());
614 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
615 Assertions.assertEquals(false, events.get(0).isIncreasing());
616 Assertions.assertSame(detectorA, events.get(0).getDetector());
617 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
618 Assertions.assertEquals(true, events.get(1).isIncreasing());
619 Assertions.assertSame(detectorA, events.get(1).getDetector());
620 }
621
622
623 @Test
624 public void testMultipleBackups() {
625
626 double maxCheck = 10;
627 double tolerance = 1e-6;
628 double t1 = 1.0, t2 = 2, t3 = 3, t4 = 4, t5 = 5, t6 = 6.5, t7 = 7;
629
630 List<Event<T>> events = new ArrayList<>();
631 ContinuousDetector detectorA = new ContinuousDetector(t6)
632 .withHandler(new FieldRecordAndContinue<>(events))
633 .withMaxCheck(maxCheck)
634 .withThreshold(v(tolerance));
635 FlatDetector detectorB = new FlatDetector(t1, t3, t4, t7)
636 .withHandler(new FieldRecordAndContinue<>(events))
637 .withMaxCheck(maxCheck)
638 .withThreshold(v(tolerance));
639 ContinuousDetector detectorC = new ContinuousDetector(t2, t5)
640 .withHandler(new FieldRecordAndContinue<>(events))
641 .withMaxCheck(maxCheck)
642 .withThreshold(v(tolerance));
643
644 FieldPropagator<T> propagator = getPropagator(10);
645 propagator.addEventDetector(detectorA);
646 propagator.addEventDetector(detectorB);
647 propagator.addEventDetector(detectorC);
648
649
650 propagator.propagate(epoch.shiftedBy(30));
651
652
653
654 Assertions.assertEquals(5, events.size());
655 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
656 Assertions.assertEquals(true, events.get(0).isIncreasing());
657 Assertions.assertEquals(detectorB, events.get(0).getDetector());
658 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
659 Assertions.assertEquals(true, events.get(1).isIncreasing());
660 Assertions.assertEquals(detectorC, events.get(1).getDetector());
661
662
663
664
665
666
667
668
669
670
671 Assertions.assertEquals(t5, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
672 Assertions.assertEquals(false, events.get(2).isIncreasing());
673 Assertions.assertEquals(detectorC, events.get(2).getDetector());
674 Assertions.assertEquals(t6, events.get(3).getState().getDate().durationFrom(epoch).getReal(), tolerance);
675 Assertions.assertEquals(true, events.get(3).isIncreasing());
676 Assertions.assertEquals(detectorA, events.get(3).getDetector());
677 Assertions.assertEquals(t7, events.get(4).getState().getDate().durationFrom(epoch).getReal(), tolerance);
678 Assertions.assertEquals(false, events.get(4).isIncreasing());
679 Assertions.assertEquals(detectorB, events.get(4).getDetector());
680 }
681
682
683 @Test
684 public void testEventCausedByStateReset() {
685
686 double maxCheck = 10;
687 double tolerance = 1e-6;
688 double t1 = 15.0;
689 FieldSpacecraftState<T> newState = new FieldSpacecraftState<>(new FieldKeplerianOrbit<>(
690 v(6378137 + 500e3), v(0), v(FastMath.PI / 2), v(0), v(0),
691 v(FastMath.PI / 2), PositionAngleType.TRUE, eci, epoch.shiftedBy(t1), v(mu)));
692
693 List<Event<T>> events = new ArrayList<>();
694 TimeDetector detectorA = new TimeDetector(t1)
695 .withHandler(new Handler<FieldEventDetector<T>>(events, Action.RESET_STATE) {
696 @Override
697 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector,
698 FieldSpacecraftState<T> oldState) {
699 return newState;
700 }
701 })
702 .withMaxCheck(maxCheck)
703 .withThreshold(v(tolerance));
704 FieldLatitudeCrossingDetector<T> detectorB =
705 new FieldLatitudeCrossingDetector<T>(field, earth, FastMath.toRadians(80))
706 .withHandler(new FieldRecordAndContinue<>(events))
707 .withMaxCheck(maxCheck)
708 .withThreshold(v(tolerance));
709
710 FieldPropagator<T> propagator = getPropagator(10);
711 propagator.addEventDetector(detectorA);
712 propagator.addEventDetector(detectorB);
713
714
715 propagator.propagate(epoch.shiftedBy(40.0));
716
717
718
719 Assertions.assertEquals(2, events.size());
720 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
721 Assertions.assertEquals(true, events.get(0).isIncreasing());
722 Assertions.assertEquals(detectorA, events.get(0).getDetector());
723 Assertions.assertEquals(t1, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
724 Assertions.assertEquals(true, events.get(1).isIncreasing());
725 Assertions.assertEquals(detectorB, events.get(1).getDetector());
726 }
727
728
729 @Test
730 public void testConvergenceTooTight() {
731
732 double maxCheck = 10;
733 double tolerance = 1e-18;
734 double t1 = 15;
735
736 List<Event<T>> events = new ArrayList<>();
737 ContinuousDetector detectorA = new ContinuousDetector(t1)
738 .withHandler(new FieldRecordAndContinue<>(events))
739 .withMaxCheck(maxCheck)
740 .withThreshold(v(tolerance));
741 FieldPropagator<T> propagator = getPropagator(10);
742 propagator.addEventDetector(detectorA);
743
744
745 propagator.propagate(epoch.shiftedBy(30));
746
747
748 Assertions.assertEquals(1, events.size());
749 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
750 Assertions.assertEquals(true, events.get(0).isIncreasing());
751 Assertions.assertSame(detectorA, events.get(0).getDetector());
752 }
753
754
755
756
757
758
759
760 @Test
761 public void testEventChangesGFunctionDefinition() {
762
763 double maxCheck = 5;
764 double tolerance = 1e-6;
765 double t1 = 11, t2 = 19;
766
767 List<Event<T>> events = new ArrayList<>();
768
769 boolean[] swap = new boolean[1];
770 final ContinuousDetector detectorA = new ContinuousDetector(t1)
771 .withMaxCheck(maxCheck)
772 .withThreshold(v(tolerance))
773 .withHandler(new FieldRecordAndContinue<T>(events) {
774 @Override
775 public Action eventOccurred(FieldSpacecraftState<T> s,
776 FieldEventDetector<T> detector,
777 boolean increasing) {
778 swap[0] = true;
779 return super.eventOccurred(s, detector, increasing);
780 }
781 });
782 ContinuousDetector detectorB = new ContinuousDetector(t2);
783 FieldEventDetector<T> detectorC = new Definition(maxCheck, tolerance, swap, detectorB, detectorB, events);
784 FieldPropagator<T> propagator = getPropagator(10);
785 propagator.addEventDetector(detectorA);
786 propagator.addEventDetector(detectorC);
787
788
789 propagator.propagate(epoch.shiftedBy(30));
790
791
792 Assertions.assertEquals(2, events.size());
793 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
794 Assertions.assertEquals(true, events.get(0).isIncreasing());
795 Assertions.assertSame(detectorA, events.get(0).getDetector());
796 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
797 Assertions.assertEquals(true, events.get(1).isIncreasing());
798 Assertions.assertSame(detectorC, events.get(1).getDetector());
799 }
800
801
802
803
804
805
806 @Test
807 public void testEventChangesGFunctionDefinitionCancel() {
808
809 double maxCheck = 5;
810 double tolerance = 1e-6;
811 double t1 = 11, t2 = 11.1;
812
813 List<Event<T>> events = new ArrayList<>();
814
815 boolean[] swap = new boolean[1];
816 final ContinuousDetector detectorA = new ContinuousDetector(t1)
817 .withMaxCheck(maxCheck)
818 .withThreshold(v(tolerance))
819 .withHandler(new FieldRecordAndContinue<T>(events) {
820 @Override
821 public Action eventOccurred(FieldSpacecraftState<T> state,
822 FieldEventDetector<T> detector,
823 boolean increasing) {
824 swap[0] = true;
825 super.eventOccurred(state, detector, increasing);
826 return Action.RESET_EVENTS;
827 }
828 });
829 final ContinuousDetector detectorB = new ContinuousDetector(t2);
830 FieldEventDetector<T> detectorC = new Cancel(maxCheck, tolerance, swap, detectorB, detectorB, events);
831 FieldPropagator<T> propagator = getPropagator(10);
832 propagator.addEventDetector(detectorA);
833 propagator.addEventDetector(detectorC);
834
835
836 propagator.propagate(epoch.shiftedBy(30));
837
838
839 Assertions.assertEquals(1, events.size());
840 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
841 Assertions.assertEquals(true, events.get(0).isIncreasing());
842 Assertions.assertSame(detectorA, events.get(0).getDetector());
843 }
844
845
846
847
848
849
850 @Test
851 public void testEventChangesGFunctionDefinitionDelay() {
852
853 double maxCheck = 5;
854 double tolerance = 1e-6;
855 double t1 = 11, t2 = 11.1, t3 = 11.2;
856
857 List<Event<T>> events = new ArrayList<>();
858
859 boolean[] swap = new boolean[1];
860 final ContinuousDetector detectorA = new ContinuousDetector(t1)
861 .withMaxCheck(maxCheck)
862 .withThreshold(v(tolerance))
863 .withHandler(new FieldRecordAndContinue<T>(events) {
864 @Override
865 public Action eventOccurred(FieldSpacecraftState<T> state,
866 FieldEventDetector<T> detector,
867 boolean increasing) {
868 swap[0] = true;
869 super.eventOccurred(state, detector, increasing);
870 return Action.RESET_EVENTS;
871 }
872 });
873 final ContinuousDetector detectorB = new ContinuousDetector(t2);
874 final ContinuousDetector detectorD = new ContinuousDetector(t3);
875 FieldEventDetector<T> detectorC = new Delay(maxCheck, tolerance, swap, detectorB, detectorD, events);
876 FieldPropagator<T> propagator = getPropagator(10);
877 propagator.addEventDetector(detectorA);
878 propagator.addEventDetector(detectorC);
879
880
881 propagator.propagate(epoch.shiftedBy(30));
882
883
884 Assertions.assertEquals(2, events.size());
885 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
886 Assertions.assertEquals(true, events.get(0).isIncreasing());
887 Assertions.assertSame(detectorA, events.get(0).getDetector());
888 Assertions.assertEquals(t3, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
889 Assertions.assertEquals(true, events.get(1).isIncreasing());
890 Assertions.assertSame(detectorC, events.get(1).getDetector());
891 }
892
893
894
895
896
897
898 @Test
899 public void testEventChangesGFunctionDefinitionAccelerate() {
900
901 double maxCheck = 5;
902 double tolerance = 1e-6;
903 double t1 = 11, t2 = 11.1, t3 = 11.2;
904
905 List<Event<T>> events = new ArrayList<>();
906
907 boolean[] swap = new boolean[1];
908 final ContinuousDetector detectorA = new ContinuousDetector(t1)
909 .withMaxCheck(maxCheck)
910 .withThreshold(v(tolerance))
911 .withHandler(new FieldRecordAndContinue<T>(events) {
912 @Override
913 public Action eventOccurred(FieldSpacecraftState<T> state,
914 FieldEventDetector<T> detector,
915 boolean increasing) {
916 swap[0] = true;
917 super.eventOccurred(state, detector, increasing);
918 return Action.RESET_EVENTS;
919 }
920 });
921 final ContinuousDetector detectorB = new ContinuousDetector(t2);
922 final ContinuousDetector detectorD = new ContinuousDetector(t3);
923 FieldEventDetector<T> detectorC = new Accelerate(maxCheck, tolerance, swap, detectorB, detectorD, events);
924 FieldPropagator<T> propagator = getPropagator(10);
925 propagator.addEventDetector(detectorA);
926 propagator.addEventDetector(detectorC);
927
928
929 propagator.propagate(epoch.shiftedBy(30));
930
931
932 Assertions.assertEquals(2, events.size());
933 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
934 Assertions.assertEquals(true, events.get(0).isIncreasing());
935 Assertions.assertSame(detectorA, events.get(0).getDetector());
936 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
937 Assertions.assertEquals(true, events.get(1).isIncreasing());
938 Assertions.assertSame(detectorC, events.get(1).getDetector());
939 }
940
941
942 @Test
943 public void testToleranceStop() {
944
945 double maxCheck = 10;
946 double tolerance = 1e-18;
947 double t1 = 15.1;
948
949 List<Event<T>> events = new ArrayList<>();
950 FlatDetector detectorA = new FlatDetector(t1)
951 .withHandler(new Handler<>(events, Action.STOP))
952 .withMaxCheck(maxCheck)
953 .withThreshold(v(tolerance));
954 FieldPropagator<T> propagator = getPropagator(10);
955 propagator.addEventDetector(detectorA);
956
957
958 FieldSpacecraftState<T> finalState = propagator.propagate(epoch.shiftedBy(30));
959
960
961 Assertions.assertEquals(1, events.size());
962
963 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
964 Assertions.assertEquals(true, events.get(0).isIncreasing());
965 Assertions.assertSame(detectorA, events.get(0).getDetector());
966 Assertions.assertEquals(t1, finalState.getDate().durationFrom(epoch).getReal(), tolerance);
967
968
969 finalState = propagator.propagate(epoch.shiftedBy(30));
970
971
972 Assertions.assertEquals(30.0, finalState.getDate().durationFrom(epoch).getReal(), 0.0);
973 }
974
975
976
977
978
979
980 @Test
981 public void testShortBracketingInterval() {
982
983 double maxCheck = 10;
984 double tolerance = 1e-6;
985 final double t1 = FastMath.nextUp(10.0), t2 = 10.5;
986
987 List<Event<T>> events = new ArrayList<>();
988
989 FieldEventDetector<T> detectorA = new ShortInfDetector(maxCheck, tolerance, t1, t2, events);
990 TimeDetector detectorB = new TimeDetector(t1)
991 .withHandler(new FieldRecordAndContinue<>(events))
992 .withMaxCheck(maxCheck)
993 .withThreshold(v(tolerance));
994 FieldPropagator<T> propagator = getPropagator(10);
995 propagator.addEventDetector(detectorA);
996 propagator.addEventDetector(detectorB);
997
998
999 propagator.propagate(epoch.shiftedBy(30.0));
1000
1001
1002 Assertions.assertEquals(3, events.size());
1003 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1004 Assertions.assertEquals(true, events.get(0).isIncreasing());
1005 Assertions.assertSame(detectorA, events.get(0).getDetector());
1006 Assertions.assertEquals(t1, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1007 Assertions.assertEquals(true, events.get(1).isIncreasing());
1008 Assertions.assertSame(detectorB, events.get(1).getDetector());
1009 Assertions.assertEquals(t2, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1010 Assertions.assertEquals(false, events.get(2).isIncreasing());
1011 Assertions.assertSame(detectorA, events.get(2).getDetector());
1012 }
1013
1014
1015 @Test
1016 public void testToleranceMaxIterations() {
1017
1018 double maxCheck = 10;
1019 double tolerance = 1e-18;
1020 FieldAbsoluteDate<T> t1 = epoch.shiftedBy(15).shiftedBy(FastMath.ulp(15.0) / 8);
1021
1022 List<Event<T>> events = new ArrayList<>();
1023 FlatDetector detectorA = new FlatDetector(t1)
1024 .withHandler(new FieldRecordAndContinue<>(events))
1025 .withMaxCheck(maxCheck)
1026 .withThreshold(v(tolerance));
1027 FieldPropagator<T> propagator = getPropagator(10);
1028 propagator.addEventDetector(detectorA);
1029
1030
1031 propagator.propagate(epoch.shiftedBy(30));
1032
1033
1034 Assertions.assertEquals(1, events.size());
1035
1036 Assertions.assertEquals(t1.durationFrom(epoch).getReal(),
1037 events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1038 Assertions.assertEquals(true, events.get(0).isIncreasing());
1039 Assertions.assertSame(detectorA, events.get(0).getDetector());
1040 }
1041
1042
1043 @Test
1044 public void testEventStepHandler() {
1045
1046 double tolerance = 1e-18;
1047 FieldPropagator<T> propagator = getPropagator(10);
1048 propagator.addEventDetector(new TimeDetector(5)
1049 .withHandler(new Handler<>(Action.CONTINUE))
1050 .withThreshold(v(tolerance)));
1051 StepHandler<T> stepHandler = new StepHandler<>();
1052 propagator.setStepHandler(stepHandler);
1053
1054
1055 FieldSpacecraftState<T> finalState = propagator.propagate(epoch.shiftedBy(10));
1056
1057
1058 Assertions.assertEquals(10.0, finalState.getDate().durationFrom(epoch).getReal(), tolerance);
1059 Assertions.assertEquals(0.0,
1060 stepHandler.initialState.getDate().durationFrom(epoch).getReal(), tolerance);
1061 Assertions.assertEquals(10.0, stepHandler.targetDate.durationFrom(epoch).getReal(), tolerance);
1062 Assertions.assertEquals(10.0,
1063 stepHandler.finalState.getDate().durationFrom(epoch).getReal(), tolerance);
1064 FieldOrekitStepInterpolator<T> interpolator = stepHandler.interpolators.get(0);
1065 Assertions.assertEquals(0.0,
1066 interpolator.getPreviousState().getDate().durationFrom(epoch).getReal(), tolerance);
1067 Assertions.assertEquals(5.0,
1068 interpolator.getCurrentState().getDate().durationFrom(epoch).getReal(), tolerance);
1069 interpolator = stepHandler.interpolators.get(1);
1070 Assertions.assertEquals(5.0,
1071 interpolator.getPreviousState().getDate().durationFrom(epoch).getReal(), tolerance);
1072 Assertions.assertEquals(10.0,
1073 interpolator.getCurrentState().getDate().durationFrom(epoch).getReal(), tolerance);
1074 Assertions.assertEquals(2, stepHandler.interpolators.size());
1075 }
1076
1077
1078
1079
1080
1081 @Test
1082 public void testEventCausedByDerivativesReset() {
1083
1084 TimeDetector detectorA = new TimeDetector(15.0)
1085 .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){
1086 @Override
1087 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> d,
1088 FieldSpacecraftState<T> s) {
1089 return null;
1090 }
1091 })
1092 .withMaxCheck(10)
1093 .withThreshold(v(1e-6));
1094 FieldPropagator<T> propagator = getPropagator(10);
1095 propagator.addEventDetector(detectorA);
1096
1097 try {
1098
1099 propagator.propagate(epoch.shiftedBy(20.0));
1100 Assertions.fail("Expected Exception");
1101 } catch (NullPointerException e) {
1102
1103 }
1104 }
1105
1106
1107
1108
1109
1110
1111
1112 @Test
1113 public void testCloseEventsFirstOneIsResetReverse() {
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 FieldPropagator<T> propagator = getPropagator(10.0);
1125
1126
1127 double t1 = -1;
1128 Handler<FieldEventDetector<T>> handler1 = new Handler<>(Action.RESET_DERIVATIVES);
1129 TimeDetector detector1 = new TimeDetector(t1)
1130 .withHandler(handler1)
1131 .withMaxCheck(10)
1132 .withThreshold(v(1e-9));
1133 propagator.addEventDetector(detector1);
1134 FieldRecordAndContinue<T> handler2 = new FieldRecordAndContinue<>();
1135 TimeDetector detector2 = new TimeDetector(t1 - 1e-15, t1 - 4.9)
1136 .withHandler(handler2)
1137 .withMaxCheck(11)
1138 .withThreshold(v(1e-9));
1139 propagator.addEventDetector(detector2);
1140
1141
1142 propagator.propagate(epoch.shiftedBy(-20));
1143
1144
1145 List<Event<T>> events1 = handler1.getEvents();
1146 Assertions.assertEquals(1, events1.size());
1147 Assertions.assertEquals(t1, events1.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1148 List<Event<T>> events2 = handler2.getEvents();
1149 Assertions.assertEquals(0, events2.size());
1150 }
1151
1152 @Test
1153 public void testCloseEventsReverse() {
1154
1155 double tolerance = 1;
1156 FieldPropagator<T> propagator = getPropagator(10);
1157
1158 FieldRecordAndContinue<T> handler1 = new FieldRecordAndContinue<>();
1159 TimeDetector detector1 = new TimeDetector(-5)
1160 .withHandler(handler1)
1161 .withMaxCheck(10)
1162 .withThreshold(v(tolerance));
1163 propagator.addEventDetector(detector1);
1164 FieldRecordAndContinue<T> handler2 = new FieldRecordAndContinue<>();
1165 TimeDetector detector2 = new TimeDetector(-5.5)
1166 .withHandler(handler2)
1167 .withMaxCheck(10)
1168 .withThreshold(v(tolerance));
1169 propagator.addEventDetector(detector2);
1170
1171
1172 propagator.propagate(epoch.shiftedBy(-20));
1173
1174
1175 List<Event<T>> events1 = handler1.getEvents();
1176 Assertions.assertEquals(1, events1.size());
1177 Assertions.assertEquals(-5, events1.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1178 List<Event<T>> events2 = handler2.getEvents();
1179 Assertions.assertEquals(1, events2.size());
1180 Assertions.assertEquals(-5.5, events2.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1181 }
1182
1183 @Test
1184 public void testSimultaneousEventsReverse() {
1185
1186 FieldPropagator<T> propagator = getPropagator(10);
1187
1188 FieldRecordAndContinue<T> handler1 = new FieldRecordAndContinue<>();
1189 TimeDetector detector1 = new TimeDetector(-5)
1190 .withHandler(handler1)
1191 .withMaxCheck(10)
1192 .withThreshold(v(1));
1193 propagator.addEventDetector(detector1);
1194 FieldRecordAndContinue<T> handler2 = new FieldRecordAndContinue<>();
1195 TimeDetector detector2 = new TimeDetector(-5)
1196 .withHandler(handler2)
1197 .withMaxCheck(10)
1198 .withThreshold(v(1));
1199 propagator.addEventDetector(detector2);
1200
1201
1202 propagator.propagate(epoch.shiftedBy(-20));
1203
1204
1205 List<Event<T>> events1 = handler1.getEvents();
1206 Assertions.assertEquals(1, events1.size());
1207 Assertions.assertEquals(-5, events1.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1208 List<Event<T>> events2 = handler2.getEvents();
1209 Assertions.assertEquals(1, events2.size());
1210 Assertions.assertEquals(-5, events2.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1211 }
1212
1213
1214
1215
1216
1217
1218 @Test
1219 public void testSimultaneousEventsResetReverse() {
1220
1221 double tol = 1e-10;
1222 FieldPropagator<T> propagator = getPropagator(10);
1223 boolean[] firstEventOccurred = {false};
1224 List<FieldRecordAndContinue.Event<T>> events = new ArrayList<>();
1225
1226 TimeDetector detector1 = new TimeDetector(-5)
1227 .withMaxCheck(10)
1228 .withThreshold(v(tol))
1229 .withHandler(new Handler<FieldEventDetector<T>>(events, Action.RESET_STATE) {
1230 @Override
1231 public Action eventOccurred(FieldSpacecraftState<T> s, FieldEventDetector<T> detector, boolean increasing) {
1232 firstEventOccurred[0] = true;
1233 return super.eventOccurred(s, detector, increasing);
1234 }
1235
1236 @Override
1237 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> oldState) {
1238 return oldState;
1239 }
1240 });
1241 propagator.addEventDetector(detector1);
1242
1243 FieldFunctionalDetector<T> detector2 = new FieldFunctionalDetector<>(field)
1244 .withMaxCheck(1)
1245 .withThreshold(v(tol))
1246 .withHandler(new FieldRecordAndContinue<>(events))
1247 .withFunction(state -> {
1248 if (firstEventOccurred[0]) {
1249 return new TimeDetector(-1, -3, -5).g(state);
1250 }
1251 return new TimeDetector(-5).g(state);
1252 }
1253 );
1254 propagator.addEventDetector(detector2);
1255
1256
1257 propagator.propagate(epoch.shiftedBy(-20));
1258
1259
1260
1261 Assertions.assertEquals(-5, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1262 Assertions.assertTrue(events.get(0).isIncreasing());
1263 Assertions.assertEquals(detector1, events.get(0).getDetector());
1264 Assertions.assertEquals(-5, events.get(1).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1265 Assertions.assertTrue(events.get(1).isIncreasing());
1266 Assertions.assertEquals(detector2, events.get(1).getDetector());
1267 Assertions.assertEquals(2, events.size());
1268 }
1269
1270
1271
1272
1273
1274
1275
1276 @Test
1277 public void testSimultaneousDiscontinuousEventsAfterResetReverse() {
1278
1279 double t = -FastMath.PI;
1280 double tol = 1e-10;
1281 FieldPropagator<T> propagator = getPropagator(10);
1282 List<FieldRecordAndContinue.Event<T>> events = new ArrayList<>();
1283 FieldSpacecraftState<T> newState = new FieldSpacecraftState<>(new FieldKeplerianOrbit<>(
1284 v(42e6), v(0), v(0), v(0), v(0), v(0), PositionAngleType.TRUE, eci, epoch.shiftedBy(t), v(mu)));
1285
1286 TimeDetector resetDetector = new TimeDetector(t)
1287 .withHandler(new ResetHandler<>(events, newState))
1288 .withMaxCheck(10)
1289 .withThreshold(v(tol));
1290 propagator.addEventDetector(resetDetector);
1291 List<FieldEventDetector<T>> detectors = new ArrayList<>();
1292 for (int i = 0; i < 2; i++) {
1293 FieldFunctionalDetector<T> detector1 = new FieldFunctionalDetector<>(field)
1294 .withFunction(s -> s.getOrbit().getA().subtract(10e6))
1295 .withThreshold(v(tol))
1296 .withMaxCheck(10)
1297 .withHandler(new FieldRecordAndContinue<>(events));
1298 propagator.addEventDetector(detector1);
1299 detectors.add(detector1);
1300 }
1301
1302
1303 propagator.propagate(epoch.shiftedBy(-10));
1304
1305
1306 Assertions.assertEquals(t, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tol);
1307 Assertions.assertTrue(events.get(0).isIncreasing());
1308 Assertions.assertEquals(resetDetector, events.get(0).getDetector());
1309
1310 Assertions.assertEquals(t, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tol);
1311 Assertions.assertFalse(events.get(1).isIncreasing());
1312 Assertions.assertEquals(detectors.get(0), events.get(1).getDetector());
1313 Assertions.assertEquals(t, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tol);
1314 Assertions.assertFalse(events.get(2).isIncreasing());
1315 Assertions.assertEquals(detectors.get(1), events.get(2).getDetector());
1316 Assertions.assertEquals(events.size(), 3);
1317 }
1318
1319
1320
1321
1322
1323
1324 @Test
1325 public void testFastSwitchingReverse() {
1326
1327
1328 FieldPropagator<T> propagator = getPropagator(10);
1329
1330 List<Event<T>> events = new ArrayList<>();
1331 TimeDetector detector1 = new TimeDetector(-9.9, -10.1, -12)
1332 .withHandler(new FieldRecordAndContinue<>(events))
1333 .withMaxCheck(10)
1334 .withThreshold(v(0.2));
1335 propagator.addEventDetector(detector1);
1336
1337
1338 propagator.propagate(epoch.shiftedBy(-20));
1339
1340
1341
1342 Assertions.assertEquals(1, events.size());
1343 Assertions.assertEquals(-9.9, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.2);
1344 Assertions.assertEquals(true, events.get(0).isIncreasing());
1345 }
1346
1347
1348 @Test
1349 public void testTrickyCaseLowerReverse() {
1350
1351 double maxCheck = 10;
1352 double tolerance = 1e-6;
1353 double t1 = -1.0, t2 = -15, t3 = -16, t4 = -17, t5 = -18;
1354
1355 List<Event<T>> events = new ArrayList<>();
1356 TimeDetector detectorA = new TimeDetector(t3)
1357 .withHandler(new FieldRecordAndContinue<>(events))
1358 .withMaxCheck(maxCheck)
1359 .withThreshold(v(tolerance));
1360 TimeDetector detectorB = new TimeDetector(-50, t1, t2, t5)
1361 .withHandler(new FieldRecordAndContinue<>(events))
1362 .withMaxCheck(maxCheck)
1363 .withThreshold(v(tolerance));
1364 TimeDetector detectorC = new TimeDetector(t4)
1365 .withHandler(new Handler<>(events, Action.RESET_DERIVATIVES))
1366 .withMaxCheck(maxCheck)
1367 .withThreshold(v(tolerance));
1368
1369 FieldPropagator<T> propagator = getPropagator(10);
1370 propagator.addEventDetector(detectorA);
1371 propagator.addEventDetector(detectorB);
1372 propagator.addEventDetector(detectorC);
1373
1374
1375 propagator.propagate(epoch.shiftedBy(-30));
1376
1377
1378
1379
1380 Assertions.assertEquals(5, events.size());
1381 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1382 Assertions.assertEquals(false, events.get(0).isIncreasing());
1383 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1384 Assertions.assertEquals(true, events.get(1).isIncreasing());
1385 Assertions.assertEquals(t3, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1386 Assertions.assertEquals(true, events.get(2).isIncreasing());
1387 Assertions.assertEquals(t4, events.get(3).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1388 Assertions.assertEquals(true, events.get(3).isIncreasing());
1389 Assertions.assertEquals(t5, events.get(4).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1390 Assertions.assertEquals(false, events.get(4).isIncreasing());
1391 }
1392
1393
1394
1395
1396
1397
1398 @Test
1399 public void testRootFindingToleranceReverse() {
1400
1401 double maxCheck = 10;
1402 double t2 = -11, t3 = t2 - 1e-5;
1403 List<Event<T>> events = new ArrayList<>();
1404 TimeDetector detectorA = new TimeDetector(t2)
1405 .withHandler(new FieldRecordAndContinue<>(events))
1406 .withMaxCheck(maxCheck)
1407 .withThreshold(v(1e-6));
1408 FlatDetector detectorB = new FlatDetector(t3)
1409 .withHandler(new FieldRecordAndContinue<>(events))
1410 .withMaxCheck(maxCheck)
1411 .withThreshold(v(0.5));
1412 FieldPropagator<T> propagator = getPropagator(10);
1413 propagator.addEventDetector(detectorA);
1414 propagator.addEventDetector(detectorB);
1415
1416
1417 propagator.propagate(epoch.shiftedBy(-30.0));
1418
1419
1420
1421
1422 Assertions.assertSame(detectorB, events.get(0).getDetector());
1423 Assertions.assertSame(detectorA, events.get(1).getDetector());
1424 Assertions.assertTrue(events.get(0).getState().getDate().compareTo(
1425 events.get(1).getState().getDate()) > 0);
1426
1427
1428 Assertions.assertEquals(2, events.size());
1429 Assertions.assertEquals(t3, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.5);
1430 Assertions.assertEquals(true, events.get(0).isIncreasing());
1431 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), 1e-6);
1432 Assertions.assertEquals(true, events.get(1).isIncreasing());
1433 }
1434
1435
1436 @Test
1437 public void testRootPlusToleranceHasWrongSignReverse() {
1438
1439 double maxCheck = 10;
1440 double tolerance = 1e-6;
1441 final double toleranceB = 0.3;
1442 double t1 = -11, t2 = -11.1, t3 = -11.2;
1443
1444 List<Event<T>> events = new ArrayList<>();
1445 TimeDetector detectorA = new TimeDetector(t2)
1446 .withHandler(new FieldRecordAndContinue<>(events))
1447 .withMaxCheck(maxCheck)
1448 .withThreshold(v(tolerance));
1449 TimeDetector detectorB = new TimeDetector(-50, t1, t3)
1450 .withHandler(new FieldRecordAndContinue<>(events))
1451 .withMaxCheck(maxCheck)
1452 .withThreshold(v(toleranceB));
1453 FieldPropagator<T> propagator = getPropagator(10);
1454 propagator.addEventDetector(detectorA);
1455 propagator.addEventDetector(detectorB);
1456
1457
1458 propagator.propagate(epoch.shiftedBy(-30.0));
1459
1460
1461
1462 Assertions.assertEquals(3, events.size());
1463 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), toleranceB);
1464 Assertions.assertEquals(true, events.get(0).isIncreasing());
1465 Assertions.assertSame(detectorB, events.get(0).getDetector());
1466 Assertions.assertEquals(t3, events.get(1).getState().getDate().durationFrom(epoch).getReal(), toleranceB);
1467 Assertions.assertEquals(false, events.get(1).isIncreasing());
1468 Assertions.assertSame(detectorB, events.get(1).getDetector());
1469 Assertions.assertEquals(t2, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1470 Assertions.assertEquals(true, events.get(2).isIncreasing());
1471 Assertions.assertSame(detectorA, events.get(2).getDetector());
1472
1473 Assertions.assertTrue(events.get(0).getState().getDate().compareTo(
1474 events.get(1).getState().getDate()) >= 0);
1475 Assertions.assertTrue(events.get(1).getState().getDate().compareTo(
1476 events.get(2).getState().getDate()) >= 0);
1477 }
1478
1479
1480 @Test
1481 public void testRootPlusToleranceHasWrongSignAndLessThanTbReverse() {
1482
1483
1484 double maxCheck = 10;
1485 double tolerance = 0.5;
1486 double t1 = -11, t2 = -11.4, t3 = -12.0;
1487
1488 List<Event<T>> events = new ArrayList<>();
1489 FlatDetector detectorB = new FlatDetector(t1, t2, t3)
1490 .withHandler(new FieldRecordAndContinue<>(events))
1491 .withMaxCheck(maxCheck)
1492 .withThreshold(v(tolerance));
1493 FieldPropagator<T> propagator = getPropagator(10);
1494 propagator.addEventDetector(detectorB);
1495
1496
1497 propagator.propagate(epoch.shiftedBy(-30.0));
1498
1499
1500
1501 Assertions.assertEquals(1, events.size());
1502 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1503 Assertions.assertEquals(true, events.get(0).isIncreasing());
1504 Assertions.assertSame(detectorB, events.get(0).getDetector());
1505 }
1506
1507
1508
1509
1510
1511 @Test
1512 public void testDoubleRootReverse() {
1513
1514 double maxCheck = 10;
1515 double tolerance = 1e-6;
1516 double t1 = -11;
1517
1518 List<Event<T>> events = new ArrayList<>();
1519 TimeDetector detectorA = new TimeDetector(t1)
1520 .withHandler(new FieldRecordAndContinue<>(events))
1521 .withMaxCheck(maxCheck)
1522 .withThreshold(v(tolerance));
1523 TimeDetector detectorB = new TimeDetector(t1, t1)
1524 .withHandler(new FieldRecordAndContinue<>(events))
1525 .withMaxCheck(maxCheck)
1526 .withThreshold(v(tolerance));
1527 FieldPropagator<T> propagator = getPropagator(10);
1528 propagator.addEventDetector(detectorA);
1529 propagator.addEventDetector(detectorB);
1530
1531
1532 propagator.propagate(epoch.shiftedBy(-30.0));
1533
1534
1535 Assertions.assertEquals(1, events.size());
1536 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1537 Assertions.assertEquals(true, events.get(0).isIncreasing());
1538 Assertions.assertSame(detectorA, events.get(0).getDetector());
1539
1540 Assertions.assertTrue(detectorB.g(state(t1)).getReal() == 0.0);
1541 Assertions.assertTrue(detectorB.g(state(t1 + 1e-6)).getReal() < 0);
1542 Assertions.assertTrue(detectorB.g(state(t1 - 1e-6)).getReal() < 0);
1543 }
1544
1545
1546
1547
1548
1549 @Test
1550 public void testDoubleRootOppositeSignReverse() {
1551
1552 double maxCheck = 10;
1553 double tolerance = 1e-6;
1554 double t1 = -11;
1555
1556 List<Event<T>> events = new ArrayList<>();
1557 TimeDetector detectorA = new TimeDetector(t1)
1558 .withHandler(new FieldRecordAndContinue<>(events))
1559 .withMaxCheck(maxCheck)
1560 .withThreshold(v(tolerance));
1561 ContinuousDetector detectorB = new ContinuousDetector(-50, t1, t1)
1562 .withHandler(new FieldRecordAndContinue<>(events))
1563 .withMaxCheck(maxCheck)
1564 .withThreshold(v(tolerance));
1565 detectorB.g(state(t1));
1566 FieldPropagator<T> propagator = getPropagator(10);
1567 propagator.addEventDetector(detectorA);
1568 propagator.addEventDetector(detectorB);
1569
1570
1571 propagator.propagate(epoch.shiftedBy(-30.0));
1572
1573
1574 Assertions.assertEquals(1, events.size());
1575 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1576 Assertions.assertEquals(true, events.get(0).isIncreasing());
1577 Assertions.assertSame(detectorA, events.get(0).getDetector());
1578
1579 Assertions.assertEquals(0.0, detectorB.g(state(t1)).getReal(), 0.0);
1580 Assertions.assertTrue(detectorB.g(state(t1 + 1e-6)).getReal() > 0);
1581 Assertions.assertTrue(detectorB.g(state(t1 - 1e-6)).getReal() > 0);
1582 }
1583
1584
1585 @Test
1586 public void testZeroAtBeginningAndEndOfIntervalReverse() {
1587
1588 double maxCheck = 10;
1589 double tolerance = 1e-6;
1590 double t1 = -10, t2 = -20;
1591
1592 List<Event<T>> events = new ArrayList<>();
1593 ContinuousDetector detectorA = new ContinuousDetector(-50, t1, t2)
1594 .withHandler(new FieldRecordAndContinue<>(events))
1595 .withMaxCheck(maxCheck)
1596 .withThreshold(v(tolerance));
1597 FieldPropagator<T> propagator = getPropagator(10);
1598 propagator.addEventDetector(detectorA);
1599
1600
1601 propagator.propagate(epoch.shiftedBy(-30.0));
1602
1603
1604 Assertions.assertEquals(2, events.size());
1605 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1606 Assertions.assertEquals(true, events.get(0).isIncreasing());
1607 Assertions.assertSame(detectorA, events.get(0).getDetector());
1608 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1609 Assertions.assertEquals(false, events.get(1).isIncreasing());
1610 Assertions.assertSame(detectorA, events.get(1).getDetector());
1611 }
1612
1613
1614 @Test
1615 public void testZeroAtBeginningAndEndOfIntervalOppositeSignReverse() {
1616
1617 double maxCheck = 10;
1618 double tolerance = 1e-6;
1619 double t1 = -10, t2 = -20;
1620
1621 List<Event<T>> events = new ArrayList<>();
1622 ContinuousDetector detectorA = new ContinuousDetector(t1, t2)
1623 .withHandler(new FieldRecordAndContinue<>(events))
1624 .withMaxCheck(maxCheck)
1625 .withThreshold(v(tolerance));
1626 FieldPropagator<T> propagator = getPropagator(10);
1627 propagator.addEventDetector(detectorA);
1628
1629
1630 propagator.propagate(epoch.shiftedBy(-30));
1631
1632
1633 Assertions.assertEquals(2, events.size());
1634 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1635 Assertions.assertEquals(false, events.get(0).isIncreasing());
1636 Assertions.assertSame(detectorA, events.get(0).getDetector());
1637 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1638 Assertions.assertEquals(true, events.get(1).isIncreasing());
1639 Assertions.assertSame(detectorA, events.get(1).getDetector());
1640 }
1641
1642
1643 @Test
1644 public void testMultipleBackupsReverse() {
1645
1646 double maxCheck = 10;
1647 double tolerance = 1e-6;
1648 double t1 = -1.0, t2 = -2, t3 = -3, t4 = -4, t5 = -5, t6 = -6.5, t7 = -7;
1649
1650 List<Event<T>> events = new ArrayList<>();
1651 ContinuousDetector detectorA = new ContinuousDetector(t6)
1652 .withHandler(new FieldRecordAndContinue<>(events))
1653 .withMaxCheck(maxCheck)
1654 .withThreshold(v(tolerance));
1655 ContinuousDetector detectorB = new ContinuousDetector(-50, t1, t3, t4, t7)
1656 .withHandler(new FieldRecordAndContinue<>(events))
1657 .withMaxCheck(maxCheck)
1658 .withThreshold(v(tolerance));
1659 ContinuousDetector detectorC = new ContinuousDetector(-50, t2, t5)
1660 .withHandler(new FieldRecordAndContinue<>(events))
1661 .withMaxCheck(maxCheck)
1662 .withThreshold(v(tolerance));
1663
1664 FieldPropagator<T> propagator = getPropagator(10);
1665 propagator.addEventDetector(detectorA);
1666 propagator.addEventDetector(detectorB);
1667 propagator.addEventDetector(detectorC);
1668
1669
1670 propagator.propagate(epoch.shiftedBy(-30.0));
1671
1672
1673
1674 Assertions.assertEquals(5, events.size());
1675 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1676 Assertions.assertEquals(true, events.get(0).isIncreasing());
1677 Assertions.assertEquals(detectorB, events.get(0).getDetector());
1678 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1679 Assertions.assertEquals(true, events.get(1).isIncreasing());
1680 Assertions.assertEquals(detectorC, events.get(1).getDetector());
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691 Assertions.assertEquals(t5, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1692 Assertions.assertEquals(false, events.get(2).isIncreasing());
1693 Assertions.assertEquals(detectorC, events.get(2).getDetector());
1694 Assertions.assertEquals(t6, events.get(3).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1695 Assertions.assertEquals(true, events.get(3).isIncreasing());
1696 Assertions.assertEquals(detectorA, events.get(3).getDetector());
1697 Assertions.assertEquals(t7, events.get(4).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1698 Assertions.assertEquals(false, events.get(4).isIncreasing());
1699 Assertions.assertEquals(detectorB, events.get(4).getDetector());
1700 }
1701
1702
1703 @Test
1704 public void testEventCausedByStateResetReverse() {
1705
1706 double maxCheck = 10;
1707 double tolerance = 1e-6;
1708 double t1 = -15.0;
1709 FieldSpacecraftState<T> newState = new FieldSpacecraftState<T>(new FieldKeplerianOrbit<T>(
1710 v(6378137 + 500e3), v(0), v(FastMath.PI / 2), v(0), v(0),
1711 v(FastMath.PI / 2), PositionAngleType.TRUE, eci, epoch.shiftedBy(t1), v(mu)));
1712
1713 List<Event<T>> events = new ArrayList<>();
1714 TimeDetector detectorA = new TimeDetector(t1)
1715 .withHandler(new Handler<FieldEventDetector<T>>(events, Action.RESET_STATE) {
1716 @Override
1717 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector,
1718 FieldSpacecraftState<T> oldState) {
1719 return newState;
1720 }
1721 })
1722 .withMaxCheck(maxCheck)
1723 .withThreshold(v(tolerance));
1724 FieldLatitudeCrossingDetector<T> detectorB =
1725 new FieldLatitudeCrossingDetector<T>(field, earth, FastMath.toRadians(80))
1726 .withHandler(new FieldRecordAndContinue<>(events))
1727 .withMaxCheck(maxCheck)
1728 .withThreshold(v(tolerance));
1729
1730 FieldPropagator<T> propagator = getPropagator(10);
1731 propagator.addEventDetector(detectorA);
1732 propagator.addEventDetector(detectorB);
1733
1734
1735 propagator.propagate(epoch.shiftedBy(-40.0));
1736
1737
1738
1739 Assertions.assertEquals(2, events.size());
1740 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1741 Assertions.assertEquals(true, events.get(0).isIncreasing());
1742 Assertions.assertEquals(detectorA, events.get(0).getDetector());
1743 Assertions.assertEquals(t1, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1744 Assertions.assertEquals(false, events.get(1).isIncreasing());
1745 Assertions.assertEquals(detectorB, events.get(1).getDetector());
1746 }
1747
1748
1749 @Test
1750 public void testConvergenceTooTightReverse() {
1751
1752 double maxCheck = 10;
1753 double tolerance = 1e-18;
1754 double t1 = -15;
1755
1756 List<Event<T>> events = new ArrayList<>();
1757 ContinuousDetector detectorA = new ContinuousDetector(t1)
1758 .withHandler(new FieldRecordAndContinue<>(events))
1759 .withMaxCheck(maxCheck)
1760 .withThreshold(v(tolerance));
1761 FieldPropagator<T> propagator = getPropagator(10);
1762 propagator.addEventDetector(detectorA);
1763
1764
1765 propagator.propagate(epoch.shiftedBy(-30.0));
1766
1767
1768 Assertions.assertEquals(1, events.size());
1769 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), 0.0);
1770 Assertions.assertEquals(true, events.get(0).isIncreasing());
1771 Assertions.assertSame(detectorA, events.get(0).getDetector());
1772 }
1773
1774
1775
1776
1777
1778
1779
1780 @Test
1781 public void testEventChangesGFunctionDefinitionReverse() {
1782
1783 double maxCheck = 5;
1784 double tolerance = 1e-6;
1785 double t1 = -11, t2 = -19;
1786
1787 List<Event<T>> events = new ArrayList<>();
1788
1789 boolean[] swap = new boolean[1];
1790 ContinuousDetector detectorA = new ContinuousDetector(t1)
1791 .withMaxCheck(maxCheck)
1792 .withThreshold(v(tolerance))
1793 .withHandler(new FieldRecordAndContinue<T>(events) {
1794 @Override
1795 public Action eventOccurred(FieldSpacecraftState<T> s,
1796 FieldEventDetector<T> detector,
1797 boolean increasing) {
1798 swap[0] = true;
1799 return super.eventOccurred(s, detector, increasing);
1800 }
1801 });
1802 ContinuousDetector detectorB = new ContinuousDetector(t2);
1803 FieldEventDetector<T> detectorC = new Reverse(maxCheck, tolerance, swap, detectorB, detectorB, events);
1804 FieldPropagator<T> propagator = getPropagator(10);
1805 propagator.addEventDetector(detectorA);
1806 propagator.addEventDetector(detectorC);
1807
1808
1809 propagator.propagate(epoch.shiftedBy(-30.0));
1810
1811
1812 Assertions.assertEquals(2, events.size());
1813 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1814 Assertions.assertEquals(true, events.get(0).isIncreasing());
1815 Assertions.assertSame(detectorA, events.get(0).getDetector());
1816 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1817 Assertions.assertEquals(true, events.get(1).isIncreasing());
1818 Assertions.assertSame(detectorC, events.get(1).getDetector());
1819 }
1820
1821
1822
1823
1824
1825
1826 @Test
1827 public void testEventChangesGFunctionDefinitionCancelReverse() {
1828
1829 double maxCheck = 5;
1830 double tolerance = 1e-6;
1831 double t1 = -11, t2 = -11.1;
1832
1833 List<Event<T>> events = new ArrayList<>();
1834
1835 boolean[] swap = new boolean[1];
1836 final ContinuousDetector detectorA = new ContinuousDetector(t1)
1837 .withMaxCheck(maxCheck)
1838 .withThreshold(v(tolerance))
1839 .withHandler(new FieldRecordAndContinue<T>(events) {
1840 @Override
1841 public Action eventOccurred(FieldSpacecraftState<T> state,
1842 FieldEventDetector<T> detector,
1843 boolean increasing) {
1844 swap[0] = true;
1845 super.eventOccurred(state, detector, increasing);
1846 return Action.RESET_EVENTS;
1847 }
1848 });
1849 final ContinuousDetector detectorB = new ContinuousDetector(t2);
1850 FieldEventDetector<T> detectorC = new CancelReverse(maxCheck, tolerance, swap, detectorB, detectorB, events);
1851 FieldPropagator<T> propagator = getPropagator(10);
1852 propagator.addEventDetector(detectorA);
1853 propagator.addEventDetector(detectorC);
1854
1855
1856 propagator.propagate(epoch.shiftedBy(-30));
1857
1858
1859 Assertions.assertEquals(1, events.size());
1860 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1861 Assertions.assertEquals(true, events.get(0).isIncreasing());
1862 Assertions.assertSame(detectorA, events.get(0).getDetector());
1863 }
1864
1865
1866
1867
1868
1869
1870 @Test
1871 public void testEventChangesGFunctionDefinitionDelayReverse() {
1872
1873 double maxCheck = 5;
1874 double tolerance = 1e-6;
1875 double t1 = -11, t2 = -11.1, t3 = -11.2;
1876
1877 List<Event<T>> events = new ArrayList<>();
1878
1879 boolean[] swap = new boolean[1];
1880 final ContinuousDetector detectorA = new ContinuousDetector(t1)
1881 .withMaxCheck(maxCheck)
1882 .withThreshold(v(tolerance))
1883 .withHandler(new FieldRecordAndContinue<T>(events) {
1884 @Override
1885 public Action eventOccurred(FieldSpacecraftState<T> state,
1886 FieldEventDetector<T> detector,
1887 boolean increasing) {
1888 swap[0] = true;
1889 super.eventOccurred(state, detector, increasing);
1890 return Action.RESET_EVENTS;
1891 }
1892 });
1893 final ContinuousDetector detectorB = new ContinuousDetector(t2);
1894 final ContinuousDetector detectorD = new ContinuousDetector(t3);
1895 FieldEventDetector<T> detectorC = new DelayReverse(maxCheck, tolerance, swap, detectorB, detectorD, events);
1896 FieldPropagator<T> propagator = getPropagator(10);
1897 propagator.addEventDetector(detectorA);
1898 propagator.addEventDetector(detectorC);
1899
1900
1901 propagator.propagate(epoch.shiftedBy(-30));
1902
1903
1904 Assertions.assertEquals(2, events.size());
1905 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1906 Assertions.assertEquals(true, events.get(0).isIncreasing());
1907 Assertions.assertSame(detectorA, events.get(0).getDetector());
1908 Assertions.assertEquals(t3, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1909 Assertions.assertEquals(true, events.get(1).isIncreasing());
1910 Assertions.assertSame(detectorC, events.get(1).getDetector());
1911 }
1912
1913
1914
1915
1916
1917
1918 @Test
1919 public void testEventChangesGFunctionDefinitionAccelerateReverse() {
1920
1921 double maxCheck = 5;
1922 double tolerance = 1e-6;
1923 double t1 = -11, t2 = -11.1, t3 = -11.2;
1924
1925 List<Event<T>> events = new ArrayList<>();
1926
1927 boolean[] swap = new boolean[1];
1928 final ContinuousDetector detectorA = new ContinuousDetector(t1)
1929 .withMaxCheck(maxCheck)
1930 .withThreshold(v(tolerance))
1931 .withHandler(new FieldRecordAndContinue<T>(events) {
1932 @Override
1933 public Action eventOccurred(FieldSpacecraftState<T> state,
1934 FieldEventDetector<T> detector,
1935 boolean increasing) {
1936 swap[0] = true;
1937 super.eventOccurred(state, detector, increasing);
1938 return Action.RESET_EVENTS;
1939 }
1940 });
1941 final ContinuousDetector detectorB = new ContinuousDetector(t2);
1942 final ContinuousDetector detectorD = new ContinuousDetector(t3);
1943 FieldEventDetector<T> detectorC = new AccelerateReverse(maxCheck, tolerance, swap, detectorB, detectorD, events);
1944 FieldPropagator<T> propagator = getPropagator(10);
1945 propagator.addEventDetector(detectorA);
1946 propagator.addEventDetector(detectorC);
1947
1948
1949 propagator.propagate(epoch.shiftedBy(-30));
1950
1951
1952 Assertions.assertEquals(2, events.size());
1953 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1954 Assertions.assertEquals(true, events.get(0).isIncreasing());
1955 Assertions.assertSame(detectorA, events.get(0).getDetector());
1956 Assertions.assertEquals(t2, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
1957 Assertions.assertEquals(true, events.get(1).isIncreasing());
1958 Assertions.assertSame(detectorC, events.get(1).getDetector());
1959 }
1960
1961 private abstract class AbstractTestDetector<D extends AbstractTestDetector<D>> extends FieldAbstractDetector<D, T> {
1962 AbstractTestDetector(final double maxCheck, final double tolerance, final List<Event<T>> events) {
1963 super(new FieldEventDetectionSettings<>(FieldAdaptableInterval.of(maxCheck), v(tolerance), 100), new FieldRecordAndContinue<>(events));
1964 }
1965
1966 @Override
1967 protected D create(FieldEventDetectionSettings<T> detectionSettings, FieldEventHandler<T> newHandler) {
1968 return null;
1969 }
1970 }
1971
1972 private abstract class AbstractChangeDetector<D extends AbstractTestDetector<D>> extends AbstractTestDetector<D> {
1973 final boolean[] swap;
1974 final ContinuousDetector detectorB;
1975 final ContinuousDetector detectorD;
1976 AbstractChangeDetector(final double maxCheck, final double tolerance, final boolean[] swap,
1977 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
1978 final List<Event<T>> events) {
1979 super(maxCheck, tolerance, events);
1980 this.swap = swap;
1981 this.detectorB = detectorB;
1982 this.detectorD = detectorD;
1983 }
1984
1985 }
1986
1987 private class Definition extends AbstractChangeDetector<Definition> {
1988 Definition(final double maxCheck, final double tolerance, final boolean[] swap,
1989 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
1990 final List<Event<T>> events) {
1991 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
1992 }
1993 @Override
1994 public T g(FieldSpacecraftState<T> state) {
1995 if (swap[0]) {
1996 return detectorB.g(state);
1997 } else {
1998 return v(-1);
1999 }
2000 }
2001 }
2002
2003 private class Reverse extends AbstractChangeDetector<Reverse> {
2004 Reverse(final double maxCheck, final double tolerance, final boolean[] swap,
2005 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2006 final List<Event<T>> events) {
2007 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2008 }
2009 @Override
2010 public T g(FieldSpacecraftState<T> state) {
2011 if (swap[0]) {
2012 return detectorB.g(state);
2013 } else {
2014 return v(1);
2015 }
2016 }
2017 }
2018
2019 private class Cancel extends AbstractChangeDetector<Cancel> {
2020 Cancel(final double maxCheck, final double tolerance, final boolean[] swap,
2021 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2022 final List<Event<T>> events) {
2023 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2024 }
2025 @Override
2026 public T g(FieldSpacecraftState<T> state) {
2027 if (!swap[0]) {
2028 return detectorB.g(state);
2029 } else {
2030 return v(-1);
2031 }
2032 }
2033 }
2034
2035 private class CancelReverse extends AbstractChangeDetector<CancelReverse> {
2036 CancelReverse(final double maxCheck, final double tolerance, final boolean[] swap,
2037 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2038 final List<Event<T>> events) {
2039 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2040 }
2041 @Override
2042 public T g(FieldSpacecraftState<T> state) {
2043 if (!swap[0]) {
2044 return detectorB.g(state);
2045 } else {
2046 return v(1);
2047 }
2048 }
2049 }
2050
2051 private class Delay extends AbstractChangeDetector<Delay> {
2052 Delay(final double maxCheck, final double tolerance, final boolean[] swap,
2053 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2054 final List<Event<T>> events) {
2055 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2056 }
2057 @Override
2058 public T g(FieldSpacecraftState<T> state) {
2059 if (!swap[0]) {
2060 return detectorB.g(state);
2061 } else {
2062 return detectorD.g(state);
2063 }
2064 }
2065 }
2066
2067 private class DelayReverse extends AbstractChangeDetector<DelayReverse> {
2068 DelayReverse(final double maxCheck, final double tolerance, final boolean[] swap,
2069 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2070 final List<Event<T>> events) {
2071 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2072 }
2073 @Override
2074 public T g(FieldSpacecraftState<T> state) {
2075 if (!swap[0]) {
2076 return detectorB.g(state);
2077 } else {
2078 return detectorD.g(state);
2079 }
2080 }
2081 }
2082
2083 private class Accelerate extends AbstractChangeDetector<Accelerate> {
2084 Accelerate(final double maxCheck, final double tolerance, final boolean[] swap,
2085 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2086 final List<Event<T>> events) {
2087 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2088 }
2089 @Override
2090 public T g(FieldSpacecraftState<T> state) {
2091 if (swap[0]) {
2092 return detectorB.g(state);
2093 } else {
2094 return detectorD.g(state);
2095 }
2096 }
2097 }
2098
2099 private class AccelerateReverse extends AbstractChangeDetector<AccelerateReverse> {
2100 AccelerateReverse(final double maxCheck, final double tolerance, final boolean[] swap,
2101 final ContinuousDetector detectorB, final ContinuousDetector detectorD,
2102 final List<Event<T>> events) {
2103 super(maxCheck, tolerance, swap, detectorB, detectorD, events);
2104 }
2105 @Override
2106 public T g(FieldSpacecraftState<T> state) {
2107 if (swap[0]) {
2108 return detectorB.g(state);
2109 } else {
2110 return detectorD.g(state);
2111 }
2112 }
2113 }
2114
2115
2116 @Test
2117 public void testToleranceStopReverse() {
2118
2119 double maxCheck = 10;
2120 double tolerance = 1e-18;
2121 double t1 = -15.1;
2122
2123 List<Event<T>> events = new ArrayList<>();
2124 FlatDetector detectorA = new FlatDetector(t1)
2125 .withHandler(new Handler<>(events, Action.STOP))
2126 .withMaxCheck(maxCheck)
2127 .withThreshold(v(tolerance));
2128 FieldPropagator<T> propagator = getPropagator(10);
2129 propagator.addEventDetector(detectorA);
2130
2131
2132 FieldSpacecraftState<T> finalState = propagator.propagate(epoch.shiftedBy(-30.0));
2133
2134
2135 Assertions.assertEquals(1, events.size());
2136
2137 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
2138 Assertions.assertEquals(true, events.get(0).isIncreasing());
2139 Assertions.assertSame(detectorA, events.get(0).getDetector());
2140 Assertions.assertEquals(t1, finalState.getDate().durationFrom(epoch).getReal(), tolerance);
2141
2142
2143 finalState = propagator.propagate(epoch.shiftedBy(-30.0));
2144
2145
2146 Assertions.assertEquals(-30.0, finalState.getDate().durationFrom(epoch).getReal(), 0.0);
2147 }
2148
2149
2150
2151
2152
2153
2154 @Test
2155 public void testShortBracketingIntervalReverse() {
2156
2157 double maxCheck = 10;
2158 double tolerance = 1e-6;
2159 final double t1 = FastMath.nextDown(-10.0), t2 = -10.5;
2160
2161 List<Event<T>> events = new ArrayList<>();
2162
2163 FieldEventDetector<T> detectorA = new ShortSupDetector(maxCheck, tolerance, t1, t2, events);
2164 TimeDetector detectorB = new TimeDetector(t1)
2165 .withHandler(new FieldRecordAndContinue<>(events))
2166 .withMaxCheck(maxCheck)
2167 .withThreshold(v(tolerance));
2168 FieldPropagator<T> propagator = getPropagator(10);
2169 propagator.addEventDetector(detectorA);
2170 propagator.addEventDetector(detectorB);
2171
2172
2173 propagator.propagate(epoch.shiftedBy(-30.0));
2174
2175
2176 Assertions.assertEquals(3, events.size());
2177 Assertions.assertEquals(t1, events.get(0).getState().getDate().durationFrom(epoch).getReal(), tolerance);
2178 Assertions.assertEquals(false, events.get(0).isIncreasing());
2179 Assertions.assertSame(detectorA, events.get(0).getDetector());
2180 Assertions.assertEquals(t1, events.get(1).getState().getDate().durationFrom(epoch).getReal(), tolerance);
2181 Assertions.assertEquals(true, events.get(1).isIncreasing());
2182 Assertions.assertSame(detectorB, events.get(1).getDetector());
2183 Assertions.assertEquals(t2, events.get(2).getState().getDate().durationFrom(epoch).getReal(), tolerance);
2184 Assertions.assertEquals(true, events.get(2).isIncreasing());
2185 Assertions.assertSame(detectorA, events.get(2).getDetector());
2186 }
2187
2188 private class ShortInfDetector extends AbstractTestDetector<ShortInfDetector> {
2189
2190 final double t1;
2191 final double t2;
2192
2193 ShortInfDetector(final double maxCheck, final double tolerance,
2194 final double t1, final double t2, final List<Event<T>> events) {
2195 super(maxCheck, tolerance, events);
2196 this.t1 = t1;
2197 this.t2 = t2;
2198 }
2199
2200 @Override
2201 public T g(FieldSpacecraftState<T> state) {
2202 final FieldAbsoluteDate<T> t = state.getDate();
2203 if (t.compareTo(epoch.shiftedBy(t1)) < 0) {
2204 return v(-1);
2205 } else if (t.compareTo(epoch.shiftedBy(t2)) < 0) {
2206 return v(1);
2207 } else {
2208 return v(-1);
2209 }
2210 }
2211 }
2212
2213 private class ShortSupDetector extends AbstractTestDetector<ShortSupDetector> {
2214
2215 final double t1;
2216 final double t2;
2217
2218 ShortSupDetector(final double maxCheck, final double tolerance,
2219 final double t1, final double t2, final List<Event<T>> events) {
2220 super(maxCheck, tolerance, events);
2221 this.t1 = t1;
2222 this.t2 = t2;
2223 }
2224
2225 @Override
2226 public T g(FieldSpacecraftState<T> state) {
2227 final FieldAbsoluteDate<T> t = state.getDate();
2228 if (t.compareTo(epoch.shiftedBy(t1)) > 0) {
2229 return v(-1);
2230 } else if (t.compareTo(epoch.shiftedBy(t2)) > 0) {
2231 return v(1);
2232 } else {
2233 return v(-1);
2234 }
2235 }
2236 }
2237
2238
2239 @Test
2240 public void testToleranceMaxIterationsReverse() {
2241
2242 double maxCheck = 10;
2243 double tolerance = 1e-18;
2244 FieldAbsoluteDate<T> t1 = epoch.shiftedBy(-15).shiftedBy(FastMath.ulp(-15.0) / 8);
2245
2246 List<Event<T>> events = new ArrayList<>();
2247 FlatDetector detectorA = new FlatDetector(t1)
2248 .withHandler(new FieldRecordAndContinue<>(events))
2249 .withMaxCheck(maxCheck)
2250 .withThreshold(v(tolerance));
2251 FieldPropagator<T> propagator = getPropagator(10);
2252 propagator.addEventDetector(detectorA);
2253
2254
2255 propagator.propagate(epoch.shiftedBy(-30));
2256
2257
2258 Assertions.assertEquals(1, events.size());
2259
2260 Assertions.assertEquals(t1.durationFrom(epoch).getReal(),
2261 events.get(0).getState().getDate().durationFrom(epoch).getReal(),
2262 FastMath.ulp(-15.0));
2263 Assertions.assertEquals(true, events.get(0).isIncreasing());
2264 Assertions.assertSame(detectorA, events.get(0).getDetector());
2265 }
2266
2267
2268 @Test
2269 public void testEventStepHandlerReverse() {
2270
2271 double tolerance = 1e-18;
2272 FieldPropagator<T> propagator = getPropagator(10);
2273 propagator.addEventDetector(new TimeDetector(-5)
2274 .withHandler(new Handler<>(Action.CONTINUE))
2275 .withThreshold(v(tolerance)));
2276 StepHandler<T> stepHandler = new StepHandler<>();
2277 propagator.setStepHandler(stepHandler);
2278
2279
2280 FieldSpacecraftState<T> finalState = propagator.propagate(epoch.shiftedBy(-10));
2281
2282
2283 Assertions.assertEquals(-10.0, finalState.getDate().durationFrom(epoch).getReal(), tolerance);
2284 Assertions.assertEquals(0.0,
2285 stepHandler.initialState.getDate().durationFrom(epoch).getReal(), tolerance);
2286 Assertions.assertEquals(-10.0, stepHandler.targetDate.durationFrom(epoch).getReal(), tolerance);
2287 Assertions.assertEquals(-10.0,
2288 stepHandler.finalState.getDate().durationFrom(epoch).getReal(), tolerance);
2289 FieldOrekitStepInterpolator<T> interpolator = stepHandler.interpolators.get(0);
2290 Assertions.assertEquals(0.0,
2291 interpolator.getPreviousState().getDate().durationFrom(epoch).getReal(), tolerance);
2292 Assertions.assertEquals(-5.0,
2293 interpolator.getCurrentState().getDate().durationFrom(epoch).getReal(), tolerance);
2294 interpolator = stepHandler.interpolators.get(1);
2295 Assertions.assertEquals(-5.0,
2296 interpolator.getPreviousState().getDate().durationFrom(epoch).getReal(), tolerance);
2297 Assertions.assertEquals(-10.0,
2298 interpolator.getCurrentState().getDate().durationFrom(epoch).getReal(), tolerance);
2299 Assertions.assertEquals(2, stepHandler.interpolators.size());
2300 }
2301
2302
2303
2304
2305
2306 @Test
2307 public void testEventCausedByDerivativesResetReverse() {
2308
2309 TimeDetector detectorA = new TimeDetector(-15.0)
2310 .withHandler(new Handler<TimeDetector>(Action.RESET_STATE){
2311 @Override
2312 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> d, FieldSpacecraftState<T> s) {
2313 return null;
2314 }
2315 })
2316 .withMaxCheck(10)
2317 .withThreshold(v(1e-6));
2318 FieldPropagator<T> propagator = getPropagator(10);
2319 propagator.addEventDetector(detectorA);
2320
2321 try {
2322
2323 propagator.propagate(epoch.shiftedBy(-20.0));
2324 Assertions.fail("Expected Exception");
2325 } catch (NullPointerException e) {
2326
2327 }
2328 }
2329
2330 @Test
2331 public void testResetChangesSign() {
2332 FieldPropagator<T> propagator = getPropagator(2.5);
2333 FieldAbsoluteDate<T> t0 = propagator.getInitialState().getDate();
2334 final double small = 1.25e-11;
2335 ResetChangesSignGenerator eventsGenerator = new ResetChangesSignGenerator(t0, 0.75, 1.125, -0.5 * small).
2336 withMaxCheck(1).
2337 withThreshold(t0.getField().getZero().newInstance(small)).
2338 withMaxIter(1000);
2339 propagator.addEventDetector(eventsGenerator);
2340 final FieldSpacecraftState<T> end = propagator.propagate(propagator.getInitialState().getDate().shiftedBy(12.5));
2341 Assertions.assertEquals(2, eventsGenerator.getCount());
2342 Assertions.assertEquals(1.125 + 0.5 * small, end.getDate().durationFrom(t0).getReal(), 1.0e-12);
2343 }
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353 private FieldSpacecraftState<T> state(double t) {
2354 return new FieldSpacecraftState<>(new FieldKeplerianOrbit<>(
2355 v(6378137 + 500e3), v(0), v(0), v(0), v(0), v(0),
2356 PositionAngleType.TRUE, eci, epoch.shiftedBy(t),
2357 v(mu)));
2358 }
2359
2360 private List<FieldAbsoluteDate<T>> toDates(double[] eventTs) {
2361 Arrays.sort(eventTs);
2362 final List<FieldAbsoluteDate<T>> ret = new ArrayList<>();
2363 for (double eventT : eventTs) {
2364 ret.add(epoch.shiftedBy(eventT));
2365 }
2366 return ret;
2367 }
2368
2369
2370
2371
2372
2373
2374 public T v(double value) {
2375 return field.getZero().add(value);
2376 }
2377
2378
2379 protected class TimeDetector extends FieldAbstractDetector<TimeDetector, T> {
2380
2381
2382 private final List<FieldAbsoluteDate<T>> eventTs;
2383
2384
2385
2386
2387
2388
2389 public TimeDetector(double... eventTs) {
2390 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK), v(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER,
2391 new FieldStopOnEvent<>(), toDates(eventTs));
2392 }
2393
2394
2395
2396
2397
2398
2399 @SafeVarargs
2400 public TimeDetector(FieldAbsoluteDate<T>... eventTs) {
2401 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK), v(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER,
2402 new FieldStopOnEvent<>(), Arrays.asList(eventTs));
2403 }
2404
2405 private TimeDetector(FieldAdaptableInterval<T> newMaxCheck,
2406 T newThreshold,
2407 int newMaxIter,
2408 FieldEventHandler<T> newHandler,
2409 List<FieldAbsoluteDate<T>> dates) {
2410 super(new FieldEventDetectionSettings<>(newMaxCheck, newThreshold, newMaxIter), newHandler);
2411 this.eventTs = dates;
2412 }
2413
2414 @Override
2415 public T g(FieldSpacecraftState<T> s) {
2416 final FieldAbsoluteDate<T> t = s.getDate();
2417 int i = 0;
2418 while (i < eventTs.size() && t.compareTo(eventTs.get(i)) > 0) {
2419 i++;
2420 }
2421 i--;
2422 if (i < 0) {
2423 return t.durationFrom(eventTs.get(0));
2424 } else {
2425 int sign = (i % 2) * 2 - 1;
2426 return (t.durationFrom(eventTs.get(i))).multiply(-sign);
2427 }
2428 }
2429
2430 @Override
2431 protected TimeDetector create(FieldEventDetectionSettings<T> detectionSettings,
2432 FieldEventHandler<T> newHandler) {
2433 return new TimeDetector(detectionSettings.getMaxCheckInterval(), detectionSettings.getThreshold(),
2434 detectionSettings.getMaxIterationCount(), newHandler, eventTs);
2435 }
2436
2437 }
2438
2439
2440
2441
2442
2443 private class FlatDetector extends FieldAbstractDetector<FlatDetector, T> {
2444
2445 private final FieldEventDetector<T> g;
2446
2447 public FlatDetector(double... eventTs) {
2448 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK), v(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER,
2449 new FieldStopOnEvent<>(), new TimeDetector(eventTs));
2450 }
2451
2452 @SafeVarargs
2453 public FlatDetector(FieldAbsoluteDate<T>... eventTs) {
2454 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK), v(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER,
2455 new FieldStopOnEvent<>(), new TimeDetector(eventTs));
2456 }
2457
2458 private FlatDetector(FieldAdaptableInterval<T> newMaxCheck,
2459 T newThreshold,
2460 int newMaxIter,
2461 FieldEventHandler<T> newHandler,
2462 FieldEventDetector<T> g) {
2463 super(new FieldEventDetectionSettings<>(newMaxCheck, newThreshold, newMaxIter), newHandler);
2464 this.g = g;
2465 }
2466
2467 @Override
2468 public T g(FieldSpacecraftState<T> s) {
2469 return FastMath.sign(g.g(s));
2470 }
2471
2472 @Override
2473 protected FlatDetector create(FieldEventDetectionSettings<T> detectionSettings,
2474 FieldEventHandler<T> newHandler) {
2475 return new FlatDetector(detectionSettings.getMaxCheckInterval(), detectionSettings.getThreshold(),
2476 detectionSettings.getMaxIterationCount(), newHandler, g);
2477 }
2478
2479 }
2480
2481
2482 private class ContinuousDetector extends FieldAbstractDetector<ContinuousDetector, T> {
2483
2484
2485 private final List<FieldAbsoluteDate<T>> eventTs;
2486
2487 public ContinuousDetector(double... eventTs) {
2488 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK), v(DEFAULT_THRESHOLD), DEFAULT_MAX_ITER,
2489 new FieldStopOnEvent<>(), toDates(eventTs));
2490 }
2491
2492 private ContinuousDetector(FieldAdaptableInterval<T> newMaxCheck,
2493 T newThreshold,
2494 int newMaxIter,
2495 FieldEventHandler<T> newHandler,
2496 List<FieldAbsoluteDate<T>> eventDates) {
2497 super(new FieldEventDetectionSettings<>(newMaxCheck, newThreshold, newMaxIter), newHandler);
2498 this.eventTs = eventDates;
2499 }
2500
2501 @Override
2502 public T g(FieldSpacecraftState<T> s) {
2503 final FieldAbsoluteDate<T> t = s.getDate();
2504 int i = 0;
2505 while (i < eventTs.size() && t.compareTo(eventTs.get(i)) > 0) {
2506 i++;
2507 }
2508 i--;
2509 if (i < 0) {
2510 return t.durationFrom(eventTs.get(0));
2511 } else if (i < eventTs.size() - 1) {
2512 int sign = (i % 2) * 2 - 1;
2513 return (t.durationFrom(eventTs.get(i)))
2514 .multiply(eventTs.get(i + 1).durationFrom(t)).multiply(-sign);
2515 } else {
2516 int sign = (i % 2) * 2 - 1;
2517 return (t.durationFrom(eventTs.get(i))).multiply(-sign);
2518 }
2519 }
2520
2521 @Override
2522 protected ContinuousDetector create(
2523 FieldEventDetectionSettings<T> detectionSettings,
2524 FieldEventHandler<T> newHandler) {
2525 return new ContinuousDetector(detectionSettings.getMaxCheckInterval(), detectionSettings.getThreshold(),
2526 detectionSettings.getMaxIterationCount(), newHandler, eventTs);
2527 }
2528
2529 }
2530
2531 private class Handler<D extends FieldEventDetector<T>> extends FieldRecordAndContinue<T> {
2532
2533 private final Action action;
2534
2535 public Handler(Action action) {
2536 this.action = action;
2537 }
2538
2539 public Handler(List<Event<T>> events, Action action) {
2540 super(events);
2541 this.action = action;
2542 }
2543
2544 @Override
2545 public Action eventOccurred(FieldSpacecraftState<T> s,
2546 FieldEventDetector<T> detector,
2547 boolean increasing) {
2548 super.eventOccurred(s, detector, increasing);
2549 return this.action;
2550 }
2551
2552 }
2553
2554 private class ResetHandler<D extends FieldEventDetector<T>> extends Handler<D> {
2555
2556 private final FieldSpacecraftState<T> newState;
2557 private final int times;
2558 private long i = 0;
2559
2560 public ResetHandler(List<Event<T>> events, FieldSpacecraftState<T> newState) {
2561 this(events, newState, Integer.MAX_VALUE);
2562 }
2563
2564 public ResetHandler(List<Event<T>> events, FieldSpacecraftState<T> newState, int times) {
2565 super(events, Action.RESET_STATE);
2566 this.newState = newState;
2567 this.times = times;
2568 }
2569
2570 @Override
2571 public Action eventOccurred(final FieldSpacecraftState<T> s, final FieldEventDetector<T> detector, final boolean increasing) {
2572 super.eventOccurred(s, detector, increasing);
2573 if (i++ < times) {
2574 return Action.RESET_STATE;
2575 }
2576 return Action.CONTINUE;
2577 }
2578
2579 @Override
2580 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> oldState) {
2581 Assertions.assertEquals(0, newState.getDate().durationFrom(oldState.getDate()).getReal(), 0);
2582 return newState;
2583 }
2584 }
2585
2586 private static class StepHandler<D extends CalculusFieldElement<D>>
2587 implements FieldOrekitStepHandler<D> {
2588
2589 private FieldSpacecraftState<D> initialState;
2590 private FieldAbsoluteDate<D> targetDate;
2591 private List<FieldOrekitStepInterpolator<D>> interpolators = new ArrayList<>();
2592 private FieldSpacecraftState<D> finalState;
2593
2594 @Override
2595 public void init(FieldSpacecraftState<D> s0, FieldAbsoluteDate<D> t) {
2596 initialState = s0;
2597 targetDate = t;
2598 }
2599
2600 @Override
2601 public void handleStep(FieldOrekitStepInterpolator<D> interpolator) {
2602 interpolators.add(interpolator);
2603 }
2604
2605 @Override
2606 public void finish(FieldSpacecraftState<D> finalState) {
2607 this.finalState = finalState;
2608 }
2609 }
2610
2611 private class ResetChangesSignGenerator extends FieldAbstractDetector<ResetChangesSignGenerator, T> {
2612
2613 final FieldAbsoluteDate<T> t0;
2614 final double y1;
2615 final double y2;
2616 final double change;
2617 double delta;
2618 int count;
2619
2620 public ResetChangesSignGenerator(final FieldAbsoluteDate<T> t0, final double y1, final double y2, final double change) {
2621 this(FieldAdaptableInterval.of(DEFAULT_MAX_CHECK),
2622 t0.getField().getZero().newInstance(DEFAULT_THRESHOLD),
2623 DEFAULT_MAX_ITER,
2624 new FieldContinueOnEvent<>(), t0, y1, y2, change);
2625 }
2626
2627 private ResetChangesSignGenerator(final FieldAdaptableInterval<T> newMaxCheck, final T newThreshold, final int newMaxIter,
2628 final FieldEventHandler<T> newHandler,
2629 final FieldAbsoluteDate<T> t0, final double y1, final double y2, final double change ) {
2630 super(new FieldEventDetectionSettings<>(newMaxCheck, newThreshold, newMaxIter), newHandler);
2631 this.t0 = t0;
2632 this.y1 = y1;
2633 this.y2 = y2;
2634 this.change = change;
2635 this.delta = 0;
2636 this.count = 0;
2637 }
2638
2639 protected ResetChangesSignGenerator create(final FieldEventDetectionSettings<T> detectionSettings,
2640 final FieldEventHandler<T> newHandler) {
2641 return new ResetChangesSignGenerator(detectionSettings.getMaxCheckInterval(), detectionSettings.getThreshold(),
2642 detectionSettings.getMaxIterationCount(), newHandler, t0, y1, y2, change);
2643 }
2644
2645 public T g(FieldSpacecraftState<T> s) {
2646 T dt = s.getDate().durationFrom(t0).add(delta);
2647 return dt.subtract(y1).multiply(dt.subtract(y2));
2648 }
2649
2650 public FieldEventHandler<T> getHandler() {
2651 return new FieldEventHandler<T>() {
2652 public Action eventOccurred(FieldSpacecraftState<T> s, FieldEventDetector<T> detector, boolean increasing) {
2653 return ++count < 2 ? Action.RESET_STATE : Action.STOP;
2654 }
2655
2656 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector, FieldSpacecraftState<T> s) {
2657 delta = change;
2658 return s;
2659 }
2660 };
2661 }
2662
2663 public int getCount() {
2664 return count;
2665 }
2666
2667 }
2668
2669 }