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