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.lang.reflect.Array;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.Field;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.ode.events.Action;
25 import org.hipparchus.ode.nonstiff.AdaptiveStepsizeFieldIntegrator;
26 import org.hipparchus.ode.nonstiff.DormandPrince853FieldIntegrator;
27 import org.hipparchus.util.Decimal64Field;
28 import org.hipparchus.util.MathArrays;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.orekit.Utils;
33 import org.orekit.frames.FramesFactory;
34 import org.orekit.orbits.FieldEquinoctialOrbit;
35 import org.orekit.orbits.FieldOrbit;
36 import org.orekit.orbits.OrbitType;
37 import org.orekit.propagation.FieldSpacecraftState;
38 import org.orekit.propagation.events.handlers.FieldContinueOnEvent;
39 import org.orekit.propagation.events.handlers.FieldEventHandler;
40 import org.orekit.propagation.integration.FieldAdditionalDerivativesProvider;
41 import org.orekit.propagation.numerical.FieldNumericalPropagator;
42 import org.orekit.propagation.sampling.FieldOrekitStepInterpolator;
43 import org.orekit.time.AbsoluteDate;
44 import org.orekit.time.FieldAbsoluteDate;
45 import org.orekit.time.FieldTimeStamped;
46 import org.orekit.time.TimeScalesFactory;
47 import org.orekit.utils.FieldPVCoordinates;
48
49 public class FieldDateDetectorTest {
50
51 private int evtno = 0;
52 private double maxCheck;
53 private double threshold;
54 private double dt;
55 private double mu;
56 private AbsoluteDate nodeDate;
57
58 @Test
59 public void testSimpleTimer() {
60 doTestSimpleTimer(Decimal64Field.getInstance());
61 }
62 @Test
63 public void testEmbeddedTimer() {
64 doTestEmbeddedTimer(Decimal64Field.getInstance());
65 }
66 @Test
67 public void testAutoEmbeddedTimer() {
68 doTestAutoEmbeddedTimer(Decimal64Field.getInstance());
69 }
70 @Test(expected=IllegalArgumentException.class)
71 public void testExceptionTimer() {
72 doTestExceptionTimer(Decimal64Field.getInstance());
73 }
74 @Test
75 public void testGenericHandler() {
76 doTestGenericHandler(Decimal64Field.getInstance());
77 }
78
79 private <T extends CalculusFieldElement<T>> void doTestSimpleTimer(final Field<T> field) {
80 T zero = field.getZero();
81 final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add( 3492467.560), zero.add( -25767.25680));
82 final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231));
83 FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<>(field, 1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
84 FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(position, velocity),
85 FramesFactory.getEME2000(), iniDate, zero.add(mu));
86 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(iniOrbit);
87 double[] absTolerance = {
88 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
89 };
90 double[] relTolerance = {
91 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
92 };
93 AdaptiveStepsizeFieldIntegrator<T> integrator =
94 new DormandPrince853FieldIntegrator<>(field, 0.001, 1000, absTolerance, relTolerance);
95 integrator.setInitialStepSize(60);
96 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator);
97 propagator.addAdditionalDerivativesProvider(new FieldAdditionalDerivativesProvider<T>() {
98 public String getName() { return "dummy"; }
99 public int getDimension() { return 1; }
100 public T[] derivatives(FieldSpacecraftState<T> s) { return MathArrays.buildArray(field, 1); }
101 });
102 propagator.getMultiplexer().add(interpolator -> {
103 FieldSpacecraftState<T> prev = interpolator.getPreviousState();
104 FieldSpacecraftState<T> curr = interpolator.getCurrentState();
105 T dt = curr.getDate().durationFrom(prev.getDate());
106 FieldOrekitStepInterpolator<T> restricted =
107 interpolator.restrictStep(prev.shiftedBy(dt.multiply(+0.25)),
108 curr.shiftedBy(dt.multiply(-0.25)));
109 FieldSpacecraftState<T> restrictedPrev = restricted.getPreviousState();
110 FieldSpacecraftState<T> restrictedCurr = restricted.getCurrentState();
111 T restrictedDt = restrictedCurr.getDate().durationFrom(restrictedPrev.getDate());
112 Assert.assertEquals(dt.multiply(0.5).getReal(), restrictedDt.getReal(), 1.0e-10);
113 });
114 propagator.setOrbitType(OrbitType.EQUINOCTIAL);
115 propagator.setInitialState(initialState.addAdditionalState("dummy", MathArrays.buildArray(field, 1)));
116
117 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(zero.add(maxCheck), zero.add(threshold),
118 toArray(iniDate.shiftedBy(2.0*dt)));
119 Assert.assertEquals(2 * dt, dateDetector.getDate().durationFrom(iniDate).getReal(), 1.0e-10);
120 propagator.addEventDetector(dateDetector);
121 final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100.*dt));
122
123 Assert.assertEquals(2.0*dt, finalState.getDate().durationFrom(iniDate).getReal(), threshold);
124 }
125
126
127 private <T extends CalculusFieldElement<T>> void doTestEmbeddedTimer(Field<T> field) {
128 T zero = field.getZero();
129 final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add( 3492467.560), zero.add( -25767.25680));
130 final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231));
131 FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<>(field, 1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
132 FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(position, velocity),
133 FramesFactory.getEME2000(), iniDate, zero.add(mu));
134 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(iniOrbit);
135 double[] absTolerance = {
136 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
137 };
138 double[] relTolerance = {
139 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
140 };
141 AdaptiveStepsizeFieldIntegrator<T> integrator =
142 new DormandPrince853FieldIntegrator<>(field, 0.001, 1000, absTolerance, relTolerance);
143 integrator.setInitialStepSize(60);
144 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator);
145 propagator.setOrbitType(OrbitType.EQUINOCTIAL);
146 propagator.setInitialState(initialState);
147 @SuppressWarnings("unchecked")
148 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(zero.add(maxCheck), zero.add(threshold),
149 (FieldTimeStamped<T>[]) Array.newInstance(FieldTimeStamped.class, 0));
150 Assert.assertNull(dateDetector.getDate());
151 FieldEventDetector<T> nodeDetector = new FieldNodeDetector<>(iniOrbit, iniOrbit.getFrame()).
152 withHandler(new FieldContinueOnEvent<FieldNodeDetector<T>, T>() {
153 public Action eventOccurred(FieldSpacecraftState<T> s, FieldNodeDetector<T> nd, boolean increasing)
154 {
155 if (increasing) {
156 nodeDate = s.getDate().toAbsoluteDate();
157 dateDetector.addEventDate(s.getDate().shiftedBy(dt));
158 }
159 return Action.CONTINUE;
160 }
161 });
162
163 propagator.addEventDetector(nodeDetector);
164 propagator.addEventDetector(dateDetector);
165 final FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100.*dt));
166
167 Assert.assertEquals(dt, finalState.getDate().durationFrom(nodeDate).getReal(), threshold);
168 }
169
170
171 private <T extends CalculusFieldElement<T>> void doTestAutoEmbeddedTimer(Field<T> field) {
172 T zero = field.getZero();
173 final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add( 3492467.560), zero.add( -25767.25680));
174 final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231));
175 FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<>(field, 1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
176 FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(position, velocity),
177 FramesFactory.getEME2000(), iniDate, zero.add(mu));
178 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(iniOrbit);
179 double[] absTolerance = {
180 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
181 };
182 double[] relTolerance = {
183 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
184 };
185 AdaptiveStepsizeFieldIntegrator<T> integrator =
186 new DormandPrince853FieldIntegrator<>(field, 0.001, 1000, absTolerance, relTolerance);
187 integrator.setInitialStepSize(60);
188 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator);
189 propagator.setOrbitType(OrbitType.EQUINOCTIAL);
190 propagator.setInitialState(initialState);
191
192 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(zero.add(maxCheck), zero.add(threshold),
193 toArray(iniDate.shiftedBy(-dt))).
194 withHandler(new FieldContinueOnEvent<FieldDateDetector<T>, T >() {
195 public Action eventOccurred(FieldSpacecraftState<T> s, FieldDateDetector<T> dd, boolean increasing)
196 {
197 FieldAbsoluteDate<T> nextDate = s.getDate().shiftedBy(-dt);
198 dd.addEventDate(nextDate);
199 ++evtno;
200 return Action.CONTINUE;
201 }
202 });
203 propagator.addEventDetector(dateDetector);
204 propagator.propagate(iniDate.shiftedBy(-100.*dt));
205
206 Assert.assertEquals(100, evtno);
207 }
208
209 private <T extends CalculusFieldElement<T>> void doTestExceptionTimer(Field<T> field) {
210 T zero = field.getZero();
211 final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add( 3492467.560), zero.add( -25767.25680));
212 final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231));
213 FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<>(field, 1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
214 FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(position, velocity),
215 FramesFactory.getEME2000(), iniDate, zero.add(mu));
216 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(iniOrbit);
217 double[] absTolerance = {
218 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
219 };
220 double[] relTolerance = {
221 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
222 };
223 AdaptiveStepsizeFieldIntegrator<T> integrator =
224 new DormandPrince853FieldIntegrator<>(field, 0.001, 1000, absTolerance, relTolerance);
225 integrator.setInitialStepSize(60);
226 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator);
227 propagator.setOrbitType(OrbitType.EQUINOCTIAL);
228 propagator.setInitialState(initialState);
229
230 FieldDateDetector<T> dateDetector = new FieldDateDetector<>(zero.add(maxCheck), zero.add(threshold),
231 toArray(iniDate.shiftedBy(dt))).
232 withHandler(new FieldContinueOnEvent<FieldDateDetector<T>, T >() {
233 public Action eventOccurred(FieldSpacecraftState<T> s, FieldDateDetector<T> dd, boolean increasing)
234 {
235 double step = (evtno % 2 == 0) ? 2.*maxCheck : maxCheck/2.;
236 FieldAbsoluteDate<T> nextDate = s.getDate().shiftedBy(step);
237 dd.addEventDate(nextDate);
238 ++evtno;
239 return Action.CONTINUE;
240 }
241 });
242 propagator.addEventDetector(dateDetector);
243 propagator.propagate(iniDate.shiftedBy(100.*dt));
244 }
245
246
247
248
249
250 private <T extends CalculusFieldElement<T>> void doTestGenericHandler(Field<T> field) {
251 T zero = field.getZero();
252 final FieldVector3D<T> position = new FieldVector3D<>(zero.add(-6142438.668), zero.add( 3492467.560), zero.add( -25767.25680));
253 final FieldVector3D<T> velocity = new FieldVector3D<>(zero.add(505.8479685), zero.add(942.7809215), zero.add(7435.922231));
254 FieldAbsoluteDate<T> iniDate = new FieldAbsoluteDate<>(field, 1969, 7, 28, 4, 0, 0.0, TimeScalesFactory.getTT());
255 FieldOrbit<T> iniOrbit = new FieldEquinoctialOrbit<>(new FieldPVCoordinates<>(position, velocity),
256 FramesFactory.getEME2000(), iniDate, zero.add(mu));
257 FieldSpacecraftState<T> initialState = new FieldSpacecraftState<>(iniOrbit);
258 double[] absTolerance = {
259 0.001, 1.0e-9, 1.0e-9, 1.0e-6, 1.0e-6, 1.0e-6, 0.001
260 };
261 double[] relTolerance = {
262 1.0e-7, 1.0e-4, 1.0e-4, 1.0e-7, 1.0e-7, 1.0e-7, 1.0e-7
263 };
264 AdaptiveStepsizeFieldIntegrator<T> integrator =
265 new DormandPrince853FieldIntegrator<>(field, 0.001, 1000, absTolerance, relTolerance);
266 integrator.setInitialStepSize(60);
267 FieldNumericalPropagator<T> propagator = new FieldNumericalPropagator<>(field, integrator);
268 propagator.setOrbitType(OrbitType.EQUINOCTIAL);
269 propagator.setInitialState(initialState);
270
271
272 final FieldDateDetector<T> dateDetector = new FieldDateDetector<>(zero.add(maxCheck), zero.add(threshold),
273 toArray(iniDate.shiftedBy(dt)));
274
275 FieldEventHandler<FieldEventDetector<T>, T> handler = new FieldEventHandler<FieldEventDetector<T>, T>() {
276 @Override
277 public Action eventOccurred(FieldSpacecraftState<T> s,
278 FieldEventDetector<T> detector,
279 boolean increasing)
280 {
281 return Action.STOP;
282 }
283
284 @Override
285 public FieldSpacecraftState<T> resetState(FieldEventDetector<T> detector,
286 FieldSpacecraftState<T> oldState)
287 {
288 throw new RuntimeException("Should not be called");
289 }
290 };
291
292
293 final FieldDateDetector<T> dateDetector2;
294
295 dateDetector2 = dateDetector.withHandler(handler);
296
297 propagator.addEventDetector(dateDetector2);
298 FieldSpacecraftState<T> finalState = propagator.propagate(iniDate.shiftedBy(100 * dt));
299
300
301 Assert.assertEquals(dt, finalState.getDate().durationFrom(iniDate).getReal(), threshold);
302 }
303
304 private <T extends CalculusFieldElement<T>> FieldTimeStamped<T>[] toArray(final FieldAbsoluteDate<T> date) {
305 @SuppressWarnings("unchecked")
306 final FieldTimeStamped<T>[] array = (FieldTimeStamped<T>[]) Array.newInstance(FieldTimeStamped.class, 1);
307 array[0] = date;
308 return array;
309 }
310
311 @Before
312 public void setUp() {
313 Utils.setDataRoot("regular-data");
314 mu = 3.9860047e14;
315 dt = 60.;
316 maxCheck = 10.;
317 threshold = 10.e-7;
318 evtno = 0;
319 }
320
321 }