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