1   package org.orekit.propagation.events;
2   
3   import org.hipparchus.CalculusFieldElement;
4   import org.hipparchus.complex.Complex;
5   import org.hipparchus.complex.ComplexField;
6   import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
7   import org.hipparchus.geometry.euclidean.threed.Vector3D;
8   import org.junit.jupiter.api.Assertions;
9   import org.junit.jupiter.api.BeforeEach;
10  import org.junit.jupiter.api.Test;
11  import org.mockito.Mockito;
12  import org.orekit.Utils;
13  import org.orekit.bodies.CelestialBodyFactory;
14  import org.orekit.frames.Frame;
15  import org.orekit.propagation.FieldSpacecraftState;
16  import org.orekit.propagation.events.handlers.FieldContinueOnEvent;
17  import org.orekit.propagation.events.handlers.FieldEventHandler;
18  import org.orekit.propagation.events.intervals.FieldAdaptableInterval;
19  import org.orekit.time.AbsoluteDate;
20  import org.orekit.time.FieldAbsoluteDate;
21  import org.orekit.utils.*;
22  
23  class FieldCylindricalShadowEclipseDetectorTest {
24  
25      @BeforeEach
26      public void setUp() {
27          Utils.setDataRoot("regular-data");
28      }
29  
30      @Test
31      void testConstructor() {
32          // GIVEN
33          final EventDetectionSettings settings = EventDetectionSettings.getDefaultEventDetectionSettings();
34          final FieldEventDetectionSettings<Complex> fieldSettings = new FieldEventDetectionSettings<>(ComplexField.getInstance(),
35                  settings);
36          // WHEN
37          final FieldCylindricalShadowEclipseDetector<Complex> detector = new FieldCylindricalShadowEclipseDetector<>(Mockito.mock(ExtendedPositionProvider.class),
38                  Complex.ONE, fieldSettings, Mockito.mock(FieldEventHandler.class));
39          // THEN
40          Assertions.assertEquals(fieldSettings.getMaxIterationCount(), detector.getDetectionSettings().getMaxIterationCount());
41          Assertions.assertEquals(fieldSettings.getThreshold(), detector.getDetectionSettings().getThreshold());
42      }
43  
44      @Test
45      void testCreate() {
46          // GIVEN
47          final ExtendedPositionProvider sun = CelestialBodyFactory.getSun();
48          final FieldCylindricalShadowEclipseDetector<Complex> eclipseDetector = new FieldCylindricalShadowEclipseDetector<>(sun,
49                  getComplexEarthRadius(), new FieldContinueOnEvent<>());
50          final FieldAdaptableInterval<Complex> adaptableInterval = FieldAdaptableInterval.of(1.);
51          final Complex expectedThreshold = new Complex(0.1);
52          final int expectedMaxIter = 10;
53          // WHEN
54          final FieldCylindricalShadowEclipseDetector<Complex> detector = eclipseDetector.create(new FieldEventDetectionSettings<>(adaptableInterval, expectedThreshold,
55                  expectedMaxIter), eclipseDetector.getHandler());
56          // THEN
57          Assertions.assertEquals(expectedMaxIter, detector.getMaxIterationCount());
58          Assertions.assertEquals(expectedThreshold, detector.getThreshold());
59          Assertions.assertEquals(adaptableInterval, detector.getMaxCheckInterval());
60      }
61  
62      @Test
63      void testG0Eclipse() {
64          // GIVEN
65          final ExtendedPositionProvider sun = new TestDirectionProvider();
66          final FieldCylindricalShadowEclipseDetector<Complex> eclipseDetector = new FieldCylindricalShadowEclipseDetector<>(sun,
67                  getComplexEarthRadius(), new FieldContinueOnEvent<>());
68          final FieldVector3D<Complex> position = new FieldVector3D<>(ComplexField.getInstance(),
69                  new Vector3D(1., eclipseDetector.getOccultingBodyRadius().getReal(), 0.));
70          final FieldSpacecraftState<Complex> mockedState = mockState(position);
71          // WHEN
72          final double g = eclipseDetector.g(mockedState).getReal();
73          // THEN
74          Assertions.assertEquals(0., g);
75      }
76  
77      @Test
78      void testGEclipse() {
79          // GIVEN
80          final ExtendedPositionProvider sun = new TestDirectionProvider();
81          final FieldCylindricalShadowEclipseDetector<Complex> eclipseDetector = new FieldCylindricalShadowEclipseDetector<>(sun,
82                  getComplexEarthRadius(), new FieldContinueOnEvent<>());
83          final FieldVector3D<Complex> position = new FieldVector3D<>(ComplexField.getInstance(), new Vector3D(1e7, 0, -1e2));
84          final FieldSpacecraftState<Complex> mockedState = mockState(position);
85          // WHEN
86          final double g = eclipseDetector.g(mockedState).getReal();
87          // THEN
88          Assertions.assertTrue(g < 0.);
89      }
90  
91      @Test
92      void testGNoEclipse() {
93          // GIVEN
94          final ExtendedPositionProvider sun = new TestDirectionProvider();
95          final FieldCylindricalShadowEclipseDetector<Complex> eclipseDetector = new FieldCylindricalShadowEclipseDetector<>(sun,
96                  getComplexEarthRadius(), new FieldContinueOnEvent<>());
97          final FieldVector3D<Complex> position = new FieldVector3D<>(ComplexField.getInstance(), new Vector3D(0., 1e4, 0.));
98          final FieldSpacecraftState<Complex> mockedState = mockState(position);
99          // WHEN
100         final double g = eclipseDetector.g(mockedState).getReal();
101         // THEN
102         Assertions.assertTrue(g > 0.);
103     }
104 
105     @Test
106     void testGNoEclipse2() {
107         // GIVEN
108         final ExtendedPositionProvider sun = new TestDirectionProvider();
109         final FieldCylindricalShadowEclipseDetector<Complex> eclipseDetector = new FieldCylindricalShadowEclipseDetector<>(sun,
110                 getComplexEarthRadius(), new FieldContinueOnEvent<>());
111         final FieldVector3D<Complex> position = new FieldVector3D<>(ComplexField.getInstance(),
112                 new Vector3D(-1e6, 1e3, 0.));
113         final FieldSpacecraftState<Complex> mockedState = mockState(position);
114         // WHEN
115         final double g = eclipseDetector.g(mockedState).getReal();
116         // THEN
117         Assertions.assertTrue(g > 0.);
118     }
119 
120     @SuppressWarnings("unchecked")
121     private FieldSpacecraftState<Complex> mockState(final FieldVector3D<Complex> position) {
122         final FieldSpacecraftState<Complex> mockedState = Mockito.mock(FieldSpacecraftState.class);
123         Mockito.when(mockedState.getDate()).thenReturn(FieldAbsoluteDate.getArbitraryEpoch(position.getX().getField()));
124         Mockito.when(mockedState.getPosition()).thenReturn(position);
125         return mockedState;
126     }
127 
128     private static Complex getComplexEarthRadius() {
129         return new Complex(Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
130     }
131 
132     private static class TestDirectionProvider implements ExtendedPositionProvider {
133 
134         @Override
135         public <T extends CalculusFieldElement<T>> FieldVector3D<T> getPosition(FieldAbsoluteDate<T> date, Frame frame) {
136             return new FieldVector3D<>(date.getField(), getPosition(date.toAbsoluteDate(), frame));
137         }
138 
139         @Override
140         public Vector3D getPosition(AbsoluteDate date, Frame frame) {
141             return Vector3D.MINUS_I;
142         }
143     }
144 
145 }