1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.propagation.events;
18
19 import org.hipparchus.exception.MathRuntimeException;
20 import org.hipparchus.geometry.euclidean.threed.Vector3D;
21 import org.hipparchus.ode.LocalizedODEFormats;
22 import org.hipparchus.ode.nonstiff.AdaptiveStepsizeIntegrator;
23 import org.hipparchus.ode.nonstiff.DormandPrince853Integrator;
24 import org.hipparchus.util.FastMath;
25 import org.junit.jupiter.api.AfterEach;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.BeforeEach;
28 import org.junit.jupiter.api.Test;
29 import org.orekit.Utils;
30 import org.orekit.bodies.CelestialBody;
31 import org.orekit.bodies.CelestialBodyFactory;
32 import org.orekit.bodies.OneAxisEllipsoid;
33 import org.orekit.errors.OrekitException;
34 import org.orekit.errors.OrekitMessages;
35 import org.orekit.frames.FramesFactory;
36 import org.orekit.orbits.CartesianOrbit;
37 import org.orekit.orbits.EquinoctialOrbit;
38 import org.orekit.orbits.KeplerianOrbit;
39 import org.orekit.orbits.Orbit;
40 import org.orekit.orbits.OrbitType;
41 import org.orekit.orbits.PositionAngleType;
42 import org.orekit.propagation.SpacecraftState;
43 import org.orekit.propagation.events.EventsLogger.LoggedEvent;
44 import org.orekit.propagation.events.handlers.ContinueOnEvent;
45 import org.orekit.propagation.events.handlers.StopOnDecreasing;
46 import org.orekit.propagation.numerical.NumericalPropagator;
47 import org.orekit.time.AbsoluteDate;
48 import org.orekit.time.TimeScalesFactory;
49 import org.orekit.utils.Constants;
50 import org.orekit.utils.IERSConventions;
51 import org.orekit.utils.PVCoordinates;
52 import org.orekit.utils.TimeStampedPVCoordinates;
53
54 import java.util.List;
55
56 class EclipseDetectorTest {
57
58 private double mu;
59 private AbsoluteDate iniDate;
60 private SpacecraftState initialState;
61 private NumericalPropagator propagator;
62
63 private CelestialBody sun;
64 private OneAxisEllipsoid earth;
65 private double sunRadius;
66
67 @Test
68 void testPolar() {
69 final KeplerianOrbit original = (KeplerianOrbit) OrbitType.KEPLERIAN.convertType(initialState.getOrbit());
70 final KeplerianOrbit polar = new KeplerianOrbit(original.getA(), original.getE(),
71 0.5 * FastMath.PI, original.getPerigeeArgument(),
72 original.getRightAscensionOfAscendingNode(),
73 original.getTrueAnomaly(), PositionAngleType.TRUE,
74 original.getFrame(), original.getDate(),
75 original.getMu());
76 propagator.resetInitialState(new SpacecraftState(polar));
77 EventsLogger logger = new EventsLogger();
78 OneAxisEllipsoid sphericalEarth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
79 0.0,
80 FramesFactory.getITRF(IERSConventions.IERS_2010,
81 true));
82 EclipseDetector withoutFlattening = new EclipseDetector(sun, sunRadius, sphericalEarth).
83 withMaxCheck(60.0).
84 withThreshold(1.0e-3).
85 withHandler(new ContinueOnEvent()).
86 withUmbra();
87 OneAxisEllipsoid obateEarth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
88 Constants.WGS84_EARTH_FLATTENING,
89 FramesFactory.getITRF(IERSConventions.IERS_2010,
90 true));
91 EclipseDetector withFlattening = new EclipseDetector(sun, sunRadius, obateEarth).
92 withMaxCheck(60.0).
93 withThreshold(1.0e-3).
94 withHandler(new ContinueOnEvent()).
95 withUmbra();
96 propagator.addEventDetector(logger.monitorDetector(withoutFlattening));
97 propagator.addEventDetector(logger.monitorDetector(withFlattening));
98 double duration = 15000.0;
99 final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(duration));
100 Assertions.assertEquals(duration, finalState.getDate().durationFrom(iniDate), 1.0e-3);
101 final List<LoggedEvent> events = logger.getLoggedEvents();
102 Assertions.assertEquals(10, events.size());
103 Assertions.assertTrue(events.get(0).getEventDetector() == withoutFlattening);
104 Assertions.assertFalse(events.get(0).isIncreasing());
105 Assertions.assertEquals( 2274.702, events.get(0).getState().getDate().durationFrom(iniDate), 1.0e-3);
106 Assertions.assertTrue(events.get(1).getEventDetector() == withFlattening);
107 Assertions.assertFalse(events.get(1).isIncreasing());
108 Assertions.assertEquals( 2280.427, events.get(1).getState().getDate().durationFrom(iniDate), 1.0e-3);
109 Assertions.assertTrue(events.get(2).getEventDetector() == withFlattening);
110 Assertions.assertTrue(events.get(2).isIncreasing());
111 Assertions.assertEquals( 4310.741, events.get(2).getState().getDate().durationFrom(iniDate), 1.0e-3);
112 Assertions.assertTrue(events.get(3).getEventDetector() == withoutFlattening);
113 Assertions.assertTrue(events.get(3).isIncreasing());
114 Assertions.assertEquals( 4317.155, events.get(3).getState().getDate().durationFrom(iniDate), 1.6e-3);
115 Assertions.assertTrue(events.get(4).getEventDetector() == withoutFlattening);
116 Assertions.assertFalse(events.get(4).isIncreasing());
117 Assertions.assertEquals( 8189.250, events.get(4).getState().getDate().durationFrom(iniDate), 1.0e-3);
118 Assertions.assertTrue(events.get(5).getEventDetector() == withFlattening);
119 Assertions.assertFalse(events.get(5).isIncreasing());
120 Assertions.assertEquals( 8194.978, events.get(5).getState().getDate().durationFrom(iniDate), 1.0e-3);
121 Assertions.assertTrue(events.get(6).getEventDetector() == withFlattening);
122 Assertions.assertTrue(events.get(6).isIncreasing());
123 Assertions.assertEquals(10225.704, events.get(6).getState().getDate().durationFrom(iniDate), 1.0e-3);
124 Assertions.assertTrue(events.get(7).getEventDetector() == withoutFlattening);
125 Assertions.assertTrue(events.get(7).isIncreasing());
126 Assertions.assertEquals(10232.115, events.get(7).getState().getDate().durationFrom(iniDate), 1.0e-3);
127 Assertions.assertTrue(events.get(8).getEventDetector() == withoutFlattening);
128 Assertions.assertFalse(events.get(8).isIncreasing());
129 Assertions.assertEquals(14103.800, events.get(8).getState().getDate().durationFrom(iniDate), 1.0e-3);
130 Assertions.assertTrue(events.get(9).getEventDetector() == withFlattening);
131 Assertions.assertFalse(events.get(9).isIncreasing());
132 Assertions.assertEquals(14109.530, events.get(9).getState().getDate().durationFrom(iniDate), 1.0e-3);
133
134 }
135
136 @Test
137 void testEclipse() {
138 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth).
139 withMaxCheck(60.0).
140 withThreshold(1.0e-3).
141 withHandler(new StopOnDecreasing()).
142 withUmbra();
143 Assertions.assertEquals(60.0, e.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
144 Assertions.assertEquals(1.0e-3, e.getThreshold(), 1.0e-15);
145 Assertions.assertEquals(AbstractDetector.DEFAULT_MAX_ITER, e.getMaxIterationCount());
146 Assertions.assertEquals(0.0, e.getMargin(), 1.0e-15);
147 Assertions.assertTrue(e.getTotalEclipse());
148 propagator.addEventDetector(e);
149 final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000));
150 Assertions.assertEquals(2303.1835, finalState.getDate().durationFrom(iniDate), 1.0e-3);
151 }
152
153 @Test
154 void testPenumbra() {
155 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth).
156 withMaxCheck(60.0).
157 withThreshold(1.0e-3).
158 withPenumbra();
159 Assertions.assertFalse(e.getTotalEclipse());
160 propagator.addEventDetector(e);
161 final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000));
162 Assertions.assertEquals(4388.155852, finalState.getDate().durationFrom(iniDate), 2.0e-6);
163 }
164
165 @Test
166 void testWithMethods() {
167 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth).
168 withHandler(new StopOnDecreasing()).
169 withMaxCheck(120.0).
170 withThreshold(1.0e-4).
171 withMaxIter(12).
172 withMargin(0.001);
173 Assertions.assertEquals(120.0, e.getMaxCheckInterval().currentInterval(null, true), 1.0e-15);
174 Assertions.assertEquals(1.0e-4, e.getThreshold(), 1.0e-15);
175 Assertions.assertEquals(12, e.getMaxIterationCount());
176 propagator.addEventDetector(e);
177 final SpacecraftState finalState = propagator.propagate(iniDate.shiftedBy(6000));
178 Assertions.assertEquals(2304.188978, finalState.getDate().durationFrom(iniDate), 1.0e-4);
179
180 }
181
182 @Test
183 void testInsideOcculting() {
184 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth);
185 SpacecraftState s = new SpacecraftState(new CartesianOrbit(new TimeStampedPVCoordinates(AbsoluteDate.J2000_EPOCH,
186 new Vector3D(1e6, 2e6, 3e6),
187 new Vector3D(1000, 0, 0)),
188 FramesFactory.getGCRF(),
189 mu));
190 try {
191 e.g(s);
192 Assertions.fail("an exception should have been thrown");
193 } catch (OrekitException oe) {
194 Assertions.assertEquals(OrekitMessages.POINT_INSIDE_ELLIPSOID, oe.getSpecifier());
195 }
196 }
197
198 @Test
199 void testInsideOcculted() {
200 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth);
201 Vector3D p = sun.getPosition(AbsoluteDate.J2000_EPOCH, FramesFactory.getGCRF());
202 SpacecraftState s = new SpacecraftState(new CartesianOrbit(new TimeStampedPVCoordinates(AbsoluteDate.J2000_EPOCH,
203 p.add(Vector3D.PLUS_I),
204 Vector3D.PLUS_K),
205 FramesFactory.getGCRF(),
206 mu));
207 Assertions.assertEquals(FastMath.PI, e.g(s), 1.0e-15);
208 }
209
210 @Test
211 void testTooSmallMaxIterationCount() {
212 int n = 5;
213 EclipseDetector e = new EclipseDetector(sun, sunRadius, earth).
214 withHandler(new StopOnDecreasing()).
215 withMaxCheck(120.0).
216 withThreshold(1.0e-4).
217 withMaxIter(n);
218 propagator.addEventDetector(e);
219 try {
220 propagator.propagate(iniDate.shiftedBy(6000));
221 Assertions.fail("an exception should have been thrown");
222 } catch (OrekitException oe) {
223 Assertions.assertEquals(LocalizedODEFormats.FIND_ROOT,
224 ((MathRuntimeException) oe.getCause()).getSpecifier());
225 }
226 }
227
228 @BeforeEach
229 public void setUp() {
230 try {
231 Utils.setDataRoot("regular-data");
232 mu = 3.9860047e14;
233 final Vector3D position = new Vector3D(-6142438.668, 3492467.560, -25767.25680);
234 final Vector3D velocity = new Vector3D(505.8479685, 942.7809215, 7435.922231);
235 iniDate = new AbsoluteDate(1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
236 final Orbit orbit = new EquinoctialOrbit(new PVCoordinates(position, velocity),
237 FramesFactory.getGCRF(), iniDate, mu);
238 initialState = new SpacecraftState(orbit);
239 double[] absTolerance = {
240 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
241 };
242 double[] relTolerance = {
243 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
244 };
245 AdaptiveStepsizeIntegrator integrator =
246 new DormandPrince853Integrator(0.001, 1000, absTolerance, relTolerance);
247 integrator.setInitialStepSize(60);
248 propagator = new NumericalPropagator(integrator);
249 propagator.setInitialState(initialState);
250 sun = CelestialBodyFactory.getSun();
251 earth = new OneAxisEllipsoid(6400000., 0.0, FramesFactory.getITRF(IERSConventions.IERS_2010, true));
252 sunRadius = 696000000.;
253 } catch (OrekitException oe) {
254 Assertions.fail(oe.getLocalizedMessage());
255 }
256 }
257
258 @AfterEach
259 public void tearDown() {
260 iniDate = null;
261 initialState = null;
262 propagator = null;
263 }
264
265 }
266